Implemented RestObject to enforce status/error keys.
This commit is contained in:
parent
c97ff36b73
commit
866a4c9932
3 changed files with 106 additions and 22 deletions
|
|
@ -52,10 +52,15 @@ namespace TShockAPI
|
|||
|
||||
public void Register(string path, RestCommandD callback)
|
||||
{
|
||||
Register(new RestCommand(path, callback));
|
||||
AddCommand(new RestCommand(path, callback));
|
||||
}
|
||||
|
||||
public virtual void Register(RestCommand com)
|
||||
public void Register(RestCommand com)
|
||||
{
|
||||
AddCommand(com);
|
||||
}
|
||||
|
||||
protected void AddCommand(RestCommand com)
|
||||
{
|
||||
commands.Add(com);
|
||||
}
|
||||
|
|
@ -65,6 +70,7 @@ namespace TShockAPI
|
|||
var obj = ProcessRequest(sender, e);
|
||||
if (obj == null)
|
||||
throw new NullReferenceException("obj");
|
||||
|
||||
var str = JsonConvert.SerializeObject(obj, Formatting.Indented);
|
||||
e.Response.Connection.Type = ConnectionType.Close;
|
||||
e.Response.Body.Write(Encoding.ASCII.GetBytes(str), 0, str.Length);
|
||||
|
|
@ -136,6 +142,64 @@ namespace TShockAPI
|
|||
|
||||
}
|
||||
|
||||
public class RestObject : Dictionary<string, string>
|
||||
{
|
||||
public string Status
|
||||
{
|
||||
get { return SafeGet("status"); }
|
||||
set { SafeSet("status", value); }
|
||||
}
|
||||
public string Error
|
||||
{
|
||||
get { return SafeGet("error"); }
|
||||
set { SafeSet("error", value); }
|
||||
}
|
||||
|
||||
public RestObject(string status)
|
||||
{
|
||||
Status = status;
|
||||
}
|
||||
public RestObject(string status, string error)
|
||||
: this(status)
|
||||
{
|
||||
Error = error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets value safely.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns>Returns null if key does not exist.</returns>
|
||||
public string SafeGet(string key)
|
||||
{
|
||||
string ret;
|
||||
if (TryGetValue(key, out ret))
|
||||
return ret;
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets/Adds value safely. If null it will remove.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SafeSet(string key, string value)
|
||||
{
|
||||
if (!ContainsKey(key))
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Add(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value != null)
|
||||
this[key] = value;
|
||||
else
|
||||
Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RestCommand
|
||||
{
|
||||
public string Name { get; protected set; }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,13 @@ using HttpServer;
|
|||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public delegate bool VerifyD(string username, string password);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="username">Username to verify</param>
|
||||
/// <param name="password">Password to verify</param>
|
||||
/// <returns>Returning a restobject with a null error means a successful verification.</returns>
|
||||
public delegate RestObject VerifyD(string username, string password);
|
||||
public class SecureRest : Rest
|
||||
{
|
||||
public Dictionary<string, object> Tokens { get; protected set; }
|
||||
|
|
@ -39,26 +45,17 @@ namespace TShockAPI
|
|||
var user = verbs["username"];
|
||||
var pass = verbs["password"];
|
||||
|
||||
if (Verify != null && !Verify(user, pass))
|
||||
return new Dictionary<string, string> { { "status", "401" } , { "error", "Invalid username/password combination provided. Please re-submit your query with a correct pair." } };
|
||||
RestObject obj = null;
|
||||
if (Verify != null)
|
||||
obj = Verify(user, pass);
|
||||
|
||||
var userAccount = TShock.Users.GetUserByName(user);
|
||||
if (userAccount == null)
|
||||
{
|
||||
return new Dictionary<string, string> { { "status", "401" }, { "error", "Invalid username/password combination provided. Please re-submit your query with a correct pair." } };
|
||||
}
|
||||
if (obj == null)
|
||||
obj = new RestObject("401", "Invalid username/password combination provided. Please re-submit your query with a correct pair.");
|
||||
|
||||
if (Tools.HashPassword(pass).ToUpper() != userAccount.Password.ToUpper())
|
||||
{
|
||||
return new Dictionary<string, string> { { "status", "401" }, { "error", "Invalid username/password combination provided. Please re-submit your query with a correct pair." } };
|
||||
}
|
||||
if (obj.Error != null)
|
||||
return obj;
|
||||
|
||||
if (!Tools.GetGroup(userAccount.Group).HasPermission("api") && userAccount.Group != "superadmin")
|
||||
{
|
||||
return new Dictionary<string, string> { { "status", "403" }, { "error", "Although your account was successfully found and identified, your account lacks the permission required to use the API. (api)" } };
|
||||
}
|
||||
|
||||
string hash = string.Empty;
|
||||
string hash;
|
||||
var rand = new Random();
|
||||
var randbytes = new byte[20];
|
||||
do
|
||||
|
|
@ -69,7 +66,8 @@ namespace TShockAPI
|
|||
|
||||
Tokens.Add(hash, user);
|
||||
|
||||
return new Dictionary<string, string> { { "status", "200" } , { "token", hash } }; ;
|
||||
obj.SafeSet("token", hash);
|
||||
return obj;
|
||||
}
|
||||
|
||||
protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ namespace TShockAPI
|
|||
public static bool OverridePort;
|
||||
public static PacketBufferer PacketBuffer;
|
||||
public static MaxMind.GeoIPCountry Geo;
|
||||
public static Rest RestApi;
|
||||
public static SecureRest RestApi;
|
||||
public static RestManager RestManager;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -177,6 +177,7 @@ namespace TShockAPI
|
|||
Itembans = new ItemManager(DB);
|
||||
RememberedPos = new RemeberedPosManager(DB);
|
||||
RestApi = new SecureRest(IPAddress.Any, 8080);
|
||||
RestApi.Verify += RestApi_Verify;
|
||||
RestManager = new RestManager(RestApi);
|
||||
RestManager.RegisterRestfulCommands();
|
||||
if (Config.EnableGeoIP)
|
||||
|
|
@ -216,6 +217,27 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
RestObject RestApi_Verify(string username, string password)
|
||||
{
|
||||
var userAccount = TShock.Users.GetUserByName(username);
|
||||
if (userAccount == null)
|
||||
{
|
||||
return new RestObject("401", "Invalid username/password combination provided. Please re-submit your query with a correct pair.");
|
||||
}
|
||||
|
||||
if (Tools.HashPassword(password).ToUpper() != userAccount.Password.ToUpper())
|
||||
{
|
||||
return new RestObject("401", "Invalid username/password combination provided. Please re-submit your query with a correct pair.");
|
||||
}
|
||||
|
||||
if (!Tools.GetGroup(userAccount.Group).HasPermission("api") && userAccount.Group != "superadmin")
|
||||
{
|
||||
return new RestObject("403", "Although your account was successfully found and identified, your account lacks the permission required to use the API. (api)");
|
||||
}
|
||||
|
||||
return new RestObject("200"); //Maybe return some user info too?
|
||||
}
|
||||
|
||||
public override void DeInitialize()
|
||||
{
|
||||
GameHooks.PostInitialize -= OnPostInit;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue