using InABox.API; using InABox.Clients; using InABox.Core; using InABox.Database; using InABox.Server; namespace InABox.Rpc; public class RpcValidateHandler : RpcCommandHandler { protected override RpcValidateResult Execute(IRpcSession session, RpcValidateParameters? parameters) { if (parameters == null) return new RpcValidateResult() { Status = ValidationStatus.INVALID }; session.Platform = parameters.Platform; session.Version = parameters.Version; User? user = null; bool reLogin = false; if (parameters.SessionID != Guid.Empty) { user = CredentialsCache.Validate(parameters.SessionID); if (user != null) { Logger.Send(LogType.Information, "", $"{parameters.SessionID} re-logged in!"); CredentialsCache.RefreshSessionExpiry(parameters.SessionID); reLogin = true; } else { Logger.Send(LogType.Information, "", $"{parameters.SessionID} re-logging failed!"); } } if (user is null) { if (parameters.UsePIN) { Logger.Send(LogType.Information, "", $"Login request for PIN {parameters.PIN}"); user = CredentialsCache.ValidateUser(parameters.PIN); } else { var userID = parameters.UserID; var password = parameters.Password; user = CredentialsCache.ValidateUser(userID, password); if (user?.ID != CoreUtils.FullGuid) { Logger.Send(LogType.Information, userID, $"Login request for {userID}"); } } } if (user == null) { Logger.Send(LogType.Information, "", $"Login failed!"); return new RpcValidateResult() { Status = ValidationStatus.INVALID }; } Guid? sessionID = null; var result = new RpcValidateResult() { Status = ValidationStatus.VALID, UserGuid = user.ID, UserID = user.UserID, SecurityID = user.SecurityGroup.ID, PasswordExpiration = UserStore.PasswordExpirationTime > TimeSpan.Zero ? user.PasswordExpiration : DateTime.MinValue }; if (user.ID != CoreUtils.FullGuid) { if (UserStore.PasswordExpirationTime != TimeSpan.Zero && user.PasswordExpiration > DateTime.MinValue && user.PasswordExpiration < DateTime.Now && !parameters.UsePIN) { Logger.Send(LogType.Information, user.UserID, $"Password for ({user.UserID}) has expired!"); result.Status = ValidationStatus.PASSWORD_EXPIRED; } else if (reLogin) { Logger.Send(LogType.Information, user.UserID, $"Login ({user.UserID}) success!"); } else if (user.Use2FA) { Logger.Send(LogType.Information, user.UserID, $"Login ({user.UserID}) requires 2FA. Sending code..."); sessionID = CredentialsCache.SendCode(user.ID, out var recipient) ?? throw new Exception("Code failed to send!"); result.Status = ValidationStatus.REQUIRE_2FA; result.Recipient2FA = recipient; } } result.SessionID = sessionID ?? (reLogin ? parameters.SessionID : user.ID == CoreUtils.FullGuid ? CredentialsCache.NewSession(user, true, DateTime.MaxValue) : CredentialsCache.NewSession(user, true)); // Store the CredentialsCache ID against the ServerSession session.ID = result.SessionID; session.UserID = user?.UserID ?? ""; Logger.Send(LogType.Information, user?.UserID ?? "", $"Validation Status is {result.Status}"); return result; } public RpcValidateHandler(IRpcServer sender) : base(sender) { } }