diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs
index c4a55cd99f..b44a80c832 100644
--- a/src/Umbraco.Web/Security/WebSecurity.cs
+++ b/src/Umbraco.Web/Security/WebSecurity.cs
@@ -232,78 +232,95 @@ namespace Umbraco.Web.Security
return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not reset password, error: " + ex.Message + " (see log for full details)", new[] { "resetPassword" }) });
}
}
- if (passwordModel.NewPassword.IsNullOrWhiteSpace() == false)
+
+ //we're not resetting it so we need to try to change it.
+
+ if (passwordModel.NewPassword.IsNullOrWhiteSpace())
{
- //we're not resetting it so we need to try to change it.
+ return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Cannot set an empty password", new[] { "value" }) });
+ }
- if (passwordModel.OldPassword.IsNullOrWhiteSpace() && membershipProvider.EnablePasswordRetrieval == false)
+ //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
{
- //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[] { "value" }) });
+ 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());
}
- if (passwordModel.OldPassword.IsNullOrWhiteSpace() == false)
+ catch (Exception ex)
{
- //if an old password is suplied try to change it
-
- try
- {
- var result = membershipProvider.ChangePassword(username, passwordModel.OldPassword, passwordModel.NewPassword);
- if (result == false)
- {
- return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, invalid username or password", new[] { "value" }) });
- }
- }
- catch (Exception ex)
- {
- LogHelper.WarnWithException
("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 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[] { "value" }) });
- }
- else 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" }) });
- }
- else
- {
- //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);
- if (result == false)
- {
- return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password", new[] { "value" }) });
- }
- }
- catch (Exception ex1)
- {
- LogHelper.WarnWithException("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)
- {
- LogHelper.WarnWithException("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" }) });
- }
+ LogHelper.WarnWithException("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" }) });
}
}
- //woot!
- return Attempt.Succeed(new PasswordChangedModel());
+ //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[] { "value" }) });
+ }
+
+ 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);
+ 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)
+ {
+ LogHelper.WarnWithException("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[] { "value" }) });
+ }
+ 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)
+ {
+ LogHelper.WarnWithException("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)
+ {
+ LogHelper.WarnWithException("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" }) });
+ }
}
///
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/passwordChanger.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/passwordChanger.ascx.cs
index 1a87a1ef20..482d36d77f 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/passwordChanger.ascx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/passwordChanger.ascx.cs
@@ -10,6 +10,7 @@ using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Umbraco.Core;
+using Umbraco.Core.Security;
using Umbraco.Web.Models;
namespace umbraco.controls
@@ -23,6 +24,23 @@ namespace umbraco.controls
get { return Membership.Providers[MembershipProviderName]; }
}
+ ///
+ /// Determines whether to show the old password field or not
+ ///
+ protected bool ShowOldPassword
+ {
+ get
+ {
+ var umbProvider = Provider as MembershipProviderBase;
+ if (umbProvider != null && umbProvider.AllowManuallyChangingPassword)
+ {
+ return false;
+ }
+
+ return Provider.EnablePasswordRetrieval == false;
+ }
+ }
+
public bool IsChangingPassword
{
get
diff --git a/src/umbraco.providers/UsersMembershipProvider.cs b/src/umbraco.providers/UsersMembershipProvider.cs
index 889cff8fab..ddce6a7c2e 100644
--- a/src/umbraco.providers/UsersMembershipProvider.cs
+++ b/src/umbraco.providers/UsersMembershipProvider.cs
@@ -18,6 +18,30 @@ namespace umbraco.providers
///
public class UsersMembershipProvider : MembershipProviderBase
{
+ ///
+ /// Override to maintain backwards compatibility with 0 required non-alphanumeric chars
+ ///
+ protected override int DefaultMinNonAlphanumericChars
+ {
+ get { return 0; }
+ }
+
+ ///
+ /// Override to maintain backwards compatibility with only 4 required length
+ ///
+ protected override int DefaultMinPasswordLength
+ {
+ get { return 4; }
+ }
+
+ ///
+ /// Override to maintain backwards compatibility
+ ///
+ protected override bool DefaultUseLegacyEncoding
+ {
+ get { return true; }
+ }
+
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (config == null) throw new ArgumentNullException("config");
@@ -41,8 +65,10 @@ namespace umbraco.providers
/// During installation the application will not be configured, if this is the case and the 'default' password
/// is stored in the database then we will validate the user - this will allow for an admin password reset if required
///
- public override bool ChangePassword(string username, string oldPassword, string newPassword)
+ protected override bool PerformChangePassword(string username, string oldPassword, string newPassword)
{
+
+
if (ApplicationContext.Current.IsConfigured == false && oldPassword == "default"
|| ValidateUser(username, oldPassword))
{
diff --git a/src/umbraco.providers/members/MembersMembershipProvider.cs b/src/umbraco.providers/members/MembersMembershipProvider.cs
index 49139f5e74..a9f3c85ea3 100644
--- a/src/umbraco.providers/members/MembersMembershipProvider.cs
+++ b/src/umbraco.providers/members/MembersMembershipProvider.cs
@@ -66,6 +66,38 @@ namespace umbraco.providers.members
}
#endregion
+
+ ///
+ /// Override to maintain backwards compatibility with 0 required non-alphanumeric chars
+ ///
+ protected override int DefaultMinNonAlphanumericChars
+ {
+ get { return 0; }
+ }
+
+ ///
+ /// Override to maintain backwards compatibility with only 4 required length
+ ///
+ protected override int DefaultMinPasswordLength
+ {
+ get { return 4; }
+ }
+
+ ///
+ /// Override to maintain backwards compatibility
+ ///
+ protected override bool DefaultUseLegacyEncoding
+ {
+ get { return true; }
+ }
+
+ ///
+ /// For backwards compatibility, this provider supports this option
+ ///
+ internal override bool AllowManuallyChangingPassword
+ {
+ get { return true; }
+ }
#region Initialization Method
///
@@ -148,16 +180,19 @@ namespace umbraco.providers.members
/// Processes a request to update the password for a membership user.
///
/// The user to update the password for.
- /// The current password for the specified user.
+ /// This property is ignore for this provider
/// The new password for the specified user.
///
/// true if the password was updated successfully; otherwise, false.
///
- public override bool ChangePassword(string username, string oldPassword, string newPassword)
+ protected override bool PerformChangePassword(string username, string oldPassword, string newPassword)
{
-
+ //NOTE: due to backwards compatibilty reasons, this provider doesn't care about the old password and
+ // allows simply setting the password manually so we don't really care about the old password.
+ // This is allowed based on the overridden AllowManuallyChangingPassword option.
+
// in order to support updating passwords from the umbraco core, we can't validate the old password
- var m = Member.GetMemberFromLoginNameAndPassword(username, oldPassword);
+ var m = Member.GetMemberFromLoginName(username);
if (m == null) return false;
var args = new ValidatePasswordEventArgs(username, newPassword, false);