Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
QuickLoginUser.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading.Tasks;
5using Waher.Content;
11using Waher.Things;
12
14{
19 {
20 private readonly LegalIdentity id;
21 private readonly string petitionId;
22 private readonly Dictionary<string, object> properties;
23 private readonly Dictionary<string, object>[] attachments;
24
32 public QuickLoginUser(LegalIdentity ID, string PetitionId, Dictionary<string, object> Properties,
33 Dictionary<string, object>[] Attachments)
34 {
35 this.id = ID;
36 this.petitionId = PetitionId;
37 this.properties = Properties;
38 this.attachments = Attachments;
39 }
40
44 public LegalIdentity LegalId => this.id;
45
49 public string Id => this.id.Id;
50
54 public string Key => this.petitionId;
55
59 public string Provider => this.id.Provider;
60
64 public string ClientKeyName => this.id.ClientKeyName;
65
69 public DateTime Created => this.id.Created;
70
74 public DateTime? Updated => this.id.Updated == DateTime.MinValue ? (DateTime?)null : this.id.Updated;
75
79 public DateTime From => this.id.From;
80
84 public DateTime To => this.id.To;
85
89 public bool HasClientPublicKey => this.id.HasClientPublicKey;
90
94 public string ClientPubKey => this.id.HasClientPublicKey ? Convert.ToBase64String(this.id.ClientSignature) : null;
95
99 public Dictionary<string, object> Properties => this.properties;
100
104 public Dictionary<string, object>[] Attachments => this.attachments;
105
109 public string ServerSignature => Convert.ToBase64String(this.id.ServerSignature);
110
114 public IdentityState State => this.id.State;
115
119 public string UserName
120 {
121 get
122 {
123 if (this.properties.ContainsKey("FIRST") && this.properties.ContainsKey("LAST"))
124 {
125 StringBuilder sb = null;
126
127 this.Append(ref sb, "FIRST", " ");
128 this.Append(ref sb, "MIDDLE", " ");
129 this.Append(ref sb, "LAST", " ");
130
131 return sb?.ToString() ?? "N/A";
132 }
133 else
134 {
135 string s = this.Jid;
136 if (string.IsNullOrEmpty(s))
137 s = this.id?.Id;
138
139 if (string.IsNullOrEmpty(s))
140 return "N/A";
141
142 int i = s.IndexOf('@');
143 if (i < 0)
144 return s;
145
146 string LocalPart = s.Substring(0, i);
147
148 if (Guid.TryParse(LocalPart, out _) && !(this.id is null))
149 {
150 string EMail = this.id["EMAIL"];
151 if (!string.IsNullOrEmpty(EMail))
152 return EMail;
153
154 string PhoneNr = this.id["PHONE"];
155 if (!string.IsNullOrEmpty(PhoneNr))
156 return PhoneNr;
157 }
158
159 string Domain = s.Substring(i + 1);
160
161 if (Gateway.IsDomain(Domain, true))
162 return LocalPart;
163 else
164 return s;
165 }
166 }
167 }
168
172 public string FullAddress
173 {
174 get
175 {
176 StringBuilder sb = null;
177
178 this.Append(ref sb, "ADDR", ", ");
179 this.Append(ref sb, "ADDR2", ", ");
180 this.Append(ref sb, "AREA", ", ");
181 this.Append(ref sb, "ZIP", ", ");
182 this.Append(ref sb, "CITY", ", ");
183 this.Append(ref sb, "REGION", ", ");
184 this.Append(ref sb, "COUNTRY", ", ");
185
186 if (!(sb is null))
187 return sb.ToString();
188
189 this.Append(ref sb, "ORGNAME", ", ");
190 this.Append(ref sb, "ORGDEPT", ", ");
191 this.Append(ref sb, "ORGADDR", ", ");
192 this.Append(ref sb, "ORGADDR2", ", ");
193 this.Append(ref sb, "ORGAREA", ", ");
194 this.Append(ref sb, "ORGZIP", ", ");
195 this.Append(ref sb, "ORGCITY", ", ");
196 this.Append(ref sb, "ORGREGION", ", ");
197 this.Append(ref sb, "ORGCOUNTRY", ", ");
198
199 return sb?.ToString() ?? "N/A";
200 }
201 }
202
206 public string Jid
207 {
208 get
209 {
210 if (this.properties.TryGetValue("JID", out object Obj) && Obj is string s)
211 return s;
212 else
213 return null;
214 }
215 }
216
217 private void Append(ref StringBuilder sb, string Name, string Delimiter)
218 {
219 if (this.properties.TryGetValue(Name, out object Obj))
220 User.AppendValue(ref sb, Obj, Delimiter);
221 }
222
226 public string PasswordHash => string.Empty;
227
231 public string PasswordHashType => string.Empty;
232
238 public bool HasPrivilege(string Privilege)
239 {
240 return false;
241 }
242
246 public string AvatarUrl
247 {
248 get
249 {
250 if (!(this.attachments is null))
251 {
252 foreach (Dictionary<string, object> Attachment in this.attachments)
253 {
254 if (Attachment.TryGetValue("ContentType", out object Obj) &&
255 Obj is string ContentType &&
256 ContentType.StartsWith("image/") &&
257 Attachment.TryGetValue("BackEndUrl", out Obj) &&
258 Obj is string BackEndUrl)
259 {
260 return Gateway.GetUrl(BackEndUrl);
261 }
262 }
263 }
264
265 return Gateway.GetUrl("/Images/NeuroAccess.png");
266 }
267 }
268
274 public bool IsUserAttachment(string Url, out string AttachmentId)
275 {
276 if (this.attachments is null)
277 {
278 AttachmentId = null;
279 return false;
280 }
281
282 foreach (Dictionary<string, object> Attachment in this.attachments)
283 {
284 if (Attachment.TryGetValue("Url", out object Obj) &&
285 Obj is string s &&
286 string.Compare(s, Url, true) == 0 &&
287 Attachment.TryGetValue("Id", out Obj) &&
288 Obj is string Id)
289 {
290 AttachmentId = Id;
291 return true;
292 }
293 }
294
295 AttachmentId = null;
296 return false;
297 }
298
302 public Task<RequestOrigin> GetOrigin()
303 {
304 return Task.FromResult(new RequestOrigin(this.Jid, null, null, null));
305 }
306
312 public object this[string Key]
313 {
314 get
315 {
316 if (this.properties.TryGetValue(Key, out object Obj))
317 return Obj;
318 else
319 return null;
320 }
321 }
322
328 public Task<IEnumerable<KeyValuePair<string, object>>> CreateClaims(bool Encrypted)
329 {
330 int IssuedAt = (int)Math.Round(DateTime.UtcNow.Subtract(JSON.UnixEpoch).TotalSeconds);
331 int Expires = IssuedAt + 3600;
332 DateTime Now = DateTime.Now;
333
334 if (this.From > Now || this.To < Now || this.State != IdentityState.Approved)
335 return Task.FromResult<IEnumerable<KeyValuePair<string, object>>>(null);
336
337 List<KeyValuePair<string, object>> Claims = new List<KeyValuePair<string, object>>()
338 {
339 new KeyValuePair<string, object>(JwtClaims.JwtId, Convert.ToBase64String(Gateway.NextBytes(32))),
340 new KeyValuePair<string, object>(JwtClaims.Issuer, Gateway.Domain.Value),
341 new KeyValuePair<string, object>(JwtClaims.Subject, this.Jid),
342 new KeyValuePair<string, object>(JwtClaims.SubjectIdentifier, this.Id),
343 new KeyValuePair<string, object>(JwtClaims.Name, this.UserName),
344 new KeyValuePair<string, object>(JwtClaims.IssueTime, IssuedAt),
345 new KeyValuePair<string, object>(JwtClaims.ExpirationTime, Expires),
346 new KeyValuePair<string, object>(JwtClaims.Picture, this.AvatarUrl)
347 };
348
349 AddClaim(Claims, JwtClaims.WebSite, this["AGENT"]);
350
351 if (Encrypted)
352 {
353 AddClaim(Claims, JwtClaims.GivenName, this["FIRST"]);
354 AddClaim(Claims, JwtClaims.MiddleName, this["MIDDLE"]);
355 AddClaim(Claims, JwtClaims.FamilyName, this["LAST"]);
356 AddClaim(Claims, JwtClaims.EMail, this["EMAIL"]);
357 AddClaim(Claims, JwtClaims.EMailVerified, "true");
358 AddClaim(Claims, JwtClaims.PhoneNumber, this["PHONE"]);
359 AddClaim(Claims, JwtClaims.PhoneNumberVerified, "true");
360 AddClaim(Claims, JwtClaims.Gender, this["GENDER"]);
361 AddClaim(Claims, JwtClaims.Nationalities, this["NATIONALITY"]);
362
363 string BDay = this["BDAY"]?.ToString() ?? string.Empty;
364 string BMonth = this["BMONTH"]?.ToString() ?? string.Empty;
365 string BYear = this["BYEAR"]?.ToString() ?? string.Empty;
366
367 if (int.TryParse(BDay, out int BDayNr) && int.TryParse(BMonth, out int BMonthNr) && int.TryParse(BYear, out int BYearNr) &&
368 BMonthNr >= 1 && BMonthNr <= 12 && BYearNr >= 1900 && BYearNr <= 2100 && BDayNr >= 1 && BDayNr <= DateTime.DaysInMonth(BYearNr, BMonthNr))
369 {
370 AddClaim(Claims, JwtClaims.BirthDate, XML.Encode(new DateTime(BYearNr, BMonthNr, BDayNr)));
371 }
372
373 AddClaim(Claims, JwtClaims.Address, this.FullAddress);
374 }
375
376 return Task.FromResult<IEnumerable<KeyValuePair<string, object>>>(Claims);
377 }
378
379 private static void AddClaim(List<KeyValuePair<string, object>> Claims, string Key, object Value)
380 {
381 if (!(Value is null))
382 {
383 if (Value is string s && s == "N/A")
384 return;
385
386 Claims.Add(new KeyValuePair<string, object>(Key, Value));
387 }
388 }
389
396 public async Task<string> CreateToken(JwtFactory Factory, bool Encrypted)
397 {
398 return Factory.Create(await this.CreateClaims(Encrypted));
399 }
400
401 }
402}
Helps with common JSON-related tasks.
Definition: JSON.cs:14
static readonly DateTime UnixEpoch
Unix Date and Time epoch, starting at 1970-01-01T00:00:00Z
Definition: JSON.cs:18
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:27
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:126
static CaseInsensitiveString Domain
Domain name.
Definition: Gateway.cs:2354
static bool IsDomain(string DomainOrHost, bool IncludeAlternativeDomains)
If a domain or host name represents the gateway.
Definition: Gateway.cs:4258
static byte[] NextBytes(int NrBytes)
Generates an array of random bytes.
Definition: Gateway.cs:3534
static string GetUrl(string LocalResource)
Gets a URL for a resource.
Definition: Gateway.cs:4167
Contains a reference to an attachment assigned to a legal object.
Definition: Attachment.cs:9
Represents a digital signature on a contract.
Represents a server signature on a contract.
Static class containing predefined JWT claim names.
Definition: JwtClaims.cs:10
const string Issuer
Issuer of the JWT
Definition: JwtClaims.cs:14
const string GivenName
Given name(s) or first name(s)
Definition: JwtClaims.cs:54
const string EMailVerified
True if the e-mail address has been verified; otherwise false
Definition: JwtClaims.cs:99
const string WebSite
Web page or blog URL
Definition: JwtClaims.cs:89
const string IssueTime
Time at which the JWT was issued; can be used to determine age of the JWT
Definition: JwtClaims.cs:39
const string Name
Full name
Definition: JwtClaims.cs:49
const string JwtId
Unique identifier; can be used to prevent the JWT from being replayed (allows a token to be used only...
Definition: JwtClaims.cs:44
const string Picture
Profile picture URL
Definition: JwtClaims.cs:84
const string EMail
Preferred e-mail address
Definition: JwtClaims.cs:94
const string BirthDate
Birthday
Definition: JwtClaims.cs:109
const string SubjectIdentifier
Subject Identifier
Definition: JwtClaims.cs:220
const string Nationalities
String array representing the End-User's nationalities.
Definition: JwtClaims.cs:184
const string PhoneNumber
Preferred telephone number
Definition: JwtClaims.cs:124
const string Gender
Gender
Definition: JwtClaims.cs:104
const string MiddleName
Middle name(s)
Definition: JwtClaims.cs:64
const string Subject
Subject of the JWT (the user)
Definition: JwtClaims.cs:19
const string PhoneNumberVerified
True if the phone number has been verified; otherwise false
Definition: JwtClaims.cs:129
const string ExpirationTime
Time after which the JWT expires
Definition: JwtClaims.cs:29
const string Address
Preferred postal address
Definition: JwtClaims.cs:134
const string FamilyName
Surname(s) or last name(s)
Definition: JwtClaims.cs:59
A factory that can create and validate JWT tokens.
Definition: JwtFactory.cs:53
string Create(params KeyValuePair< string, object >[] Claims)
Creates a new JWT token.
Definition: JwtFactory.cs:248
Corresponds to a privilege in the system.
Definition: Privilege.cs:17
Corresponds to a user in the system.
Definition: User.cs:21
static void AppendValue(ref StringBuilder Output, object Value, string Delimiter)
Appends a value to a StringBuilder.
Definition: User.cs:236
Tokens available in request.
Definition: RequestOrigin.cs:9
A User that can participate in distributed operations, where the user is identified using a JWT token...
Interface for requestors that can act as an origin for distributed requests.
IdentityState
Lists recognized legal identity states.