Exemplo n.º 1
0
        protected internal virtual void CloseAccount()
        {
            Tracing.Information("[UserAccount.CloseAccount] called for accountID: {0}", this.ID);

            this.ClearVerificationKey();
            this.ClearMobileAuthCode();

            IsLoginAllowed             = false;
            CurrentTwoFactorAuthStatus = TwoFactorAuthMode.None;

            if (!IsAccountClosed)
            {
                Tracing.Verbose("[UserAccount.CloseAccount] success");

                IsAccountClosed = true;
                AccountClosed   = UtcNow;

                this.AddEvent(new AccountClosedEvent {
                    Account = this
                });
            }
            else
            {
                Tracing.Warning("[UserAccount.CloseAccount] account already closed");
            }
        }
Exemplo n.º 2
0
        protected internal virtual void ClearMobilePhoneNumber()
        {
            Tracing.Information("[UserAccount.ClearMobilePhoneNumber] called for accountID: {0}", this.ID);

            if (this.AccountTwoFactorAuthMode == TwoFactorAuthMode.Mobile)
            {
                Tracing.Verbose("[UserAccount.ClearMobilePhoneNumber] disabling two factor auth");
                this.ConfigureTwoFactorAuthentication(TwoFactorAuthMode.None);
            }

            if (String.IsNullOrWhiteSpace(MobilePhoneNumber))
            {
                Tracing.Warning("[UserAccount.ClearMobilePhoneNumber] nothing to do -- no mobile associated with account");
                return;
            }

            Tracing.Verbose("[UserAccount.ClearMobilePhoneNumber] success");

            this.ClearMobileAuthCode();
            this.MobilePhoneNumber = null;

            this.AddEvent(new MobilePhoneRemovedEvent {
                Account = this
            });
        }
        public virtual bool ChangeMobilePhoneFromCode(Guid accountID, string code)
        {
            Tracing.Information(String.Format("[UserAccountService.ChangeMobileFromCode] called: {0}", accountID));

            if (String.IsNullOrWhiteSpace(code))
            {
                return(false);
            }

            var account = this.GetByID(accountID);

            if (account == null)
            {
                throw new ArgumentException("Invalid AccountID");
            }

            Tracing.Verbose(String.Format("[UserAccountService.ChangeMobileFromCode] account located: {0}, {1}", account.Tenant, account.Username));

            var result = account.ConfirmMobilePhoneNumberFromCode(code);

            Update(account);

            Tracing.Warning(String.Format("[UserAccountService.ChangeMobileFromCode] outcome: {0}, {1}, {2}", account.Tenant, account.Username, result));

            return(result);
        }
        public virtual UserAccount GetByEmail(string tenant, string email)
        {
            if (!SecuritySettings.MultiTenant)
            {
                Tracing.Verbose("[UserAccountService.GetByEmail] applying default tenant");
                tenant = SecuritySettings.DefaultTenant;
            }

            if (String.IsNullOrWhiteSpace(tenant))
            {
                return(null);
            }
            if (String.IsNullOrWhiteSpace(email))
            {
                return(null);
            }

            var account = userRepository.GetAll().Where(x => x.Tenant == tenant && x.Email == email).SingleOrDefault();

            if (account == null)
            {
                Tracing.Warning("[UserAccountService.GetByEmail] failed to locate account: {0}, {1}", tenant, email);
            }
            return(account);
        }
        public virtual UserAccount GetByCertificate(string tenant, string thumbprint)
        {
            if (!SecuritySettings.MultiTenant)
            {
                Tracing.Verbose("[UserAccountService.GetByCertificate] applying default tenant");
                tenant = SecuritySettings.DefaultTenant;
            }

            if (String.IsNullOrWhiteSpace(tenant))
            {
                return(null);
            }
            if (String.IsNullOrWhiteSpace(thumbprint))
            {
                return(null);
            }

            var query =
                from u in userRepository.GetAll()
                where u.Tenant == tenant
                from c in u.Certificates
                where c.Thumbprint == thumbprint
                select u;

            var account = query.SingleOrDefault();

            if (account == null)
            {
                Tracing.Warning("[UserAccountService.GetByCertificate] failed to locate by certificate thumbprint: {0}, {1}", tenant, thumbprint);
            }
            return(account);
        }
        public virtual bool ChangeEmailFromKey(
            string password, string key, string newEmail,
            int failedLoginCount, TimeSpan lockoutDuration)
        {
            Tracing.Information(String.Format("[UserAccountService.ChangeEmailFromKey] called: {0}, {1}", key, newEmail));

            if (String.IsNullOrWhiteSpace(password))
            {
                return(false);
            }
            if (String.IsNullOrWhiteSpace(key))
            {
                return(false);
            }
            if (String.IsNullOrWhiteSpace(newEmail))
            {
                return(false);
            }

            var account = this.GetByVerificationKey(key);

            if (account == null)
            {
                return(false);
            }

            Tracing.Verbose(String.Format("[UserAccountService.ChangeEmailFromKey] account located: {0}, {1}", account.Tenant, account.Username));

            if (!Authenticate(account, password, failedLoginCount, lockoutDuration))
            {
                return(false);
            }

            var oldEmail = account.Email;
            var result   = account.ChangeEmailFromKey(key, newEmail);

            if (result && SecuritySettings.Instance.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;
            }

            Tracing.Verbose(String.Format("[UserAccountService.ChangeEmailFromKey] change email outcome: {0}, {1}, {2}", account.Tenant, account.Username, result ? "Successful" : "Failed"));

            if (result)
            {
                using (var tx = new TransactionScope())
                {
                    this.userRepository.SaveChanges();

                    if (this.notificationService != null)
                    {
                        this.notificationService.SendEmailChangedNotice(account, oldEmail);
                    }

                    tx.Complete();
                }
            }
            return(result);
        }
        public virtual UserAccount GetByID(Guid id)
        {
            var account = this.userRepository.Get(id);

            if (account == null)
            {
                Tracing.Warning("[UserAccountService.GetByID] failed to locate account: {0}", id);
            }
            return(account);
        }
        public virtual UserAccount GetByVerificationKey(string key)
        {
            if (String.IsNullOrWhiteSpace(key))
            {
                return(null);
            }

            var account = userRepository.GetAll().Where(x => x.VerificationKey == key).SingleOrDefault();

            if (account == null)
            {
                Tracing.Warning("[UserAccountService.GetByVerificationKey] failed to locate account: {0}", key);
            }
            return(account);
        }
        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);
        }
