/// <summary> /// Changes the users password /// </summary> /// <param name="data"></param> /// <returns> /// If the password is being reset it will return the newly reset password, otherwise will return an empty value /// </returns> public ModelWithNotifications<string> PostChangePassword(ChangingPasswordModel data) { var userProvider = Membership.Providers[UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider]; if (userProvider == null) { throw new InvalidOperationException("No membership provider found with the name " + UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider); } //TODO: WE need to support this! - requires UI updates, etc... if (userProvider.RequiresQuestionAndAnswer) { throw new NotSupportedException("Currently the user editor does not support providers that have RequiresQuestionAndAnswer specified"); } var passwordChangeResult = Security.ChangePassword(Security.CurrentUser.Username, data, userProvider); if (passwordChangeResult.Success) { //even if we weren't resetting this, it is the correct value (null), otherwise if we were resetting then it will contain the new pword var result = new ModelWithNotifications<string>(passwordChangeResult.Result.ResetPassword); result.AddSuccessNotification(ui.Text("user", "password"), ui.Text("user", "passwordChanged")); return result; } //it wasn't successful, so add the change error to the model state, we've name the property alias _umb_password on the form // so that is why it is being used here. ModelState.AddPropertyError( passwordChangeResult.Result.ChangeError, string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); }
/// <summary> /// Changes the users password /// </summary> /// <param name="data"></param> /// <returns> /// If the password is being reset it will return the newly reset password, otherwise will return an empty value /// </returns> public ModelWithNotifications <string> PostChangePassword(ChangingPasswordModel data) { var userProvider = Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider(); //TODO: WE need to support this! - requires UI updates, etc... if (userProvider.RequiresQuestionAndAnswer) { throw new NotSupportedException("Currently the user editor does not support providers that have RequiresQuestionAndAnswer specified"); } var passwordChangeResult = Members.ChangePassword(Security.CurrentUser.Username, data, userProvider); if (passwordChangeResult.Success) { //even if we weren't resetting this, it is the correct value (null), otherwise if we were resetting then it will contain the new pword var result = new ModelWithNotifications <string>(passwordChangeResult.Result.ResetPassword); result.AddSuccessNotification(ui.Text("user", "password"), ui.Text("user", "passwordChanged")); return(result); } //it wasn't successful, so add the change error to the model state, we've name the property alias _umb_password on the form // so that is why it is being used here. ModelState.AddPropertyError( passwordChangeResult.Result.ChangeError, string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); }
/// <summary> /// Changes the users password /// </summary> /// <param name="changingPasswordModel">The changing password model</param> /// <returns> /// If the password is being reset it will return the newly reset password, otherwise will return an empty value /// </returns> public async Task <ActionResult <ModelWithNotifications <string?> >?> PostChangePassword( ChangingPasswordModel changingPasswordModel) { IUser?currentUser = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser; if (currentUser is null) { return(null); } changingPasswordModel.Id = currentUser.Id; // all current users have access to reset/manually change their password Attempt <PasswordChangedModel?> passwordChangeResult = await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _backOfficeUserManager); if (passwordChangeResult.Success) { // even if we weren't resetting this, it is the correct value (null), otherwise if we were resetting then it will contain the new pword var result = new ModelWithNotifications <string?>(passwordChangeResult.Result?.ResetPassword); result.AddSuccessNotification(_localizedTextService.Localize("user", "password"), _localizedTextService.Localize("user", "passwordChanged")); return(result); } if (passwordChangeResult.Result?.ChangeError?.MemberNames is not null) { foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames) { ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage ?? string.Empty); } } return(ValidationProblem(ModelState)); }
/// <summary> /// Changes the users password /// </summary> /// <param name="data"></param> /// <returns> /// If the password is being reset it will return the newly reset password, otherwise will return an empty value /// </returns> public async Task <ModelWithNotifications <string> > PostChangePassword(ChangingPasswordModel data) { var passwordChanger = new PasswordChanger(Logger, Services.UserService, UmbracoContext.HttpContext); var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, Security.CurrentUser, data, UserManager); if (passwordChangeResult.Success) { var userMgr = this.TryGetOwinContext().Result.GetBackOfficeUserManager(); //raise the reset event // TODO: I don't think this is required anymore since from 7.7 we no longer display the reset password checkbox since that didn't make sense. if (data.Reset.HasValue && data.Reset.Value) { userMgr.RaisePasswordResetEvent(Security.CurrentUser.Id); } //even if we weren't resetting this, it is the correct value (null), otherwise if we were resetting then it will contain the new pword var result = new ModelWithNotifications <string>(passwordChangeResult.Result.ResetPassword); result.AddSuccessNotification(Services.TextService.Localize("user/password"), Services.TextService.Localize("user/passwordChanged")); return(result); } foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames) { ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage); } throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); }
/// <summary> /// </summary> /// <param name="changingPasswordModel"></param> /// <returns></returns> public async Task<ActionResult<ModelWithNotifications<string?>>> PostChangePassword( ChangingPasswordModel changingPasswordModel) { changingPasswordModel = changingPasswordModel ?? throw new ArgumentNullException(nameof(changingPasswordModel)); if (ModelState.IsValid == false) { return ValidationProblem(ModelState); } IUser? found = _userService.GetUserById(changingPasswordModel.Id); if (found == null) { return NotFound(); } IUser? currentUser = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser; // if it's the current user, the current user cannot reset their own password without providing their old password if (currentUser?.Username == found.Username && string.IsNullOrEmpty(changingPasswordModel.OldPassword)) { return ValidationProblem("Password reset is not allowed without providing old password"); } if ((!currentUser?.IsAdmin() ?? false) && found.IsAdmin()) { return ValidationProblem("The current user cannot change the password for the specified user"); } Attempt<PasswordChangedModel?> passwordChangeResult = await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _userManager); if (passwordChangeResult.Success) { var result = new ModelWithNotifications<string?>(passwordChangeResult.Result?.ResetPassword); result.AddSuccessNotification(_localizedTextService.Localize("general", "success"), _localizedTextService.Localize("user", "passwordChangedGeneric")); return result; } if (passwordChangeResult.Result?.ChangeError is not null) { foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames) { ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage ?? string.Empty); } } return ValidationProblem(ModelState); }
/// <summary> /// /// </summary> /// <param name="changingPasswordModel"></param> /// <returns></returns> public async Task <ModelWithNotifications <string> > PostChangePassword(ChangingPasswordModel changingPasswordModel) { changingPasswordModel = changingPasswordModel ?? throw new ArgumentNullException(nameof(changingPasswordModel)); if (ModelState.IsValid == false) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); } var intId = changingPasswordModel.Id.TryConvertTo <int>(); if (intId.Success == false) { throw new HttpResponseException(HttpStatusCode.NotFound); } var found = Services.UserService.GetUserById(intId.Result); if (found == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } var passwordChanger = new PasswordChanger(Logger, Services.UserService, UmbracoContext.HttpContext); var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, found, changingPasswordModel, UserManager); if (passwordChangeResult.Success) { var result = new ModelWithNotifications <string>(passwordChangeResult.Result.ResetPassword); result.AddSuccessNotification(Services.TextService.Localize("general", "success"), Services.TextService.Localize("user", "passwordChangedGeneric")); return(result); } foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames) { ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage); } throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); }