예제 #1
0
        /// <summary>
        /// Changes password for a member/user given the membership provider and the password change model
        /// </summary>
        /// <param name="username">The username of the user having their password changed</param>
        /// <param name="passwordModel"></param>
        /// <param name="membershipProvider"></param>
        /// <returns></returns>
        public Attempt <PasswordChangedModel> ChangePasswordWithMembershipProvider(string username, ChangingPasswordModel passwordModel, MembershipProvider membershipProvider)
        {
            // YES! It is completely insane how many options you have to take into account based on the membership provider. yikes!

            if (passwordModel == null)
            {
                throw new ArgumentNullException("passwordModel");
            }
            if (membershipProvider == null)
            {
                throw new ArgumentNullException("membershipProvider");
            }

            BackOfficeUserManager <BackOfficeIdentityUser> backofficeUserManager = null;
            var userId = -1;

            if (membershipProvider.IsUmbracoUsersProvider())
            {
                backofficeUserManager = _httpContext.GetOwinContext().GetBackOfficeUserManager();
                if (backofficeUserManager != null)
                {
                    var profile = _userService.GetProfileByUserName(username);
                    if (profile != null)
                    {
                        int.TryParse(profile.Id.ToString(), out userId);
                    }
                }
            }

            //Are we resetting the password??
            //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 (passwordModel.Reset.HasValue && passwordModel.Reset.Value)
            {
                var canReset = membershipProvider.CanResetPassword(_userService);
                if (canReset == false)
                {
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Password reset is not enabled", new[] { "resetPassword" })
                    }));
                }
                if (membershipProvider.RequiresQuestionAndAnswer && passwordModel.Answer.IsNullOrWhiteSpace())
                {
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Password reset requires a password answer", new[] { "resetPassword" })
                    }));
                }
                //ok, we should be able to reset it
                try
                {
                    var newPass = membershipProvider.ResetPassword(
                        username,
                        membershipProvider.RequiresQuestionAndAnswer ? passwordModel.Answer : null);

                    if (membershipProvider.IsUmbracoUsersProvider() && backofficeUserManager != null && userId >= 0)
                    {
                        backofficeUserManager.RaisePasswordResetEvent(userId);
                    }

                    //return the generated pword
                    return(Attempt.Succeed(new PasswordChangedModel {
                        ResetPassword = newPass
                    }));
                }
                catch (Exception ex)
                {
                    _logger.WarnWithException <PasswordChanger>("Could not reset member password", ex);
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Could not reset password, error: " + ex.Message + " (see log for full details)", new[] { "resetPassword" })
                    }));
                }
            }

            //we're not resetting it so we need to try to change it.

            if (passwordModel.NewPassword.IsNullOrWhiteSpace())
            {
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Cannot set an empty password", new[] { "value" })
                }));
            }

            //This is an edge case and is only necessary for backwards compatibility:
            var umbracoBaseProvider = membershipProvider as MembershipProviderBase;

            if (umbracoBaseProvider != null && umbracoBaseProvider.AllowManuallyChangingPassword)
            {
                //this provider allows manually changing the password without the old password, so we can just do it
                try
                {
                    var result = umbracoBaseProvider.ChangePassword(username, "", passwordModel.NewPassword);
                    return(result == false
                        ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "value" }) })
                        : Attempt.Succeed(new PasswordChangedModel()));
                }
                catch (Exception ex)
                {
                    _logger.WarnWithException <PasswordChanger>("Could not change member password", ex);
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Could not change password, error: " + ex.Message + " (see log for full details)", new[] { "value" })
                    }));
                }
            }

            //The provider does not support manually chaning the password but no old password supplied - need to return an error
            if (passwordModel.OldPassword.IsNullOrWhiteSpace() && membershipProvider.EnablePasswordRetrieval == false)
            {
                //if password retrieval is not enabled but there is no old password we cannot continue
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Password cannot be changed without the old password", new[] { "oldPassword" })
                }));
            }

            if (passwordModel.OldPassword.IsNullOrWhiteSpace() == false)
            {
                //if an old password is suplied try to change it

                try
                {
                    var result = membershipProvider.ChangePassword(username, passwordModel.OldPassword, passwordModel.NewPassword);

                    if (result && backofficeUserManager != null && userId >= 0)
                    {
                        backofficeUserManager.RaisePasswordChangedEvent(userId);
                    }

                    return(result == false
                        ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "oldPassword" }) })
                        : Attempt.Succeed(new PasswordChangedModel()));
                }
                catch (Exception ex)
                {
                    _logger.WarnWithException <PasswordChanger>("Could not change member password", ex);
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Could not change password, error: " + ex.Message + " (see log for full details)", new[] { "value" })
                    }));
                }
            }

            if (membershipProvider.EnablePasswordRetrieval == false)
            {
                //we cannot continue if we cannot get the current password
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Password cannot be changed without the old password", new[] { "oldPassword" })
                }));
            }
            if (membershipProvider.RequiresQuestionAndAnswer && passwordModel.Answer.IsNullOrWhiteSpace())
            {
                //if the question answer is required but there isn't one, we cannot continue
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Password cannot be changed without the password answer", new[] { "value" })
                }));
            }

            //lets try to get the old one so we can change it
            try
            {
                var oldPassword = membershipProvider.GetPassword(
                    username,
                    membershipProvider.RequiresQuestionAndAnswer ? passwordModel.Answer : null);

                try
                {
                    var result = membershipProvider.ChangePassword(username, oldPassword, passwordModel.NewPassword);
                    return(result == false
                        ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password", new[] { "value" }) })
                        : Attempt.Succeed(new PasswordChangedModel()));
                }
                catch (Exception ex1)
                {
                    _logger.WarnWithException <PasswordChanger>("Could not change member password", ex1);
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Could not change password, error: " + ex1.Message + " (see log for full details)", new[] { "value" })
                    }));
                }
            }
            catch (Exception ex2)
            {
                _logger.WarnWithException <PasswordChanger>("Could not retrieve member password", ex2);
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Could not change password, error: " + ex2.Message + " (see log for full details)", new[] { "value" })
                }));
            }
        }
