Exemplo n.º 1
0
        public async Task AddTwoStepLoginFailureAsync()
        {
            int userId = Manager.SessionSettings.SiteSettings.GetValue <int>(LoginTwoStepController.IDENTITY_TWOSTEP_USERID);

            if (userId == 0)
            {
                throw new InternalError("No user id available in AddTwoStepLoginFailure");
            }
            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                UserDefinition user = await userDP.GetItemByUserIdAsync(userId);

                if (user == null)
                {
                    throw new InternalError("Unexpected error in AddTwoStepLoginFailure - no user found");
                }
                LoginConfigData config = await LoginConfigDataProvider.GetConfigAsync();

                user.LoginFailures = user.LoginFailures + 1;
                if (config.MaxLoginFailures != 0 && user.LoginFailures >= config.MaxLoginFailures)
                {
                    if (user.UserStatus != UserStatusEnum.Suspended)
                    {
                        user.UserStatus = UserStatusEnum.Suspended;
                    }
                }
                UpdateStatusEnum status = await userDP.UpdateItemAsync(user);

                if (status != UpdateStatusEnum.OK)
                {
                    throw new InternalError("Unexpected status {0} updating user account in AddTwoStepLoginFailure", status);
                }
            }
        }
Exemplo n.º 2
0
        public async Task AddEnabledTwoStepAuthenticationAsync(int userId, string auth)
        {
            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                UserDefinition user = await userDP.GetItemByUserIdAsync(userId);

                if (user == null)
                {
                    throw new InternalError($"Unexpected error in {nameof(AddEnabledTwoStepAuthenticationAsync)} - no user found");
                }
                TwoStepDefinition authDef = new DataProvider.TwoStepDefinition {
                    Name = auth
                };
                if (!user.EnabledTwoStepAuthentications.Contains(authDef, new TwoStepDefinitionComparer()))
                {
                    user.EnabledTwoStepAuthentications.Add(authDef);
                    UpdateStatusEnum status = await userDP.UpdateItemAsync(user);

                    if (status != UpdateStatusEnum.OK)
                    {
                        throw new InternalError($"Unexpected status {status} updating user account in {nameof(AddEnabledTwoStepAuthenticationAsync)}");
                    }
                    Manager.Need2FAState = null;//reevaluate now that user has enabled a two-step authentication
                }
            }
        }
