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); } } }
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 } } }
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); } } } } }
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)}"); } } } }
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))); } }
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)); } }
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 } } }
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); } }
// 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; } } }
// 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; } } }
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 } } }
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); } } } }
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); }
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")); } } }
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)); } }
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 }