Merge pull request #530 from Olink/general-devel

Added LastAccessed time field and KnownIPs field to the user database. Note: extent of testing was starting TShock again, so may have broken something important (e.g. stat tracking)
This commit is contained in:
Lucas Nicodemus 2013-09-21 18:04:39 -07:00
commit 222042cc4d
8 changed files with 67 additions and 26 deletions

View file

@ -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 <username>:<password> superadmin");
args.Player.SendInfoMessage("You are now superadmin, please do the following to finish your install:");
args.Player.SendInfoMessage("/user add <username> <password> superadmin");
args.Player.SendInfoMessage("Creates: <username> with the password <password> as part of the superadmin group.");
args.Player.SendInfoMessage("Please use /login <username> <password> to login from now on.");
args.Player.SendInfoMessage("If you understand, please /login <username> <password> 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 <username>:<password> superadmin");
args.Player.SendInfoMessage("Creates: <username> with the password <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 <username> <password> to login from now on.");
args.Player.SendInfoMessage("If you understand, please /login <username> <password> 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");

View file

@ -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)

View file

@ -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
}
}
/// <summary>
/// Sets the Hashed Password for a given username
/// </summary>
@ -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<string>("Usergroup");
user.Password = result.Get<string>("Password");
user.Name = result.Get<string>("Username");
user.LastAccessed = result.Get<string>("LastAccessed");
user.KnownIps = result.Get<string>("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 = "";
}
}

View file

@ -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)

View file

@ -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);

View file

@ -408,7 +408,7 @@ namespace TShockAPI
TilesDestroyed = new Dictionary<Vector2, TileData>();
TilesCreated = new Dictionary<Vector2, TileData>();
Index = index;
Group = new Group(TShock.Config.DefaultGuestGroupName);
Group = Group.DefaultGroup;
IceTiles = new List<Point>();
AwaitingResponse = new Dictionary<string, Action<object>>();
}
@ -419,7 +419,7 @@ namespace TShockAPI
TilesCreated = new Dictionary<Vector2, TileData>();
Index = -1;
FakePlayer = new Player {name = playerName, whoAmi = -1};
Group = new Group(TShock.Config.DefaultGuestGroupName);
Group = Group.DefaultGroup;
AwaitingResponse = new Dictionary<string, Action<object>>();
}

View file

@ -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<String> KnownIps = new List<string>();
if (!string.IsNullOrWhiteSpace(u.KnownIps))
{
KnownIps = JsonConvert.DeserializeObject<List<String>>(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;

View file

@ -741,7 +741,7 @@ namespace TShockAPI
return TShock.Groups.groups[i];
}
}
return new Group(TShock.Config.DefaultGuestGroupName);
return Group.DefaultGroup;
}
/// <summary>