| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 | using System;using System.Collections.Generic;using System.IO;using System.Runtime.InteropServices.ComTypes;using InABox.Core;namespace InABox.Clients{    public class Credentials : ISerializeBinary    {        [Obsolete]        public string? UserID { get; set; }        [Obsolete]        public string? Password { get; set; }        public string Platform { get; set; }        public string Version { get; set; }        public Guid Session { get; set; }        public void SerializeBinary(BinaryWriter writer)        {            writer.Write(UserID ?? "");            writer.Write(Password ?? "");            writer.Write(Platform);            writer.Write(Version);            writer.Write(Session);        }        public void DeserializeBinary(BinaryReader reader)        {            UserID = reader.ReadString();            Password = reader.ReadString();            Platform = reader.ReadString();            Version = reader.ReadString();            Session = reader.ReadGuid();        }    }    public abstract class Request    {        public Request()        {            Credentials = new Credentials();        }        public static Action<Request>? BeforeRequest { get; set; }        public Credentials Credentials { get; set; }        public abstract RequestMethod GetMethod();        public virtual void SerializeBinary(BinaryWriter writer)        {            Credentials.SerializeBinary(writer);        }        public virtual void DeserializeBinary(BinaryReader reader)        {            Credentials.DeserializeBinary(reader);        }    }    public enum StatusCode    {        OK,        Incomplete,        Error,        Unauthenticated,        BadServer    }    public enum RequestMethod    {        Info,        Ping,        Check2FA,        Validate,        MultiQuery,        MultiDelete,        Delete,        Save,        MultiSave,        Query,        Notify    }    public abstract class Response    {        public Response()        {            Status = StatusCode.Incomplete;            Messages = new List<string>();        }        public StatusCode Status { get; set; }        public List<string> Messages { get; }        public virtual void DeserializeBinary(BinaryReader reader)        {            Status = (StatusCode)Enum.ToObject(typeof(StatusCode), reader.ReadInt32());            Messages.Clear();            var nMessages = reader.ReadInt32();            for (int i = 0; i < nMessages; ++i)            {                Messages.Add(reader.ReadString());            }        }        public virtual void SerializeBinary(BinaryWriter writer)        {            writer.Write((int)Status);            writer.Write(Messages.Count);            foreach(var message in Messages)            {                writer.Write(message);            }        }    }    public abstract class BaseRequest<TEntity> : Request where TEntity : Entity, new()    {    }    public abstract class BaseResponse<TEntity> : Response where TEntity : Entity, new()    {    }    /*public class ListRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()    {        public Filter<TEntity>? Filter { get; set; }        public Columns<TEntity>? Columns { get; set; }        public SortOrder<TEntity>? Sort { get; set; }        public override RequestMethod GetMethod() => RequestMethod.Query;    }        public class ListResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()    {        public IEnumerable<object[]> Data { get; set; }    }*/    public class QueryRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()    {        public Filter<TEntity>? Filter { get; set; }        public Columns<TEntity>? Columns { get; set; }        public SortOrder<TEntity>? Sort { get; set; }        public override RequestMethod GetMethod() => RequestMethod.Query;    }    public class QueryResponse<TEntity> : BaseResponse<TEntity>, ISerializeBinary where TEntity : Entity, new()    {        public CoreTable? Items { get; set; }        public override void DeserializeBinary(BinaryReader reader)        {            base.DeserializeBinary(reader);            if (reader.ReadBoolean())            {                Items = new CoreTable();                Items.DeserializeBinary(reader);            }            else            {                Items = null;            }        }        public override void SerializeBinary(BinaryWriter writer)        {            base.SerializeBinary(writer);            if(Items is null)            {                writer.Write(false);            }            else            {                writer.Write(true);                Items.SerializeBinary(writer);            }        }    }    /*public class LoadRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()    {        public Filter<TEntity>? Filter { get; set; }        public SortOrder<TEntity>? Sort { get; set; }    }    public class LoadResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()    {        public TEntity[] Items { get; set; }    }*/    public class MultiSaveRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()    {        public TEntity[] Items { get; set; }        public string AuditNote { get; set; }        [Obsolete("We don't like this; it should always be true.")]        // Added 11/04/23 to address incompatibility, remove as soon as possible; the relevant code to update is in RestService; update assuming that ReturnOnlyChanged is always true.        public bool ReturnOnlyChanged { get; set; } = false;        public override RequestMethod GetMethod() => RequestMethod.MultiSave;        public override void SerializeBinary(BinaryWriter writer)        {            base.SerializeBinary(writer);            writer.WriteObjects(Items);            writer.Write(AuditNote);            writer.Write(ReturnOnlyChanged);        }        public override void DeserializeBinary(BinaryReader reader)        {            base.DeserializeBinary(reader);            Items = reader.ReadObjects<TEntity>().ToArray();            AuditNote = reader.ReadString();            ReturnOnlyChanged = reader.ReadBoolean();        }    }    public class MultiSaveResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()    {        //public Guid[] IDs { get; set; }        public TEntity[] Items { get; set; }        public List<Dictionary<string, object?>> ChangedValues { get; set; } = new List<Dictionary<string, object?>>();    }    public class SaveRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()    {        public TEntity Item { get; set; }        public string AuditNote { get; set; }        public bool ReturnOnlyChanged { get; set; } = false;        public override RequestMethod GetMethod() => RequestMethod.Save;        public override void SerializeBinary(BinaryWriter writer)        {            base.SerializeBinary(writer);            writer.WriteObject(Item);            writer.Write(AuditNote);            writer.Write(ReturnOnlyChanged);        }        public override void DeserializeBinary(BinaryReader reader)        {            base.DeserializeBinary(reader);            Item = reader.ReadObject<TEntity>();            AuditNote = reader.ReadString();            ReturnOnlyChanged = reader.ReadBoolean();        }    }    public class SaveResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()    {        //public Guid ID { get; set; }        public TEntity Item { get; set; }        public Dictionary<string, object?> ChangedValues { get; set; } = new Dictionary<string, object?>();    }    public class DeleteRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()    {        public TEntity Item { get; set; }        public string AuditNote { get; set; }        public override RequestMethod GetMethod() => RequestMethod.Delete;    }    public class DeleteResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()    {    }    public class MultiDeleteRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()    {        public TEntity[] Items { get; set; }        public string AuditNote { get; set; }        public override RequestMethod GetMethod() => RequestMethod.MultiDelete;    }    public class MultiDeleteResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()    {    }    public class MultiQueryRequest : Request    {        public Dictionary<string, string> TableTypes { get; set; }        public Dictionary<string, string> Filters { get; set; }        public Dictionary<string, string> Columns { get; set; }        public Dictionary<string, string> Sorts { get; set; }        public override RequestMethod GetMethod() => RequestMethod.MultiQuery;    }    public class MultiQueryResponse : Response, ISerializeBinary    {        public MultiQueryResponse()        {            Tables = new Dictionary<string, CoreTable>();        }        public Dictionary<string, CoreTable> Tables { get; set; }        public override void DeserializeBinary(BinaryReader reader)        {            base.DeserializeBinary(reader);            Tables.Clear();            var nTables = reader.ReadInt32();            for(int i = 0; i < nTables; ++i)            {                var name = reader.ReadString();                var table = new CoreTable();                table.DeserializeBinary(reader);                Tables[name] = table;            }        }        public override void SerializeBinary(BinaryWriter writer)        {            base.SerializeBinary(writer);            writer.Write(Tables.Count);            foreach(var (name, table) in Tables)            {                writer.Write(name);                table.SerializeBinary(writer);            }        }    }    public enum ValidationResult    {        VALID,        INVALID,        REQUIRE_2FA,        PASSWORD_EXPIRED    }    public class ValidateRequest : Request    {        public string? UserID { get; set; }        public string? Password { get; set; }        public string? PIN { get; set; }        public bool UsePIN { get; set; }        public override RequestMethod GetMethod() => RequestMethod.Validate;    }    public class ValidateResponse : Response    {        public ValidationResult ValidationResult { get; set; }        public Guid UserGuid { get; set; }        public string UserID { get; set; }        public Guid SecurityID { get; set; }        public Guid Session { get; set; }        public string? Recipient2FA { get; set; }        public DateTime PasswordExpiration { get; set; }            }    public class Check2FARequest : Request    {        public string Code { get; set; }        public override RequestMethod GetMethod() => RequestMethod.Check2FA;    }    public class Check2FAResponse : Response    {        public bool Valid { get; set; }    }    public class PingRequest : Request    {        public override RequestMethod GetMethod() => RequestMethod.Ping;    }    public class PingResponse : Response { }        public class InfoRequest : Request    {        public override RequestMethod GetMethod() => RequestMethod.Info;    }    public class DatabaseInfo    {        public string? ColorScheme { get; set; }        public byte[]? Logo { get; set; }        public string Version { get; set; }    }        public class InfoResponse : Response    {        public DatabaseInfo Info { get; set; }        public InfoResponse() : base()        {            Info = new DatabaseInfo();        }    }    public static class Extensions    {        public static T Status<T>(this T response, StatusCode status) where T : Response        {            response.Status = status;            return response;        }    }    public class RequestException : Exception    {        public StatusCode Status { get; set; }        public RequestMethod Method { get; set; }        public RequestException(string message, StatusCode status, Request request): base(message)        {            Status = status;            Method = request.GetMethod();        }    }}
 |