Exemplo n.º 3
0
        public async Task RemoveRoleFromUserAsync(int userId, string roleName)
        {
            int roleId;

            // get the role id for roleName
            using (RoleDefinitionDataProvider roleDP = new RoleDefinitionDataProvider()) {
                RoleDefinition role = await roleDP.GetItemAsync(roleName);

                if (role == null)
                {
                    throw new InternalError("Unexpected error in AddRoleToUser - expected role {0} not found", roleName);
                }
                roleId = role.RoleId;
            }
            // remove the role from the user
            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                UserDefinition user = await userDP.GetItemByUserIdAsync(userId);

                if (user != null)
                {
                    Role role = (from Role r in user.RolesList where r.RoleId == roleId select r).FirstOrDefault();
                    if (role != null)
                    {
                        user.RolesList.Remove(role);
                        UpdateStatusEnum status = await userDP.UpdateItemAsync(user);

                        if (status != UpdateStatusEnum.OK)
                        {
                            throw new InternalError("Unexpected status {0} updating user account in RemoveRoleFromUser", status);
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        public async Task SetUserStatusAsync(int userId, UserStatusEnum userStatus)
        {
            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                UserDefinition user = await userDP.GetItemByUserIdAsync(userId);

                if (user == null)
                {
                    throw new InternalError($"Unknown user (user id {userId})");
                }
                if (user.UserStatus != userStatus)
                {
                    user.UserStatus = userStatus;
                    if (userStatus == UserStatusEnum.Approved)
                    {
                        user.LoginFailures = 0;
                    }
                    UpdateStatusEnum status = await userDP.UpdateItemAsync(user);

                    if (status != UpdateStatusEnum.OK)
                    {
                        throw new InternalError($"Unexpected status {status} updating user account in {nameof(SetUserStatusAsync)}");
                    }
                }
            }
        }
Exemplo n.º 5
0
        public async Task <ActionResult> Suspend(string userName)
        {
            using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider()) {
                UserDefinition user = await GetUserAsync(userName, dataProvider);

                if (user.UserStatus != UserStatusEnum.Suspended)
                {
                    user.UserStatus = UserStatusEnum.Suspended;
                    UpdateStatusEnum status = await dataProvider.UpdateItemAsync(user);

                    switch (status)
                    {
                    default:
                    case UpdateStatusEnum.NewKeyExists:
                        throw new InternalError("Unexpected status {0}", status);

                    case UpdateStatusEnum.RecordDeleted:
                        throw new Error(this.__ResStr("rejectUserNotFound", "The user account for user {0} no longer exists.", userName));

                    case UpdateStatusEnum.OK:
                        break;
                    }
                }
                Emails emails = new Emails();
                await emails.SendSuspendedAsync(user);

                return(Reload(null, Reload: ReloadEnum.ModuleParts, PopupText: this.__ResStr("userSuspended", "The user account for user {0} has been marked as suspended. An email has been sent to the user.", userName)));
            }
        }
Exemplo n.º 6
0
        private async Task GenerateRecoveryCodeAsync(UserDefinitionDataProvider userDP, UserDefinition user)
        {
            user.RecoveryCode = Guid.NewGuid().ToString().Substring(0, 12);
            UpdateStatusEnum status = await userDP.UpdateItemAsync(user);

            if (status != UpdateStatusEnum.OK)
            {
                throw new Error(this.__ResStr("cantUpdate", "Updating user information failed - {0}", status));
            }
        }
Exemplo n.º 7
0
        public async Task UpdatePasswordExpiration(List <string> errorList)
        {
            long ticks = WebConfigHelper.GetValue <long>(YetaWF.Modules.Identity.Controllers.AreaRegistration.CurrentPackage.AreaName, "PasswordRenewal", new TimeSpan(0, 0, 0).Ticks); // 0  = indefinitely

            if (ticks <= 0)
            {
                return;                                // nothing to do
            }
            TimeSpan interval   = new TimeSpan(ticks); // renewal interval
            DateTime oldestDate = DateTime.UtcNow.Subtract(interval);

            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                int       offset = 0;
                const int CHUNK  = 50;

                for (;;)
                {
                    List <DataProviderFilterInfo> filters = null;
                    filters = DataProviderFilterInfo.Join(filters, new DataProviderFilterInfo {
                        Field = nameof(UserDefinition.UserStatus), Operator = "==", Value = UserStatusEnum.Approved
                    });
                    filters = DataProviderFilterInfo.Join(filters, new DataProviderFilterInfo {
                        Field = nameof(UserDefinition.NeedsNewPassword), Operator = "==", Value = false
                    });
                    DataProviderGetRecords <UserDefinition> usersInfo = await userDP.GetItemsAsync(offset, CHUNK, null, filters);

                    if (usersInfo.Data.Count == 0)
                    {
                        return;
                    }

                    foreach (UserDefinition user in usersInfo.Data)
                    {
                        bool forceUpdate = false;
                        if (user.LastPasswordChangedDate != null && user.LastPasswordChangedDate < oldestDate)
                        {
                            forceUpdate = true;
                        }
                        else if (user.LastPasswordChangedDate == null && user.Created < oldestDate)
                        {
                            forceUpdate = true;
                        }
                        if (forceUpdate)
                        {
                            user.NeedsNewPassword = true;
                            await userDP.UpdateItemAsync(user);

                            Logging.AddLog($"Updated {user.Id} {user.UserName} - requires password");
                        }
                    }
                    offset += CHUNK;
                    System.Threading.Thread.Sleep(5 * 1000); // wait some 5 seconds
                }
            }
        }
Exemplo n.º 8
0
        public async Task <IdentityResult> UpdateAsync(UserDefinition user, CancellationToken cancellationToken)
        {
            using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider(this.CurrentSiteIdentity)) {
                UpdateStatusEnum status = await dataProvider.UpdateItemAsync(user);

                switch (status)
                {
                default:
                case UpdateStatusEnum.NewKeyExists:
                    throw new InternalError("Unexpected update status");

                case UpdateStatusEnum.RecordDeleted:
                    throw new Error(this.__ResStr("userDeleted", "User {0} not found.", user.UserName));

                case UpdateStatusEnum.OK:
                    break;
                }
                return(IdentityResult.Success);
            }
        }
