Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ValidateContract.cs
1using System;
3using System.Threading.Tasks;
4using Waher.Content;
12
14{
16 {
17 public ValidateContract()
18 : base("/ValidateContract")
19 {
20 }
21
22 public override bool HandlesSubPaths => false;
23 public override bool UserSessions => true;
24 public bool AllowsPOST => true;
25
26 public async Task POST(HttpRequest Request, HttpResponse Response)
27 {
28 Gateway.AssertUserAuthenticated(Request, "Admin.Legal.Validate.Contract");
29
30 if (!Request.HasData)
31 {
32 await Response.SendResponse(new BadRequestException());
33 return;
34 }
35
36 ContentResponse Content = await Request.DecodeDataAsync();
37 if (Content.HasError || !(Content.Decoded is Dictionary<string, object> RequestObj) ||
38 !RequestObj.TryGetValue("ContractId", out object Obj) || !(Obj is string ContractId) ||
39 !RequestObj.TryGetValue("Purpose", out Obj) || !(Obj is string Purpose) ||
40 !RequestObj.TryGetValue("Password", out Obj) || !(Obj is string Password) ||
41 !RequestObj.TryGetValue("TabID", out Obj) || !(Obj is string TabID))
42 {
43 await Response.SendResponse(new BadRequestException());
44 return;
45 }
46
47 if (ContractId.IndexOf('@') < 0)
48 {
49 await Response.SendResponse(new BadRequestException("Invalid contract identity."));
50 return;
51 }
52
53 if (Gateway.ContractsClient is null)
54 {
55 await Response.SendResponse(new ServiceUnavailableException("Broker not connected to a legal service."));
56 return;
57 }
58
59 Dictionary<string, object> ResponseObj;
60
61 try
62 {
64 ResponseObj = await this.Encode(Contract);
65 }
66 catch (Exception)
67 {
68 string PetitionId = Guid.NewGuid().ToString();
69
70 Purpose = Purpose.Trim();
71 if (string.IsNullOrEmpty(Purpose))
72 Purpose = "Validating Contract through web interface at " + Gateway.Domain;
73
74 if (!await Gateway.PetitionContract(ContractId, PetitionId, Purpose, Password, async (_, e) =>
75 {
76 await ClientEvents.PushEvent(new string[] { TabID }, "PetitionResponseReceived", JSON.Encode(new Dictionary<string, object>()
77 {
78 { "PetitionId", e.PetitionId },
79 { "PetitionResponse", e.Response },
80 { "Contract", await this.Encode(e.RequestedContract) },
81 { "Declined", e.RequestedContract is null && !(e.Message is null) },
82 { "Timeout", e.Message is null }
83 }, false), true);
84 }, TimeSpan.FromMinutes(5)))
85 {
86 await Response.SendResponse(new ForbiddenException(Request, "Unable to sign petition. Either password is incorrect, or no legal identity assigned to broker."));
87 return;
88 }
89
90 ResponseObj = new Dictionary<string, object>()
91 {
92 { "Id", ContractId },
93 { "Petition", true },
94 { "PetitionId", PetitionId },
95 { "Message", "The information has been petitioned from the owner. If the owner accepts to share the information, it will be displayed here when it arrives." }
96 };
97 }
98
99 await Response.Return(ResponseObj);
100 }
101
102 private async Task<Dictionary<string, object>> Encode(Contract Contract)
103 {
104 if (Contract is null)
105 return null;
106
108 ContractStatus Status = e.Status;
109 List<Dictionary<string, object>> List = new List<Dictionary<string, object>>();
110 Dictionary<string, object> ResponseObj = new Dictionary<string, object>()
111 {
112 { "ContractId", Contract.ContractId },
113 { "ContractIdUri", Contract.ContractIdUriString },
114 { "Petition", false },
115 { "Provider", Contract.Provider },
116 { "State", Contract.State.ToString() },
117 { "ValidationStatus", Status.ToString() },
118 { "ValidationStatusTags", e.Tags },
119 { "Visibility", Contract.Visibility },
120 { "Created", Contract.Created },
121 { "Updated", Contract.Updated },
122 { "From", Contract.From },
123 { "To", Contract.To },
124 { "SignAfter", Contract.SignAfter },
125 { "SignBefore", Contract.SignBefore },
126 { "Duration", Contract.Duration.ToString() },
127 { "ArchiveOptional", Contract.ArchiveOptional.ToString() },
128 { "ArchiveRequired", Contract.ArchiveRequired.ToString() },
129 { "TemplateId", Contract.TemplateId },
130 { "TemplateIdUri", Contract.TemplateIdUriString },
131 { "CanActAsTemplate", Contract.CanActAsTemplate },
132 { "PartsMode", Contract.PartsMode.ToString() },
133 { "DefaultLanguage", Contract.DefaultLanguage },
134 { "ForHumans", await this.Encode(Contract.ForHumans, Contract) },
135 { "ContentSchemaDigest", Contract.ContentSchemaDigest is null ? null : Convert.ToBase64String(Contract.ContentSchemaDigest) },
136 { "ContentSchemaHashFunction", Contract.ContentSchemaHashFunction.ToString() },
137 { "ForMachinesLocalName", Contract.ForMachinesLocalName },
138 { "ForMachinesNamespace", Contract.ForMachinesNamespace },
139 { "ForMachines", XML.PrettyXml(Contract.ForMachines) }
140 };
141
142 if (!(Contract.Roles is null))
143 {
144 foreach (Role Role in Contract.Roles)
145 {
146 List.Add(new Dictionary<string, object>()
147 {
148 { "Name", Role.Name },
149 { "MinCount", Role.MinCount },
150 { "MaxCount", Role.MaxCount },
151 { "CanRevoke", Role.CanRevoke },
152 { "Descriptions", await this.Encode(Role.Descriptions, Contract) }
153 });
154 }
155
156 ResponseObj["Roles"] = List.ToArray();
157 List.Clear();
158 }
159
160 if (!(Contract.Parts is null))
161 {
162 foreach (Part Part in Contract.Parts)
163 {
164 List.Add(new Dictionary<string, object>()
165 {
166 { "LegalId", Part.LegalId },
167 { "LegalIdUri", Part.LegalIdUriString },
168 { "Role", Part.Role }
169 });
170 }
171
172 ResponseObj["Parts"] = List.ToArray();
173 List.Clear();
174 }
175
176 if (!(Contract.Parameters is null))
177 {
179 {
180 List.Add(new Dictionary<string, object>()
181 {
182 { "Name", Parameter.Name },
183 { "Value", Parameter.ObjectValue },
184 { "Descriptions", await this .Encode(Parameter.Descriptions, Contract) }
185 });
186 }
187
188 ResponseObj["Parameters"] = List.ToArray();
189 List.Clear();
190 }
191
192 if (!(Contract.ClientSignatures is null))
193 {
195 {
196 List.Add(new Dictionary<string, object>()
197 {
198 { "BareJid", ClientSignature.BareJid },
199 { "DigitalSignature", Convert.ToBase64String(ClientSignature.DigitalSignature) },
200 { "LegalId", ClientSignature.LegalId },
201 { "LegalIdUri", ClientSignature.LegalIdUriString },
202 { "Role", ClientSignature.Role },
203 { "Timestamp", ClientSignature.Timestamp },
204 { "Transferable", ClientSignature.Transferable }
205 });
206 }
207
208 ResponseObj["ClientSignatures"] = List.ToArray();
209 List.Clear();
210 }
211
212 if (!(Contract.Attachments is null))
213 {
215 {
216 List.Add(new Dictionary<string, object>()
217 {
218 { "BareJid", ClientSignature.BareJid },
219 { "DigitalSignature", Convert.ToBase64String(ClientSignature.DigitalSignature) },
220 { "LegalId", ClientSignature.LegalId },
221 { "LegalIdUri", ClientSignature.LegalIdUriString },
222 { "Role", ClientSignature.Role },
223 { "Timestamp", ClientSignature.Timestamp },
224 { "Transferable", ClientSignature.Transferable }
225 });
226 }
227
228 ResponseObj["ClientSignatures"] = List.ToArray();
229 List.Clear();
230 }
231
232 if (!(Contract.Attachments is null))
233 {
235 {
236 List.Add(new Dictionary<string, object>()
237 {
238 { "Id", Attachment.Id },
239 { "ContentType", Attachment.ContentType },
240 { "FileName", Attachment.FileName },
241 { "Url", Attachment.Url },
242 { "Signature", Convert.ToBase64String(Attachment.Signature) },
243 { "Timestamp", Attachment.Timestamp },
244 });
245 }
246
247 ResponseObj["Attachments"] = List.ToArray();
248 List.Clear();
249 }
250
251 ResponseObj["ServerSignature"] = new Dictionary<string, object>()
252 {
253 { "DigitalSignature", Convert.ToBase64String(Contract.ServerSignature.DigitalSignature) },
254 { "Timestamp", Contract.ServerSignature.Timestamp }
255 };
256
257 return ResponseObj;
258 }
259
260 private async Task<Dictionary<string, object>[]> Encode(HumanReadableText[] Text, Contract Contract)
261 {
262 List<Dictionary<string, object>> List = new List<Dictionary<string, object>>();
263
264 foreach (HumanReadableText Localization in Text)
265 {
266 List.Add(new Dictionary<string, object>()
267 {
268 { "Language", Localization.Language },
269 { "IsWellDefined", await Localization.IsWellDefined() },
270 { "Html", HtmlDocument.GetBody(await Localization.GenerateHTML(Contract)) }
271 });
272 }
273
274 return List.ToArray();
275 }
276
277 }
278}
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.
Definition: JSON.cs:16
static string Encode(string s)
Encodes a string for inclusion in JSON.
Definition: JSON.cs:537
Helps with common XML-related tasks.
Definition: XML.cs:21
static string PrettyXml(string Xml)
Reformats XML to make it easier to read.
Definition: XML.cs:1734
The ClientEvents class allows applications to push information asynchronously to web clients connecte...
Definition: ClientEvents.cs:51
static Task< int > PushEvent(string[] TabIDs, string Type, object Data)
Puses an event to a set of Tabs, given their Tab IDs.
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:147
static CaseInsensitiveString Domain
Domain name.
Definition: Gateway.cs:3087
static IUser AssertUserAuthenticated(HttpRequest Request, string Privilege)
Makes sure a request is being made from a session with a successful user login.
Definition: Gateway.cs:3868
static ContractsClient ContractsClient
XMPP Contracts Client, if such a compoent is available on the XMPP broker.
Definition: Gateway.cs:5299
static 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.
Definition: Gateway.cs:5491
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.
Definition: HttpRequest.cs:22
bool HasData
If the request has data.
Definition: HttpRequest.cs:113
async Task< ContentResponse > DecodeDataAsync()
Decodes data sent in request.
Definition: HttpRequest.cs:139
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:23
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
Task Return(Exception ex)
Returns an error to the client.
Base class for all synchronous HTTP resources. A synchronous resource responds within the method hand...
The server is currently unable to handle the request due to a temporary overloading or maintenance of...
Contains a reference to an attachment assigned to a legal object.
Definition: Attachment.cs:10
byte[] Signature
Binary signature of the attachment, generated by an approved legal identity of the account-holder....
Definition: Attachment.cs:76
Represents a digital signature on a contract.
Contains the definition of a contract
Definition: Contract.cs:22
byte[] ContentSchemaDigest
The hash digest of the schema used to validate the machine-readable contents (ForMachines) of the sma...
Definition: Contract.cs:221
Security.HashFunction ContentSchemaHashFunction
Hash function of the schema used to validate the machine-readable contents (ForMachines) of the smart...
Definition: Contract.cs:231
Parameter[] Parameters
Defined parameters for the smart contract.
Definition: Contract.cs:267
Duration? ArchiveRequired
Requied time to archive a signed smart contract, after it becomes obsolete.
Definition: Contract.cs:202
ClientSignature[] ClientSignatures
Client signatures of the contract.
Definition: Contract.cs:309
HumanReadableText[] ForHumans
Human-readable contents of the contract.
Definition: Contract.cs:300
Attachment[] Attachments
Attachments assigned to the legal identity.
Definition: Contract.cs:318
Duration? ArchiveOptional
Optional time to archive a signed smart contract, after it becomes obsolete, and after its required a...
Definition: Contract.cs:211
XmlElement ForMachines
Machine-readable contents of the contract.
Definition: Contract.cs:276
Role[] Roles
Roles defined in the smart contract.
Definition: Contract.cs:240
ContractParts PartsMode
How parts are defined in the smart contract.
Definition: Contract.cs:249
ContractState State
Contract state
Definition: Contract.cs:121
Part[] Parts
Defined parts for the smart contract.
Definition: Contract.cs:258
Duration? Duration
Duration of the contract. Is counted from the time it is signed by the required parties.
Definition: Contract.cs:193
ServerSignature ServerSignature
Server signature attesting to the validity of the contents of the contract.
Definition: Contract.cs:327
Task< Contract > GetContractAsync(string ContractId)
Gets a contract
Task< IdentityValidationEventArgs > ValidateAsync(LegalIdentity Identity)
Validates a legal identity.
override async Task< HumanReadableElement > IsWellDefined()
Checks if the element is well-defined.
Definition: Blocks.cs:30
async Task< string > GenerateHTML(Contract Contract)
Generates HTML for the human-readable text.
HumanReadableText[] Descriptions
Discriptions of the object, in different languages.
Abstract base class for contractual parameters
Definition: Parameter.cs:17
Class defining a part in a contract
Definition: Part.cs:30
Class defining a role
Definition: Role.cs:7
byte[] DigitalSignature
Digital Signature
Definition: Signature.cs:27
bool AllowsPOST
If the POST method is allowed.
async Task POST(HttpRequest Request, HttpResponse Response)
Executes the POST method on the resource.
POST Interface for HTTP resources.
Definition: ImplTypes.g.cs:58
ContractStatus
Validation Status of smart contract
override string ToString()
Definition: Duration.cs:516