Fixes ability to reset your own password in the user section
This commit is contained in:
@@ -5,7 +5,10 @@
|
||||
bool KeepUserLoggedIn { get; }
|
||||
|
||||
bool HideDisabledUsersInBackoffice { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used to enable/disable the forgot password functionality on the back office login screen
|
||||
/// </summary>
|
||||
bool AllowPasswordReset { get; }
|
||||
|
||||
string AuthCookieName { get; }
|
||||
|
||||
@@ -16,6 +16,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return GetOptionalTextElement("hideDisabledUsersInBackoffice", false); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to enable/disable the forgot password functionality on the back office login screen
|
||||
/// </summary>
|
||||
[ConfigurationProperty("allowPasswordReset")]
|
||||
internal InnerTextConfigurationElement<bool> AllowPasswordReset
|
||||
{
|
||||
@@ -44,6 +47,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return HideDisabledUsersInBackoffice; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to enable/disable the forgot password functionality on the back office login screen
|
||||
/// </summary>
|
||||
bool ISecuritySection.AllowPasswordReset
|
||||
{
|
||||
get { return AllowPasswordReset; }
|
||||
|
||||
@@ -18,6 +18,9 @@ namespace Umbraco.Core.Security
|
||||
/// <param name="provider"></param>
|
||||
/// <param name="userService"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// An Admin can always reset the password
|
||||
/// </remarks>
|
||||
internal static bool CanResetPassword(this MembershipProvider provider, IUserService userService)
|
||||
{
|
||||
if (provider == null) throw new ArgumentNullException("provider");
|
||||
|
||||
@@ -119,7 +119,7 @@ angular.module("umbraco")
|
||||
$scope.changePasswordModel.config = data;
|
||||
//ensure the hasPassword config option is set to true (the user of course has a password already assigned)
|
||||
//this will ensure the oldPassword is shown so they can change it
|
||||
// disable reset password functionality beacuse it does not make sense inside the backoffice
|
||||
// disable reset password functionality beacuse it does not make sense for the current user.
|
||||
$scope.changePasswordModel.config.hasPassword = true;
|
||||
$scope.changePasswordModel.config.disableToggle = true;
|
||||
$scope.changePasswordModel.config.enableReset = false;
|
||||
|
||||
@@ -78,6 +78,9 @@
|
||||
vm.changePasswordModel.config.hasPassword = vm.user.userState !== 3 && vm.user.userState !== 4;
|
||||
|
||||
vm.changePasswordModel.config.disableToggle = true;
|
||||
|
||||
//if it's the current user then disable password reset since that doesn't make sense.
|
||||
vm.changePasswordModel.config.enableReset = !vm.user.isCurrentUser;
|
||||
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Umbraco.Web.Editors
|
||||
public async Task<ModelWithNotifications<string>> PostChangePassword(ChangingPasswordModel data)
|
||||
{
|
||||
var passwordChanger = new PasswordChanger(Logger, Services.UserService);
|
||||
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, data, ModelState, UserManager);
|
||||
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, Security.CurrentUser, data, ModelState, UserManager);
|
||||
|
||||
if (passwordChangeResult.Success)
|
||||
{
|
||||
|
||||
@@ -27,9 +27,19 @@ namespace Umbraco.Web.Editors
|
||||
_logger = logger;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Changes the password for a user based on the many different rules and config options
|
||||
/// </summary>
|
||||
/// <param name="currentUser">The user performing the password save action</param>
|
||||
/// <param name="savingUser">The user who's password is being changed</param>
|
||||
/// <param name="passwordModel"></param>
|
||||
/// <param name="modelState"></param>
|
||||
/// <param name="userMgr"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<Attempt<PasswordChangedModel>> ChangePasswordWithIdentityAsync(
|
||||
IUser currentUser,
|
||||
IUser savingUser,
|
||||
ChangingPasswordModel passwordModel,
|
||||
ModelStateDictionary modelState,
|
||||
BackOfficeUserManager<BackOfficeIdentityUser> userMgr)
|
||||
@@ -48,7 +58,7 @@ namespace Umbraco.Web.Editors
|
||||
//if this isn't using an IUserAwarePasswordHasher, then fallback to the old way
|
||||
if (membershipPasswordHasher.MembershipProvider.RequiresQuestionAndAnswer)
|
||||
throw new NotSupportedException("Currently the user editor does not support providers that have RequiresQuestionAndAnswer specified");
|
||||
return ChangePasswordWithMembershipProvider(currentUser.Username, passwordModel, membershipPasswordHasher.MembershipProvider);
|
||||
return ChangePasswordWithMembershipProvider(savingUser.Username, passwordModel, membershipPasswordHasher.MembershipProvider);
|
||||
}
|
||||
|
||||
//if we are here, then a IUserAwarePasswordHasher is available, however we cannot proceed in that case if for some odd reason
|
||||
@@ -62,10 +72,16 @@ namespace Umbraco.Web.Editors
|
||||
//Are we resetting the password??
|
||||
if (passwordModel.Reset.HasValue && passwordModel.Reset.Value)
|
||||
{
|
||||
//if it's the current user, the current user cannot reset their own password
|
||||
if (currentUser.Username == savingUser.Username)
|
||||
{
|
||||
return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Password reset is not allowed", new[] { "resetPassword" }) });
|
||||
}
|
||||
|
||||
//ok, we should be able to reset it
|
||||
var resetToken = await userMgr.GeneratePasswordResetTokenAsync(currentUser.Id);
|
||||
var resetToken = await userMgr.GeneratePasswordResetTokenAsync(savingUser.Id);
|
||||
var newPass = userMgr.GeneratePassword();
|
||||
var resetResult = await userMgr.ResetPasswordAsync(currentUser.Id, resetToken, newPass);
|
||||
var resetResult = await userMgr.ResetPasswordAsync(savingUser.Id, resetToken, newPass);
|
||||
|
||||
if (resetResult.Succeeded == false)
|
||||
{
|
||||
@@ -95,7 +111,7 @@ namespace Umbraco.Web.Editors
|
||||
if (passwordModel.OldPassword.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
//if an old password is suplied try to change it
|
||||
var changeResult = await userMgr.ChangePasswordAsync(currentUser.Id, passwordModel.OldPassword, passwordModel.NewPassword);
|
||||
var changeResult = await userMgr.ChangePasswordAsync(savingUser.Id, passwordModel.OldPassword, passwordModel.NewPassword);
|
||||
if (changeResult.Succeeded == false)
|
||||
{
|
||||
var errors = string.Join(". ", changeResult.Errors);
|
||||
@@ -112,7 +128,7 @@ namespace Umbraco.Web.Editors
|
||||
/// <summary>
|
||||
/// Changes password for a member/user given the membership provider and the password change model
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="username">The username of the user having their password changed</param>
|
||||
/// <param name="passwordModel"></param>
|
||||
/// <param name="membershipProvider"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
@@ -522,7 +522,7 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
var passwordChanger = new PasswordChanger(Logger, Services.UserService);
|
||||
|
||||
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(found, userSave.ChangePassword, ModelState, UserManager);
|
||||
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, found, userSave.ChangePassword, ModelState, UserManager);
|
||||
if (passwordChangeResult.Success)
|
||||
{
|
||||
//depending on how the provider is configured, the password may be reset so let's store that for later
|
||||
|
||||
Reference in New Issue
Block a user