Exemplo n.º 9
0
        // Change a user password
        private async Task ChangePasswordAsync(string userName, string newPassword)
        {
            using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider()) {
                UserDefinition user = await dataProvider.GetItemAsync(userName);

                if (user == null)
                {
                    throw new Error(this.__ResStr("notFound", "User {0} not found", userName));
                }

                UserManager <UserDefinition> userManager = Managers.GetUserManager();
                string hashedNewPassword;
#if MVC6
                IPasswordHasher <UserDefinition> passwordHasher = (IPasswordHasher <UserDefinition>)YetaWFManager.ServiceProvider.GetService(typeof(IPasswordHasher <UserDefinition>));
                hashedNewPassword = passwordHasher.HashPassword(user, newPassword);
#else
                hashedNewPassword = userManager.PasswordHasher.HashPassword(newPassword);
#endif
                //ModuleDefinition.GetPermanentGuid(typeof(RegisterModule))
                LoginConfigData config = await LoginConfigDataProvider.GetConfigAsync();

                user.PasswordPlainText = config.SavePlainTextPassword ? newPassword : null;
                user.PasswordHash      = hashedNewPassword;
                UpdateStatusEnum status = await dataProvider.UpdateItemAsync(user);

                switch (status)
                {
                default:
                case UpdateStatusEnum.NewKeyExists:
                    throw new InternalError("Unexpected status {0}", status);

                case UpdateStatusEnum.RecordDeleted:
                    throw new Error(this.__ResStr("changeUserNotFound", "The user account for user {0} no longer exists.", userName));

                case UpdateStatusEnum.OK:
                    break;
                }
            }
        }
Exemplo n.º 10
0
        // IUserLoginStore
        // IUserLoginStore
        // IUserLoginStore
        public async Task AddLoginAsync(UserDefinition user, UserLoginInfo login, CancellationToken cancellationToken)
        {
            using (UserLoginInfoDataProvider logInfoDP = new DataProvider.UserLoginInfoDataProvider(CurrentSiteIdentity)) {
                await logInfoDP.AddItemAsync(user.UserId, login.LoginProvider, login.ProviderKey);
            }

            using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider(this.CurrentSiteIdentity)) {
                UpdateStatusEnum status = await dataProvider.UpdateItemAsync(user);

                switch (status)
                {
                case UpdateStatusEnum.RecordDeleted:
                    throw new Error(this.__ResStr("delUser", "Can't update user {0}, because the user has been deleted.", user.UserName));

                default:
                case UpdateStatusEnum.NewKeyExists:
                    throw new InternalError("Unexpected update status");

                case UpdateStatusEnum.OK:
                    break;
                }
            }
        }
Exemplo n.º 11
0
        public async Task RemoveEnabledTwoStepAuthenticationAsync(int userId, string auth)
        {
            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                UserDefinition user = await userDP.GetItemByUserIdAsync(userId);

                if (user == null)
                {
                    throw new InternalError("Unexpected error in RemoveEnabledTwoStepAuthentication - no user found");
                }
                TwoStepDefinition authDef = user.EnabledTwoStepAuthentications.Find(m => m.Name == auth);
                if (authDef != null)
                {
                    user.EnabledTwoStepAuthentications.Remove(authDef);
                    UpdateStatusEnum status = await userDP.UpdateItemAsync(user);

                    if (status != UpdateStatusEnum.OK)
                    {
                        throw new InternalError("Unexpected status {0} updating user account in RemoveEnabledTwoStepAuthentication", status);
                    }
                    Manager.Need2FAState = null;//reevaluate now that user has removed a two-step authentication
                }
            }
        }
Exemplo n.º 12
0
        public async Task AddRoleToUserAsync(int userId, string roleName)
        {
            int roleId;

            // get the role id for roleName
            using (RoleDefinitionDataProvider roleDP = new RoleDefinitionDataProvider()) {
                RoleDefinition role = await roleDP.GetItemAsync(roleName);

                if (role == null)
                {
                    throw new InternalError("Unexpected error in AddRoleToUser - expected role {0} not found", roleName);
                }
                roleId = role.RoleId;
            }
            // add the role to the user
            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                UserDefinition user = await userDP.GetItemByUserIdAsync(userId);

                if (user == null)
                {
                    throw new InternalError("Unexpected error in AddRoleToUser - no user found");
                }
                Role role = new Role {
                    RoleId = roleId
                };
                if (!user.RolesList.Contains(role, new RoleComparer()))
                {
                    user.RolesList.Add(role);
                    UpdateStatusEnum status = await userDP.UpdateItemAsync(user);

                    if (status != UpdateStatusEnum.OK)
                    {
                        throw new InternalError("Unexpected status {0} updating user account in AddRoleToUser", status);
                    }
                }
            }
        }
