Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Account.cs
1using System;
3using System.Text;
4using System.Text.RegularExpressions;
5using System.Threading.Tasks;
6using System.Xml;
7using Waher.Content;
10using Waher.Events;
25
27{
31 [CollectionName("BrokerAccounts")]
32 [TypeName(TypeNameSerialization.None)]
33 [ObsoleteMethod(nameof(ObsoleteProperties))]
34 [ArchivingTime]
35 [Index("UserName")]
36 [Index("ApiKey", "UserName")]
37 [Index("EMail", "UserName")]
38 [Index("PhoneNr", "UserName")]
39 [FullTextSearch("FTS_Accounts")]
41 {
45 public const string AccountCreatedCounterName = "Broker.Accounts.Created";
46
50 public const string AccountDeletedCounterName = "Broker.Accounts.Deleted";
51
52 internal static readonly Regex FromSaveUnsaved = new Regex(@"Waher[.]Persistence[.]Files[.]ObjectBTreeFile[.+]<?SaveUnsaved>?\w*[.]\w*",
53 RegexOptions.Compiled | RegexOptions.Singleline);
54 internal static readonly Regex FromUpdateObject = new Regex(@"Waher[.]Persistence[.]Files[.]ObjectBTreeFile[.+]<?UpdateObject>?\w*[.]\w*",
55 RegexOptions.Compiled | RegexOptions.Singleline);
56 private static readonly ICallStackCheck[] approvedSources = new ICallStackCheck[]
57 {
58 new ProhibitAssembly(typeof(Script.Expression).Assembly),
59 new ProhibitAssembly(typeof(Script.Persistence.SQL.Select).Assembly),
60 new ApproveAssembly(typeof(XmppServerModule).Assembly),
61 new ApproveAssembly(typeof(XmppServer).Assembly),
62 new ApproveAssembly(typeof(SmtpServer).Assembly),
63 new ApproveAssembly(typeof(Persistence.NeuroLedger.NeuroLedgerProvider).Assembly),
64 new ApproveAssembly(typeof(NeuroLedger.NeuroLedgerModule).Assembly),
65 new ApproveAssembly(typeof(Networking.SASL.AuthenticationMechanism).Assembly),
66 new ApproveType(typeof(Networking.HTTP.Authentication.BasicAuthentication)),
67 new ApproveType(typeof(Networking.HTTP.Authentication.DigestAlgorithm)),
68 new ApproveRegex(FromSaveUnsaved),
69 new ApproveRegex(FromUpdateObject)
70 };
71 private static readonly ICallStackCheck[] approvedSources2 = new ICallStackCheck[]
72 {
73 new ApproveAssembly(typeof(WsToX).Assembly),
74 new ApproveType(typeof(AgentApi)),
75 new ApproveType(typeof(Content.Markdown.Web.MarkdownToHtmlConverter))
76 };
77
78 private readonly Dictionary<string, bool> privileges = new Dictionary<string, bool>();
79 private string objectId = null;
80 private string apiKey = string.Empty;
82 private string password = string.Empty;
85 private CaseInsensitiveString latestIdentity = CaseInsensitiveString.Empty;
89 private CaseInsensitiveString personalNumber = CaseInsensitiveString.Empty;
96 private IdentityState? latestIdentityState = null;
97 private string[] roleIds = null;
98 private Role[] roles = null;
99 private string ftpRootFolder = null;
100 private long? ftpMaxStorage = null;
101 private bool ftpCanRead = false;
102 private bool ftpCanWrite = false;
103 private bool enabled = true;
104 private bool canRelayMessages = false;
105 private DateTime created = DateTime.MinValue;
106 private DateTime? updated = null;
107 private DateTime? eMailVerified = null;
108 private DateTime? phoneNrVerified = null;
109 private AccountLogin accountLogin = null;
110
114 public Account()
115 {
116 }
117
121 [ObjectId]
122 public string ObjectId
123 {
124 get => this.objectId;
125 set => this.objectId = value;
126 }
127
131 public string ApiKey
132 {
133 get => this.apiKey;
134 set => this.apiKey = value;
135 }
136
141 {
142 get => this.userName;
143 set => this.userName = value;
144 }
145
149 [Encrypted(32)]
150 public string Password
151 {
152 get
153 {
154 Assert.CallFromSource(approvedSources2, approvedSources);
155 return this.password;
156 }
157
158 set
159 {
160 if (!string.IsNullOrEmpty(this.password))
161 Assert.CallFromSource(approvedSources2, approvedSources);
162
163 this.password = value;
164 }
165 }
166
170 public string[] EncryptedProperties => new string[] { nameof(this.Password) };
171
176 {
177 get => this.eMail;
178 set => this.eMail = value;
179 }
180
185 {
186 get => this.phoneNr;
187 set => this.phoneNr = value;
188 }
189
194 [DefaultValueStringEmpty]
196 {
197 get => this.latestIdentity;
198 set => this.latestIdentity = value;
199 }
200
204 [DefaultValueNull]
206 {
207 get => this.latestIdentityState;
208 set => this.latestIdentityState = value;
209 }
210
214 [DefaultValueStringEmpty]
216 {
217 get => this.firstName;
218 set => this.firstName = value;
219 }
220
224 [DefaultValueStringEmpty]
226 {
227 get => this.middleNames;
228 set => this.middleNames = value;
229 }
230
234 [DefaultValueStringEmpty]
236 {
237 get => this.lastNames;
238 set => this.lastNames = value;
239 }
240
244 [DefaultValueStringEmpty]
246 {
247 get => this.personalNumber;
248 set => this.personalNumber = value;
249 }
250
254 [DefaultValueStringEmpty]
256 {
257 get => this.country;
258 set => this.country = value;
259 }
260
264 [DefaultValueStringEmpty]
266 {
267 get => this.orgNumber;
268 set => this.orgNumber = value;
269 }
270
274 [DefaultValueStringEmpty]
276 {
277 get => this.orgName;
278 set => this.orgName = value;
279 }
280
284 [DefaultValueStringEmpty]
286 {
287 get => this.orgRole;
288 set => this.orgRole = value;
289 }
290
294 [DefaultValueStringEmpty]
296 {
297 get => this.orgDepartment;
298 set => this.orgDepartment = value;
299 }
300
304 [DefaultValueStringEmpty]
306 {
307 get => this.orgCountry;
308 set => this.orgCountry = value;
309 }
310
314 [DefaultValueDateTimeMinValue]
315 public DateTime Created
316 {
317 get => this.created;
318 set => this.created = value;
319 }
320
324 [DefaultValueNull]
325 public DateTime? Updated
326 {
327 get => this.updated;
328 set => this.updated = value;
329 }
330
334 public DateTime? EMailVerified
335 {
336 get => this.eMailVerified;
337 set => this.eMailVerified = value;
338 }
339
343 public DateTime? PhoneNrVerified
344 {
345 get => this.phoneNrVerified;
346 set => this.phoneNrVerified = value;
347 }
348
352 [DefaultValue(true)]
353 public bool Enabled
354 {
355 get => this.enabled;
356 set => this.enabled = value;
357 }
358
362 [DefaultValue(false)]
364 {
365 get => this.canRelayMessages;
366 set => this.canRelayMessages = value;
367 }
368
372 public string FtpRootFolder
373 {
374 get => this.ftpRootFolder;
375 set => this.ftpRootFolder = value;
376 }
377
381 public bool FtpCanRead
382 {
383 get => this.ftpCanRead;
384 set => this.ftpCanRead = value;
385 }
386
390 public bool FtpCanWrite
391 {
392 get => this.ftpCanWrite;
393 set => this.ftpCanWrite = value;
394 }
395
400 public long? FtpMaxStorage
401 {
402 get => this.ftpMaxStorage;
403 set => this.ftpMaxStorage = value;
404 }
405
409 [DefaultValueNull]
410 public string[] RoleIds
411 {
412 get => this.roleIds;
413 set
414 {
415 this.roleIds = value;
416
417 lock (this.privileges)
418 {
419 this.roles = null;
420 this.privileges.Clear();
421 }
422 }
423 }
424
429 public async Task<Role[]> LoadRoles()
430 {
431 Role[] Roles = this.roles;
432
433 if (Roles is null)
434 {
435 string[] Ids = this.roleIds;
436 int i, c = Ids?.Length ?? 0;
437
438 Roles = new Role[c];
439 for (i = 0; i < c; i++)
440 Roles[i] = await Security.Users.Roles.GetRole(Ids[i]);
441
442 this.roles = Roles;
443 }
444
445 return Roles;
446 }
447
453 public bool HasPrivilege(string Privilege)
454 {
456 return this.canRelayMessages;
457
459 {
460 return this.ftpCanRead &&
461 !Privilege.Contains("..") &&
462 !Privilege.Contains(':') &&
463 !Privilege.Contains("//") &&
464 !Privilege.Contains("\\\\");
465 }
466
468 {
469 return this.ftpCanWrite &&
470 !Privilege.Contains("..") &&
471 !Privilege.Contains(':') &&
472 !Privilege.Contains("//") &&
473 !Privilege.Contains("\\\\");
474 }
475
476 if (string.IsNullOrEmpty(Privilege))
477 return true;
478
479 lock (this.privileges)
480 {
481 if (this.privileges.TryGetValue(Privilege, out bool Result))
482 return Result;
483 }
484
485 Role[] Roles = this.roles ?? this.LoadRoles().Result;
486
487 bool HasPrivilege = false;
488
489 foreach (Role Role in Roles)
490 {
492 {
493 HasPrivilege = true;
494 break;
495 }
496 }
497
498 lock (this.privileges)
499 {
500 this.privileges[Privilege] = HasPrivilege;
501 }
502
503 Task.Run(async () =>
504 {
505 try
506 {
508 }
509 catch (Exception ex)
510 {
511 Log.Exception(ex);
512 }
513 });
514
515 return HasPrivilege;
516 }
517
522 public async void ObsoleteProperties(Dictionary<string, object> Properties)
523 {
524 try
525 {
526 AccountLogin Login = await this.GetAccountLogin();
527 bool Updated = false;
528
529 if (string.IsNullOrEmpty(Login.RemoteEndPoint) &&
530 Properties.TryGetValue("RemoteEndpoint", out object Obj) &&
531 Obj is string RemoteEndPoint)
532 {
533 Login.RemoteEndPoint = RemoteEndPoint;
534 Updated = true;
535 }
536
537 if (Login.LastLogin == DateTime.MinValue &&
538 Properties.TryGetValue("LastLogin", out Obj) &&
539 Obj is DateTime LastLogin)
540 {
541 Login.LastLogin = LastLogin;
542 Updated = true;
543 }
544
545 if (Updated)
546 await Database.Update(Login);
547 }
548 catch (Exception ex)
549 {
550 Log.Exception(ex);
551 }
552 }
553
558 public async Task LoggedIn(string RemoteEndPoint)
559 {
560 AccountLogin Login = await this.GetAccountLogin();
561
562 Login.LastLogin = DateTime.Now;
563 Login.RemoteEndPoint = RemoteEndPoint;
564
565 await Database.Update(Login);
566 }
567
572 public async Task<AccountLogin> GetAccountLogin()
573 {
574 if (!(this.accountLogin is null))
575 return this.accountLogin;
576
577 this.accountLogin = await Database.FindFirstDeleteRest<AccountLogin>(new FilterFieldEqualTo("UserName", this.userName));
578 if (!(this.accountLogin is null))
579 return this.accountLogin;
580
581 this.accountLogin = new AccountLogin()
582 {
583 UserName = this.userName,
584 RemoteEndPoint = string.Empty,
585 LastLogin = DateTime.MinValue
586 };
587
588 await Database.Insert(this.accountLogin);
589
590 return this.accountLogin;
591 }
592
596 public string FullName => Concat(" ", this.firstName, this.middleNames, this.lastNames);
597
601 public string PersonalInformation => Concat(", ", this.FullName, this.personalNumber, this.country);
602
606 public string OrganizationInformation => Concat(", ", this.orgRole, this.orgDepartment, this.orgName, this.orgNumber, this.orgCountry);
607
612 {
613 get
614 {
615 return
616 !CaseInsensitiveString.IsNullOrEmpty(this.firstName) ||
617 !CaseInsensitiveString.IsNullOrEmpty(this.middleNames) ||
618 !CaseInsensitiveString.IsNullOrEmpty(this.lastNames) ||
619 !CaseInsensitiveString.IsNullOrEmpty(this.personalNumber) ||
620 !CaseInsensitiveString.IsNullOrEmpty(this.orgNumber) ||
621 !CaseInsensitiveString.IsNullOrEmpty(this.orgName) ||
622 !CaseInsensitiveString.IsNullOrEmpty(this.orgRole) ||
623 !CaseInsensitiveString.IsNullOrEmpty(this.orgDepartment) ||
624 !CaseInsensitiveString.IsNullOrEmpty(this.orgCountry);
625 }
626 }
627
628 private static string Concat(string Delimiter, params CaseInsensitiveString[] Segments)
629 {
630 StringBuilder sb = new StringBuilder();
631 bool First = true;
632
633 foreach (string Segment in Segments)
634 Append(sb, ref First, Segment, Delimiter);
635
636 return sb.ToString();
637 }
638
639 private static void Append(StringBuilder sb, ref bool First, CaseInsensitiveString Segment, string Delimiter)
640 {
641 if (!string.IsNullOrEmpty(Segment))
642 {
643 if (First)
644 First = false;
645 else
646 sb.Append(Delimiter);
647
648 sb.Append(Segment.Value);
649 }
650 }
651
657 internal void AppendAccountXml(StringBuilder sb, bool IncludeNamespace)
658 {
659 sb.Append("<Account");
660 if (IncludeNamespace)
661 sb.Append(" xmlns=\"http://waher.se/schema/Onboarding/v1.xsd\"");
662
663 sb.Append(" userName=\"");
664 sb.Append(XML.Encode(this.userName));
665 sb.Append("\" password=\"");
666 sb.Append(XML.Encode(this.password));
667 sb.Append("\" domain=\"");
668 sb.Append(XML.Encode(Gateway.Domain.Value));
669 sb.Append("\" enabled=\"");
670 sb.Append(CommonTypes.Encode(this.enabled));
671 sb.Append("\" created=\"");
672 sb.Append(XML.Encode(this.created));
673
674 if (this.updated.HasValue)
675 {
676 sb.Append("\" updated=\"");
677 sb.Append(XML.Encode(this.updated.Value));
678 }
679
680 if (!CaseInsensitiveString.IsNullOrEmpty(this.eMail))
681 {
682 sb.Append("\" eMail=\"");
683 sb.Append(XML.Encode(this.eMail.Value));
684
685 if (this.eMailVerified.HasValue)
686 {
687 sb.Append("\" eMailVerified=\"");
688 sb.Append(XML.Encode(this.eMailVerified.Value));
689 }
690 }
691
692 if (!CaseInsensitiveString.IsNullOrEmpty(this.phoneNr))
693 {
694 sb.Append("\" phoneNr=\"");
695 sb.Append(XML.Encode(this.phoneNr.Value));
696
697 if (this.phoneNrVerified.HasValue)
698 {
699 sb.Append("\" phoneNrVerified=\"");
700 sb.Append(XML.Encode(this.phoneNrVerified.Value));
701 }
702 }
703
704 if (!CaseInsensitiveString.IsNullOrEmpty(this.latestIdentity))
705 {
706 sb.Append("\" latestIdentity=\"");
707 sb.Append(XML.Encode(this.latestIdentity.Value));
708 }
709
710 if (!CaseInsensitiveString.IsNullOrEmpty(this.firstName))
711 {
712 sb.Append("\" firstName=\"");
713 sb.Append(XML.Encode(this.firstName.Value));
714 }
715
716 if (!CaseInsensitiveString.IsNullOrEmpty(this.middleNames))
717 {
718 sb.Append("\" middleNames=\"");
719 sb.Append(XML.Encode(this.middleNames.Value));
720 }
721
722 if (!CaseInsensitiveString.IsNullOrEmpty(this.lastNames))
723 {
724 sb.Append("\" lastNames=\"");
725 sb.Append(XML.Encode(this.lastNames.Value));
726 }
727
728 if (!CaseInsensitiveString.IsNullOrEmpty(this.personalNumber))
729 {
730 sb.Append("\" personalNumber=\"");
731 sb.Append(XML.Encode(this.personalNumber.Value));
732 }
733
734 if (!CaseInsensitiveString.IsNullOrEmpty(this.country))
735 {
736 sb.Append("\" country=\"");
737 sb.Append(XML.Encode(this.country.Value));
738 }
739
740 if (!CaseInsensitiveString.IsNullOrEmpty(this.orgNumber))
741 {
742 sb.Append("\" orgNumber=\"");
743 sb.Append(XML.Encode(this.orgNumber.Value));
744 }
745
746 if (!CaseInsensitiveString.IsNullOrEmpty(this.orgName))
747 {
748 sb.Append("\" orgName=\"");
749 sb.Append(XML.Encode(this.orgName.Value));
750 }
751
752 if (!CaseInsensitiveString.IsNullOrEmpty(this.orgRole))
753 {
754 sb.Append("\" orgRole=\"");
755 sb.Append(XML.Encode(this.orgRole.Value));
756 }
757
758 if (!CaseInsensitiveString.IsNullOrEmpty(this.orgDepartment))
759 {
760 sb.Append("\" orgDepartment=\"");
761 sb.Append(XML.Encode(this.orgDepartment.Value));
762 }
763
764 if (!CaseInsensitiveString.IsNullOrEmpty(this.orgCountry))
765 {
766 sb.Append("\" orgCountry=\"");
767 sb.Append(XML.Encode(this.orgCountry.Value));
768 }
769
770 sb.Append("\" />");
771 }
772
780 public async Task<string> GetOnboardingUrl(DateTime Expires)
781 {
782 StringBuilder sb = new StringBuilder();
783
784 this.AppendAccountXml(sb, true);
785
786 byte[] Bin = Encoding.UTF8.GetBytes(sb.ToString());
787 byte[] Key = Gateway.NextBytes(16);
788 byte[] IV = Gateway.NextBytes(16);
789 Bin = Aes256Encrypt.Encrypt(Bin, Key, IV);
790
791 sb.Clear();
792 sb.Append("<Info xmlns=\"http://waher.se/schema/Onboarding/v1.xsd\" base64=\"");
793 sb.Append(Convert.ToBase64String(Bin));
794 sb.Append("\" once=\"true\" expires=\"");
795 sb.Append(XML.Encode(Expires.ToUniversalTime()));
796 sb.Append("\" />");
797
798 string OnboardingDomainName = await LegalComponent.GetOnboardingNeuronDomainName();
799
800 XmlElement Info = await Gateway.XmppClient.IqSetAsync("onboarding." + OnboardingDomainName, sb.ToString());
801
802 foreach (XmlNode N in Info.ChildNodes)
803 {
804 if (N is XmlElement E && E.LocalName == "Code")
805 {
806 string Code = XML.Attribute(E, "code");
807 return "obinfo:" + OnboardingDomainName + ":" + Code + ":" +
808 Convert.ToBase64String(Key) + ":" +
809 Convert.ToBase64String(IV);
810 }
811 }
812
813 throw new Exception("Unexpected response returned: " + Info.OuterXml);
814 }
815
816 }
817}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:15
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Definition: CommonTypes.cs:596
Converts Web Script-files to desired output, by evaluating the web script and encoding the results in...
Definition: WsToX.cs:16
Helps with common XML-related tasks.
Definition: XML.cs:21
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
Definition: XML.cs:1062
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:29
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
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:147
static CaseInsensitiveString Domain
Domain name.
Definition: Gateway.cs:3087
static byte[] NextBytes(int NrBytes)
Generates an array of random bytes.
Definition: Gateway.cs:4335
static XmppClient XmppClient
XMPP Client connection of gateway.
Definition: Gateway.cs:4038
Implements a simple FTP Server, as defined in:
Definition: FtpServer.cs:38
const string FtpWritePrivilegePrefix
Prefix of FTP Write Privileges
Definition: FtpServer.cs:72
const string FtpReadPrivilegePrefix
Prefix of FTP Read Privileges
Definition: FtpServer.cs:67
Implements a simple SMTP Server, as defined in:
Definition: SmtpServer.cs:45
const string SmtpRelayPrivilegeID
SmtpRelay
Definition: SmtpServer.cs:69
Represents a case-insensitive string.
string Value
String-representation of the case-insensitive string. (Representation is case sensitive....
static readonly CaseInsensitiveString Empty
Empty case-insensitive string
static bool IsNullOrEmpty(CaseInsensitiveString value)
Indicates whether the specified string is null or an CaseInsensitiveString.Empty string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static async Task Update(object Object)
Updates an object in the database.
Definition: Database.cs:1211
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Definition: Database.cs:97
This filter selects objects that have a named field equal to a given value.
static byte[] Encrypt(byte[] Data, byte[] Key, byte[] IV, CipherMode CipherMode=CipherMode.CBC, PaddingMode PaddingMode=PaddingMode.PKCS7)
Performs AES encryption of data.
Checks for an approved assembly in the call stack.
Checks for approved sources in the call stack using a regular expression.
Definition: ApproveRegex.cs:11
Checks for an approved type in the call stack.
Definition: ApproveType.cs:10
Static class containing methods that can be used to make sure calls are made from appropriate locatio...
Definition: Assert.cs:15
static void CallFromSource(params string[] Sources)
Makes sure the call is made from one of the listed sources.
Definition: Assert.cs:54
Checks for a prohibited assembly in the call stack.
Corresponds to a privilege in the system.
Definition: Privilege.cs:16
Maintains the collection of all privileges in the system.
Definition: Privileges.cs:13
static async Task< Privilege > GetPrivilege(string PrivilegeId)
Gets the Privilege object corresponding to a full Privilege ID.
Definition: Privileges.cs:23
Corresponds to a role in the system.
Definition: Role.cs:15
bool HasPrivilege(string Privilege)
If the user has a given privilege.
Definition: Role.cs:72
Maintains the collection of all roles in the system.
Definition: Roles.cs:14
static Task< Role > GetRole(string RoleId)
Gets the Role object corresponding to a Role ID.
Definition: Roles.cs:23
Contains information about a broker account.
Definition: Account.cs:41
DateTime? PhoneNrVerified
When Phone Number was verified.
Definition: Account.cs:344
CaseInsensitiveString PersonalNumber
Phone Number associated with account holder.
Definition: Account.cs:246
CaseInsensitiveString EMail
E-mail address associated with account.
Definition: Account.cs:176
CaseInsensitiveString UserName
User Name of account
Definition: Account.cs:141
bool Enabled
If account is enabled
Definition: Account.cs:354
CaseInsensitiveString OrgRole
Organization role associated with account holder.
Definition: Account.cs:286
async void ObsoleteProperties(Dictionary< string, object > Properties)
Method called when loading the object and properties were found that are no longer recognized.
Definition: Account.cs:522
CaseInsensitiveString FirstName
First name associated with account holder.
Definition: Account.cs:216
string PersonalInformation
Personal information of account holder.
Definition: Account.cs:601
async Task< AccountLogin > GetAccountLogin()
Gets the object with the associated account login status information.
Definition: Account.cs:572
bool HasPrivilege(string Privilege)
If account has a certain privilege.
Definition: Account.cs:453
DateTime? EMailVerified
When e-Mail was verified.
Definition: Account.cs:335
string Password
Password of account
Definition: Account.cs:151
CaseInsensitiveString Country
Country code associated with account holder.
Definition: Account.cs:256
string OrganizationInformation
Organizational information of account holder.
Definition: Account.cs:606
IdentityState? LatestIdentityState
State of Last Legal Identity approved for account.
Definition: Account.cs:206
CaseInsensitiveString LastNames
Last name(s) associated with account holder.
Definition: Account.cs:236
CaseInsensitiveString PhoneNr
Phone number associated with account.
Definition: Account.cs:185
async Task< string > GetOnboardingUrl(DateTime Expires)
Generates an oninfo URI for onboarding the account, valid until the specified expiration date.
Definition: Account.cs:780
string FtpRootFolder
FTP Root Folder, if account has access to FTP.
Definition: Account.cs:373
Account()
Contains information about a broker account.
Definition: Account.cs:114
CaseInsensitiveString OrgDepartment
Organization department associated with account holder.
Definition: Account.cs:296
const string AccountDeletedCounterName
Name of counter that counts the number of accounts deleted.
Definition: Account.cs:50
bool FtpCanWrite
If FTP Write access is granted to the root folder and subfolders.
Definition: Account.cs:391
const string AccountCreatedCounterName
Name of counter that counts the number of accounts created.
Definition: Account.cs:45
async Task< Role[]> LoadRoles()
Load role objects.
Definition: Account.cs:429
bool FtpCanRead
If FTP Read access is granted to the root folder and subfolders.
Definition: Account.cs:382
bool CanRelayMessages
If account is allowed to relay e-mail messages
Definition: Account.cs:364
CaseInsensitiveString OrgNumber
Organization number associated with account holder.
Definition: Account.cs:266
string FullName
Full name of account holder.
Definition: Account.cs:596
long? FtpMaxStorage
Maximum storage allowed, in bytes. 0 means no storage. A negative value means unlimited storage.
Definition: Account.cs:401
DateTime? Updated
When account was created associated with account holder.
Definition: Account.cs:326
DateTime Created
When account was created associated with account holder.
Definition: Account.cs:316
async Task LoggedIn(string RemoteEndPoint)
Registers a log-in event on the account.
Definition: Account.cs:558
CaseInsensitiveString OrgName
Organization name associated with account holder.
Definition: Account.cs:276
CaseInsensitiveString OrgCountry
Country code of organization associated with account holder.
Definition: Account.cs:306
CaseInsensitiveString MiddleNames
Middle name(s) associated with account holder.
Definition: Account.cs:226
CaseInsensitiveString LatestIdentity
Last Legal Identity approved for account. Note: Identity object might not be approved any longer.
Definition: Account.cs:196
bool HasExtendedPersonalInformation
If the account has extended personal information associated with it.
Definition: Account.cs:612
string[] EncryptedProperties
Array of properties that are encrypted.
Definition: Account.cs:170
Service Module hosting the XMPP broker and its components.
Interface for XMPP user accounts.
Definition: IAccount.cs:9
Interface for objects containing encrypted properties. Mark the properties that are encrypted with th...
Interface for call stack checks.
TypeNameSerialization
How the type name should be serialized.