4using System.Runtime.ExceptionServices;
6using System.Text.RegularExpressions;
7using System.Threading.Tasks;
34 internal static readonly Regex FromSaveUnsavedRegex =
new Regex(
@"Waher[.]Persistence[.]Files[.]ObjectBTreeFile[.+]((<SaveUnsaved>\w*[.]\w*)|(SaveUnsavedLocked))",
35 RegexOptions.Compiled | RegexOptions.Singleline);
36 internal static readonly Regex FromUpdateObjectRegex =
new Regex(
@"Waher[.]Persistence[.]Files[.]ObjectBTreeFile[.+]((<UpdateObject>\w*[.]\w*)|(UpdateObjectLocked))",
37 RegexOptions.Compiled | RegexOptions.Singleline);
38 internal static readonly Regex GatewayStartupRegex =
new Regex(
@"Waher[.]IoTGateway[.]Gateway([.]Start|[.+]<?Start>?\w*[.]\w*)",
39 RegexOptions.Compiled | RegexOptions.Singleline);
40 internal static readonly Regex ApplyLegalIdentityRegex =
new Regex(
@"Waher[.]IoTGateway[.]Setup[.]LegalIdentityConfiguration([.]ApplyLegalIdentity|[.+]<?ApplyLegalIdentity>?\w*[.]\w*)",
41 RegexOptions.Compiled | RegexOptions.Singleline);
42 internal static readonly Regex ApplyIdRegex =
new Regex(
@"Waher[.]IoTGateway[.]Setup[.]LegalIdentityConfiguration([.]ApplyId|[.+]<?ApplyId>?\w*[.]\w*)",
43 RegexOptions.Compiled | RegexOptions.Singleline);
44 internal static readonly Regex GenerateNewKeysRegex =
new Regex(
@"Waher[.]Networking[.]XMPP[.]Contracts[.]ContractsClient([.]GenerateNewKeys|[.+]<?GenerateNewKeys>?\w*[.]\w*)",
45 RegexOptions.Compiled | RegexOptions.Singleline);
46 internal static readonly Regex GetAttachmentRegex =
new Regex(
@"Waher[.]Networking[.]XMPP[.]Contracts[.]ContractsClient[.+]<?GetAttachmentAsync>?\w*[.]\w*",
47 RegexOptions.Compiled | RegexOptions.Singleline);
48 internal static readonly Regex CreateCredentialRegex =
new Regex(
@"Waher[.]Security[.]TOTP[.]ExternalCredential[.+](CreateAsync|<?CreateAsync>?\w*[.]\w*)",
49 RegexOptions.Compiled | RegexOptions.Singleline);
50 internal static readonly Regex ExportCredentialsRegex =
new Regex(
@"Waher[.]Security[.]TOTP[.]ExternalCredential[.+](ExportAsync|<?ExportAsync>?\w*[.]\w*)",
51 RegexOptions.Compiled | RegexOptions.Singleline);
54 "Waher.Persistence.NeuroLedger.NeuroLedgerProvider",
55 typeof(Content.Markdown.Web.MarkdownToHtmlConverter),
56 "Waher.IoTGateway.Setup.LegalIdentityConfiguration.UpdateClients",
58 FromUpdateObjectRegex,
63 "Waher.Service.IoTBroker.Legal.MFA.QuickLogin",
64 "Waher.Service.IoTBroker.Marketplace.MarketplaceProcessor",
65 "Waher.Service.IoTBroker.WebServices.Agent.Account.RemoteQuickLogin",
66 "Waher.Service.Abc4Io.Model.Actions.Contract.SignContract",
67 ApplyLegalIdentityRegex,
75 typeof(Content.Markdown.Web.MarkdownToHtmlConverter),
77 FromUpdateObjectRegex,
79 CreateCredentialRegex,
80 ExportCredentialsRegex
90 private bool useLegalIdentity =
false;
91 private bool protectWithPassword =
false;
92 private string firstName =
string.Empty;
93 private string middleName =
string.Empty;
94 private string lastName =
string.Empty;
95 private string personalNumber =
string.Empty;
96 private string address =
string.Empty;
97 private string address2 =
string.Empty;
98 private string postalCode =
string.Empty;
99 private string area =
string.Empty;
100 private string city =
string.Empty;
101 private string region =
string.Empty;
102 private string country =
string.Empty;
103 private string nationality =
string.Empty;
104 private string gender =
string.Empty;
105 private string orgName =
string.Empty;
106 private string orgDepartment =
string.Empty;
107 private string orgRole =
string.Empty;
108 private string orgNumber =
string.Empty;
109 private string orgAddress =
string.Empty;
110 private string orgAddress2 =
string.Empty;
111 private string orgPostalCode =
string.Empty;
112 private string orgArea =
string.Empty;
113 private string orgCity =
string.Empty;
114 private string orgRegion =
string.Empty;
115 private string orgCountry =
string.Empty;
118 private DateTime checkApprovedExpiry = DateTime.MinValue;
119 private DateTime? birthDate =
null;
136 [DefaultValue(
false)]
139 get => this.useLegalIdentity;
140 set => this.useLegalIdentity = value;
146 [DefaultValueStringEmpty]
149 get => this.firstName;
150 set => this.firstName = value;
156 [DefaultValueStringEmpty]
159 get => this.middleName;
160 set => this.middleName = value;
166 [DefaultValueStringEmpty]
169 get => this.lastName;
170 set => this.lastName = value;
176 [DefaultValueStringEmpty]
179 get => this.personalNumber;
180 set => this.personalNumber = value;
186 [DefaultValueStringEmpty]
190 set => this.address = value;
196 [DefaultValueStringEmpty]
199 get => this.address2;
200 set => this.address2 = value;
206 [DefaultValueStringEmpty]
209 get => this.postalCode;
210 set => this.postalCode = value;
216 [DefaultValueStringEmpty]
220 set => this.area = value;
226 [DefaultValueStringEmpty]
230 set => this.city = value;
236 [DefaultValueStringEmpty]
240 set => this.region = value;
246 [DefaultValueStringEmpty]
250 set => this.country = value;
256 [DefaultValueStringEmpty]
259 get => this.nationality;
260 set => this.nationality = value;
266 [DefaultValueStringEmpty]
270 set => this.gender = value;
279 get => this.birthDate;
280 set => this.birthDate = value;
286 [DefaultValueStringEmpty]
290 set => this.orgName = value;
296 [DefaultValueStringEmpty]
299 get => this.orgDepartment;
300 set => this.orgDepartment = value;
306 [DefaultValueStringEmpty]
310 set => this.orgRole = value;
316 [DefaultValueStringEmpty]
319 get => this.orgNumber;
320 set => this.orgNumber = value;
326 [DefaultValueStringEmpty]
329 get => this.orgAddress;
330 set => this.orgAddress = value;
336 [DefaultValueStringEmpty]
339 get => this.orgAddress2;
340 set => this.orgAddress2 = value;
346 [DefaultValueStringEmpty]
349 get => this.orgPostalCode;
350 set => this.orgPostalCode = value;
356 [DefaultValueStringEmpty]
360 set => this.orgArea = value;
366 [DefaultValueStringEmpty]
370 set => this.orgCity = value;
376 [DefaultValueStringEmpty]
379 get => this.orgRegion;
380 set => this.orgRegion = value;
386 [DefaultValueStringEmpty]
389 get => this.orgCountry;
390 set => this.orgCountry = value;
399 get => this.altFields;
400 set => this.altFields = value;
406 [DefaultValue(
false)]
409 get => this.protectWithPassword;
412 if (this.protectWithPassword != value)
414 if (this.protectWithPassword)
417 this.protectWithPassword = value;
430 if (!(this.passwordHashes is
null))
433 return this.passwordHashes;
438 if (!(this.passwordHashes is
null))
441 this.passwordHashes = value;
448 public override string Resource =>
"/Settings/LegalIdentity.md";
480 await this.AddHandlers();
483 private async Task AddHandlers()
487 this.handlersAdded =
true;
490 Gateway.XmppClient.OnStateChanged += this.XmppClient_OnStateChanged;
492 Gateway.ContractsClient.ContractDeleted += this.ContractsClient_ContractDeleted;
493 Gateway.ContractsClient.ContractSigned += this.ContractsClient_ContractSigned;
494 Gateway.ContractsClient.ContractUpdated += this.ContractsClient_ContractUpdated;
495 Gateway.ContractsClient.IdentityUpdated += this.ContractsClient_IdentityUpdated;
496 Gateway.ContractsClient.PetitionedIdentityResponseReceived += this.ContractsClient_PetitionedIdentityResponseReceived;
497 Gateway.ContractsClient.PetitionedContractResponseReceived += this.ContractsClient_PetitionedContractResponseReceived;
503 await this.GetLegalIdentities(
null);
507 private bool handlersAdded =
false;
510 private async Task XmppClient_OnStateChanged(
object Sender,
XmppState NewState)
513 await this.GetLegalIdentities(
null);
516 private Task GetLegalIdentities(
object P)
519 return Task.CompletedTask;
525 approvedIdentities = this.SetLegalIdentities(e.Identities, null, false);
526 allIdentities = this.SetLegalIdentities(e.Identities, null, true);
531 return Task.CompletedTask;
538 List<LegalIdentity> Result =
new List<LegalIdentity>();
542 if (!(Identities is
null))
546 if (Changed is
null || ID.
Id != Changed.
Id)
554 if (All || ID2.
State == Networking.XMPP.Contracts.IdentityState.Approved)
559 if (!Added && !(Changed is
null) && (All || Changed.
State == Networking.XMPP.Contracts.IdentityState.Approved))
562 Result.Sort((i1, i2) => Math.Sign((i2.Created - i1.Created).Ticks));
564 return Result.ToArray();
575 return allIdentities;
586 List<Dictionary<string, object>> Result =
new List<Dictionary<string, object>>();
588 if (!(allIdentities is
null))
592 Dictionary<string, object> ID2 =
new Dictionary<string, object>()
595 {
"Created", ID.Created },
596 {
"Properties", ID.Properties },
597 {
"Attachments", ID.Attachments },
600 {
"State", ID.State },
640 return Result.ToArray();
652 return approvedIdentities;
676 if (allIdentities is
null)
681 if (LegalId == ID.
Id)
698 if (approvedIdentities is
null)
703 if (LegalId == ID.
Id)
714 List<KeyValuePair<string, object>> Tags =
new List<KeyValuePair<string, object>>()
716 new KeyValuePair<string, object>(
"State", ID.
State),
717 new KeyValuePair<string, object>(
"Provider", ID.
Provider),
718 new KeyValuePair<string, object>(
"Created", ID.
Created),
719 new KeyValuePair<string, object>(
"Updated", ID.
Updated),
720 new KeyValuePair<string, object>(
"From", ID.
From),
721 new KeyValuePair<string, object>(
"KeyAlgorithm", ID.
ClientKeyName),
722 new KeyValuePair<string, object>(
"PublicKey", Convert.ToBase64String(ID.
ClientPubKey))
726 Tags.Add(
new KeyValuePair<string, object>(P.
Name, P.
Value));
730 await this.UpdateClients(ID);
735 allIdentities = this.SetLegalIdentities(allIdentities, ID,
true);
736 approvedIdentities = this.SetLegalIdentities(approvedIdentities, ID,
false);
738 return this.UpdateClients();
741 private async Task UpdateClients()
750 if (TabIDs.Length > 0)
752 string FileName = Path.Combine(
Gateway.
RootFolder,
"Settings",
"LegalIdentities.md");
753 if (File.Exists(FileName))
771 return Task.CompletedTask;
777 return Task.CompletedTask;
783 return Task.CompletedTask;
792 this.applyLegalIdentity = WebServer.
Register(
"/Settings/ApplyLegalIdentity",
null, this.ApplyLegalIdentity,
true,
false,
true);
793 this.contractAction = WebServer.
Register(
"/Settings/ContractAction",
null, this.ContractAction,
true,
false,
true);
795 this.checkApprovedExpiry =
Gateway.
ScheduleEvent(this.CheckApprovedExpiry, DateTime.Now.AddMinutes(5),
true);
797 return base.InitSetup(WebServer);
806 WebServer.
Unregister(this.applyLegalIdentity);
810 this.checkApprovedExpiry = DateTime.MinValue;
812 return base.UnregisterSetup(WebServer);
815 private async Task CheckApprovedExpiry(
object State)
817 if (!(State is
bool Reschedule))
820 DateTime Now = DateTime.Now;
821 DateTime Today = Now.Date;
824 this.checkApprovedExpiry =
Gateway.
ScheduleEvent(this.CheckApprovedExpiry, Today.AddDays(1).AddMinutes(5),
true);
826 if (!this.useLegalIdentity)
842 int Days = (int)(Expires - Today).TotalDays;
849 await
Gateway.
SendNotification(
"The approved Legal Identity for the gateway **expires today**.",
string.Empty);
853 await
Gateway.
SendNotification(
"The approved Legal Identity for the gateway **expires tomorrow**.",
string.Empty);
857 await
Gateway.
SendNotification(
"The approved Legal Identity for the gateway **expires in " + Days.ToString() +
" days**.",
string.Empty);
877 await this.AddHandlers();
879 return await base.SetupConfiguration(WebServer);
898 if (Content.
HasError || !(Content.
Decoded is Dictionary<string, object> Parameters))
904 if (!Parameters.TryGetValue(
"protectWithPassword", out
object Obj) || !(Obj is
bool ProtectWithPassword) ||
905 !Parameters.TryGetValue(
"password", out Obj) || !(Obj is
string Password) ||
906 !Parameters.TryGetValue(
"password2", out Obj) || !(Obj is
string Password2) ||
907 !Parameters.TryGetValue(
"firstName", out Obj) || !(Obj is
string FirstName) ||
908 !Parameters.TryGetValue(
"middleName", out Obj) || !(Obj is
string MiddleName) ||
909 !Parameters.TryGetValue(
"lastName", out Obj) || !(Obj is
string LastName) ||
910 !Parameters.TryGetValue(
"pNr", out Obj) || !(Obj is
string PNr) ||
911 !Parameters.TryGetValue(
"address", out Obj) || !(Obj is
string Address) ||
912 !Parameters.TryGetValue(
"address2", out Obj) || !(Obj is
string Address2) ||
913 !Parameters.TryGetValue(
"postalCode", out Obj) || !(Obj is
string PostalCode) ||
914 !Parameters.TryGetValue(
"area", out Obj) || !(Obj is
string Area) ||
915 !Parameters.TryGetValue(
"city", out Obj) || !(Obj is
string City) ||
916 !Parameters.TryGetValue(
"region", out Obj) || !(Obj is
string Region) ||
917 !Parameters.TryGetValue(
"country", out Obj) || !(Obj is
string Country) ||
918 !Parameters.TryGetValue(
"nationality", out Obj) || !(Obj is
string Nationality) ||
919 !Parameters.TryGetValue(
"gender", out Obj) || !(Obj is
string Gender) ||
920 !Parameters.TryGetValue(
"birthDate", out Obj) || !(Obj is
string BirthDateStr) ||
921 !Parameters.TryGetValue(
"orgName", out Obj) || !(Obj is
string OrgName) ||
922 !Parameters.TryGetValue(
"orgDepartment", out Obj) || !(Obj is
string OrgDepartment) ||
923 !Parameters.TryGetValue(
"orgRole", out Obj) || !(Obj is
string OrgRole) ||
924 !Parameters.TryGetValue(
"orgNr", out Obj) || !(Obj is
string OrgNr) ||
925 !Parameters.TryGetValue(
"orgAddress", out Obj) || !(Obj is
string OrgAddress) ||
926 !Parameters.TryGetValue(
"orgAddress2", out Obj) || !(Obj is
string OrgAddress2) ||
927 !Parameters.TryGetValue(
"orgPostalCode", out Obj) || !(Obj is
string OrgPostalCode) ||
928 !Parameters.TryGetValue(
"orgArea", out Obj) || !(Obj is
string OrgArea) ||
929 !Parameters.TryGetValue(
"orgCity", out Obj) || !(Obj is
string OrgCity) ||
930 !Parameters.TryGetValue(
"orgRegion", out Obj) || !(Obj is
string OrgRegion) ||
931 !Parameters.TryGetValue(
"orgCountry", out Obj) || !(Obj is
string OrgCountry))
939 if (
string.IsNullOrEmpty(Password))
945 if (Password != Password2)
954 if (Parameters.TryGetValue(
"alternative", out Obj) && Obj is Dictionary<string, object> Alternative)
956 foreach (KeyValuePair<string, object> P
in Alternative)
958 switch (P.Key.ToUpper())
997 string TabID = Request.
Header[
"X-TabID"];
998 if (
string.IsNullOrEmpty(TabID))
1004 if (!
string.IsNullOrEmpty(BirthDateStr))
1006 if (!DateTime.TryParse(BirthDateStr, out DateTime
BirthDate))
1015 this.birthDate =
null;
1017 this.useLegalIdentity =
true;
1021 this.personalNumber = PNr;
1034 this.orgNumber = OrgNr;
1046 Response.StatusCode = 200;
1047 Response.StatusMessage =
"OK";
1056 public Task
Reapply(TaskCompletionSource<bool> Response)
1058 return this.ApplyId(
null,
null,
false,
true, Response);
1062 bool Reapplication, TaskCompletionSource<bool> Response)
1071 object[] P = (
object[])e.
State;
1072 string Password = (
string)P[0];
1073 string TabID = (string)P[1];
1075 bool Reapplication = (bool)P[3];
1076 TaskCompletionSource<bool> Response = (TaskCompletionSource<bool>)P[4];
1086 Dictionary<string, AlternativeField> ById =
new Dictionary<string, AlternativeField>();
1088 if (!(this.passwordHashes is
null))
1097 ById.Values.CopyTo(
Hashes, 0);
1099 this.passwordHashes =
Hashes;
1105 if (!
string.IsNullOrEmpty(TabID))
1109 await this.UpdateClients(e.
Identity);
1111 Response?.TrySetResult(
true);
1115 if (!
string.IsNullOrEmpty(TabID))
1118 Response?.TrySetResult(
false);
1122 private string CalcPasswordHash(
LegalIdentity ID,
string Password)
1124 StringBuilder sb =
new StringBuilder();
1125 SortedDictionary<string, string> Sorted =
new SortedDictionary<string, string>();
1129 if (Sorted.TryGetValue(P.
Name, out
string s))
1140 foreach (KeyValuePair<string, string> P
in Sorted)
1154 return Convert.ToBase64String(Digest);
1159 List<Property> Properties =
new List<Property>();
1161 if (!
string.IsNullOrEmpty(this.firstName))
1164 if (!
string.IsNullOrEmpty(this.middleName))
1167 if (!
string.IsNullOrEmpty(this.lastName))
1170 if (!
string.IsNullOrEmpty(this.personalNumber))
1173 if (!
string.IsNullOrEmpty(this.address))
1176 if (!
string.IsNullOrEmpty(this.address2))
1179 if (!
string.IsNullOrEmpty(this.postalCode))
1182 if (!
string.IsNullOrEmpty(this.area))
1185 if (!
string.IsNullOrEmpty(this.city))
1188 if (!
string.IsNullOrEmpty(this.region))
1191 if (!
string.IsNullOrEmpty(this.country))
1194 if (!
string.IsNullOrEmpty(this.nationality))
1197 if (!
string.IsNullOrEmpty(this.gender))
1200 if (!(this.birthDate is
null))
1207 if (!
string.IsNullOrEmpty(this.orgName))
1210 if (!
string.IsNullOrEmpty(this.orgDepartment))
1213 if (!
string.IsNullOrEmpty(this.orgRole))
1216 if (!
string.IsNullOrEmpty(this.orgNumber))
1219 if (!
string.IsNullOrEmpty(this.orgAddress))
1222 if (!
string.IsNullOrEmpty(this.orgAddress2))
1225 if (!
string.IsNullOrEmpty(this.orgPostalCode))
1228 if (!
string.IsNullOrEmpty(this.orgArea))
1231 if (!
string.IsNullOrEmpty(this.orgCity))
1234 if (!
string.IsNullOrEmpty(this.orgRegion))
1237 if (!
string.IsNullOrEmpty(this.orgCountry))
1240 if (!(this.altFields is
null))
1243 Properties.Add(
new Property(F.Key, F.Value));
1246 return Properties.ToArray();
1261 if (Content.
HasError || !(Content.
Decoded is Dictionary<string, object> Parameters))
1267 if (!Parameters.TryGetValue(
"requestId", out
object Obj) || !(Obj is
string RequestId) ||
1268 !Parameters.TryGetValue(
"sign", out Obj) || !(Obj is
bool Sign) ||
1269 !Parameters.TryGetValue(
"protect", out Obj) || !(Obj is
bool Protect))
1277 if (!Parameters.TryGetValue(
"password", out Obj) || !(Obj is
string s))
1286 Password =
string.Empty;
1289 if (SignatureRequest is
null)
1295 if (SignatureRequest.
Signed.HasValue)
1310 if (
string.IsNullOrEmpty(Id))
1316 else if (this.protectWithPassword)
1327 SignatureRequest.Signed = DateTime.Now;
1333 Response.StatusCode = 200;
1334 Response.StatusMessage =
"OK";
1345 get => !(approvedIdentities is
null) && approvedIdentities.Length > 0;
1362 if (Latest is
null || Identity.
Created > Latest.Created)
1389 return DateTime.MinValue;
1402 if (approvedIdentities is
null || approvedIdentities.Length == 0)
1407 string H = this.CalcPasswordHash(ID, Password);
1435 EventHandlerAsync<LegalIdentityPetitionResponseEventArgs> Callback, TimeSpan Timeout,
1438 if (this.protectWithPassword)
1439 throw new ForbiddenException(Request,
"Petitioning legal identities is protected using passwords on this machine.");
1455 EventHandlerAsync<LegalIdentityPetitionResponseEventArgs> Callback, TimeSpan Timeout)
1460 if (this.protectWithPassword)
1463 if (
string.IsNullOrEmpty(Id))
1467 lock (this.identityPetitionCallbackMethods)
1469 if (this.identityPetitionCallbackMethods.ContainsKey(PetitionId))
1470 throw new ArgumentException(
"Petition ID already used.", nameof(PetitionId));
1472 this.identityPetitionCallbackMethods[PetitionId] = Callback;
1483 }, DateTime.Now.Add(Timeout), PetitionId);
1485 catch (Exception ex)
1487 lock (this.identityPetitionCallbackMethods)
1489 this.identityPetitionCallbackMethods.Remove(PetitionId);
1492 ExceptionDispatchInfo.Capture(ex).Throw();
1510 EventHandlerAsync<ContractPetitionResponseEventArgs> Callback, TimeSpan Timeout,
1513 if (this.protectWithPassword)
1514 throw new ForbiddenException(Request,
"Petitioning legal identities is protected using passwords on this machine.");
1516 return this.
PetitionContract(ContractId, PetitionId, Purpose,
string.Empty, Callback, Timeout);
1529 public async Task<bool>
PetitionContract(
string ContractId,
string PetitionId,
string Purpose,
string Password,
1530 EventHandlerAsync<ContractPetitionResponseEventArgs> Callback, TimeSpan Timeout)
1535 if (this.protectWithPassword)
1538 if (
string.IsNullOrEmpty(Id))
1542 lock (this.contractPetitionCallbackMethods)
1544 if (this.contractPetitionCallbackMethods.ContainsKey(PetitionId))
1545 throw new ArgumentException(
"Petition ID already used.", nameof(PetitionId));
1547 this.contractPetitionCallbackMethods[PetitionId] = Callback;
1558 }, DateTime.Now.Add(Timeout), PetitionId);
1560 catch (Exception ex)
1562 lock (this.contractPetitionCallbackMethods)
1564 this.contractPetitionCallbackMethods.Remove(PetitionId);
1567 ExceptionDispatchInfo.Capture(ex).Throw();
1573 private readonly Dictionary<string, EventHandlerAsync<LegalIdentityPetitionResponseEventArgs>> identityPetitionCallbackMethods =
new Dictionary<string, EventHandlerAsync<LegalIdentityPetitionResponseEventArgs>>();
1574 private readonly Dictionary<string, EventHandlerAsync<ContractPetitionResponseEventArgs>> contractPetitionCallbackMethods =
new Dictionary<string, EventHandlerAsync<ContractPetitionResponseEventArgs>>();
1578 EventHandlerAsync<LegalIdentityPetitionResponseEventArgs> Callback;
1581 lock (this.identityPetitionCallbackMethods)
1583 if (!this.identityPetitionCallbackMethods.TryGetValue(PetitionId, out Callback))
1584 return Task.CompletedTask;
1586 this.identityPetitionCallbackMethods.Remove(PetitionId);
1589 return Callback.Raise(Sender, e);
1594 EventHandlerAsync<ContractPetitionResponseEventArgs> Callback;
1597 lock (this.contractPetitionCallbackMethods)
1599 if (!this.contractPetitionCallbackMethods.TryGetValue(PetitionId, out Callback))
1600 return Task.CompletedTask;
1602 this.contractPetitionCallbackMethods.Remove(PetitionId);
1605 return Callback.Raise(Sender, e);
1614 return Task.FromResult(
true);
1772 if (!this.useLegalIdentity)
1775 this.firstName = Environment.GetEnvironmentVariable(
GATEWAY_ID_FIRST) ??
string.Empty;
1776 this.middleName = Environment.GetEnvironmentVariable(
GATEWAY_ID_MIDDLE) ??
string.Empty;
1777 this.lastName = Environment.GetEnvironmentVariable(
GATEWAY_ID_LAST) ??
string.Empty;
1778 this.personalNumber = Environment.GetEnvironmentVariable(
GATEWAY_ID_PNR) ??
string.Empty;
1779 this.address = Environment.GetEnvironmentVariable(
GATEWAY_ID_ADDR) ??
string.Empty;
1780 this.address2 = Environment.GetEnvironmentVariable(
GATEWAY_ID_ADDR2) ??
string.Empty;
1781 this.postalCode = Environment.GetEnvironmentVariable(
GATEWAY_ID_ZIP) ??
string.Empty;
1782 this.area = Environment.GetEnvironmentVariable(
GATEWAY_ID_AREA) ??
string.Empty;
1783 this.city = Environment.GetEnvironmentVariable(
GATEWAY_ID_CITY) ??
string.Empty;
1784 this.region = Environment.GetEnvironmentVariable(
GATEWAY_ID_REGION) ??
string.Empty;
1785 this.country = Environment.GetEnvironmentVariable(
GATEWAY_ID_COUNTRY) ??
string.Empty;
1787 this.gender = Environment.GetEnvironmentVariable(
GATEWAY_ID_GENDER) ??
string.Empty;
1788 this.orgName = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGNAME) ??
string.Empty;
1789 this.orgDepartment = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGDEPT) ??
string.Empty;
1790 this.orgRole = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGROLE) ??
string.Empty;
1791 this.orgNumber = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGNR) ??
string.Empty;
1792 this.orgAddress = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGADDR) ??
string.Empty;
1793 this.orgAddress2 = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGADDR2) ??
string.Empty;
1794 this.orgPostalCode = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGZIP) ??
string.Empty;
1795 this.orgArea = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGAREA) ??
string.Empty;
1796 this.orgCity = Environment.GetEnvironmentVariable(
GATEWAY_ID_ORGCITY) ??
string.Empty;
1803 List<AlternativeField> Fields =
new List<AlternativeField>();
1807 string[] Parts = Value.Split(
',');
1809 foreach (
string Part in Parts)
1820 this.altFields = Fields.ToArray();
1824 TaskCompletionSource<bool> Result =
new TaskCompletionSource<bool>();
1827 Task
_ = Task.Delay(30000).ContinueWith(Prev => Result?.TrySetException(
new TimeoutException()));
1829 await this.ApplyId(Value,
null, !
string.IsNullOrEmpty(Value),
false, Result);
1831 if (await Result.Task)
1836 catch (Exception ex)
Contains information about a response to a content request.
bool HasError
If an error occurred.
object Decoded
Decoded object.
static string GetBody(string Html)
Extracts the contents of the BODY element in a HTML string.
Helps with common JSON-related tasks.
static string Encode(string s)
Encodes a string for inclusion in JSON.
const string DefaultContentType
application/json
Contains a markdown document. This markdown document class supports original markdown,...
async Task< string > GenerateHTML()
Generates HTML from the markdown text.
static Task< MarkdownDocument > CreateAsync(string MarkdownText, params Type[] TransparentExceptionTypes)
Contains a markdown document. This markdown document class supports original markdown,...
Contains settings that the Markdown parser uses to customize its behavior.
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Notice(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a notice event.
The ClientEvents class allows applications to push information asynchronously to web clients connecte...
static string[] GetTabIDsForLocation(string Location)
Gets the Tab IDs of all tabs that display a particular resource.
static Task< int > PushEvent(string[] TabIDs, string Type, object Data)
Puses an event to a set of Tabs, given their Tab IDs.
static string[] GetTabIDs()
Gets all open Tab IDs.
Static class managing the runtime environment of the IoT Gateway.
static IUser AssertUserAuthenticated(HttpRequest Request, string Privilege)
Makes sure a request is being made from a session with a successful user login.
static bool Configuring
If the gateway is being configured.
static Task SendNotification(Graph Graph)
Sends a graph as a notification message to configured notification recipients.
static ContractsClient ContractsClient
XMPP Contracts Client, if such a compoent is available on the XMPP broker.
static DateTime ScheduleEvent(Action< object > Callback, DateTime When, object State)
Schedules a one-time event.
static Emoji1LocalFiles Emoji1_24x24
Emojis.
static XmppClient XmppClient
XMPP Client connection of gateway.
static string RootFolder
Web root folder.
static bool CancelScheduledEvent(DateTime When)
Cancels a scheduled event.
Represents an alternative field in a legal identity.
string Key
Alternative field name.
Contains information about a contract signature request.
DateTime? Signed
When contract was signed.
async Task< Contract > GetContract()
Gets the parsed contract.
void SetContract(Contract Contract)
Sets a parsed contract.
string Role
Requested role.
Configures legal identity for the gateway.
LegalIdentityConfiguration()
Configures legal identity for the gateway.
static bool TryGetMyIdentity(CaseInsensitiveString LegalId, out LegalIdentity Identity)
Tries to get one of the legal identities belonging to the current instance.
const string GATEWAY_ID_ORGDEPT
Organization department of legal identity.
Task< bool > PetitionLegalIdentity(string LegalId, string PetitionId, string Purpose, EventHandlerAsync< LegalIdentityPetitionResponseEventArgs > Callback, TimeSpan Timeout, HttpRequest Request)
Petitions information about a legal identity from its owner.
const string GATEWAY_ID_NATIONALITY
Nationality of legal identity.
const string GATEWAY_ID_ORGADDR2
Organization address(line 2) of legal identity.
string OrgArea
Organization Area
override async Task< bool > EnvironmentConfiguration()
Environment configuration by configuring values available in environment variables.
string GetPasswordLegalId(string Password)
Gets the legal identity that corresponds to a given password, from the corresponding hash digests.
AlternativeField[] AlternativeFields
Alternative fields.
string Nationality
Nationality
const string GATEWAY_ID_ORGROLE
Organization role of legal identity.
const string GATEWAY_ID_ORGNR
Organization number of legal identity.
const string GATEWAY_ID_AREA
Area of legal identity.
Task< bool > PetitionContract(string ContractId, string PetitionId, string Purpose, EventHandlerAsync< ContractPetitionResponseEventArgs > Callback, TimeSpan Timeout, HttpRequest Request)
Petitions information about a smart contract from its owner.
const string GATEWAY_ID_ALT_
Value for alternative field field to send in the identity application.
const string GATEWAY_ID_ADDR2
Address(line 2) of legal identity.
static LegalIdentityConfiguration Instance
Instance of configuration object.
Task Reapply(TaskCompletionSource< bool > Response)
Resends an identity application with the same properties as last time.
string OrgAddress2
Organization Address, 2nd row
static bool IsMe(CaseInsensitiveString LegalId)
Checks if a Legal Identity refers to the gateway.
string OrgPostalCode
Organization Postal Code (or zip code)
static DateTime LatestApprovedLegalIdentityExpires
Expiry date of latest approved legal identity.
string OrgName
Organization Name
const string GATEWAY_ID_ORGREGION
Organization region of legal identity.
const string GATEWAY_ID_REGION
Region of legal identity.
const string GATEWAY_ID_ORGAREA
Organization area of legal identity.
string OrgCountry
Organization Country
const string GATEWAY_ID_ORGADDR
Organization address (line 1) of legal identity.
async Task< bool > PetitionContract(string ContractId, string PetitionId, string Purpose, string Password, EventHandlerAsync< ContractPetitionResponseEventArgs > Callback, TimeSpan Timeout)
Petitions information about a smart contract from its owner.
string PersonalNumber
Personal number (or organizational number)
override Task InitSetup(HttpServer WebServer)
Initializes the setup object.
const string GATEWAY_ID_GENDER
Gender of legal identity.
static bool IsMeApproved(CaseInsensitiveString LegalId)
Checks if a Legal Identity refers to an approved ID of the gateway.
string Address2
Address, 2nd row
static LegalIdentity[] ApprovedIdentities
Approved Legal Identities associated with account.
override string ConfigPrivilege
Minimum required privilege for a user to be allowed to change the configuration defined by the class.
string OrgAddress
Organization Address
const string GATEWAY_ID_MIDDLE
Middle name of legal identity.
DateTime? BirthDate
Birth Date
string MiddleName
Middle Name
const string GATEWAY_ID_FIRST
First name of legal identity.
const string GATEWAY_ID_USE
If a legal identity is to be used by the gateway.If used, the folllowing optional variables can be us...
const string GATEWAY_ID_PNR
Personal number of legal identity.
static Dictionary< string, object >[] AllIdentitiesJSON
Public profile of all Legal Identities associated with account, as dictionaries.
override async Task ConfigureSystem()
Is called during startup to configure the system.
const string GATEWAY_ID_ALT
Comma-separated list of alternative fields to send in identity application.
string PostalCode
Postal Code (or zip code)
override int Priority
Priority of the setting. Configurations are sorted in ascending order.
string OrgRegion
Organization Region
async Task< bool > PetitionLegalIdentity(string LegalId, string PetitionId, string Purpose, string Password, EventHandlerAsync< LegalIdentityPetitionResponseEventArgs > Callback, TimeSpan Timeout)
Petitions information about a legal identity from its owner.
const string GATEWAY_ID_COUNTRY
Country of legal identity.
const string GATEWAY_ID_ORGCITY
Organization city of legal identity.
static bool HasApprovedLegalIdentities
If there are approved legal identities configured.
bool ProtectWithPassword
If the legal identity should be protected with a password.
const string GATEWAY_ID_ZIP
Postal code of legal identity.
override Task< bool > SimplifiedConfiguration()
Simplified configuration by configuring simple default values.
string OrgRole
Organization Role
const string GATEWAY_ID_ORGNAME
Organization name of legal identity.
string OrgDepartment
Organization Department
override Task UnregisterSetup(HttpServer WebServer)
Unregisters the setup object.
string OrgCity
Organization City
const string GATEWAY_ID_LAST
Last name of legal identity.
override async Task< bool > SetupConfiguration(HttpServer WebServer)
Waits for the user to provide configuration.
static LegalIdentity[] AllIdentities
All Legal Identities associated with account.
const string GATEWAY_ID_ORGCOUNTRY
Organization country of legal identity.
static string LatestApprovedLegalIdentityId
Latest approved Legal Identity ID.
string OrgNumber
Organization number
const string GATEWAY_ID_BDATE
Birth Date of legal identity.
const string GATEWAY_ID_CITY
City of legal identity.
const string GATEWAY_ID_ADDR
Address (line 1) of legal identity.
AlternativeField[] PasswordHashes
Password hash, if legal identity is protected by password.
override void SetStaticInstance(ISystemConfiguration Configuration)
Sets the static instance of the configuration.
override Task< string > Title(Language Language)
Gets a title for the system configuration.
const string GATEWAY_ID_ORGZIP
Organization postal code of legal identity.
bool UseLegalIdentity
If the gateway will use a legal identity.
static LegalIdentity LatestApprovedLegalIdentity
Latest approved Legal Identity.
string FirstName
First Name
const string GATEWAY_ID_PASSWORD
Protect legal identity with this password.
bool Complete
If the configuration is complete.
bool TryGetEnvironmentVariable(string VariableName, bool Required, out string Value)
Tries to get a string-valued environment variable.
Abstract base class for multi-step system configurations.
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
The server understood the request, but is refusing to fulfill it. Authorization will not help and the...
Represents an HTTP request.
HttpRequestHeader Header
Request header.
bool HasData
If the request has data.
async Task< ContentResponse > DecodeDataAsync()
Decodes data sent in request.
Base class for all HTTP resources.
Represets a response of an HTTP client request.
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
Task Write(byte[] Data)
Returns binary data in the response.
Implements an HTTP server.
static SessionVariables CreateSessionVariables()
Creates a new collection of variables, that contains access to the global set of variables.
HttpResource Register(HttpResource Resource)
Registers a resource with the server.
bool Unregister(HttpResource Resource)
Unregisters a resource from the server.
The server has not found anything matching the Request-URI. No indication is given of whether the con...
Contains the definition of a contract
Adds support for legal identities, smart contracts and signatures to an XMPP client.
async Task GenerateNewKeys()
Generates new keys for the contracts clients.
Task PetitionIdentityAsync(string LegalId, string PetitionId, string Purpose)
Sends a petition to the owner of a legal identity, to access the information in the identity....
void SetAllowedSources(object[] ApprovedSources)
If access to sensitive methods is only accessible from a set of approved sources.
Task PetitionContractAsync(string ContractId, string PetitionId, string Purpose)
Sends a petition to the parts of a smart contract, to access the information in the contract....
Task< Contract > SignContractAsync(Contract Contract, string Role, bool Transferable)
Signs a contract
Task GetLegalIdentities(EventHandlerAsync< LegalIdentitiesEventArgs > Callback, object State)
Gets legal identities registered with the account.
Task Apply(Property[] Properties, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Applies for a legal identity to be registered.
Event arguments for smart contract petition responses
string PetitionId
Petition ID
Event arguments for events referencing a contract.
string ContractId
ID of contract being signed.
Event arguments for contract signature events
string Role
Role the legal identity has signed.
string LegalId
ID of legal identity signing the contract.
Event arguments for legal identity responses
LegalIdentity Identity
Legal Identity
Event arguments for legal identity petition responses
string PetitionId
Petition ID
DateTime From
From what point in time the legal identity is valid.
DateTime Updated
When the identity object was last updated
DateTime To
To what point in time the legal identity is valid.
DateTime Created
When the identity object was created
IdentityState State
Current state of identity
string ClientKeyName
Type of key used for client signatures
string Provider
Provider where the identity is maintained.
byte[] ClientPubKey
Client Public key
string Id
ID of the legal identity
Property[] Properties
Properties detailing the legal identity.
Class defining a part in a contract
string Name
Name of property
string Value
Property value
bool Ok
If the response is an OK result response (true), or an error response (false).
object State
State object passed to the original request.
string ErrorText
Any error specific text.
XmppState State
Current state of connection.
Task Connect()
Connects the client.
Represents a case-insensitive string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static async Task Update(object Object)
Updates an object in the database.
static async Task Delete(object Object)
Deletes an object in the database.
static Task< object > TryLoadObject(string CollectionName, object ObjectId)
Tries to load an object given its Object ID ObjectId and its collection name CollectionName .
static async Task< string > ReadAllTextAsync(string FileName)
Reads a text file asynchronously.
Contains information about a language.
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
Static class containing methods that can be used to make sure calls are made from appropriate locatio...
static ICallStackCheck[] Convert(params object[] Sources)
Converts an array of objects into an array of ICallStackCheck objects, assuming each listed source is...
static void CallFromSource(params string[] Sources)
Makes sure the call is made from one of the listed sources.
Contains methods for simple hash calculations.
static byte[] ComputeHMACSHA256Hash(byte[] Key, byte[] Data)
Computes the HMAC-SHA-256 hash of a block of binary data.
Contains OTP secret information for an OTP endpoint.
static void SetAllowedSources(ICallStackCheck[] ApprovedSources)
If access to sensitive methods is only accessible from a set of approved sources.
Interface for system configurations. The gateway will scan all module for system configuration classe...
Interface for call stack checks.
Gender
Gender classification in a legal ID.
XmppState
State of XMPP connection.