Exemplo n.º 13
0
        public async Task <AddUserInfo> AddUserAsync(string name, string email, string password, bool needsNewPassword, string comment)
        {
            AddUserInfo     info   = new AddUserInfo();
            LoginConfigData config = await LoginConfigDataProvider.GetConfigAsync();

            UserDefinition user = new UserDefinition {
                UserName          = name,
                Email             = email,
                PasswordPlainText = config.SavePlainTextPassword || needsNewPassword ? password : null,
                Comment           = comment,
            };

            if (config.RegistrationType == RegistrationTypeEnum.NameAndEmail)
            {
                using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider()) {
                    // Email == user.Email
                    List <DataProviderFilterInfo> filters = new List <DataProviderFilterInfo> {
                        new DataProviderFilterInfo {
                            Field = nameof(UserDefinition.Email), Operator = "==", Value = user.Email,
                        },
                    };
                    UserDefinition userExists = await dataProvider.GetItemAsync(filters);

                    if (userExists != null && user.UserName != userExists.Email)
                    {
                        info.ErrorType = AddUserInfo.ErrorTypeEnum.Email;
                        info.Errors.Add(this.__ResStr("emailUsed", "An account with email address {0} already exists.", user.Email));
                        return(info);
                    }
                }
            }
            user.UserStatus = UserStatusEnum.Approved;

            // create user
            var result = await Managers.GetUserManager().CreateAsync(user, password);

            if (!result.Succeeded)
            {
                info.ErrorType = AddUserInfo.ErrorTypeEnum.Name;
                foreach (var error in result.Errors)
                {
#if MVC6
                    info.Errors.Add(error.Description);
#else
                    info.Errors.Add(error);
#endif
                    return(info);
                }
            }
            if (needsNewPassword)
            {
                using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                    user.NeedsNewPassword = true;
                    if (await userDP.UpdateItemAsync(user) != UpdateStatusEnum.OK)
                    {
                        throw new InternalError($"Failed to update new user to set {nameof(user.NeedsNewPassword)}");
                    }
                }
            }

            info.ErrorType = AddUserInfo.ErrorTypeEnum.None;
            info.UserId    = user.UserId;
            return(info);
        }
