Request.cs 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Runtime.InteropServices.ComTypes;
  5. using System.Text.Json.Serialization;
  6. using InABox.Core;
  7. namespace InABox.Clients
  8. {
  9. public class Credentials : ISerializeBinary
  10. {
  11. [Obsolete]
  12. public string? UserID { get; set; }
  13. [Obsolete]
  14. public string? Password { get; set; }
  15. public Platform Platform { get; set; }
  16. public string? Version { get; set; }
  17. public Guid Session { get; set; }
  18. public void SerializeBinary(CoreBinaryWriter writer)
  19. {
  20. writer.Write(UserID ?? string.Empty);
  21. writer.Write(Password ?? string.Empty);
  22. writer.Write(Platform.ToString());
  23. writer.Write(Version ?? string.Empty);
  24. writer.Write(Session);
  25. }
  26. public void DeserializeBinary(CoreBinaryReader reader)
  27. {
  28. UserID = reader.ReadString();
  29. Password = reader.ReadString();
  30. if(Enum.TryParse<Platform>(reader.ReadString(), out var platform))
  31. {
  32. Platform = platform;
  33. }
  34. Version = reader.ReadString();
  35. Session = reader.ReadGuid();
  36. }
  37. }
  38. public abstract class Request
  39. {
  40. public Request()
  41. {
  42. Credentials = new Credentials();
  43. }
  44. public static Action<Request>? BeforeRequest { get; set; }
  45. public Credentials Credentials { get; set; }
  46. public abstract RequestMethod GetMethod();
  47. public virtual void SerializeBinary(CoreBinaryWriter writer)
  48. {
  49. Credentials.SerializeBinary(writer);
  50. }
  51. public virtual void DeserializeBinary(CoreBinaryReader reader)
  52. {
  53. Credentials.DeserializeBinary(reader);
  54. }
  55. }
  56. public enum StatusCode
  57. {
  58. OK,
  59. Incomplete,
  60. Error,
  61. Unauthenticated,
  62. BadServer
  63. }
  64. public enum RequestMethod
  65. {
  66. Info,
  67. Ping,
  68. Check2FA,
  69. Validate,
  70. MultiQuery,
  71. MultiDelete,
  72. Delete,
  73. Save,
  74. MultiSave,
  75. Query,
  76. Push,
  77. Version,
  78. ReleaseNotes,
  79. Installer
  80. }
  81. public abstract class Response
  82. {
  83. public Response()
  84. {
  85. Status = StatusCode.Incomplete;
  86. Messages = new List<string>();
  87. }
  88. public StatusCode Status { get; set; }
  89. public List<string> Messages { get; }
  90. public virtual void DeserializeBinary(CoreBinaryReader reader)
  91. {
  92. Status = (StatusCode)Enum.ToObject(typeof(StatusCode), reader.ReadInt32());
  93. Messages.Clear();
  94. var nMessages = reader.ReadInt32();
  95. for (int i = 0; i < nMessages; ++i)
  96. {
  97. Messages.Add(reader.ReadString());
  98. }
  99. }
  100. public virtual void SerializeBinary(CoreBinaryWriter writer)
  101. {
  102. writer.Write((int)Status);
  103. writer.Write(Messages.Count);
  104. foreach(var message in Messages)
  105. {
  106. writer.Write(message);
  107. }
  108. }
  109. }
  110. public abstract class BaseRequest<TEntity> : Request where TEntity : Entity, new()
  111. {
  112. }
  113. public abstract class BaseResponse<TEntity> : Response where TEntity : Entity, new()
  114. {
  115. }
  116. /*public class ListRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()
  117. {
  118. public Filter<TEntity>? Filter { get; set; }
  119. public Columns<TEntity>? Columns { get; set; }
  120. public SortOrder<TEntity>? Sort { get; set; }
  121. public override RequestMethod GetMethod() => RequestMethod.Query;
  122. }
  123. public class ListResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  124. {
  125. public IEnumerable<object[]> Data { get; set; }
  126. }*/
  127. public interface IQueryRequest : ISerializeBinary
  128. {
  129. public IFilter? Filter { get; set; }
  130. public IColumns? Columns { get; set; }
  131. public ISortOrder? Sort { get; set; }
  132. public CoreRange? Range { get; set; }
  133. }
  134. public class QueryRequest<TEntity> : BaseRequest<TEntity>, IQueryRequest, ISerializeBinary where TEntity : Entity, new()
  135. {
  136. IFilter? IQueryRequest.Filter
  137. {
  138. get => Filter;
  139. set => Filter = value as Filter<TEntity>;
  140. }
  141. public Filter<TEntity>? Filter { get; set; }
  142. IColumns? IQueryRequest.Columns
  143. {
  144. get => Columns;
  145. set => Columns = value as Columns<TEntity>;
  146. }
  147. public Columns<TEntity>? Columns { get; set; }
  148. ISortOrder? IQueryRequest.Sort
  149. {
  150. get => Sort;
  151. set => Sort = value as SortOrder<TEntity>;
  152. }
  153. public SortOrder<TEntity>? Sort { get; set; }
  154. public CoreRange? Range { get; set; }
  155. [JsonConstructor]
  156. public QueryRequest()
  157. {
  158. Filter = null;
  159. Columns = null;
  160. Sort = null;
  161. Range = null;
  162. }
  163. public QueryRequest(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort, CoreRange? range)
  164. {
  165. Filter = filter;
  166. Columns = columns;
  167. Sort = sort;
  168. Range = range;
  169. }
  170. public override RequestMethod GetMethod() => RequestMethod.Query;
  171. public override void SerializeBinary(CoreBinaryWriter writer)
  172. {
  173. base.SerializeBinary(writer);
  174. writer.Write(Filter);
  175. writer.Write(Columns);
  176. writer.Write(Sort);
  177. writer.WriteBinaryValue(Range);
  178. }
  179. public override void DeserializeBinary(CoreBinaryReader reader)
  180. {
  181. base.DeserializeBinary(reader);
  182. Filter = reader.ReadFilter<TEntity>();
  183. Columns = reader.ReadColumns<TEntity>();
  184. Sort = reader.ReadSortOrder<TEntity>();
  185. Range = reader.ReadBinaryValue<CoreRange>();
  186. }
  187. }
  188. public class QueryResponse<TEntity> : BaseResponse<TEntity>, ISerializeBinary where TEntity : Entity, new()
  189. {
  190. public CoreTable Items { get; set; } = new CoreTable();
  191. public override void DeserializeBinary(CoreBinaryReader reader)
  192. {
  193. base.DeserializeBinary(reader);
  194. Items = new CoreTable();
  195. Items.DeserializeBinary(reader);
  196. }
  197. public override void SerializeBinary(CoreBinaryWriter writer)
  198. {
  199. base.SerializeBinary(writer);
  200. Items.SerializeBinary(writer);
  201. }
  202. }
  203. /*public class LoadRequest<TEntity> : BaseRequest<TEntity> where TEntity : Entity, new()
  204. {
  205. public Filter<TEntity>? Filter { get; set; }
  206. public SortOrder<TEntity>? Sort { get; set; }
  207. }
  208. public class LoadResponse<TEntity> : BaseResponse<TEntity> where TEntity : Entity, new()
  209. {
  210. public TEntity[] Items { get; set; }
  211. }*/
  212. public class MultiSaveRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()
  213. {
  214. public TEntity[] Items { get; set; }
  215. public string AuditNote { get; set; }
  216. [Obsolete("We don't like this; it should always be true.")]
  217. // 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.
  218. public bool ReturnOnlyChanged { get; set; } = false;
  219. [JsonConstructor]
  220. public MultiSaveRequest()
  221. {
  222. Items = Array.Empty<TEntity>();
  223. AuditNote = "";
  224. }
  225. public MultiSaveRequest(TEntity[] items, string auditNode)
  226. {
  227. Items = items;
  228. AuditNote = auditNode;
  229. }
  230. public override RequestMethod GetMethod() => RequestMethod.MultiSave;
  231. public override void SerializeBinary(CoreBinaryWriter writer)
  232. {
  233. base.SerializeBinary(writer);
  234. writer.WriteObjects(Items);
  235. writer.Write(AuditNote);
  236. writer.Write(ReturnOnlyChanged);
  237. }
  238. public override void DeserializeBinary(CoreBinaryReader reader)
  239. {
  240. base.DeserializeBinary(reader);
  241. Items = reader.ReadObjects<TEntity>().ToArray();
  242. AuditNote = reader.ReadString();
  243. ReturnOnlyChanged = reader.ReadBoolean();
  244. }
  245. }
  246. public class MultiSaveResponse<TEntity> : BaseResponse<TEntity>, ISerializeBinary where TEntity : Entity, new()
  247. {
  248. //public Guid[] IDs { get; set; }
  249. public TEntity[]? Items { get; set; }
  250. public List<Dictionary<string, object?>> ChangedValues { get; set; } = new List<Dictionary<string, object?>>();
  251. public override void SerializeBinary(CoreBinaryWriter writer)
  252. {
  253. base.SerializeBinary(writer);
  254. if(Items is null)
  255. {
  256. writer.Write(false);
  257. }
  258. else
  259. {
  260. writer.Write(true);
  261. writer.WriteObjects(Items);
  262. }
  263. writer.Write(ChangedValues.Count);
  264. foreach(var changed in ChangedValues)
  265. {
  266. SaveResponse<TEntity>.SerializeChangedValues(writer, changed);
  267. }
  268. }
  269. public override void DeserializeBinary(CoreBinaryReader reader)
  270. {
  271. base.DeserializeBinary(reader);
  272. if (reader.ReadBoolean())
  273. {
  274. Items = reader.ReadObjects<TEntity>().ToArray();
  275. }
  276. else
  277. {
  278. Items = null;
  279. }
  280. ChangedValues.Clear();
  281. var nChangedValues = reader.ReadInt32();
  282. for(int i = 0; i < nChangedValues; ++i)
  283. {
  284. ChangedValues.Add(SaveResponse<TEntity>.DeserializeChangedValues(reader));
  285. }
  286. }
  287. }
  288. public class SaveRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()
  289. {
  290. public TEntity Item { get; set; }
  291. public string AuditNote { get; set; }
  292. public bool ReturnOnlyChanged { get; set; } = false;
  293. [JsonConstructor]
  294. public SaveRequest()
  295. {
  296. // Newtonsoft should initialise Item to non-null
  297. }
  298. public SaveRequest(TEntity item, string auditNote)
  299. {
  300. Item = item;
  301. AuditNote = auditNote;
  302. }
  303. public override RequestMethod GetMethod() => RequestMethod.Save;
  304. public override void SerializeBinary(CoreBinaryWriter writer)
  305. {
  306. base.SerializeBinary(writer);
  307. writer.WriteObject(Item);
  308. writer.Write(AuditNote);
  309. writer.Write(ReturnOnlyChanged);
  310. }
  311. public override void DeserializeBinary(CoreBinaryReader reader)
  312. {
  313. base.DeserializeBinary(reader);
  314. Item = reader.ReadObject<TEntity>();
  315. AuditNote = reader.ReadString();
  316. ReturnOnlyChanged = reader.ReadBoolean();
  317. }
  318. }
  319. public class SaveResponse<TEntity> : BaseResponse<TEntity>, ISerializeBinary where TEntity : Entity, new()
  320. {
  321. //public Guid ID { get; set; }
  322. public TEntity? Item { get; set; }
  323. public Dictionary<string, object?> ChangedValues { get; set; } = new Dictionary<string, object?>();
  324. public override void SerializeBinary(CoreBinaryWriter writer)
  325. {
  326. base.SerializeBinary(writer);
  327. if (Item is null)
  328. {
  329. writer.Write(false);
  330. }
  331. else
  332. {
  333. writer.Write(true);
  334. writer.WriteObject(Item);
  335. }
  336. SerializeChangedValues(writer, ChangedValues);
  337. }
  338. public override void DeserializeBinary(CoreBinaryReader reader)
  339. {
  340. base.DeserializeBinary(reader);
  341. if (reader.ReadBoolean())
  342. {
  343. Item = reader.ReadObject<TEntity>();
  344. }
  345. ChangedValues = DeserializeChangedValues(reader);
  346. }
  347. public static void SerializeChangedValues(CoreBinaryWriter writer, Dictionary<string, object?> changedValues)
  348. {
  349. var props = new List<Tuple<string, Type, object?>>();
  350. writer.Write(changedValues.Count);
  351. foreach (var (key, value) in changedValues)
  352. {
  353. var property = DatabaseSchema.Property(typeof(TEntity), key);
  354. if (property != null)
  355. {
  356. props.Add(new Tuple<string, Type, object?>(key, property.PropertyType, value));
  357. }
  358. else
  359. {
  360. Logger.Send(LogType.Error, "", $"Error serializing changedValues: Property {key} does not exist");
  361. }
  362. }
  363. foreach (var (key, type, value) in props)
  364. {
  365. writer.Write(key);
  366. writer.WriteBinaryValue(type, value);
  367. }
  368. }
  369. public static Dictionary<string, object?> DeserializeChangedValues(CoreBinaryReader reader)
  370. {
  371. var changedDict = new Dictionary<string, object?>();
  372. var nChanged = reader.ReadInt32();
  373. for (int j = 0; j < nChanged; ++j)
  374. {
  375. var key = reader.ReadString();
  376. var property = DatabaseSchema.Property(typeof(TEntity), key);
  377. if (property != null)
  378. {
  379. changedDict.Add(key, reader.ReadBinaryValue(property.PropertyType));
  380. }
  381. else
  382. {
  383. throw new Exception($"Property {key} does not exist");
  384. }
  385. }
  386. return changedDict;
  387. }
  388. }
  389. public class DeleteRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()
  390. {
  391. public TEntity Item { get; set; }
  392. public string AuditNote { get; set; }
  393. [JsonConstructor]
  394. public DeleteRequest()
  395. {
  396. // Newtonsoft should initialise Item to non-null.
  397. }
  398. public DeleteRequest(TEntity item, string auditNote)
  399. {
  400. Item = item;
  401. AuditNote = auditNote;
  402. }
  403. public override RequestMethod GetMethod() => RequestMethod.Delete;
  404. public override void SerializeBinary(CoreBinaryWriter writer)
  405. {
  406. base.SerializeBinary(writer);
  407. writer.WriteObject(Item);
  408. writer.Write(AuditNote);
  409. }
  410. public override void DeserializeBinary(CoreBinaryReader reader)
  411. {
  412. base.DeserializeBinary(reader);
  413. Item = reader.ReadObject<TEntity>();
  414. AuditNote = reader.ReadString();
  415. }
  416. }
  417. public class DeleteResponse<TEntity> : BaseResponse<TEntity>, ISerializeBinary where TEntity : Entity, new()
  418. {
  419. }
  420. public class MultiDeleteRequest<TEntity> : BaseRequest<TEntity>, ISerializeBinary where TEntity : Entity, new()
  421. {
  422. public TEntity[] Items { get; set; }
  423. public string AuditNote { get; set; }
  424. [JsonConstructor]
  425. public MultiDeleteRequest()
  426. {
  427. // Newtonsoft should initialise Items to non-null.
  428. }
  429. public MultiDeleteRequest(TEntity[] items, string auditNote)
  430. {
  431. Items = items;
  432. AuditNote = auditNote;
  433. }
  434. public override RequestMethod GetMethod() => RequestMethod.MultiDelete;
  435. public override void SerializeBinary(CoreBinaryWriter writer)
  436. {
  437. base.SerializeBinary(writer);
  438. writer.WriteObjects(Items);
  439. writer.Write(AuditNote);
  440. }
  441. public override void DeserializeBinary(CoreBinaryReader reader)
  442. {
  443. base.DeserializeBinary(reader);
  444. Items = reader.ReadObjects<TEntity>().ToArray();
  445. AuditNote = reader.ReadString();
  446. }
  447. }
  448. public class MultiDeleteResponse<TEntity> : BaseResponse<TEntity>, ISerializeBinary where TEntity : Entity, new()
  449. {
  450. }
  451. public interface IMultiQueryTableQuery
  452. {
  453. string Type { get; }
  454. IFilter? Filter { get; set; }
  455. IColumns? Columns { get; set; }
  456. ISortOrder? Sort { get; set; }
  457. void SerializeBinary(CoreBinaryWriter writer) => SerializeBinary(this, writer);
  458. public static void SerializeBinary(IMultiQueryTableQuery query, CoreBinaryWriter writer)
  459. {
  460. writer.Write(query.Type);
  461. }
  462. public static IMultiQueryTableQuery DeserializeBinary(CoreBinaryReader reader)
  463. {
  464. var typeString = reader.ReadString();
  465. var type = CoreUtils.GetEntity(typeString);
  466. var query = (Activator.CreateInstance(typeof(MultiQueryTableQuery<>).MakeGenericType(type)) as ISerializeBinary)!;
  467. query.DeserializeBinary(reader);
  468. return (query as IMultiQueryTableQuery)!;
  469. }
  470. }
  471. public class MultiQueryTableQuery<TEntity> : IMultiQueryTableQuery, ISerializeBinary
  472. where TEntity : Entity, new()
  473. {
  474. public string Type => typeof(TEntity).EntityName();
  475. public Filter<TEntity>? Filter { get; set; }
  476. public Columns<TEntity>? Columns { get; set; }
  477. public SortOrder<TEntity>? Sort { get; set; }
  478. IFilter? IMultiQueryTableQuery.Filter { get => Filter; set => Filter = value as Filter<TEntity>; }
  479. IColumns? IMultiQueryTableQuery.Columns { get => Columns; set => Columns = value as Columns<TEntity>; }
  480. ISortOrder? IMultiQueryTableQuery.Sort { get => Sort; set => Sort = value as SortOrder<TEntity>; }
  481. public void SerializeBinary(CoreBinaryWriter writer)
  482. {
  483. IMultiQueryTableQuery.SerializeBinary(this, writer);
  484. writer.Write(Filter);
  485. writer.Write(Columns);
  486. writer.Write(Sort);
  487. }
  488. public void DeserializeBinary(CoreBinaryReader reader)
  489. {
  490. Filter = reader.ReadFilter<TEntity>();
  491. Columns = reader.ReadColumns<TEntity>();
  492. Sort = reader.ReadSortOrder<TEntity>();
  493. }
  494. }
  495. public class MultiQueryRequest : Request, ISerializeBinary
  496. {
  497. public Dictionary<string, IMultiQueryTableQuery> Queries { get; set; } = new Dictionary<string, IMultiQueryTableQuery>();
  498. public void AddQuery(string key, IQueryDef queryDef)
  499. {
  500. var query = (Activator.CreateInstance(typeof(MultiQueryTableQuery<>).MakeGenericType(queryDef.Type)) as IMultiQueryTableQuery)!;
  501. query.Filter = queryDef.Filter;
  502. query.Columns = queryDef.Columns;
  503. query.Sort = queryDef.SortOrder;
  504. Queries.Add(key, query);
  505. }
  506. public override RequestMethod GetMethod() => RequestMethod.MultiQuery;
  507. public override void SerializeBinary(CoreBinaryWriter writer)
  508. {
  509. base.SerializeBinary(writer);
  510. writer.Write(Queries.Count);
  511. foreach(var (key, query) in Queries)
  512. {
  513. writer.Write(key);
  514. query.SerializeBinary(writer);
  515. }
  516. }
  517. public override void DeserializeBinary(CoreBinaryReader reader)
  518. {
  519. base.DeserializeBinary(reader);
  520. var nQueries = reader.ReadInt32();
  521. for(int i = 0; i < nQueries; ++i)
  522. {
  523. var key = reader.ReadString();
  524. var query = IMultiQueryTableQuery.DeserializeBinary(reader);
  525. Queries[key] = query;
  526. }
  527. }
  528. }
  529. public class MultiQueryResponse : Response, ISerializeBinary
  530. {
  531. public MultiQueryResponse()
  532. {
  533. Tables = new Dictionary<string, CoreTable>();
  534. }
  535. public Dictionary<string, CoreTable> Tables { get; set; }
  536. public override void DeserializeBinary(CoreBinaryReader reader)
  537. {
  538. base.DeserializeBinary(reader);
  539. Tables.Clear();
  540. var nTables = reader.ReadInt32();
  541. for(int i = 0; i < nTables; ++i)
  542. {
  543. var name = reader.ReadString();
  544. var table = new CoreTable();
  545. table.DeserializeBinary(reader);
  546. Tables[name] = table;
  547. }
  548. }
  549. public override void SerializeBinary(CoreBinaryWriter writer)
  550. {
  551. base.SerializeBinary(writer);
  552. writer.Write(Tables.Count);
  553. foreach(var (name, table) in Tables)
  554. {
  555. writer.Write(name);
  556. table.SerializeBinary(writer);
  557. }
  558. }
  559. }
  560. public enum ValidationStatus
  561. {
  562. VALID,
  563. INVALID,
  564. REQUIRE_2FA,
  565. PASSWORD_EXPIRED
  566. }
  567. public class ValidateRequest : Request, ISerializeBinary
  568. {
  569. public string? UserID { get; set; }
  570. public string? Password { get; set; }
  571. public string? PIN { get; set; }
  572. public bool UsePIN { get; set; }
  573. public override RequestMethod GetMethod() => RequestMethod.Validate;
  574. public override void SerializeBinary(CoreBinaryWriter writer)
  575. {
  576. base.SerializeBinary(writer);
  577. writer.Write(UserID ?? string.Empty);
  578. writer.Write(Password ?? string.Empty);
  579. writer.Write(PIN ?? string.Empty);
  580. writer.Write(UsePIN);
  581. }
  582. public override void DeserializeBinary(CoreBinaryReader reader)
  583. {
  584. base.DeserializeBinary(reader);
  585. UserID = reader.ReadString();
  586. Password = reader.ReadString();
  587. PIN = reader.ReadString();
  588. UsePIN = reader.ReadBoolean();
  589. }
  590. }
  591. public class ValidateResponse : Response, ISerializeBinary
  592. {
  593. public ValidationStatus ValidationStatus { get; set; }
  594. public Guid UserGuid { get; set; }
  595. public string? UserID { get; set; }
  596. public Guid SecurityID { get; set; }
  597. public Guid Session { get; set; }
  598. public string? Recipient2FA { get; set; }
  599. public DateTime PasswordExpiration { get; set; }
  600. public override void SerializeBinary(CoreBinaryWriter writer)
  601. {
  602. base.SerializeBinary(writer);
  603. writer.Write((int)ValidationStatus);
  604. writer.Write(UserGuid);
  605. writer.Write(UserID ?? string.Empty);
  606. writer.Write(SecurityID);
  607. writer.Write(Session);
  608. writer.Write(Recipient2FA ?? string.Empty);
  609. writer.Write(PasswordExpiration.ToUniversalTime().Ticks);
  610. }
  611. public override void DeserializeBinary(CoreBinaryReader reader)
  612. {
  613. base.DeserializeBinary(reader);
  614. ValidationStatus = (ValidationStatus)reader.ReadInt32();
  615. UserGuid = reader.ReadGuid();
  616. UserID = reader.ReadString();
  617. SecurityID = reader.ReadGuid();
  618. Session = reader.ReadGuid();
  619. Recipient2FA = reader.ReadString();
  620. PasswordExpiration = new DateTime(reader.ReadInt64(), DateTimeKind.Utc).ToLocalTime();
  621. }
  622. }
  623. public class Check2FARequest : Request, ISerializeBinary
  624. {
  625. public string Code { get; set; }
  626. [JsonConstructor]
  627. public Check2FARequest()
  628. {
  629. Code = "";
  630. }
  631. public Check2FARequest(string code)
  632. {
  633. Code = code;
  634. }
  635. public override RequestMethod GetMethod() => RequestMethod.Check2FA;
  636. public override void SerializeBinary(CoreBinaryWriter writer)
  637. {
  638. base.SerializeBinary(writer);
  639. writer.Write(Code);
  640. }
  641. public override void DeserializeBinary(CoreBinaryReader reader)
  642. {
  643. base.DeserializeBinary(reader);
  644. Code = reader.ReadString();
  645. }
  646. }
  647. public class Check2FAResponse : Response, ISerializeBinary
  648. {
  649. public bool Valid { get; set; }
  650. [JsonConstructor]
  651. public Check2FAResponse()
  652. {
  653. }
  654. public Check2FAResponse(bool valid)
  655. {
  656. Valid = valid;
  657. }
  658. public override void SerializeBinary(CoreBinaryWriter writer)
  659. {
  660. base.SerializeBinary(writer);
  661. writer.Write(Valid);
  662. }
  663. public override void DeserializeBinary(CoreBinaryReader reader)
  664. {
  665. base.DeserializeBinary(reader);
  666. Valid = reader.ReadBoolean();
  667. }
  668. }
  669. public class PingRequest : Request, ISerializeBinary
  670. {
  671. public override RequestMethod GetMethod() => RequestMethod.Ping;
  672. }
  673. public class PingResponse : Response, ISerializeBinary { }
  674. public class InfoRequest : Request, ISerializeBinary
  675. {
  676. public override RequestMethod GetMethod() => RequestMethod.Info;
  677. }
  678. public class DatabaseInfo : ISerializeBinary
  679. {
  680. public string? ColorScheme { get; set; }
  681. public byte[]? Logo { get; set; }
  682. public string Version { get; set; }
  683. public bool IsHTTPS { get; set; }
  684. // Ideally, we should not need these. However, there is currently a bug in RPCServer
  685. // that crashes the server when uploading large files (ie photos)
  686. // So we need to be a able to maintain both a Rest and RPC-style connection
  687. // to the server to try and have both session (RPC) capabilities
  688. // as well as having stable upload performance :-(
  689. // Once the RPC listeners are stable, then this needs to be removed.
  690. public int RestPort { get; set; }
  691. public int RPCPort { get; set; }
  692. public Guid DatabaseID { get; set; }
  693. [JsonConstructor]
  694. public DatabaseInfo()
  695. {
  696. Version = "";
  697. }
  698. public DatabaseInfo(string? colorScheme, byte[]? logo, string version, bool isHTTTPS, int restPort, int rpcPort, Guid databaseID)
  699. {
  700. ColorScheme = colorScheme;
  701. Logo = logo;
  702. Version = version;
  703. IsHTTPS = isHTTTPS;
  704. RestPort = restPort;
  705. RPCPort = rpcPort;
  706. DatabaseID = databaseID;
  707. }
  708. public void SerializeBinary(CoreBinaryWriter writer)
  709. {
  710. writer.Write(ColorScheme ?? string.Empty);
  711. if (Logo is null)
  712. {
  713. writer.Write(0);
  714. }
  715. else
  716. {
  717. writer.Write(Logo.Length);
  718. writer.Write(Logo);
  719. }
  720. writer.Write(Version);
  721. writer.Write(IsHTTPS);
  722. if (String.CompareOrdinal(writer.Settings.Version, "1.1") > 0)
  723. {
  724. writer.Write(RestPort);
  725. writer.Write(RPCPort);
  726. }
  727. writer.Write(DatabaseID);
  728. }
  729. public void DeserializeBinary(CoreBinaryReader reader)
  730. {
  731. ColorScheme = reader.ReadString();
  732. var nLogoBytes = reader.ReadInt32();
  733. Logo = reader.ReadBytes(nLogoBytes);
  734. Version = reader.ReadString();
  735. IsHTTPS = reader.ReadBoolean();
  736. if (String.CompareOrdinal(reader.Settings.Version, "1.1") > 0)
  737. {
  738. try
  739. {
  740. RestPort = reader.ReadInt32();
  741. RPCPort = reader.ReadInt32();
  742. }
  743. catch
  744. {
  745. Logger.Send(LogType.Error,"","Unable to read RestPort and RPCPort Values");
  746. }
  747. }
  748. DatabaseID = reader.ReadGuid();
  749. }
  750. }
  751. public class InfoResponse : Response, ISerializeBinary
  752. {
  753. public DatabaseInfo Info { get; set; }
  754. [JsonConstructor]
  755. public InfoResponse() : base()
  756. {
  757. Info = new DatabaseInfo();
  758. }
  759. public InfoResponse(DatabaseInfo info)
  760. {
  761. Info = info;
  762. }
  763. public override void SerializeBinary(CoreBinaryWriter writer)
  764. {
  765. base.SerializeBinary(writer);
  766. Info.SerializeBinary(writer);
  767. }
  768. public override void DeserializeBinary(CoreBinaryReader reader)
  769. {
  770. base.DeserializeBinary(reader);
  771. Info.DeserializeBinary(reader);
  772. }
  773. }
  774. public class VersionRequest : Request, ISerializeBinary
  775. {
  776. public override RequestMethod GetMethod() => RequestMethod.Version;
  777. }
  778. public class VersionResponse : Response, ISerializeBinary
  779. {
  780. public string Version { get; set; } = "";
  781. public override void SerializeBinary(CoreBinaryWriter writer)
  782. {
  783. base.SerializeBinary(writer);
  784. writer.Write(Version);
  785. }
  786. public override void DeserializeBinary(CoreBinaryReader reader)
  787. {
  788. base.DeserializeBinary(reader);
  789. Version = reader.ReadString();
  790. }
  791. }
  792. public class ReleaseNotesRequest : Request, ISerializeBinary
  793. {
  794. public override RequestMethod GetMethod() => RequestMethod.ReleaseNotes;
  795. }
  796. public class ReleaseNotesResponse : Response, ISerializeBinary
  797. {
  798. public string ReleaseNotes { get; set; } = "";
  799. public override void SerializeBinary(CoreBinaryWriter writer)
  800. {
  801. base.SerializeBinary(writer);
  802. writer.Write(ReleaseNotes);
  803. }
  804. public override void DeserializeBinary(CoreBinaryReader reader)
  805. {
  806. base.DeserializeBinary(reader);
  807. ReleaseNotes = reader.ReadString();
  808. }
  809. }
  810. public class InstallerRequest : Request, ISerializeBinary
  811. {
  812. public override RequestMethod GetMethod() => RequestMethod.Installer;
  813. }
  814. public class InstallerResponse : Response, ISerializeBinary
  815. {
  816. public byte[]? Installer { get; set; }
  817. public override void SerializeBinary(CoreBinaryWriter writer)
  818. {
  819. base.SerializeBinary(writer);
  820. if(Installer != null)
  821. {
  822. writer.Write(Installer.Length);
  823. writer.Write(Installer);
  824. }
  825. else
  826. {
  827. writer.Write(0);
  828. }
  829. }
  830. public override void DeserializeBinary(CoreBinaryReader reader)
  831. {
  832. base.DeserializeBinary(reader);
  833. Installer = reader.ReadBytes(reader.ReadInt32());
  834. if(Installer.Length == 0)
  835. {
  836. Installer = null;
  837. }
  838. }
  839. }
  840. public static class Extensions
  841. {
  842. public static T Status<T>(this T response, StatusCode status) where T : Response
  843. {
  844. response.Status = status;
  845. return response;
  846. }
  847. }
  848. public class RequestException : Exception
  849. {
  850. public StatusCode Status { get; set; }
  851. public RequestMethod Method { get; set; }
  852. public RequestException(string message, StatusCode status, Request request): base(message)
  853. {
  854. Status = status;
  855. Method = request.GetMethod();
  856. }
  857. }
  858. }