From 7c0bcceb9f4feb2884a0b98ff3a1fadd0664383b Mon Sep 17 00:00:00 2001 From: Zack Piispanen Date: Sat, 21 Sep 2013 20:57:14 -0400 Subject: [PATCH] Added LastAccessed time field and KnownIPs field to the user database. This resulted in some changes everywhere, such as new logic with default groups. Apparently, somehow, the ip based stuff worked even though no ips were set to properly grab the user group. The wrong group was being assigned to new users resulting in a player with 0 permissions. This is now fixed. --- TShockAPI/Commands.cs | 18 +++--------------- TShockAPI/DB/GroupManager.cs | 6 ++++-- TShockAPI/DB/UserManager.cs | 28 +++++++++++++++++++++++++--- TShockAPI/Group.cs | 1 + TShockAPI/Rest/RestManager.cs | 2 +- TShockAPI/TSPlayer.cs | 4 ++-- TShockAPI/TShock.cs | 32 ++++++++++++++++++++++++++++++-- TShockAPI/Utils.cs | 2 +- 8 files changed, 67 insertions(+), 26 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 8577fc89..f43aae1f 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -3210,10 +3210,9 @@ namespace TShockAPI { try { - TShock.Users.AddUser(new User("", "", "superadmin")); args.Player.Group = TShock.Utils.GetGroup("superadmin"); - args.Player.SendInfoMessage("This IP address is now superadmin. Please perform the following command:"); - args.Player.SendInfoMessage("/user add : superadmin"); + args.Player.SendInfoMessage("You are now superadmin, please do the following to finish your install:"); + args.Player.SendInfoMessage("/user add superadmin"); args.Player.SendInfoMessage("Creates: with the password as part of the superadmin group."); args.Player.SendInfoMessage("Please use /login to login from now on."); args.Player.SendInfoMessage("If you understand, please /login now, and type /auth-verify."); @@ -3229,9 +3228,7 @@ namespace TShockAPI if (args.Player.Group.Name == "superadmin") { args.Player.SendInfoMessage("Please disable the auth system! If you need help, consult the forums. http://tshock.co/"); - args.Player.SendInfoMessage("This IP address is now superadmin. Please perform the following command:"); - args.Player.SendInfoMessage("/user add : superadmin"); - args.Player.SendInfoMessage("Creates: with the password as part of the superadmin group."); + args.Player.SendInfoMessage("This account is superadmin, please do the following to finish your install:"); args.Player.SendInfoMessage("Please use /login to login from now on."); args.Player.SendInfoMessage("If you understand, please /login now, and type /auth-verify."); return; @@ -3250,15 +3247,6 @@ namespace TShockAPI return; } - if (!args.Player.IsLoggedIn) - { - args.Player.SendWarningMessage("You must be logged in to disable the auth system."); - args.Player.SendWarningMessage("This is a security measure designed to prevent insecure administration setups."); - args.Player.SendWarningMessage("Please re-run /auth and read the instructions!"); - args.Player.SendWarningMessage("If you're still confused, consult the forums: http://tshock.co/"); - return; - } - args.Player.SendSuccessMessage("Your new account has been verified, and the /auth system has been turned off."); args.Player.SendSuccessMessage("You can always use the /user command to manage players. Don't just delete the auth.lck."); args.Player.SendSuccessMessage("Thank you for using TShock! http://tshock.co/ & http://github.com/TShock/TShock"); diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index ab9fe61d..bd91f09b 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -53,13 +53,15 @@ namespace TShockAPI.DB LoadPermisions(); // Add default groups if they don't exist - AddDefaultGroup("guest", "", "canbuild,canregister,canlogin,canpartychat,cantalkinthird"); - AddDefaultGroup("default", "guest", "warp,canchangepassword"); + AddDefaultGroup(TShock.Config.DefaultGuestGroupName, "", "canbuild,canregister,canlogin,canpartychat,cantalkinthird"); + AddDefaultGroup("default", TShock.Config.DefaultGuestGroupName, "warp,canchangepassword"); AddDefaultGroup("newadmin", "default", "kick,editspawn,reservedslot"); AddDefaultGroup("admin", "newadmin", "ban,unban,whitelist,causeevents,spawnboss,spawnmob,managewarp,time,tp,pvpfun,kill,logs,immunetokick,tphere"); AddDefaultGroup("trustedadmin", "admin", "maintenance,cfg,butcher,item,heal,immunetoban,usebanneditem,manageusers"); AddDefaultGroup("vip", "default", "reservedslot"); + + Group.DefaultGroup = GetGroupByName(TShock.Config.DefaultGuestGroupName); } private void AddDefaultGroup(string name, string parent, string permissions) diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index 515bad6c..c8af324c 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -37,7 +37,9 @@ namespace TShockAPI.DB new SqlColumn("ID", MySqlDbType.Int32) {Primary = true, AutoIncrement = true}, new SqlColumn("Username", MySqlDbType.VarChar, 32) {Unique = true}, new SqlColumn("Password", MySqlDbType.VarChar, 128), - new SqlColumn("Usergroup", MySqlDbType.Text) + new SqlColumn("Usergroup", MySqlDbType.Text), + new SqlColumn("LastAccessed", MySqlDbType.Text), + new SqlColumn("KnownIPs", MySqlDbType.Text) ); var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite @@ -92,7 +94,6 @@ namespace TShockAPI.DB } } - /// /// Sets the Hashed Password for a given username /// @@ -141,6 +142,19 @@ namespace TShockAPI.DB } } + public void UpdateLogin(User user) + { + try + { + if (database.Query("UPDATE Users SET LastAccessed = @0, KnownIps = @1 WHERE Username = @2;", DateTime.Now.ToString("G"), user.KnownIps, user.Name) == 0) + throw new UserNotExistException(user.Name); + } + catch (Exception ex) + { + throw new UserManagerException("UpdateLogin SQL returned an error", ex); + } + } + public int GetUserID(string username) { try @@ -254,6 +268,8 @@ namespace TShockAPI.DB user.Group = result.Get("Usergroup"); user.Password = result.Get("Password"); user.Name = result.Get("Username"); + user.LastAccessed = result.Get("LastAccessed"); + user.KnownIps = result.Get("KnownIps"); return user; } } @@ -264,12 +280,16 @@ namespace TShockAPI.DB public string Name { get; set; } public string Password { get; set; } public string Group { get; set; } + public string LastAccessed { get; set; } + public string KnownIps { get; set; } - public User(string name, string pass, string group) + public User(string name, string pass, string group, string last, string known) { Name = name; Password = pass; Group = group; + LastAccessed = last; + KnownIps = known; } public User() @@ -277,6 +297,8 @@ namespace TShockAPI.DB Name = ""; Password = ""; Group = ""; + LastAccessed = ""; + KnownIps = ""; } } diff --git a/TShockAPI/Group.cs b/TShockAPI/Group.cs index 50995b51..08a2aa9b 100644 --- a/TShockAPI/Group.cs +++ b/TShockAPI/Group.cs @@ -152,6 +152,7 @@ namespace TShockAPI public byte G = 255; public byte B = 255; + public static Group DefaultGroup = null; #if COMPAT_SIGS [Obsolete("This constructor is for signature compatibility for external code only")] public Group(string groupname, Group parentgroup, string chatcolor) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index 67aca06a..1c170a88 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -307,7 +307,7 @@ namespace TShockAPI return RestMissingParam("password"); // NOTE: ip can be blank - User user = new User(username, password, group); + User user = new User(username, password, group, "", ""); try { TShock.Users.AddUser(user); diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 824758dc..3dcfb24f 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -408,7 +408,7 @@ namespace TShockAPI TilesDestroyed = new Dictionary(); TilesCreated = new Dictionary(); Index = index; - Group = new Group(TShock.Config.DefaultGuestGroupName); + Group = Group.DefaultGroup; IceTiles = new List(); AwaitingResponse = new Dictionary>(); } @@ -419,7 +419,7 @@ namespace TShockAPI TilesCreated = new Dictionary(); Index = -1; FakePlayer = new Player {name = playerName, whoAmi = -1}; - Group = new Group(TShock.Config.DefaultGuestGroupName); + Group = Group.DefaultGroup; AwaitingResponse = new Dictionary>(); } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 96643f4d..1b15f63e 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -24,12 +24,14 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; +using System.Linq; using System.Net; using System.Reflection; using Hooks; using MaxMind; using Mono.Data.Sqlite; using MySql.Data.MySqlClient; +using Newtonsoft.Json; using Rests; using Terraria; using TShockAPI.DB; @@ -248,6 +250,7 @@ namespace TShockAPI WorldHooks.SaveWorld += SaveManager.Instance.OnSaveWorld; WorldHooks.ChristmasCheck += OnXmasCheck; NetHooks.NameCollision += NetHooks_NameCollision; + TShockAPI.Hooks.PlayerHooks.PlayerPostLogin += OnPlayerLogin; GetDataHandlers.InitGetDataHandler(); Commands.InitCommands(); @@ -322,6 +325,7 @@ namespace TShockAPI WorldHooks.SaveWorld -= SaveManager.Instance.OnSaveWorld; WorldHooks.ChristmasCheck -= OnXmasCheck; NetHooks.NameCollision -= NetHooks_NameCollision; + TShockAPI.Hooks.PlayerHooks.PlayerPostLogin -= OnPlayerLogin; if (File.Exists(Path.Combine(SavePath, "tshock.pid"))) { @@ -334,7 +338,31 @@ namespace TShockAPI base.Dispose(disposing); } - void NetHooks_NameCollision(int who, string name, HandledEventArgs e) + private void OnPlayerLogin(Hooks.PlayerPostLoginEventArgs args) + { + User u = Users.GetUserByName(args.Player.UserAccountName); + List KnownIps = new List(); + if (!string.IsNullOrWhiteSpace(u.KnownIps)) + { + KnownIps = JsonConvert.DeserializeObject>(u.KnownIps); + } + + bool found = KnownIps.Any(s => s.Equals(args.Player.IP)); + if (!found) + { + if (KnownIps.Count == 100) + { + KnownIps.RemoveAt(0); + } + + KnownIps.Add(args.Player.IP); + } + + u.KnownIps = JsonConvert.SerializeObject(KnownIps, Formatting.Indented); + Users.UpdateLogin(u); + } + + private void NetHooks_NameCollision(int who, string name, HandledEventArgs e) { string ip = TShock.Utils.GetRealIP(Netplay.serverSock[who].tcpClient.Client.RemoteEndPoint.ToString()); foreach (TSPlayer ply in TShock.Players) @@ -365,7 +393,7 @@ namespace TShockAPI return; } - void OnXmasCheck(ChristmasCheckEventArgs args) + private void OnXmasCheck(ChristmasCheckEventArgs args) { if (args.Handled) return; diff --git a/TShockAPI/Utils.cs b/TShockAPI/Utils.cs index 4178130c..4d6cc106 100644 --- a/TShockAPI/Utils.cs +++ b/TShockAPI/Utils.cs @@ -741,7 +741,7 @@ namespace TShockAPI return TShock.Groups.groups[i]; } } - return new Group(TShock.Config.DefaultGuestGroupName); + return Group.DefaultGroup; } ///