diff --git a/src/ZirconiumPlugins/InBandLogin/InBandLogin.csproj b/src/ZirconiumPlugins/InBandLogin/InBandLogin.csproj new file mode 100644 index 0000000..2cf1f24 --- /dev/null +++ b/src/ZirconiumPlugins/InBandLogin/InBandLogin.csproj @@ -0,0 +1,14 @@ + + + + netcoreapp3.1 + + + + + runtime + + + + + diff --git a/src/ZirconiumPlugins/InBandLogin/Plugin.cs b/src/ZirconiumPlugins/InBandLogin/Plugin.cs new file mode 100644 index 0000000..08e053e --- /dev/null +++ b/src/ZirconiumPlugins/InBandLogin/Plugin.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Zirconium.Core.Logging; +using Zirconium.Core.Models; +using Zirconium.Core.Plugins.Interfaces; +using Zirconium.Utils; + +namespace InBandLogin +{ + public class InBandLoginPlugin : IPluginAPI + { + class LoginRequestPayload + { + [JsonProperty("username")] + public string Username { get; set; } + + [JsonProperty("password")] + public string Password { get; set; } + } + + class LoginResponsePayload + { + [JsonProperty("authToken")] + public string AuthToken { get; set; } + + [JsonProperty("deviceID")] + public string DeviceID { get; set; } + } + + class RegisterRequestPayload + { + [JsonProperty("username")] + public string Username { get; set; } + + [JsonProperty("password")] + public string Password { get; set; } + + [JsonProperty("loginOnSuccess")] + public bool LoginOnSuccess { get; set; } + } + + class RegisterResponsePayload + { + [JsonProperty("userID")] + public string UserID { get; set; } + + [JsonProperty("authToken")] + public string AuthToken { get; set; } + + [JsonProperty("deviceID")] + public string DeviceID { get; set; } + } + + private IPluginHostAPI pluginHostAPI; + + public string GetPluginUniqueName() + { + return "InBandLogin"; + } + + public void Initialize(IPluginHostAPI hostModuleAPI) + { + this.pluginHostAPI = hostModuleAPI; + pluginHostAPI.Hook(new LoginC2SHandler(pluginHostAPI)); + pluginHostAPI.Hook(new RegisterC2SHandler(pluginHostAPI)); + } + + class LoginC2SHandler : IC2SMessageHandler + { + private const string errID = "invalid_creds"; + private IPluginHostAPI _phostAPI; + public LoginC2SHandler(IPluginHostAPI pluginHostAPI) + { + this._phostAPI = pluginHostAPI; + } + + public string GetHandlerUniqueID() + { + return "LoginC2SHandler"; + } + + public string GetHandlingMessageType() + { + return "profile:login"; + } + + public void HandleMessage(Session session, BaseMessage message) + { + var pObj = message.Payload.ToObject(); + var authProvider = _phostAPI.GetAuthProvider(); + if (authProvider.TestPassword(pObj.Username, pObj.Password)) + { + BaseMessage reply = new BaseMessage(message, true); + var p = new LoginResponsePayload(); + string deviceID = "ABCDEF"; // TODO fix device id system + p.AuthToken = _phostAPI.GenerateAuthToken($"@{pObj.Username}@{_phostAPI.GetServerID()}", deviceID); + p.DeviceID = deviceID; + reply.Payload = p.ToDictionary(); + reply.Ok = true; + var msg = JsonConvert.SerializeObject(reply); + session.ConnectionHandler.SendMessage(msg); + } + else + { + var reply = OtherUtils.GenerateProtocolError( + message, + errID, + "Username/password isn't valid", + new Dictionary() + ).ToDictionary(); + var msg = JsonConvert.SerializeObject(reply); + session.ConnectionHandler.SendMessage(msg); + } + } + + public bool IsAuthorizationRequired() + { + return false; + } + } + + class RegisterC2SHandler : IC2SMessageHandler + { + + private IPluginHostAPI _pluginHostAPI; + + public RegisterC2SHandler(IPluginHostAPI pluginHostAPI) + { + this._pluginHostAPI = pluginHostAPI; + } + + + public string GetHandlerUniqueID() + { + return "RegisterC2SHandler"; + } + + public string GetHandlingMessageType() + { + return "profile:register"; + } + + public void HandleMessage(Session session, BaseMessage message) + { + var pObj = message.Payload.ToObject(); + var authProvider = _pluginHostAPI.GetAuthProvider(); + try + { + authProvider.CreateUser(pObj.Username, pObj.Password); + } + catch (Exception e) + { + BaseMessage errorReply; + if (e.Message.Contains("E11000")) + { + errorReply = OtherUtils.GenerateProtocolError( + message, + "id_exists", + "Username already taken", + new Dictionary() + ); + } + else + { + errorReply = OtherUtils.GenerateProtocolError( + message, + "other", + e.ToString(), + new Dictionary() + ); + } + var errorMsg = JsonConvert.SerializeObject(errorReply); + session.ConnectionHandler.SendMessage(errorMsg); + return; + } + BaseMessage reply = new BaseMessage(message, true); + var p = new RegisterResponsePayload(); + p.UserID = $"@{pObj.Username}:{_pluginHostAPI.GetServerID()}"; + if (pObj.LoginOnSuccess) + { + string deviceID = "ABCDEF"; // TODO fix device id system + p.AuthToken = _pluginHostAPI.GenerateAuthToken($"@{pObj.Username}@{_pluginHostAPI.GetServerID()}", deviceID); + p.DeviceID = deviceID; + } + reply.Payload = p.ToDictionary(); + reply.Ok = true; + var msg = JsonConvert.SerializeObject(reply); + session.ConnectionHandler.SendMessage(msg); + } + + public bool IsAuthorizationRequired() + { + return false; + } + } + } +}