Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
PreviewAuthenticator.cs
1using Paiwise;
2using System;
4using System.IO;
5using System.Threading.Tasks;
6using System.Xml;
7using Waher.Events;
13
15{
20 {
25 {
26 }
27
31 public Task Start()
32 {
33 return Task.CompletedTask;
34 }
35
39 public Task Stop()
40 {
41 return Task.CompletedTask;
42 }
43
50 {
51 foreach (KeyValuePair<string, object> Claim in Application.Claims)
52 {
53 if (Claim.Key == PersonalInformation.PreviewTag)
54 {
55 if (!(Claim.Value is string s) || string.IsNullOrEmpty(s))
56 return Grade.NotAtAll;
57
58 if (!Guid.TryParse(s, out _))
59 return Grade.NotAtAll;
60
61 try
62 {
63 string FileName = LegalComponent.GetPreviewFileName(s, ".id");
64 return File.Exists(FileName) ? Grade.Perfect : Grade.NotAtAll;
65 }
66 catch (Exception ex)
67 {
68 Log.Exception(ex);
69 return Grade.NotAtAll;
70 }
71 }
72 }
73
74 return Grade.NotAtAll;
75 }
76
81 public async Task Validate(IIdentityApplication Application)
82 {
83 try
84 {
85 ChunkedList<string> PreviewFileNames = new ChunkedList<string>();
86 string PreviewId = null;
87
88 foreach (KeyValuePair<string, object> Claim in Application.Claims)
89 {
90 if (Claim.Key != PersonalInformation.PreviewTag)
91 continue;
92
93 if (!(Claim.Value is string s) ||
94 string.IsNullOrEmpty(s) ||
95 !Guid.TryParse(s, out _))
96 {
97 Application.ReportError("Invalid preview identifier.", "en", string.Empty,
98 ValidationErrorType.Client, this);
99 return;
100 }
101
102 PreviewId = s;
103 break;
104 }
105
106 KeyValuePair<LegalIdentity, bool> P = await LegalComponent.GetLocalLegalIdentity(PreviewId, true);
107 Dictionary<string, string> PotentialClaims = new Dictionary<string, string>();
108 LegalIdentity Identity = P.Key;
109 bool Preview = P.Value;
110 byte[] Salt;
111
112 if (!Preview || Identity is null)
113 {
114 Application.ClaimInvalid(PersonalInformation.PreviewTag, "Invalid preview reference.", "en",
115 string.Empty, this);
116 return;
117 }
118
119 PreviewFileNames.Add(LegalComponent.GetPreviewFileName(Identity.Id, ".id"));
120
121 foreach (AttachmentReference Ref in Identity.Attachments)
122 {
123 PreviewFileNames.Add(LegalComponent.GetPreviewFileName(Ref.Id, ".att"));
124
125 if (Ref.FileName == "ApplicationReview.xml")
126 {
127 try
128 {
129 byte[] Bin = await LegalComponent.GetPreviewAttachment(Ref);
130 using MemoryStream ms = new MemoryStream(Bin);
131 XmlDocument Doc = new XmlDocument();
132 Doc.Load(ms);
133
134 if (Doc.DocumentElement.LocalName != "identityReview" ||
135 !LegalComponent.IsNamespaceLegalIdentity(Doc.DocumentElement.NamespaceURI))
136 {
137 continue;
138 }
139
140 // Note: Clients cannot freely add identityReview attachments.
141
142 IdentityReviewEventArgs e = new IdentityReviewEventArgs(null, Identity.Id);
143 Networking.XMPP.Contracts.ContractsClient.ParseValidationDetails(
144 Doc.DocumentElement, e);
145
146 if (e.HasPotentialClaims)
147 {
148 foreach (Networking.XMPP.Contracts.PotentialClaim Claim in
150 {
151 PotentialClaims[Claim.Claim] = Claim.Value;
152 }
153 }
154 }
155 catch (Exception ex)
156 {
157 Log.Exception(ex);
158 continue;
159 }
160 }
161 }
162
163 Application.ClaimValid(PersonalInformation.PreviewTag, this);
164
165 foreach (KeyValuePair<string, object> Claim in Application.Claims)
166 {
167 switch (Claim.Key)
168 {
170 case "ID":
171 case "State":
172 case "Created":
173 case "Updated":
174 case "From":
175 case "To":
176 continue;
177 }
178
179 string ClaimValue = Claim.Value?.ToString() ?? string.Empty;
180 string Value = Identity[Claim.Key];
181
182 if (string.IsNullOrEmpty(Value))
183 {
184 if (!PotentialClaims.TryGetValue(Claim.Key, out Value))
185 continue;
186 }
187
188 if (Value == ClaimValue)
189 Application.ClaimValid(Claim.Key, this);
190 else
191 {
192 Application.ClaimInvalid(Claim.Key,
193 "Does not match previewed value.", "en", "PreviewMismatch",
194 this);
195 }
196 }
197
198 foreach (IPhoto Photo in Application.Photos)
199 {
200 foreach (AttachmentReference Ref in Identity.Attachments)
201 {
202 if (Photo.FileName != Ref.FileName)
203 continue;
204
205 string AttachmentFileName = LegalComponent.GetPreviewFileName(Ref.Id, ".att");
206
207 if (!File.Exists(AttachmentFileName))
208 {
209 Application.PhotoInvalid(Photo,
210 "Previewed attachment not found.", "en", "PreviewMismatch",
211 this);
212 }
213 else
214 {
215 KeyValuePair<byte[], string> P2 = await LegalComponent.GetPreviewSalt(AttachmentFileName);
216 Salt = P2.Key;
217
218 byte[] Blob = await XmppServerModule.LoadEncryptedFile(AttachmentFileName, Salt);
219 using MemoryStream ms = new MemoryStream(Blob);
220 using Stream Decoded = await XmppServerModule.DecodeBlob(ms);
221 byte[] Data = await Decoded.ReadAllAsync();
222
223 if (Data.Length == Photo.Binary.Length &&
224 Convert.ToBase64String(Data) == Convert.ToBase64String(Photo.Binary))
225 {
226 Application.PhotoValid(Photo, this);
227 }
228 else
229 {
230 Application.PhotoInvalid(Photo,
231 "Does not match previewed photo.", "en", "PreviewMismatch",
232 this);
233 }
234 }
235
236 break;
237 }
238 }
239
240 if (Application.IsValid.HasValue &&
241 Application.IsValid.Value &&
242 PreviewFileNames.HasFirstItem)
243 {
244 foreach (string FileName in PreviewFileNames)
245 {
246 try
247 {
248 if (File.Exists(FileName))
249 File.Delete(FileName);
250
251 await LegalComponent.RemovePreviewSalt(FileName);
252 }
253 catch (Exception ex)
254 {
255 Log.Exception(ex, FileName);
256 }
257 }
258 }
259 }
260 catch (Exception ex)
261 {
262 Application.ReportError(ex.Message, string.Empty, string.Empty,
263 ValidationErrorType.Service, this);
264 }
265 }
266 }
267}
Contains personal information found in a legal identity.
Represents a photo in an identity application.
Definition: Photo.cs:11
string FileName
File Name of photo.
Definition: Photo.cs:43
byte[] Binary
Binary representation of photo.
Definition: Photo.cs:48
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:14
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.
Definition: Log.cs:1657
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
Service Module hosting the XMPP broker and its components.
static Task< byte[]> LoadEncryptedFile(string FileName, byte[] Salt)
Loads an encrypted file.
static async Task< Stream > DecodeBlob(Stream Data)
Decodes a variable-length BLOB encoded by the EncodeBlob method. The length prefix is read first,...
Interface for identity applications.
Interface for identity application authenticator services.
Interface for photos.
Definition: IPhoto.cs:10
Definition: ImplTypes.g.cs:58
ValidationErrorType
Type of validation error.
Grade
Grade enumeration
Definition: Grade.cs:7