Exemplo n.º 14
0
        public async Task <ActionResult> ForgotPassword_Partial(EditModel model)
        {
            LoginConfigData config = await LoginConfigDataProvider.GetConfigAsync();

            if (model.ShowCaptcha != config.CaptchaForgotPassword)
            {
                throw new InternalError("Hidden field tampering detected");
            }

            await model.UpdateAsync();

            model.ShowCaptcha      = config.CaptchaForgotPassword;
            model.RegistrationType = config.RegistrationType;
            if (!ModelState.IsValid)
            {
                return(PartialView(model));
            }

            using (UserDefinitionDataProvider userDP = new UserDefinitionDataProvider()) {
                UserDefinition userDef;
                switch (model.RegistrationType)
                {
                case RegistrationTypeEnum.NameOnly:
                    userDef = await userDP.GetItemAsync(model.UserName);

                    if (userDef == null)
                    {
                        ModelState.AddModelError(nameof(model.UserName), this.__ResStr("badName", "According to our records there is no account associated with this name"));
                        return(PartialView(model));
                    }
                    break;

                case RegistrationTypeEnum.NameAndEmail:
                    userDef = await userDP.GetItemAsync(model.UserNameOrEmail);

                    if (userDef == null)
                    {
                        userDef = await userDP.GetItemByEmailAsync(model.UserNameOrEmail);

                        if (userDef == null)
                        {
                            ModelState.AddModelError(nameof(model.UserNameOrEmail), this.__ResStr("badNameEmail", "According to our records there is no account associated with this name or email address"));
                            return(PartialView(model));
                        }
                    }
                    break;

                default:
                case RegistrationTypeEnum.EmailOnly:
                    userDef = await userDP.GetItemByEmailAsync(model.Email);

                    if (userDef == null)
                    {
                        ModelState.AddModelError(nameof(model.Email), this.__ResStr("badEmail", "According to our records there is no account associated with this email address"));
                        return(PartialView(model));
                    }
                    break;
                }

                using (UserLoginInfoDataProvider logInfoDP = new UserLoginInfoDataProvider()) {
                    if (await logInfoDP.IsExternalUserAsync(userDef.UserId))
                    {
                        ModelState.AddModelError(nameof(model.Email), this.__ResStr("extEmail", "According to our records there is no account associated with this email address"));
                        ModelState.AddModelError(nameof(model.UserName), this.__ResStr("extName", "According to our records there is no account associated with this name"));
                        ModelState.AddModelError(nameof(model.UserNameOrEmail), this.__ResStr("extUser", "According to our records there is no account associated with this name or email address"));
                        return(PartialView(model));
                    }
                }
                switch (userDef.UserStatus)
                {
                case UserStatusEnum.Approved:
                    Emails emails = new Emails();
                    if (config.SavePlainTextPassword)
                    {
                        await emails.SendForgottenEmailAsync(userDef, config.BccForgottenPassword?Manager.CurrentSite.AdminEmail : null);

                        string from = emails.GetSendingEmailAddress();
                        return(FormProcessed(model, this.__ResStr("okForgot", "We just sent an email to your email address with your password information - Please allow a few minutes for delivery and make sure your spam filters allow emails from {0}", from), OnClose: OnCloseEnum.Nothing, OnPopupClose: OnPopupCloseEnum.ReloadModule));
                    }
                    else
                    {
                        if (userDef.ResetKey != null && userDef.ResetValidUntil != null && userDef.ResetValidUntil > DateTime.UtcNow)
                        {
                            // preserve existing key in case user resends
                        }
                        else
                        {
                            userDef.ResetKey        = Guid.NewGuid();
                            userDef.ResetValidUntil = DateTime.UtcNow.Add(config.ResetTimeSpan);
                            if (await userDP.UpdateItemAsync(userDef) != Core.DataProvider.UpdateStatusEnum.OK)    // update reset key info
                            {
                                throw new Error(this.__ResStr("resetUpdate", "User information could not be updated"));
                            }
                        }
                        await emails.SendPasswordResetEmailAsync(userDef, config.BccForgottenPassword?Manager.CurrentSite.AdminEmail : null);

                        string from = emails.GetSendingEmailAddress();
                        return(FormProcessed(model, this.__ResStr("okReset", "We just sent an email to your email address to reset your password - Please allow a few minutes for delivery and make sure your spam filters allow emails from {0}", from), OnClose: OnCloseEnum.Nothing, OnPopupClose: OnPopupCloseEnum.ReloadModule));
                    }

                case UserStatusEnum.NeedApproval:
                    throw new Error(this.__ResStr("needApproval", "This account has not yet been approved and is awaiting approval by the site administrator"));

                case UserStatusEnum.NeedValidation:
                    throw new Error(this.__ResStr("needValidation", "This account has not yet been verified - Please check your emails for our verification email"));

                case UserStatusEnum.Rejected:
                    throw new Error(this.__ResStr("rejected", "This account has been rejected and is not accessible"));

                case UserStatusEnum.Suspended:
                    throw new Error(this.__ResStr("suspended", "This account has been suspended and is not accessible"));

                default:
                    throw new Error(this.__ResStr("unknownState", "This account is in an undefined state and is not accessible"));
                }
            }
        }
Exemplo n.º 15
0
        public async Task <ActionResult> UsersEdit_Partial(EditModel model)
        {
            using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider()) {
                string         originalUserName = model.OriginalUserName;
                UserDefinition user             = await dataProvider.GetItemAsync(originalUserName);

                if (user == null)
                {
                    throw new Error(this.__ResStr("alreadyDeleted", "The user named \"{0}\" has been removed and can no longer be updated.", originalUserName));
                }
                if (!ModelState.IsValid)
                {
                    return(PartialView(model));
                }

                LoginConfigData config = await LoginConfigDataProvider.GetConfigAsync();

                switch (config.RegistrationType)
                {
                case RegistrationTypeEnum.NameAndEmail: {
                    List <DataProviderFilterInfo> filters = DataProviderFilterInfo.Join(null, new DataProviderFilterInfo {
                            Field = nameof(UserDefinition.Email), Operator = "==", Value = model.Email,
                        });
                    UserDefinition userExists = await dataProvider.GetItemAsync(filters);

                    if (userExists != null && user.UserName != userExists.UserName)
                    {
                        ModelState.AddModelError(nameof(model.Email), this.__ResStr("emailUsed", "An account using email address {0} already exists.", model.Email));
                        return(PartialView(model));
                    }
                    break;
                }

                case RegistrationTypeEnum.EmailOnly:
                    model.UserName = model.Email;
                    break;

                case RegistrationTypeEnum.NameOnly:
                    model.Email = model.UserName;
                    break;
                }

                user = model.GetData(user); // merge new data into original
                model.SetData(user);        // and all the data back into model for final display

                switch (await dataProvider.UpdateItemAsync(originalUserName, user))
                {
                default:
                case UpdateStatusEnum.RecordDeleted:
                    throw new Error(this.__ResStr("alreadyDeleted", "The user named \"{0}\" has been removed and can no longer be updated.", originalUserName));

                case UpdateStatusEnum.NewKeyExists:
                    ModelState.AddModelError(nameof(model.UserName), this.__ResStr("alreadyExists", "A user named \"{0}\" already exists.", model.UserName));
                    return(PartialView(model));

                case UpdateStatusEnum.OK:
                    break;
                }
                return(FormProcessed(model, this.__ResStr("okSaved", "User updated"), OnPopupClose: OnPopupCloseEnum.ReloadModule));
            }
        }
