public virtual void Update(UserAccount account) { if (account == null) { Tracing.Error("[UserAccountService.Update] called -- failed null account"); throw new ArgumentNullException("account"); } Tracing.Information("[UserAccountService.Update] called for account: {0}", account.ID); account.LastUpdated = account.UtcNow; this.userRepository.Update(account); }
public virtual void DeleteAccount(Guid accountID) { Tracing.Information("[UserAccountService.DeleteAccount] called: {0}", accountID); var account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } DeleteAccount(account); }
protected virtual void UpdateLinkedAccount(LinkedAccount account, IEnumerable <Claim> claims = null) { Tracing.Information("[UserAccount.UpdateLinkedAccount] called for accountID: {0}", this.ID); if (account == null) { Tracing.Error("[UserAccount.UpdateLinkedAccount] failed -- null account"); throw new ArgumentNullException("account"); } account.LastLogin = UtcNow; account.UpdateClaims(claims); }
protected internal virtual bool RequestTwoFactorAuthCode() { Tracing.Information("[UserAccount.RequestTwoFactorAuthCode] called for accountID: {0}", this.ID); if (!this.IsAccountVerified) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCode] failed -- account not verified"); return(false); } if (this.IsAccountClosed) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCode] failed -- account closed"); return(false); } if (!this.IsLoginAllowed) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCode] failed -- login not allowed"); return(false); } if (this.AccountTwoFactorAuthMode != TwoFactorAuthMode.Mobile) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCode] failed -- AccountTwoFactorAuthMode not mobile"); return(false); } if (String.IsNullOrWhiteSpace(MobilePhoneNumber)) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCode] failed -- empty MobilePhoneNumber"); return(false); } if (this.IsMobileCodeStale || this.VerificationPurpose == VerificationKeyPurpose.ChangeMobile) { Tracing.Verbose("[UserAccount.RequestTwoFactorAuthCode] new mobile code issued"); this.IssueMobileCode(); } Tracing.Verbose("[UserAccount.RequestTwoFactorAuthCode] success"); this.CurrentTwoFactorAuthStatus = TwoFactorAuthMode.Mobile; this.AddEvent(new TwoFactorAuthenticationCodeNotificationEvent { Account = this }); return(true); }
public virtual void SendTwoFactorAuthenticationCode(Guid accountID) { Tracing.Information(String.Format("[UserAccountService.SendTwoFactorAuthenticationCode] called: {0}", accountID)); var account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } account.RequestTwoFactorAuthCode(); Update(account); }
public virtual void RemoveLinkedAccount(string provider) { Tracing.Information("[UserAccount.RemoveLinkedAccount] called for accountID: {0}", this.ID); var linked = this.LinkedAccounts.Where(x => x.ProviderName == provider); foreach (var item in linked) { this.LinkedAccounts.Remove(item); this.AddEvent(new LinkedAccountRemovedEvent { Account = this, LinkedAccount = item }); } }
public virtual void RemoveLinkedAccount(string provider, string id) { Tracing.Information("[UserAccount.RemoveLinkedAccount] called for accountID: {0}", this.ID); var linked = GetLinkedAccount(provider, id); if (linked != null) { this.LinkedAccounts.Remove(linked); this.AddEvent(new LinkedAccountRemovedEvent { Account = this, LinkedAccount = linked }); } }
public virtual void ConfigureTwoFactorAuthentication(Guid accountID, TwoFactorAuthMode mode) { Tracing.Information("[UserAccountService.ConfigureTwoFactorAuthentication] called: {0}", accountID); var account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } account.ConfigureTwoFactorAuthentication(mode); Update(account); }
public virtual void RemoveMobilePhone(Guid accountID) { Tracing.Information("[UserAccountService.RemoveMobilePhone] called: {0}", accountID); var account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } account.ClearMobilePhoneNumber(); Update(account); }
internal protected virtual void Init(string tenant, string username, string password, string email) { Tracing.Information("[UserAccount.Init] called"); if (String.IsNullOrWhiteSpace(tenant)) { Tracing.Error("[UserAccount.Init] failed -- no tenant"); throw new ArgumentNullException("tenant"); } if (String.IsNullOrWhiteSpace(username)) { Tracing.Error("[UserAccount.Init] failed -- no username"); throw new ValidationException("Username is required."); } if (String.IsNullOrWhiteSpace(password)) { Tracing.Error("[UserAccount.Init] failed -- no password"); throw new ValidationException("Password is required."); } if (String.IsNullOrWhiteSpace(email)) { Tracing.Error("[UserAccount.Init] failed -- no email"); throw new ValidationException("Email is required."); } if (this.ID != Guid.Empty) { Tracing.Error("[UserAccount.Init] failed -- ID already assigned"); throw new Exception("Can't call Init if UserAccount is already assigned an ID"); } this.ID = Guid.NewGuid(); this.Tenant = tenant; this.Username = username; this.Email = email; this.Created = this.UtcNow; this.LastUpdated = this.Created; this.HashedPassword = HashPassword(password); this.PasswordChanged = this.Created; this.IsAccountVerified = false; this.IsLoginAllowed = false; this.AccountTwoFactorAuthMode = TwoFactorAuthMode.None; this.CurrentTwoFactorAuthStatus = TwoFactorAuthMode.None; this.SetVerificationKey(VerificationKeyPurpose.VerifyAccount); this.AddEvent(new AccountCreatedEvent { Account = this }); }
public virtual bool ChangeEmailFromKey(Guid accountID, string password, string key, string newEmail) { Tracing.Information("[UserAccountService.ChangeEmailFromKey] called: {0}, {1}", accountID, newEmail); if (String.IsNullOrWhiteSpace(password)) { Tracing.Error("[UserAccountService.ChangeEmailFromKey] failed -- null password"); throw new ValidationException("Invalid password."); } if (String.IsNullOrWhiteSpace(key)) { Tracing.Error("[UserAccountService.ChangeEmailFromKey] failed -- null key"); throw new ValidationException("Invalid key."); } if (String.IsNullOrWhiteSpace(newEmail)) { Tracing.Error("[UserAccountService.ChangeEmailFromKey] failed -- null newEmail"); throw new ValidationException("Invalid email."); } var account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } if (!Authenticate(account, password, AuthenticationPurpose.VerifyPassword)) { Tracing.Error("[UserAccountService.ChangeEmailFromKey] failed -- authN failed"); throw new ValidationException("Invalid password."); } ValidateEmail(account, newEmail); var result = account.ChangeEmailFromKey(key, newEmail); if (result && SecuritySettings.EmailIsUsername) { Tracing.Verbose("[UserAccountService.ChangeEmailFromKey] security setting EmailIsUsername is true and AllowEmailChangeWhenEmailIsUsername is true, so changing username: {0}, to: {1}", account.Username, newEmail); account.Username = newEmail; } Update(account); Tracing.Verbose("[UserAccountService.ChangeEmailFromKey] result: {0}", result); return(result); }
public virtual void SignOut() { Tracing.Information(String.Format("[ClaimsBasedAuthenticationService.SignOut] called: {0}", ClaimsPrincipal.Current.Claims.GetValue(ClaimTypes.NameIdentifier))); // clear cookie var sam = FederatedAuthentication.SessionAuthenticationModule; if (sam == null) { Tracing.Verbose("[ClaimsBasedAuthenticationService.Signout] SessionAuthenticationModule is not configured"); throw new Exception("SessionAuthenticationModule is not configured and it needs to be."); } sam.SignOut(); }
public virtual bool ChangeEmailFromKey(Guid accountID, string password, string key, string newEmail) { Tracing.Information(String.Format("[UserAccountService.ChangeEmailFromKey] called: {0}, {1}, {2}", accountID, key, newEmail)); if (String.IsNullOrWhiteSpace(password)) { throw new ValidationException("Invalid password."); } if (String.IsNullOrWhiteSpace(key)) { throw new ValidationException("Invalid key."); } if (String.IsNullOrWhiteSpace(newEmail)) { throw new ValidationException("Invalid email."); } var account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } Tracing.Verbose(String.Format("[UserAccountService.ChangeEmailFromKey] account located: {0}, {1}", account.Tenant, account.Username)); if (!Authenticate(account, password, AuthenticationPurpose.VerifyPassword)) { throw new ValidationException("Invalid password."); } ValidateEmail(account, newEmail); var result = account.ChangeEmailFromKey(key, newEmail); if (result && SecuritySettings.EmailIsUsername) { Tracing.Warning(String.Format("[UserAccountService.ChangeEmailFromKey] security setting EmailIsUsername is true and AllowEmailChangeWhenEmailIsUsername is true, so changing username: {0}, to: {1}", account.Username, newEmail)); account.Username = newEmail; } Update(account); Tracing.Verbose(String.Format("[UserAccountService.ChangeEmailFromKey] change email outcome: {0}, {1}, {2}", account.Tenant, account.Username, result ? "Successful" : "Failed")); return(result); }
public virtual void SetPassword(string tenant, string username, string newPassword) { Tracing.Information(String.Format("[UserAccountService.SetPassword] called: {0}, {1}", tenant, username)); if (!SecuritySettings.Instance.MultiTenant) { tenant = SecuritySettings.Instance.DefaultTenant; } if (String.IsNullOrWhiteSpace(tenant)) { throw new ValidationException("Invalid tenant."); } if (String.IsNullOrWhiteSpace(username)) { throw new ValidationException("Invalid username."); } if (String.IsNullOrWhiteSpace(newPassword)) { throw new ValidationException("Invalid newPassword."); } ValidatePassword(tenant, username, newPassword); var account = this.GetByUsername(tenant, username); if (account == null) { throw new ValidationException("Invalid tenant and/or username."); } Tracing.Information(String.Format("[UserAccountService.SetPassword] setting new password for: {0}, {1}", tenant, username)); using (var tx = new TransactionScope()) { account.SetPassword(newPassword); this.userRepository.SaveChanges(); if (this.notificationService != null) { this.notificationService.SendPasswordChangeNotice(account); } tx.Complete(); } }
public virtual void RemoveCertificate(X509Certificate2 certificate) { Tracing.Information("[UserAccount.RemoveCertificate] called for accountID: {0}", this.ID); if (certificate == null) { Tracing.Error("[UserAccount.RemoveCertificate] failed -- null certificate"); throw new ArgumentNullException("certificate"); } if (certificate.Handle == IntPtr.Zero) { Tracing.Error("[UserAccount.RemoveCertificate] failed -- invalid certificate handle"); throw new ArgumentException("Invalid certificate"); } RemoveCertificate(certificate.Thumbprint); }
protected internal virtual bool VerifyAccount(string key) { Tracing.Information("[UserAccount.VerifyAccount] called for accountID: {0}", this.ID); if (String.IsNullOrWhiteSpace(key)) { Tracing.Error("[UserAccount.VerifyAccount] failed -- no key"); return(false); } if (IsAccountVerified) { Tracing.Error("[UserAccount.VerifyAccount] failed -- account already verified"); return(false); } if (this.VerificationPurpose != VerificationKeyPurpose.VerifyAccount) { Tracing.Error("[UserAccount.VerifyAccount] failed -- verification purpose invalid"); return(false); } if (IsVerificationKeyStale) { Tracing.Error("[UserAccount.VerifyAccount] failed -- verification key stale"); return(false); } if (this.VerificationKey != key) { Tracing.Error("[UserAccount.VerifyAccount] failed -- verification key doesn't match"); return(false); } Tracing.Verbose("[UserAccount.VerifyAccount] succeeded"); this.IsAccountVerified = true; this.ClearVerificationKey(); this.AddEvent(new AccountVerifiedEvent { Account = this }); return(true); }
public virtual bool AuthenticateWithCode(Guid accountID, string code, out UserAccount account) { Tracing.Information("[UserAccountService.AuthenticateWithCode] called {0}", accountID); account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } var result = account.VerifyTwoFactorAuthCode(code); Update(account); Tracing.Verbose("[UserAccountService.AuthenticateWithCode] result {0}", result); return(result); }
protected internal virtual void ChangeUsername(string newUsername) { Tracing.Information("[UserAccount.ChangeUsername] called for accountID: {0}", this.ID); if (String.IsNullOrWhiteSpace(newUsername)) { Tracing.Error("[UserAccount.ChangeUsername] failed -- invalid newUsername"); throw new ArgumentNullException(newUsername); } Tracing.Verbose("[UserAccount.ChangeUsername] success"); this.Username = newUsername; this.AddEvent(new UsernameChangedEvent { Account = this }); }
public virtual bool VerifyAccount(string key) { Tracing.Information("[UserAccountService.VerifyAccount] called: {0}", key); var account = this.GetByVerificationKey(key); if (account == null) { return(false); } var result = account.VerifyAccount(key); Update(account); Tracing.Verbose("[UserAccountService.VerifyAccount] result: {0}", result); return(result); }
protected internal virtual bool ChangePasswordFromResetKey(string key, string newPassword) { Tracing.Information("[UserAccount.ChangePasswordFromResetKey] called for accountID: {0}", this.ID); if (String.IsNullOrWhiteSpace(key)) { Tracing.Error("[UserAccount.ChangePasswordFromResetKey] failed -- no key"); return(false); } if (!this.IsAccountVerified) { Tracing.Error("[UserAccount.ChangePasswordFromResetKey] failed -- account not verified"); return(false); } // if the key is too old don't honor it if (IsVerificationKeyStale) { Tracing.Error("[UserAccount.ChangePasswordFromResetKey] failed -- verification key too old"); return(false); } if (this.VerificationPurpose != VerificationKeyPurpose.ChangePassword) { Tracing.Error("[UserAccount.ChangePasswordFromResetKey] failed -- invalid verification key purpose"); return(false); } // check if key matches if (this.VerificationKey != key) { Tracing.Error("[UserAccount.ChangePasswordFromResetKey] failed -- verification keys don't match"); return(false); } Tracing.Verbose("[UserAccount.ChangePasswordFromResetKey] success"); this.ClearVerificationKey(); this.SetPassword(newPassword); return(true); }
public virtual bool VerifyAccount(string key) { Tracing.Information(String.Format("[UserAccountService.VerifyAccount] called: {0}", key)); var account = this.GetByVerificationKey(key); if (account == null) { return(false); } Tracing.Verbose(String.Format("[UserAccountService.VerifyAccount] account located: {0}, {1}", account.Tenant, account.Username)); var result = account.VerifyAccount(key); Update(account); return(result); }
public void Send(Message msg) { Tracing.Information("[SmtpMessageDelivery.Send] sending mail to " + msg.To); if (!String.IsNullOrWhiteSpace(msg.Cc)) { Tracing.Information("[SmtpMessageDelivery.Send] cc'ing mail to " + msg.Cc); } if (String.IsNullOrWhiteSpace(msg.From)) { SmtpSection smtp = ConfigurationManager.GetSection("system.net/mailSettings/smtp") as SmtpSection; msg.From = smtp.From; } using (SmtpClient smtp = new SmtpClient()) { smtp.Timeout = SmtpTimeout; try { MailMessage mailMessage = new MailMessage(msg.From, msg.To, msg.Subject, msg.Body) { IsBodyHtml = SendAsHtml }; if (!String.IsNullOrWhiteSpace(msg.Cc)) { foreach (string email in msg.Cc.Split(',', ';')) { mailMessage.CC.Add(email); } } smtp.Send(mailMessage); } catch (SmtpException e) { Tracing.Error("[SmtpMessageDelivery.Send] SmtpException: " + e.Message); } catch (Exception e) { Tracing.Error("[SmtpMessageDelivery.Send] Exception: " + e.Message); } } }
protected internal virtual void ConfigureTwoFactorAuthentication(TwoFactorAuthMode mode) { Tracing.Information("[UserAccount.ConfigureTwoFactorAuthentication] called for accountID: {0}, mode: {1}", this.ID, mode); if (this.AccountTwoFactorAuthMode == mode) { Tracing.Warning("[UserAccount.ConfigureTwoFactorAuthentication] nothing to do -- mode is same as current value"); return; } if (mode == TwoFactorAuthMode.Mobile && String.IsNullOrWhiteSpace(this.MobilePhoneNumber)) { Tracing.Error("[UserAccount.ConfigureTwoFactorAuthentication] failed -- mobile requested but no mobile phone for account"); throw new ValidationException("Register a mobile phone number to enable mobile two factor authentication."); } if (mode == TwoFactorAuthMode.Certificate && !this.Certificates.Any()) { Tracing.Error("[UserAccount.ConfigureTwoFactorAuthentication] failed -- certificate requested but no certificates for account"); throw new ValidationException("Add a client certificate to enable certificate two factor authentication."); } this.ClearMobileAuthCode(); this.AccountTwoFactorAuthMode = mode; if (mode == TwoFactorAuthMode.None) { Tracing.Verbose("[UserAccount.ConfigureTwoFactorAuthentication] success -- two factor auth disabled"); this.AddEvent(new TwoFactorAuthenticationDisabledEvent { Account = this }); } else { Tracing.Verbose("[UserAccount.ConfigureTwoFactorAuthentication] success -- two factor auth enabled, mode: {0}", mode); this.AddEvent(new TwoFactorAuthenticationEnabledEvent { Account = this, Mode = mode }); } }
public virtual bool AuthenticateWithCertificate(X509Certificate2 certificate, out UserAccount account) { Tracing.Information("[UserAccountService.AuthenticateWithCertificate] called"); certificate.Validate(); account = this.GetByCertificate(certificate.Thumbprint); if (account == null) { return(false); } var result = account.Authenticate(certificate); Update(account); Tracing.Verbose("[UserAccountService.AuthenticateWithCertificate] result {0}", result); return(result); }
protected internal virtual void SetPassword(string password) { Tracing.Information("[UserAccount.SetPassword] called for accountID: {0}", this.ID); if (String.IsNullOrWhiteSpace(password)) { Tracing.Error("[UserAccount.SetPassword] failed -- no password provided"); throw new ValidationException("Invalid password."); } Tracing.Verbose("[UserAccount.SetPassword] setting new password hash"); HashedPassword = HashPassword(password); PasswordChanged = UtcNow; RequiresPasswordReset = false; this.AddEvent(new PasswordChangedEvent { Account = this, NewPassword = password }); }
public virtual void ChangeMobilePhoneRequest(Guid accountID, string newMobilePhoneNumber) { Tracing.Information("[UserAccountService.ChangeMobilePhoneRequest] called: {0}, {1}", accountID, newMobilePhoneNumber); if (String.IsNullOrWhiteSpace(newMobilePhoneNumber)) { Tracing.Error("[UserAccountService.ChangeMobilePhoneRequest] failed -- null newMobilePhoneNumber"); throw new ValidationException("Invalid Phone Number."); } var account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } account.RequestChangeMobilePhoneNumber(newMobilePhoneNumber); Update(account); }
public virtual bool AuthenticateWithCertificate(Guid accountID, X509Certificate2 certificate, out UserAccount account) { Tracing.Information("[UserAccountService.AuthenticateWithCertificate] called for userID: {0}", accountID); certificate.Validate(); account = this.GetByID(accountID); if (account == null) { throw new ArgumentException("Invalid AccountID"); } var result = account.Authenticate(certificate); Update(account); Tracing.Verbose("[UserAccountService.AuthenticateWithCertificate] result: {0}", result); return(result); }
protected internal virtual bool ConfirmMobilePhoneNumberFromCode(string code) { Tracing.Information("[UserAccount.ConfirmMobilePhoneNumberFromCode] called for accountID: {0}", this.ID); if (String.IsNullOrWhiteSpace(code)) { Tracing.Error("[UserAccount.ConfirmMobilePhoneNumberFromCode] failed -- no code"); return(false); } if (this.VerificationPurpose != VerificationKeyPurpose.ChangeMobile) { Tracing.Error("[UserAccount.ConfirmMobilePhoneNumberFromCode] failed -- invalid verification key purpose"); return(false); } if (this.IsMobileCodeStale) { Tracing.Error("[UserAccount.ConfirmMobilePhoneNumberFromCode] failed -- stale mobile code"); return(false); } if (code != this.MobileCode) { Tracing.Error("[UserAccount.ConfirmMobilePhoneNumberFromCode] failed -- codes don't match"); return(false); } Tracing.Verbose("[UserAccount.ConfirmMobilePhoneNumberFromCode] success"); this.MobilePhoneNumber = this.VerificationKey; this.ClearVerificationKey(); this.ClearMobileAuthCode(); this.AddEvent(new MobilePhoneChangedEvent { Account = this }); return(true); }
public virtual bool CancelNewAccount(string key) { Tracing.Information("[UserAccountService.CancelNewAccount] called: {0}", key); var account = this.GetByVerificationKey(key); if (account == null) { return(false); } if (account.CancelNewAccount(key)) { Tracing.Verbose("[UserAccountService.CancelNewAccount] account cancelled"); DeleteAccount(account); return(true); } Tracing.Verbose("[UserAccountService.CancelNewAccount] account not cancelled"); return(false); }
protected internal virtual bool RequestTwoFactorAuthCertificate() { Tracing.Information("[UserAccount.RequestTwoFactorAuthCertificate] called for accountID: {0}", this.ID); if (!this.IsAccountVerified) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCertificate] failed -- account not verified"); return(false); } if (this.IsAccountClosed) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCertificate] failed -- account closed"); return(false); } if (!this.IsLoginAllowed) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCertificate] failed -- login not allowed"); return(false); } if (this.AccountTwoFactorAuthMode != TwoFactorAuthMode.Certificate) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCertificate] failed -- current auth mode is not certificate"); return(false); } if (!this.Certificates.Any()) { Tracing.Error("[UserAccount.RequestTwoFactorAuthCertificate] failed -- no certificates"); return(false); } Tracing.Verbose("[UserAccount.RequestTwoFactorAuthCertificate] success"); this.CurrentTwoFactorAuthStatus = TwoFactorAuthMode.Certificate; return(true); }