Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
LegalIdentityGetter.cs
1using System;
3using System.Collections.Specialized;
4using System.Security.Cryptography.X509Certificates;
5using System.Text;
6using System.Threading.Tasks;
7using System.Web;
8using Waher.Content;
14
16{
20 public class LegalIdentityGetter : IContentGetter, IDisposable
21 {
22 private static string defaultPurpose = string.Empty;
23
24 private readonly Dictionary<string, TaskCompletionSource<LegalIdentityPetitionResponseEventArgs>> identityPetitions = new Dictionary<string, TaskCompletionSource<LegalIdentityPetitionResponseEventArgs>>();
25 private readonly object syncObj = new object();
26 private bool handlerAdded = false;
27
32 {
33 }
34
38 public static string DefaultPurpose
39 {
40 get => defaultPurpose;
41 set
42 {
43 if (string.IsNullOrEmpty(value))
44 throw new ArgumentException("Default purpose cannot be empty.", nameof(DefaultPurpose));
45
46 defaultPurpose = value;
47 }
48 }
49
53 public string[] UriSchemes => new string[] { "iotid" };
54
61 public bool CanGet(Uri Uri, out Grade Grade)
62 {
63 if (string.Compare(Uri.Scheme, "iotid", true) == 0)
64 {
65 Grade = Grade.Ok;
66 return true;
67 }
68 else
69 {
70 Grade = Grade.NotAtAll;
71 return false;
72 }
73 }
74
78 public void Dispose()
79 {
80 lock (this.syncObj)
81 {
82 if (this.handlerAdded)
83 {
84 Gateway.ContractsClient.PetitionedIdentityResponseReceived -= this.Client_PetitionedIdentityResponseReceived;
85 this.handlerAdded = false;
86 }
87 }
88 }
89
98 public Task<ContentResponse> GetAsync(Uri Uri, X509Certificate Certificate, EventHandler<RemoteCertificateEventArgs> RemoteCertificateValidator,
99 params KeyValuePair<string, string>[] Headers)
100 {
101 return this.GetAsync(Uri, Certificate, RemoteCertificateValidator, InternetContent.DefaultTimeout, Headers);
102 }
103
113 public async Task<ContentResponse> GetAsync(Uri Uri, X509Certificate Certificate, EventHandler<RemoteCertificateEventArgs> RemoteCertificateValidator,
114 int TimeoutMs, params KeyValuePair<string, string>[] Headers)
115 {
117 if (Client is null)
118 return new ContentResponse(new NotSupportedException("Contracts feature not supported or activated on this system."));
119
120 lock (this.syncObj)
121 {
122 if (!this.handlerAdded)
123 {
124 Client.PetitionedIdentityResponseReceived += this.Client_PetitionedIdentityResponseReceived;
125 this.handlerAdded = true;
126 }
127 }
128
129 string LegalId = Uri.AbsolutePath;
130
131 try
132 {
133 LegalIdentity Identity = await Client.GetLegalIdentityAsync(LegalId);
134 return new ContentResponse(string.Empty, Identity, Array.Empty<byte>());
135 }
136 catch (Exception)
137 {
138 TaskCompletionSource<LegalIdentityPetitionResponseEventArgs> Result = new TaskCompletionSource<LegalIdentityPetitionResponseEventArgs>();
139 string PetitionId = Guid.NewGuid().ToString();
140 string Purpose = null;
141
142 if (!string.IsNullOrEmpty(Uri.Query))
143 {
144 NameValueCollection Parameters = HttpUtility.ParseQueryString(Uri.Query);
145
146 foreach (string Parameter in Parameters.AllKeys)
147 {
148 switch (Parameter.ToLower())
149 {
150 case "p":
151 case "purpose":
152 Purpose = Parameters[Parameter];
153 break;
154 }
155 }
156 }
157
158 if (string.IsNullOrEmpty(Purpose))
159 Purpose = "Processing referenced identity.";
160
161 lock (this.syncObj)
162 {
163 this.identityPetitions[PetitionId] = Result;
164 }
165
166 try
167 {
168 await Client.PetitionIdentityAsync(LegalId, PetitionId, Purpose);
169
170 Task _ = Task.Delay(TimeoutMs).ContinueWith((T) =>
171 {
172 Result.TrySetException(new TimeoutException("Response to petition not received within allotted time."));
173 return Task.CompletedTask;
174 });
175 }
176 catch (Exception ex)
177 {
178 lock (this.syncObj)
179 {
180 this.identityPetitions.Remove(PetitionId);
181 }
182
183 return new ContentResponse(ex);
184 }
185
186 LegalIdentityPetitionResponseEventArgs e = await Result.Task;
187
188 return new ContentResponse(string.Empty, e.RequestedIdentity, Array.Empty<byte>());
189 }
190 }
191
192 private Task Client_PetitionedIdentityResponseReceived(object Sender, LegalIdentityPetitionResponseEventArgs e)
193 {
194 lock (this.syncObj)
195 {
196 if (this.identityPetitions.TryGetValue(e.PetitionId, out TaskCompletionSource<LegalIdentityPetitionResponseEventArgs> Result))
197 Result.TrySetResult(e);
198 }
199
200 return Task.CompletedTask;
201 }
202
211 public Task<ContentStreamResponse> GetTempStreamAsync(Uri Uri, X509Certificate Certificate,
212 EventHandler<RemoteCertificateEventArgs> RemoteCertificateValidator, params KeyValuePair<string, string>[] Headers)
213 {
214 return this.GetTempStreamAsync(Uri, Certificate, RemoteCertificateValidator, InternetContent.DefaultTimeout, Headers);
215 }
216
226 public Task<ContentStreamResponse> GetTempStreamAsync(Uri Uri, X509Certificate Certificate,
227 EventHandler<RemoteCertificateEventArgs> RemoteCertificateValidator, TemporaryStream Destination, params KeyValuePair<string, string>[] Headers)
228 {
229 return this.GetTempStreamAsync(Uri, Certificate, RemoteCertificateValidator, InternetContent.DefaultTimeout, Destination, Headers);
230 }
231
241 public Task<ContentStreamResponse> GetTempStreamAsync(Uri Uri, X509Certificate Certificate,
242 EventHandler<RemoteCertificateEventArgs> RemoteCertificateValidator, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
243 {
244 return this.GetTempStreamAsync(Uri, Certificate, RemoteCertificateValidator, TimeoutMs, null, Headers);
245 }
246
257 public async Task<ContentStreamResponse> GetTempStreamAsync(Uri Uri, X509Certificate Certificate,
258 EventHandler<RemoteCertificateEventArgs> RemoteCertificateValidator, int TimeoutMs, TemporaryStream Destination,
259 params KeyValuePair<string, string>[] Headers)
260 {
261 ContentResponse Content = await this.GetAsync(Uri, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
262 if (Content.HasError)
263 return new ContentStreamResponse(Content.Error);
264
265 LegalIdentity Identity = (LegalIdentity)Content.Decoded;
266 StringBuilder Xml = new StringBuilder();
267 Identity.Serialize(Xml, true, true, true, true, true, true, true);
268 byte[] Bin = Encoding.UTF8.GetBytes(Xml.ToString());
269 bool DestinationCreated = false;
270
271 if (Destination is null)
272 {
273 Destination = new TemporaryStream();
274 DestinationCreated = true;
275 }
276
277 try
278 {
279 await Destination.WriteAsync(Bin, 0, Bin.Length);
280 }
281 catch (Exception ex)
282 {
283 if (DestinationCreated)
284 Destination.Dispose();
285
286 return new ContentStreamResponse(ex);
287 }
288
289 return new ContentStreamResponse("application/xml; charset=utf-8", Destination);
290 }
291 }
292}
Contains information about a response to a content request.
bool HasError
If an error occurred.
object Decoded
Decoded object.
Exception Error
Error response.
Contains information about a stream response to a content request.
Static class managing encoding and decoding of internet content.
static int DefaultTimeout
Default timeout of internet access methods, in milliseconds.
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:147
static ContractsClient ContractsClient
XMPP Contracts Client, if such a compoent is available on the XMPP broker.
Definition: Gateway.cs:5299
Adds support for legal identities, smart contracts and signatures to an XMPP client.
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....
Task< LegalIdentity > GetLegalIdentityAsync(string LegalIdentityId)
Gets legal identity registered with the account.
Abstract base class for contractual parameters
Definition: Parameter.cs:17
Manages a temporary stream. Contents is kept in-memory, if below a memory threshold,...
override void Dispose(bool disposing)
Releases the unmanaged resources used by the System.IO.Stream and optionally releases the managed res...
override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
Asynchronously writes a sequence of bytes to the current stream, advances the current position within...
Basic interface for Internet Content getters. A class implementing this interface and having a defaul...
Definition: ImplTypes.g.cs:58
Grade
Grade enumeration
Definition: Grade.cs:7