using System.Collections.Generic; using System.Linq; using Dapper; using FSO.Server.Common; using FSO.Server.Database.DA.Utils; namespace FSO.Server.Database.DA.Users { public class SqlUsers : AbstractSqlDA, IUsers { public SqlUsers(ISqlContext context) : base(context) { } public User GetByUsername(string username) { return Context.Connection.Query("SELECT * FROM fso_users WHERE username = @username", new { username = username }).FirstOrDefault(); } public UserAuthenticate GetAuthenticationSettings(uint userId) { return Context.Connection.Query("SELECT * FROM fso_user_authenticate WHERE user_id = @user_id", new { user_id = userId }).FirstOrDefault(); } public User GetById(uint id) { return Context.Connection.Query("SELECT * FROM fso_users WHERE user_id = @user_id", new { user_id = id }).FirstOrDefault(); } public User GetByEmail(string email) { return Context.Connection.Query("SELECT * FROM fso_users WHERE email = @email", new { email = email }).FirstOrDefault(); } public List GetByRegisterIP(string ip) { return Context.Connection.Query("SELECT * FROM fso_users WHERE register_ip = @ip ORDER BY register_date DESC", new { ip = ip }).AsList(); } public void UpdateConnectIP(uint id, string ip) { Context.Connection.Execute("UPDATE fso_users SET last_ip = @ip WHERE user_id = @user_id", new { user_id = id, ip = ip }); } public void UpdateClientID(uint id, string uid) { Context.Connection.Execute("UPDATE fso_users SET client_id = @id WHERE user_id = @user_id", new { user_id = id, id = uid }); } public void UpdateBanned(uint id, bool banned) { Context.Connection.Execute("UPDATE fso_users SET is_banned = @ban WHERE user_id = @user_id", new { user_id = id, ban = banned }); } public void UpdateLastLogin(uint id, uint last_login) { Context.Connection.Execute("UPDATE fso_users SET last_login = @last_login WHERE user_id = @user_id", new { user_id = id, last_login = last_login }); } public PagedList All(int offset = 1, int limit = 20, string orderBy = "register_date") { var connection = Context.Connection; var total = connection.Query("SELECT COUNT(*) FROM fso_users").FirstOrDefault(); var results = connection.Query("SELECT * FROM fso_users ORDER BY @order LIMIT @offset, @limit", new { order = orderBy, offset = offset, limit = limit }); return new PagedList(results, offset, total); } public uint Create(User user) { return Context.Connection.Query( "insert into fso_users set username = @username, email = @email, register_date = @register_date, register_ip = @register_ip, last_ip = @last_ip, " + "is_admin = @is_admin, is_moderator = @is_moderator, is_banned = @is_banned; select LAST_INSERT_ID();", user ).First(); } public void CreateAuth(UserAuthenticate auth) { Context.Connection.Execute( "insert into fso_user_authenticate set user_id = @user_id, scheme_class = @scheme_class, data = @data;", auth ); } public void UpdateAuth(UserAuthenticate auth) { Context.Connection.Execute( "UPDATE fso_user_authenticate SET scheme_class = @scheme_class, data = @data WHERE user_id = @user_id;", new { auth.scheme_class, auth.data, auth.user_id } ); } public DbAuthAttempt GetRemainingAuth(uint user_id, string ip) { var result = Context.Connection.Query( "SELECT * FROM fso_auth_attempts WHERE user_id = @user_id AND ip = @ip AND invalidated = 0 ORDER BY expire_time DESC", new { user_id, ip } ).FirstOrDefault(); if (result != null && result.active && result.expire_time < Epoch.Now) return null; else return result; } public int FailedConsecutive(uint user_id, string ip) { return Context.Connection.Query( "SELECT COUNT(*) FROM fso_auth_attempts WHERE user_id = @user_id AND ip = @ip AND active = 1 AND invalidated = 0", new { user_id, ip } ).First(); } public int FailedAuth(uint attempt_id, uint delay, int failLimit) { Context.Connection.Execute( "UPDATE fso_auth_attempts SET count = count + 1, expire_time = @time WHERE attempt_id = @attempt_id", new { attempt_id, time = Epoch.Now + delay } ); var result = Context.Connection.Query( "SELECT * FROM fso_auth_attempts WHERE attempt_id = @attempt_id", new { attempt_id }).FirstOrDefault(); if (result != null) { if (result.count >= failLimit) { Context.Connection.Execute( "UPDATE fso_auth_attempts SET active = 1 WHERE attempt_id = @attempt_id", new { attempt_id }); return 0; } else { return failLimit - result.count; } } else { return failLimit; } } public void NewFailedAuth(uint user_id, string ip, uint delay) { //create a new entry Context.Connection.Execute( "INSERT INTO fso_auth_attempts (ip, user_id, expire_time, count) VALUES (@ip, @user_id, @time, 1)", new { user_id, ip, time = Epoch.Now + delay } ); } public void SuccessfulAuth(uint user_id, string ip) { Context.Connection.Execute( "UPDATE fso_auth_attempts SET invalidated = 1 WHERE user_id = @user_id AND ip = @ip", new { user_id, ip } ); } } }