Request.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Runtime.InteropServices.ComTypes;
  5. using InABox.Core;
  6. namespace InABox.Clients
  7. {
  8. public class Credentials : ISerializeBinary
  9. {
  10. [Obsolete]
  11. public string? UserID { get; set; }
  12. [Obsolete]
  13. public string? Password { get; set; }
  14. public Platform Platform { get; set; }
  15. public string Version { get; set; }
  16. public Guid Session { get; set; }
  17. public void SerializeBinary(CoreBinaryWriter writer)
  18. {
  19. writer.Write(UserID ?? "");
  20. writer.Write(Password ?? "");
  21. writer.Write(Platform.ToString());
  22. writer.Write(Version);
  23. writer.Write(Session);
  24. }
  25. public void DeserializeBinary(CoreBinaryReader reader)
  26. {
  27. UserID = reader.ReadString();
  28. Password = reader.ReadString();
  29. if(Enum.TryParse<Platform>(reader.ReadString(), out var platform))
  30. {
  31. Platform = platform;
  32. }
  33. Version = reader.ReadString();
  34. Session = reader.ReadGuid();
  35. }
  36. }
  37. public abstract class Request
  38. {
  39. public Request()
  40. {
  41. Credentials = new Credentials();
  42. }
  43. public static Action<Request>? BeforeRequest { get; set; }
  44. public Credentials Credentials { get; set; }
  45. public abstract RequestMethod GetMethod();
  46. public virtual void SerializeBinary(CoreBinaryWriter writer)
  47. {
  48. Credentials.SerializeBinary(writer);
  49. }
  50. public virtual void DeserializeBinary(CoreBinaryReader reader)
  51. {
  52. Credentials.DeserializeBinary(reader);
  53. }
  54. }
  55. public enum StatusCode
  56. {
  57. OK,
  58. Incomplete,
  59. Error,
  60. Unauthenticated,
  61. BadServer
  62. }
  63. public enum RequestMethod
  64. {
  65. Info,
  66. Ping,
  67. Check2FA,
  68. Validate,
  69. MultiQuery,
  70. MultiDelete,
  71. Delete,
  72. Save,
  73. MultiSave,
  74. Query,
  75. Notify
  76. }
  77. public abstract class Response
  78. {
  79. public Response()
  80. {
  81. Status = StatusCode.Incomplete;
  82. Messages = new List<string>();
  83. }
  84. public StatusCode Status { get; set; }
  85. public List<string> Messages { get; }
  86. public virtual void DeserializeBinary(CoreBinaryReader reader)
  87. {
  88. Status = (StatusCode)Enum.ToObject(typeof(StatusCode), reader.ReadInt32());
  89. Messages.Clear();
  90. var nMessages = reader.ReadInt32();
  91. for (int i = 0; i < nMessages; ++i)
  92. {
  93. Messages.Add(reader.ReadString());
  94. }
  95. }
  96. public virtual void SerializeBinary(CoreBinaryWriter writer)
  97. {
  98. writer.Write((int)Status);
  99. writer.Write(Messages.Count);
  100. foreach(var message in Messages)
  101. {
  102. writer.Write(message);
  103. }
  104. }
  105. }
  106. public abstract class BaseRequest<TEntity> : Request where TEntity : Entity, new()
  107. {
  108. }
  109. public abstract class BaseResponse<TEntity> : Response where TEntity : Entity, new()
  110. {
  111. }
  112. /*public class ListRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()
  113. {
  114. public Filter<TEntity>? Filter { get; set; }
  115. public Columns<TEntity>? Columns { get; set; }
  116. public SortOrder<TEntity>? Sort { get; set; }
  117. public override RequestMethod GetMethod() => RequestMethod.Query;
  118. }
  119. public class ListResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  120. {
  121. public IEnumerable<object[]> Data { get; set; }
  122. }*/
  123. public class QueryRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()
  124. {
  125. public Filter<TEntity>? Filter { get; set; }
  126. public Columns<TEntity>? Columns { get; set; }
  127. public SortOrder<TEntity>? Sort { get; set; }
  128. public override RequestMethod GetMethod() => RequestMethod.Query;
  129. }
  130. public class QueryResponse<TEntity> : BaseResponse<TEntity>, ISerializeBinary where TEntity : Entity, new()
  131. {
  132. public CoreTable? Items { get; set; }
  133. public override void DeserializeBinary(CoreBinaryReader reader)
  134. {
  135. base.DeserializeBinary(reader);
  136. if (reader.ReadBoolean())
  137. {
  138. Items = new CoreTable();
  139. Items.DeserializeBinary(reader);
  140. }
  141. else
  142. {
  143. Items = null;
  144. }
  145. }
  146. public override void SerializeBinary(CoreBinaryWriter writer)
  147. {
  148. base.SerializeBinary(writer);
  149. if(Items is null)
  150. {
  151. writer.Write(false);
  152. }
  153. else
  154. {
  155. writer.Write(true);
  156. Items.SerializeBinary(writer);
  157. }
  158. }
  159. }
  160. /*public class LoadRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()
  161. {
  162. public Filter<TEntity>? Filter { get; set; }
  163. public SortOrder<TEntity>? Sort { get; set; }
  164. }
  165. public class LoadResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  166. {
  167. public TEntity[] Items { get; set; }
  168. }*/
  169. public class MultiSaveRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()
  170. {
  171. public TEntity[] Items { get; set; }
  172. public string AuditNote { get; set; }
  173. [Obsolete("We don't like this; it should always be true.")]
  174. // 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.
  175. public bool ReturnOnlyChanged { get; set; } = false;
  176. public override RequestMethod GetMethod() => RequestMethod.MultiSave;
  177. public override void SerializeBinary(CoreBinaryWriter writer)
  178. {
  179. base.SerializeBinary(writer);
  180. writer.WriteObjects(Items);
  181. writer.Write(AuditNote);
  182. writer.Write(ReturnOnlyChanged);
  183. }
  184. public override void DeserializeBinary(CoreBinaryReader reader)
  185. {
  186. base.DeserializeBinary(reader);
  187. Items = reader.ReadObjects<TEntity>().ToArray();
  188. AuditNote = reader.ReadString();
  189. ReturnOnlyChanged = reader.ReadBoolean();
  190. }
  191. }
  192. public class MultiSaveResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  193. {
  194. //public Guid[] IDs { get; set; }
  195. public TEntity[] Items { get; set; }
  196. public List<Dictionary<string, object?>> ChangedValues { get; set; } = new List<Dictionary<string, object?>>();
  197. }
  198. public class SaveRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()
  199. {
  200. public TEntity Item { get; set; }
  201. public string AuditNote { get; set; }
  202. public bool ReturnOnlyChanged { get; set; } = false;
  203. public override RequestMethod GetMethod() => RequestMethod.Save;
  204. public override void SerializeBinary(CoreBinaryWriter writer)
  205. {
  206. base.SerializeBinary(writer);
  207. writer.WriteObject(Item);
  208. writer.Write(AuditNote);
  209. writer.Write(ReturnOnlyChanged);
  210. }
  211. public override void DeserializeBinary(CoreBinaryReader reader)
  212. {
  213. base.DeserializeBinary(reader);
  214. Item = reader.ReadObject<TEntity>();
  215. AuditNote = reader.ReadString();
  216. ReturnOnlyChanged = reader.ReadBoolean();
  217. }
  218. }
  219. public class SaveResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  220. {
  221. //public Guid ID { get; set; }
  222. public TEntity Item { get; set; }
  223. public Dictionary<string, object?> ChangedValues { get; set; } = new Dictionary<string, object?>();
  224. }
  225. public class DeleteRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()
  226. {
  227. public TEntity Item { get; set; }
  228. public string AuditNote { get; set; }
  229. public override RequestMethod GetMethod() => RequestMethod.Delete;
  230. }
  231. public class DeleteResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  232. {
  233. }
  234. public class MultiDeleteRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()
  235. {
  236. public TEntity[] Items { get; set; }
  237. public string AuditNote { get; set; }
  238. public override RequestMethod GetMethod() => RequestMethod.MultiDelete;
  239. }
  240. public class MultiDeleteResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  241. {
  242. }
  243. public class MultiQueryRequest : Request
  244. {
  245. public Dictionary<string, string> TableTypes { get; set; }
  246. public Dictionary<string, string> Filters { get; set; }
  247. public Dictionary<string, string> Columns { get; set; }
  248. public Dictionary<string, string> Sorts { get; set; }
  249. public override RequestMethod GetMethod() => RequestMethod.MultiQuery;
  250. }
  251. public class MultiQueryResponse : Response, ISerializeBinary
  252. {
  253. public MultiQueryResponse()
  254. {
  255. Tables = new Dictionary<string, CoreTable>();
  256. }
  257. public Dictionary<string, CoreTable> Tables { get; set; }
  258. public override void DeserializeBinary(CoreBinaryReader reader)
  259. {
  260. base.DeserializeBinary(reader);
  261. Tables.Clear();
  262. var nTables = reader.ReadInt32();
  263. for(int i = 0; i < nTables; ++i)
  264. {
  265. var name = reader.ReadString();
  266. var table = new CoreTable();
  267. table.DeserializeBinary(reader);
  268. Tables[name] = table;
  269. }
  270. }
  271. public override void SerializeBinary(CoreBinaryWriter writer)
  272. {
  273. base.SerializeBinary(writer);
  274. writer.Write(Tables.Count);
  275. foreach(var (name, table) in Tables)
  276. {
  277. writer.Write(name);
  278. table.SerializeBinary(writer);
  279. }
  280. }
  281. }
  282. public enum ValidationResult
  283. {
  284. VALID,
  285. INVALID,
  286. REQUIRE_2FA,
  287. PASSWORD_EXPIRED
  288. }
  289. public class ValidateRequest : Request
  290. {
  291. public string? UserID { get; set; }
  292. public string? Password { get; set; }
  293. public string? PIN { get; set; }
  294. public bool UsePIN { get; set; }
  295. public override RequestMethod GetMethod() => RequestMethod.Validate;
  296. }
  297. public class ValidateResponse : Response
  298. {
  299. public ValidationResult ValidationResult { get; set; }
  300. public Guid UserGuid { get; set; }
  301. public string UserID { get; set; }
  302. public Guid SecurityID { get; set; }
  303. public Guid Session { get; set; }
  304. public string? Recipient2FA { get; set; }
  305. public DateTime PasswordExpiration { get; set; }
  306. }
  307. public class Check2FARequest : Request
  308. {
  309. public string Code { get; set; }
  310. public override RequestMethod GetMethod() => RequestMethod.Check2FA;
  311. }
  312. public class Check2FAResponse : Response
  313. {
  314. public bool Valid { get; set; }
  315. }
  316. public class PingRequest : Request
  317. {
  318. public override RequestMethod GetMethod() => RequestMethod.Ping;
  319. }
  320. public class PingResponse : Response { }
  321. public class InfoRequest : Request
  322. {
  323. public override RequestMethod GetMethod() => RequestMethod.Info;
  324. }
  325. public class DatabaseInfo
  326. {
  327. public string? ColorScheme { get; set; }
  328. public byte[]? Logo { get; set; }
  329. public string Version { get; set; }
  330. public bool IsHTTPS { get; set; }
  331. }
  332. public class InfoResponse : Response
  333. {
  334. public DatabaseInfo Info { get; set; }
  335. public InfoResponse() : base()
  336. {
  337. Info = new DatabaseInfo();
  338. }
  339. }
  340. public static class Extensions
  341. {
  342. public static T Status<T>(this T response, StatusCode status) where T : Response
  343. {
  344. response.Status = status;
  345. return response;
  346. }
  347. }
  348. public class RequestException : Exception
  349. {
  350. public StatusCode Status { get; set; }
  351. public RequestMethod Method { get; set; }
  352. public RequestException(string message, StatusCode status, Request request): base(message)
  353. {
  354. Status = status;
  355. Method = request.GetMethod();
  356. }
  357. }
  358. }