Exemplo n.º 16
0
        public async Task <ActionResult> UserAccount_Partial(EditModel model)
        {
            // make sure this user exists
            UserManager <UserDefinition> userManager = Managers.GetUserManager();
            UserDefinition user;

#if MVC6
            user = await userManager.FindByNameAsync(model.OriginalUserName);
#else
            user = userManager.FindByName(model.OriginalUserName);
#endif
            if (user == null)
            {
                throw new Error(this.__ResStr("alreadyDeleted", "The user named \"{0}\" has been removed and can no longer be updated.", model.OriginalUserName));
            }
            if (!ModelState.IsValid)
            {
                return(PartialView(model));
            }

            // update email/user name - can't use an existing email address
            // get the registration module for some defaults
            LoginConfigData config = await LoginConfigDataProvider.GetConfigAsync();

            switch (config.RegistrationType)
            {
            default:
            case RegistrationTypeEnum.NameAndEmail: {
                using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider()) {
                    List <DataProviderFilterInfo> filters = DataProviderFilterInfo.Join(null, new DataProviderFilterInfo {
                            Field = nameof(UserDefinition.Email), Operator = "==", Value = model.Email,
                        });
                    UserDefinition userExists = await dataProvider.GetItemAsync(filters);

                    if (userExists != null && user.UserName != userExists.UserName)
                    {
                        ModelState.AddModelError(nameof(model.Email), this.__ResStr("emailUsed", "An account using email address {0} already exists.", model.Email));
                        return(PartialView(model));
                    }
                }
                break;
            }

            case RegistrationTypeEnum.EmailOnly:
                model.UserName = model.Email;
                break;

            case RegistrationTypeEnum.NameOnly:
                model.Email = model.UserName;
                break;
            }

            // save new user info
            ObjectSupport.CopyData(model, user); // merge new data into original
            model.SetData(user);                 // and all the data back into model for final display

            if (model.OriginalUserName != user.UserName)
            {
                // user name changed - change data through data provider directly
                using (UserDefinitionDataProvider dataProvider = new UserDefinitionDataProvider()) {
                    UpdateStatusEnum status = await dataProvider.UpdateItemAsync(model.OriginalUserName, user);

                    switch (status)
                    {
                    default:
                    case UpdateStatusEnum.RecordDeleted:
                        ModelState.AddModelError(nameof(model.UserName), this.__ResStr("alreadyDeleted", "The user named \"{0}\" has been removed and can no longer be updated.", model.OriginalUserName));
                        return(PartialView(model));

                    case UpdateStatusEnum.NewKeyExists:
                        ModelState.AddModelError(nameof(model.UserName), this.__ResStr("alreadyExists", "A user named \"{0}\" already exists.", model.UserName));
                        return(PartialView(model));

                    case UpdateStatusEnum.OK:
                        break;
                    }
                }
                // log the user off and back on so new name takes effect
                //IAuthenticationManager authManager = HttpContext.GetOwinContext().Authentication;
                //deleted, done in UserLogff authManager.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalBearer);
                await LoginModuleController.UserLogoffAsync();

                await LoginModuleController.UserLoginAsync(user);
            }
            else
            {
                IdentityResult result;
                result = await userManager.UpdateAsync(user);

                if (!result.Succeeded)
                {
                    throw new Error(string.Join(" - ", (from e in result.Errors select e.Description)));
                }
            }
            return(FormProcessed(model, this.__ResStr("okSaved", "Your account information has been saved"), OnClose: OnCloseEnum.ReloadPage, OnPopupClose: OnPopupCloseEnum.ReloadParentPage, ForceRedirect: true));// reload for tiny login module to refresh
        }