using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using InABox.Core; using InABox.Core.Notifications; using InABox.Mail; namespace InABox.Clients { public class BypassSession : IDisposable { public BypassSession() { ClientFactory.SetBypass(); } public void Dispose() { ClientFactory.UnsetBypass(); } } public static class ClientFactory { private static Type? _type; private static object[] _params; private static IEnumerable? SupportedTypes; private static Type ClientType => _type ?? throw new Exception("Client type has not been set!"); public static Dictionary MailerTypes = new Dictionary(); //public static Type _mailer; //private static User CurrentUser = null; public static Guid UserGuid { get; private set; } public static string UserID { get; private set; } public static Guid UserSecurityID { get; private set; } public static Guid SessionID { get; set; } public static string Platform { get; private set; } public static string Version { get; private set; } public static string? Recipient2FA { get; private set; } public static DateTime PasswordExpiration { get; private set; } public static int PINLength { get; } = 4; public static Notifications Notifications { get; set; } = new Notifications(); public delegate void RequestErrorHandler(RequestException e); public static event RequestErrorHandler? OnRequestError; public static void RaiseRequestError(RequestException e) { OnRequestError?.Invoke(e); } private static bool IsSupported(Type t) { return true; //if (SupportedTypes == null) //{ // try // { // SupportedTypes = new Client().SupportedTypes(); // } // catch (Exception e) // { // SupportedTypes = new String[] { }; // } //} //return SupportedTypes.Contains(t.EntityName().Replace(".", "_")); } public static bool IsSupported() where T : Entity, new() { return IsSupported(typeof(T)); } public static bool IsSupported() where T1 : Entity, new() where T2 : Entity, new() { return IsSupported() && IsSupported(); } public static bool IsSupported() where T1 : Entity, new() where T2 : Entity, new() where T3 : Entity, new() { return IsSupported() && IsSupported() && IsSupported(); } public static bool IsSupported() where T1 : Entity, new() where T2 : Entity, new() where T3 : Entity, new() where T4 : Entity, new() { return IsSupported() && IsSupported() && IsSupported() && IsSupported(); } public static bool IsSupported() where T1 : Entity, new() where T2 : Entity, new() where T3 : Entity, new() where T4 : Entity, new() where T5 : Entity, new() { return IsSupported() && IsSupported() && IsSupported() && IsSupported() && IsSupported(); } public static bool IsSupported(params Type[] types) { return true; //if (SupportedTypes == null) // SupportedTypes = new Client().SupportedTypes(); //bool result = true; //foreach (var type in types) // result = result && SupportedTypes.Contains(type.EntityName().Replace(".", "_")); //return result; } public static void SetClientType(Type type, string platform, string version, params object[] parameters) { _type = type; Platform = platform == null ? Platform : platform; Version = version == null ? Version : version; _params = parameters == null ? _params : parameters; SupportedTypes = parameters == null ? SupportedTypes : null; } public static void ClearClientType() { _type = null; } public static Type? GetClientType() { return _type; } // override the need to provide credentials when configuring the database public static void SetBypass() { UserGuid = CoreUtils.FullGuid; UserID = ""; Request.BeforeRequest = request => { if(request is ValidateRequest validate) { var ticks = DateTime.Now.ToUniversalTime().Ticks.ToString(); validate.UserID = Encryption.Encrypt(ticks, "wCq9rryEJEuHIifYrxRjxg", true); validate.Password = Encryption.Encrypt(ticks, "7mhvLnqMwkCAzN+zNGlyyg", true); } }; var result = Validate("", ""); if (result != ValidationResult.VALID) { Logger.Send(LogType.Error, "", "Bypass login failed"); } //Load up the data model, including Custom Properties //var props = CreateClient().Load(); //DatabaseSchema.Load(props); } public static void UnsetBypass() { Request.BeforeRequest = null; UserGuid = Guid.Empty; } public static ValidationResult Validate(string userid, string password, Guid session = default) { InvalidateUser(); var result = Client.Validate(userid, password, session); if (result.Status != ValidationResult.INVALID) { UserGuid = result.UserGuid; UserID = result.UserID; UserSecurityID = result.SecurityID; Recipient2FA = result.Recipient2FA; SessionID = result.SessionID; PasswordExpiration = result.PasswordExpiration; if(result.Status == ValidationResult.VALID) { OnValidLogin(); } return result.Status; } return result.Status; } public static ValidationResult Validate(string pin, Guid session = default) { InvalidateUser(); var result = Client.Validate(pin, session); if (result.Status != ValidationResult.INVALID) { UserGuid = result.UserGuid; UserID = result.UserID; UserSecurityID = result.SecurityID; Recipient2FA = result.Recipient2FA; SessionID = result.SessionID; PasswordExpiration = result.PasswordExpiration; if (result.Status == ValidationResult.VALID) { OnValidLogin(); } return result.Status; } return result.Status; } public static ValidationResult Validate(Guid session) { InvalidateUser(); var result = Client.Validate(session); if (result.Status != ValidationResult.INVALID) { UserGuid = result.UserGuid; UserID = result.UserID; UserSecurityID = result.SecurityID; Recipient2FA = result.Recipient2FA; SessionID = result.SessionID; PasswordExpiration = result.PasswordExpiration; if (result.Status == ValidationResult.VALID) { OnValidLogin(); } return result.Status; } return result.Status; } public static bool ValidateUser(string userid, string password) { InvalidateUser(); var result = Client.Validate(userid, password); if (result.Status == ValidationResult.VALID) { UserGuid = result.UserGuid; UserID = result.UserID; UserSecurityID = result.SecurityID; Recipient2FA = result.Recipient2FA; SessionID = result.SessionID; PasswordExpiration = result.PasswordExpiration; if (result.Status == ValidationResult.VALID) { OnValidLogin(); } return true; } return false; } public static bool ValidatePIN(string pin) { InvalidateUser(); var result = Client.Validate(pin); if (result.Status == ValidationResult.VALID) { UserGuid = result.UserGuid; UserID = result.UserID; UserSecurityID = result.SecurityID; Recipient2FA = result.Recipient2FA; SessionID = result.SessionID; PasswordExpiration = result.PasswordExpiration; if (result.Status == ValidationResult.VALID) { OnValidLogin(); } return true; } return false; } public static bool Check2FA(string code, Guid? session = null) { var result = Client.Check2FA(code, session); if (result) { OnValidLogin(); } return result; } public static void OnValidLogin() { //Load up the data model, including Custom Properties var props = new Client().Load(); DatabaseSchema.Load(props); } public static void InvalidateUser() { //CurrentUser = null; UserGuid = Guid.Empty; UserID = ""; UserSecurityID = Guid.Empty; SessionID = Guid.Empty; Security.Reset(); } public static event LogEvent? OnLog; public static IClient CreateClient() where TEntity : Entity, new() { var type = ClientType.MakeGenericType(typeof(TEntity)); var client = (IClient)Activator.CreateInstance(type, _params); //client.UserID = UserID; //client.Password = Password; //client.Platform = Platform; //client.Version = Version; client.OnLog += OnLog; return client; } public static IClient CreateClient(Type t) { var type = ClientType.MakeGenericType(t); var client = (IClient)Activator.CreateInstance(type, _params); //client.UserID = UserID; //client.Password = Password; //client.Platform = Platform; //client.Version = Version; client.OnLog += OnLog; return client; } public static CoreTable[] MultiQuery(params IQueryDef[] queries) { var tasks = new Dictionary>(); for (var i = 0; i < queries.Length; i++) { var def = queries[i]; var task = Task.Run(() => { return CreateClient(def.Type).Query(def.Filter, def.Columns, def.SortOrder); }); tasks[i] = task; } Task.WaitAll(tasks.Values.ToArray()); var results = new List(); for (var i = 0; i < queries.Length; i++) results.Add(tasks[i].Result); return results.ToArray(); } public static void MultiQuery(IQueryDef[] queries, Action OnResults) { Task.Run(() => { var tasks = new Dictionary>(); for (var i = 0; i < queries.Length; i++) { var def = queries[i]; var task = Task.Run(() => { return CreateClient(def.Type).Query(def.Filter, def.Columns, def.SortOrder); }); tasks[i] = task; } Task.WaitAll(tasks.Values.ToArray()); var results = new List(); for (var i = 0; i < queries.Length; i++) results.Add(tasks[i].Result); OnResults.Invoke(results.ToArray()); }); } public static void RegisterMailer(EmailType type, Type mailer) { MailerTypes[type] = mailer; } public static ICoreMailer? CreateMailer() { var row = new Client().Query( new Filter(x => x.ID).IsEqualTo(UserGuid), new Columns( x => x.EmailType, x => x.EmailHost, x => x.EmailPort, x => x.EmailDomain, x => x.EmailUserID, x => x.EmailPassword, x => x.SMTPHost, x => x.SMPTPort, x => x.SMTPUserName, x => x.SMTPPassword ) ).Rows.FirstOrDefault(); if (row == null) return null; var type = row.Get(x => x.EmailType); if (type == EmailType.None) return null; var result = (Activator.CreateInstance(MailerTypes[type]) as ICoreMailer)!; result.MailboxHost = row.Get(x => x.EmailHost); result.MailboxPort = row.Get(x => x.EmailPort); result.MailboxDomain = row.Get(x => x.EmailDomain); result.MailboxUserName = row.Get(x => x.EmailUserID); result.MailboxPassword = row.Get(x => x.EmailPassword); result.SMTPHost = row.Get(x => x.SMTPHost); result.SMTPPort = row.Get(x => x.SMPTPort); result.SMTPUserName = row.Get(x => x.SMTPUserName); result.SMTPPassword = row.Get(x => x.SMTPPassword); return result; } } }