Exemplo n.º 10
0
        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 UserAccount GetByLinkedAccount(string tenant, string provider, string id)
        {
            if (!SecuritySettings.MultiTenant)
            {
                Tracing.Verbose("[UserAccountService.GetByLinkedAccount] applying default tenant");
                tenant = SecuritySettings.DefaultTenant;
            }

            if (String.IsNullOrWhiteSpace(tenant))
            {
                return(null);
            }
            if (String.IsNullOrWhiteSpace(provider))
            {
                return(null);
            }
            if (String.IsNullOrWhiteSpace(id))
            {
                return(null);
            }

            var query =
                from u in userRepository.GetAll()
                where u.Tenant == tenant
                from l in u.LinkedAccounts
                where l.ProviderName == provider && l.ProviderAccountID == id
                select u;

            var account = query.SingleOrDefault();

            if (account == null)
            {
                Tracing.Warning("[UserAccountService.GetByLinkedAccount] failed to locate by tenant: {0}, provider: {1}, id: {2}", tenant, provider, id);
            }
            return(account);
        }
        public virtual bool ResetPassword(string tenant, string email)
        {
            Tracing.Information(String.Format("[UserAccountService.ResetPassword] called: {0}, {1}", tenant, email));

            if (!SecuritySettings.Instance.MultiTenant)
            {
                tenant = SecuritySettings.Instance.DefaultTenant;
            }

            if (String.IsNullOrWhiteSpace(tenant))
            {
                return(false);
            }
            if (String.IsNullOrWhiteSpace(email))
            {
                return(false);
            }

            var account = this.GetByEmail(tenant, email);

            if (account == null)
            {
                return(false);
            }

            if (!account.IsAccountVerified)
            {
                // if they're not verified, resend the new account email
                if (SecuritySettings.Instance.RequireAccountVerification &&
                    this.notificationService != null)
                {
                    Tracing.Verbose(String.Format("[UserAccountService.ResetPassword] account not verified, re-sending account create notification: {0}, {1}", account.Tenant, account.Username));

                    this.notificationService.SendAccountCreate(account);
                    return(true);
                }

                // if we don't have a notification system then not much we can do
                Tracing.Warning(String.Format("[UserAccountService.ResetPassword] account not verified, no notification to re-send invite: {0}, {1}", account.Tenant, account.Username));

                return(false);
            }

            var result = account.ResetPassword();

            Tracing.Verbose(String.Format("[UserAccountService.ResetPassword] reset password outcome: {0}, {1}, {2}", account.Tenant, account.Username, result ? "Successful" : "Failed"));

            if (result)
            {
                using (var tx = new TransactionScope())
                {
                    this.userRepository.SaveChanges();

                    if (this.notificationService != null)
                    {
                        this.notificationService.SendResetPassword(account);
                    }

                    tx.Complete();
                }
            }
            return(result);
        }