예제 #2
0
        /// <summary>
        /// Changes password for a member/user given the membership provider and the password change model
        /// </summary>
        /// <param name="username">The username of the user having their password changed</param>
        /// <param name="passwordModel"></param>
        /// <param name="membershipProvider"></param>
        /// <returns></returns>
        public Attempt <PasswordChangedModel> ChangePasswordWithMembershipProvider(string username, ChangingPasswordModel passwordModel, MembershipProvider membershipProvider)
        {
            var umbracoBaseProvider = membershipProvider as MembershipProviderBase;

            // YES! It is completely insane how many options you have to take into account based on the membership provider. yikes!

            if (passwordModel == null)
            {
                throw new ArgumentNullException(nameof(passwordModel));
            }
            if (membershipProvider == null)
            {
                throw new ArgumentNullException(nameof(membershipProvider));
            }

            BackOfficeUserManager <BackOfficeIdentityUser> backofficeUserManager = null;
            var userId = -1;

            if (membershipProvider.IsUmbracoUsersProvider())
            {
                backofficeUserManager = _httpContext.GetOwinContext().GetBackOfficeUserManager();
                if (backofficeUserManager != null)
                {
                    var profile = _userService.GetProfileByUserName(username);
                    if (profile != null)
                    {
                        int.TryParse(profile.Id.ToString(), out userId);
                    }
                }
            }

            //Are we resetting the password?
            //This flag indicates that either an admin user is changing another user's password without knowing the original password
            // or that the password needs to be reset to an auto-generated one.
            if (passwordModel.Reset.HasValue && passwordModel.Reset.Value)
            {
                //if a new password is supplied then it's an admin user trying to change another user's password without knowing the original password
                //this is only possible when using a membership provider if the membership provider supports AllowManuallyChangingPassword
                if (passwordModel.NewPassword.IsNullOrWhiteSpace() == false)
                {
                    if (umbracoBaseProvider != null && umbracoBaseProvider.AllowManuallyChangingPassword)
                    {
                        //this provider allows manually changing the password without the old password, so we can just do it
                        try
                        {
                            var result = umbracoBaseProvider.ChangePassword(username, string.Empty, passwordModel.NewPassword);

                            if (result && backofficeUserManager != null && userId >= 0)
                            {
                                backofficeUserManager.RaisePasswordChangedEvent(userId);
                            }

                            return(result == false
                                ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "value" }) })
                                : Attempt.Succeed(new PasswordChangedModel()));
                        }
                        catch (Exception ex)
                        {
                            _logger.Warn <PasswordChanger>("Could not change member password", ex);
                            return(Attempt.Fail(new PasswordChangedModel {
                                ChangeError = new ValidationResult("Could not change password, error: " + ex.Message + " (see log for full details)", new[] { "value" })
                            }));
                        }
                    }
                    else
                    {
                        return(Attempt.Fail(new PasswordChangedModel {
                            ChangeError = new ValidationResult("Provider does not support manually changing passwords", new[] { "value" })
                        }));
                    }
                }

                //we've made it here which means we need to generate a new password

                var canReset = membershipProvider.CanResetPassword(_userService);
                if (canReset == false)
                {
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Password reset is not enabled", new[] { "resetPassword" })
                    }));
                }
                if (membershipProvider.RequiresQuestionAndAnswer && passwordModel.Answer.IsNullOrWhiteSpace())
                {
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Password reset requires a password answer", new[] { "resetPassword" })
                    }));
                }

                //ok, we should be able to reset it
                try
                {
                    var newPass = membershipProvider.ResetPassword(
                        username,
                        membershipProvider.RequiresQuestionAndAnswer ? passwordModel.Answer : null);

                    if (membershipProvider.IsUmbracoUsersProvider() && backofficeUserManager != null && userId >= 0)
                    {
                        backofficeUserManager.RaisePasswordResetEvent(userId);
                    }

                    //return the generated pword
                    return(Attempt.Succeed(new PasswordChangedModel {
                        ResetPassword = newPass
                    }));
                }
                catch (Exception ex)
                {
                    _logger.Warn <PasswordChanger>(ex, "Could not reset member password");
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Could not reset password, error: " + ex.Message + " (see log for full details)", new[] { "resetPassword" })
                    }));
                }
            }

            //we're not resetting it so we need to try to change it.

            if (passwordModel.NewPassword.IsNullOrWhiteSpace())
            {
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Cannot set an empty password", new[] { "value" })
                }));
            }

            //without being able to retrieve the original password,
            //we cannot arbitrarily change the password without knowing the old one and no old password was supplied - need to return an error
            if (passwordModel.OldPassword.IsNullOrWhiteSpace() && membershipProvider.EnablePasswordRetrieval == false)
            {
                //if password retrieval is not enabled but there is no old password we cannot continue
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Password cannot be changed without the old password", new[] { "oldPassword" })
                }));
            }

            if (passwordModel.OldPassword.IsNullOrWhiteSpace() == false)
            {
                //if an old password is supplied try to change it

                try
                {
                    var result = membershipProvider.ChangePassword(username, passwordModel.OldPassword, passwordModel.NewPassword);

                    if (result && backofficeUserManager != null && userId >= 0)
                    {
                        backofficeUserManager.RaisePasswordChangedEvent(userId);
                    }

                    return(result == false
                        ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "oldPassword" }) })
                        : Attempt.Succeed(new PasswordChangedModel()));
                }
                catch (Exception ex)
                {
                    _logger.Warn <PasswordChanger>(ex, "Could not change member password");
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Could not change password, error: " + ex.Message + " (see log for full details)", new[] { "value" })
                    }));
                }
            }

            if (membershipProvider.EnablePasswordRetrieval == false)
            {
                //we cannot continue if we cannot get the current password
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Password cannot be changed without the old password", new[] { "oldPassword" })
                }));
            }
            if (membershipProvider.RequiresQuestionAndAnswer && passwordModel.Answer.IsNullOrWhiteSpace())
            {
                //if the question answer is required but there isn't one, we cannot continue
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Password cannot be changed without the password answer", new[] { "value" })
                }));
            }

            //lets try to get the old one so we can change it
            try
            {
                var oldPassword = membershipProvider.GetPassword(
                    username,
                    membershipProvider.RequiresQuestionAndAnswer ? passwordModel.Answer : null);

                try
                {
                    var result = membershipProvider.ChangePassword(username, oldPassword, passwordModel.NewPassword);
                    return(result == false
                        ? Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password", new[] { "value" }) })
                        : Attempt.Succeed(new PasswordChangedModel()));
                }
                catch (Exception ex1)
                {
                    _logger.Warn <PasswordChanger>(ex1, "Could not change member password");
                    return(Attempt.Fail(new PasswordChangedModel {
                        ChangeError = new ValidationResult("Could not change password, error: " + ex1.Message + " (see log for full details)", new[] { "value" })
                    }));
                }
            }
            catch (Exception ex2)
            {
                _logger.Warn <PasswordChanger>(ex2, "Could not retrieve member password");
                return(Attempt.Fail(new PasswordChangedModel {
                    ChangeError = new ValidationResult("Could not change password, error: " + ex2.Message + " (see log for full details)", new[] { "value" })
                }));
            }
        }