diff --git a/src/umbraco.cms/businesslogic/member/Member.cs b/src/umbraco.cms/businesslogic/member/Member.cs index aa6b71f46c..9b051aea7b 100644 --- a/src/umbraco.cms/businesslogic/member/Member.cs +++ b/src/umbraco.cms/businesslogic/member/Member.cs @@ -466,7 +466,7 @@ namespace umbraco.cms.businesslogic.member /// /// The members password, used when logging in on the public website /// - [Obsolete("Do not use this property, use GetPassword and ChangePassword instead, if using ChangePassword ensure that the password is encrypted or hashed based on the active membership provider")] + [Obsolete("Do not use this property, use GetPassword and ChangePassword instead, if using ChangePassword ensure that the password is encrypted or hashed based on the active membership provider")] public string Password { get @@ -479,7 +479,7 @@ namespace umbraco.cms.businesslogic.member } return _password; - } + } set { // We need to use the provider for this in order for hashing, etc. support @@ -745,10 +745,10 @@ namespace umbraco.cms.businesslogic.member } } - /// - /// Sets the password for the user - ensure it is encrypted or hashed based on the active membership provider. - /// - /// + /// + /// Sets the password for the user - ensure it is encrypted or hashed based on the active membership provider. + /// + /// public void ChangePassword(string newPassword) { SqlHelper.ExecuteNonQuery( @@ -774,23 +774,8 @@ namespace umbraco.cms.businesslogic.member } return _password; } - + /// - /// Returns the currently stored password - this may be encrypted or hashed string depending on the active membership provider - /// - /// - public string GetPassword() - { - if (string.IsNullOrEmpty(m_Password)) - { - m_Password = SqlHelper.ExecuteScalar( - "select Password from cmsMember where nodeId = @id", - SqlHelper.CreateParameter("@id", Id)); - } - return m_Password; - } - - /// /// Adds the member to group with the specified id /// /// The id of the group which the member is being added to diff --git a/src/umbraco.providers/members/MembersMembershipProvider.cs b/src/umbraco.providers/members/MembersMembershipProvider.cs index b6b90b47b8..a14b47d84d 100644 --- a/src/umbraco.providers/members/MembersMembershipProvider.cs +++ b/src/umbraco.providers/members/MembersMembershipProvider.cs @@ -7,13 +7,12 @@ using System.Web.Security; using System.Configuration; using Umbraco.Core; using Umbraco.Core.Models; -using Umbraco.Core.Security; +using Umbraco.Core.Security; using umbraco.BusinessLogic; using System.Security.Cryptography; using System.Web.Util; using System.Collections.Specialized; using System.Configuration.Provider; -using umbraco.cms.businesslogic; using System.Security; using System.Security.Permissions; using System.Runtime.CompilerServices; @@ -28,7 +27,7 @@ namespace umbraco.providers.members /// Custom Membership Provider for Umbraco Members (User authentication for Frontend applications NOT umbraco CMS) /// - public class UmbracoMembershipProvider : MembershipProviderBase + public class UmbracoMembershipProvider : MembershipProviderBase { #region Fields @@ -37,15 +36,34 @@ namespace umbraco.providers.members private string _lockPropertyTypeAlias = Constants.Conventions.Member.IsLockedOut; private string _lastLockedOutPropertyTypeAlias = Constants.Conventions.Member.LastLockoutDate; private string _failedPasswordAttemptsPropertyTypeAlias = Constants.Conventions.Member.FailedPasswordAttempts; - private string _approvedPropertyTypeAlias = Constants.Conventions.Member.IsApproved; + private string _approvedPropertyTypeAlias = Constants.Conventions.Member.IsApproved; private string _commentPropertyTypeAlias = Constants.Conventions.Member.Comments; private string _lastLoginPropertyTypeAlias = Constants.Conventions.Member.LastLoginDate; private string _lastPasswordChangedPropertyTypeAlias = Constants.Conventions.Member.LastPasswordChangeDate; - private string _passwordRetrievalQuestionPropertyTypeAlias = Constants.Conventions.Member.PasswordQuestion; - private string _passwordRetrievalAnswerPropertyTypeAlias = Constants.Conventions.Member.PasswordAnswer; - - private string _providerName = Member.UmbracoMemberProviderName; + private string _passwordRetrievalQuestionPropertyTypeAlias = Constants.Conventions.Member.PasswordQuestion; + private string _passwordRetrievalAnswerPropertyTypeAlias = Constants.Conventions.Member.PasswordAnswer; + private string _providerName = Member.UmbracoMemberProviderName; + + //Need to expose these publicly so we know what field aliases to use in the editor, we only care about these 3 fields + // because they are the only 'settable' provider properties that are not stored against the IMember directly (i.e. they are + // property type properties). + + public string LockPropertyTypeAlias + { + get { return _lockPropertyTypeAlias; } + } + + public string ApprovedPropertyTypeAlias + { + get { return _approvedPropertyTypeAlias; } + } + + public string CommentPropertyTypeAlias + { + get { return _commentPropertyTypeAlias; } + } + #endregion /// @@ -97,28 +115,28 @@ namespace umbraco.providers.members if (config == null) throw new ArgumentNullException("config"); if (string.IsNullOrEmpty(name)) name = "UmbracoMembershipProvider"; - + base.Initialize(name, config); - - _providerName = name; - + + _providerName = name; + // test for membertype (if not specified, choose the first member type available) if (config["defaultMemberTypeAlias"] != null) - _defaultMemberTypeAlias = config["defaultMemberTypeAlias"]; + _defaultMemberTypeAlias = config["defaultMemberTypeAlias"]; else if (MemberType.GetAll.Length == 1) - _defaultMemberTypeAlias = MemberType.GetAll[0].Alias; + _defaultMemberTypeAlias = MemberType.GetAll[0].Alias; else throw new ProviderException("No default MemberType alias is specified in the web.config string. Please add a 'defaultMemberTypeAlias' to the add element in the provider declaration in web.config"); // test for approve status if (config["umbracoApprovePropertyTypeAlias"] != null) { - _approvedPropertyTypeAlias = config["umbracoApprovePropertyTypeAlias"]; + _approvedPropertyTypeAlias = config["umbracoApprovePropertyTypeAlias"]; } // test for lock attempts if (config["umbracoLockPropertyTypeAlias"] != null) { - _lockPropertyTypeAlias = config["umbracoLockPropertyTypeAlias"]; + _lockPropertyTypeAlias = config["umbracoLockPropertyTypeAlias"]; } if (config["umbracoLastLockedPropertyTypeAlias"] != null) { @@ -130,26 +148,26 @@ namespace umbraco.providers.members } if (config["umbracoFailedPasswordAttemptsPropertyTypeAlias"] != null) { - _failedPasswordAttemptsPropertyTypeAlias = config["umbracoFailedPasswordAttemptsPropertyTypeAlias"]; + _failedPasswordAttemptsPropertyTypeAlias = config["umbracoFailedPasswordAttemptsPropertyTypeAlias"]; } // comment property if (config["umbracoCommentPropertyTypeAlias"] != null) { - _commentPropertyTypeAlias = config["umbracoCommentPropertyTypeAlias"]; + _commentPropertyTypeAlias = config["umbracoCommentPropertyTypeAlias"]; } // last login date if (config["umbracoLastLoginPropertyTypeAlias"] != null) { - _lastLoginPropertyTypeAlias = config["umbracoLastLoginPropertyTypeAlias"]; + _lastLoginPropertyTypeAlias = config["umbracoLastLoginPropertyTypeAlias"]; } // password retrieval if (config["umbracoPasswordRetrievalQuestionPropertyTypeAlias"] != null) { - _passwordRetrievalQuestionPropertyTypeAlias = config["umbracoPasswordRetrievalQuestionPropertyTypeAlias"]; + _passwordRetrievalQuestionPropertyTypeAlias = config["umbracoPasswordRetrievalQuestionPropertyTypeAlias"]; } if (config["umbracoPasswordRetrievalAnswerPropertyTypeAlias"] != null) { - _passwordRetrievalAnswerPropertyTypeAlias = config["umbracoPasswordRetrievalAnswerPropertyTypeAlias"]; + _passwordRetrievalAnswerPropertyTypeAlias = config["umbracoPasswordRetrievalAnswerPropertyTypeAlias"]; } } @@ -173,29 +191,29 @@ namespace umbraco.providers.members // 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.GetMemberFromLoginName(username); + var m = Member.GetMemberFromLoginName(username); if (m == null) return false; - var args = new ValidatePasswordEventArgs(username, newPassword, false); + var args = new ValidatePasswordEventArgs(username, newPassword, false); OnValidatingPassword(args); if (args.Cancel) { if (args.FailureInformation != null) throw args.FailureInformation; - throw new MembershipPasswordException("Change password canceled due to password validation failure."); + throw new MembershipPasswordException("Change password canceled due to password validation failure."); } - string salt; - var encodedPassword = EncryptOrHashNewPassword(newPassword, out salt); - m.ChangePassword( + string salt; + var encodedPassword = EncryptOrHashNewPassword(newPassword, out salt); + m.ChangePassword( FormatPasswordForStorage(encodedPassword, salt)); UpdateMemberProperty(m, _lastPasswordChangedPropertyTypeAlias, DateTime.Now); - m.Save(); - - return true; + m.Save(); + + return true; } /// @@ -210,15 +228,15 @@ namespace umbraco.providers.members /// public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { - if (!String.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) && !String.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias)) + if (!String.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) && !String.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias)) { if (ValidateUser(username, password)) { Member m = Member.GetMemberFromLoginName(username); if (m != null) { - UpdateMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, newPasswordQuestion); - UpdateMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, newPasswordAnswer); + UpdateMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, newPasswordQuestion); + UpdateMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, newPasswordAnswer); m.Save(); return true; } @@ -256,23 +274,23 @@ namespace umbraco.providers.members public MembershipUser CreateUser(string memberTypeAlias, string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { - - var args = new ValidatePasswordEventArgs(username, password, true); - OnValidatingPassword(args); - if (args.Cancel) - { - status = MembershipCreateStatus.InvalidPassword; - return null; - } - + + var args = new ValidatePasswordEventArgs(username, password, true); + OnValidatingPassword(args); + if (args.Cancel) + { + status = MembershipCreateStatus.InvalidPassword; + return null; + } + if (Member.GetMemberFromLoginName(username) != null) - { + { status = MembershipCreateStatus.DuplicateUserName; - } + } else if (Member.GetMemberFromEmail(email) != null && RequiresUniqueEmail) - { + { status = MembershipCreateStatus.DuplicateEmail; - } + } else { var memberType = MemberType.GetByAlias(memberTypeAlias); @@ -281,30 +299,33 @@ namespace umbraco.providers.members throw new InvalidOperationException("Could not find a member type with alias " + memberTypeAlias + ". Ensure your membership provider configuration is up to date and that the default member type exists."); } - var m = Member.MakeNew(username, email, memberType, User.GetUser(0)); - - string salt; - var encodedPassword = EncryptOrHashNewPassword(password, out salt); - //set the password on the member - m.ChangePassword( - FormatPasswordForStorage(encodedPassword, salt)); - - var mUser = ConvertToMembershipUser(m); + var m = Member.MakeNew(username, email, memberType, User.GetUser(0)); + string salt; + var encodedPassword = EncryptOrHashNewPassword(password, out salt); + //set the password on the member + m.ChangePassword( + FormatPasswordForStorage(encodedPassword, salt)); + // custom fields - if (string.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) == false) - UpdateMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, passwordQuestion); - - if (string.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias) == false) - UpdateMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, passwordAnswer); - - if (string.IsNullOrEmpty(_approvedPropertyTypeAlias) == false) - UpdateMemberProperty(m, _approvedPropertyTypeAlias, isApproved ? 1 : 0); - - if (string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) + if (string.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) == false) { - mUser.LastActivityDate = DateTime.Now; - UpdateMemberProperty(m, _lastLoginPropertyTypeAlias, mUser.LastActivityDate); + UpdateMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, passwordQuestion); + } + + if (string.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias) == false) + { + UpdateMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, passwordAnswer); + } + + if (string.IsNullOrEmpty(ApprovedPropertyTypeAlias) == false) + { + UpdateMemberProperty(m, ApprovedPropertyTypeAlias, isApproved ? 1 : 0); + } + + if (string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) + { + UpdateMemberProperty(m, _lastLoginPropertyTypeAlias, DateTime.Now); } if (string.IsNullOrEmpty(_lastPasswordChangedPropertyTypeAlias) == false) @@ -312,6 +333,8 @@ namespace umbraco.providers.members UpdateMemberProperty(m, _lastPasswordChangedPropertyTypeAlias, DateTime.Now); } + var mUser = ConvertToMembershipUser(m); + // save m.Save(); @@ -339,7 +362,7 @@ namespace umbraco.providers.members public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { - return CreateUser(_defaultMemberTypeAlias, username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status); + return CreateUser(_defaultMemberTypeAlias, username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status); } /// @@ -377,7 +400,7 @@ namespace umbraco.providers.members var collection = new MembershipUserCollection(); foreach (var m in byEmail.Skip(pagedResult.SkipSize).Take(pageSize)) { - collection.Add(ConvertToMembershipUser(m)); + collection.Add(ConvertToMembershipUser(m)); } return collection; } @@ -473,13 +496,13 @@ namespace umbraco.providers.members if (RequiresQuestionAndAnswer) { // check if password answer property alias is set - if (string.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias) == false) + if (string.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias) == false) { // check if user is locked out - if (string.IsNullOrEmpty(_lockPropertyTypeAlias) == false) + if (string.IsNullOrEmpty(LockPropertyTypeAlias) == false) { var isLockedOut = false; - bool.TryParse(GetMemberProperty(m, _lockPropertyTypeAlias, true), out isLockedOut); + bool.TryParse(GetMemberProperty(m, LockPropertyTypeAlias, true), out isLockedOut); if (isLockedOut) { throw new MembershipPasswordException("The supplied user is locked out"); @@ -487,7 +510,7 @@ namespace umbraco.providers.members } // match password answer - if (GetMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, false) != answer) + if (GetMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, false) != answer) { throw new MembershipPasswordException("Incorrect password answer"); } @@ -532,10 +555,20 @@ namespace umbraco.providers.members /// public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { - if (String.IsNullOrEmpty(providerUserKey.ToString())) - return null; - var m = new Member(Convert.ToInt32(providerUserKey)); - return ConvertToMembershipUser(m); + var asGuid = providerUserKey.TryConvertTo(); + if (asGuid.Success) + { + var m = new Member(asGuid.Result); + return ConvertToMembershipUser(m); + } + var asInt = providerUserKey.TryConvertTo(); + if (asInt.Success) + { + var m = new Member(asInt.Result); + return ConvertToMembershipUser(m); + } + throw new InvalidOperationException("The " + GetType() + " provider only supports GUID or Int as a providerUserKey"); + } @@ -549,7 +582,7 @@ namespace umbraco.providers.members public override string GetUserNameByEmail(string email) { Member m = Member.GetMemberFromEmail(email); - return m == null ? null : m.LoginName; + return m == null ? null : m.LoginName; } /// @@ -560,66 +593,66 @@ namespace umbraco.providers.members /// The new password for the specified user. public override string ResetPassword(string username, string answer) { - if (EnablePasswordReset == false) + if (EnablePasswordReset == false) { throw new NotSupportedException("Password reset is not supported"); } - //TODO: This should be here - but how do we update failure count in this provider?? - //if (answer == null && RequiresQuestionAndAnswer) - //{ - // UpdateFailureCount(username, "passwordAnswer"); - - // throw new ProviderException("Password answer required for password reset."); - //} - - var newPassword = Membership.GeneratePassword(MinRequiredPasswordLength, MinRequiredNonAlphanumericCharacters); - - var args = new ValidatePasswordEventArgs(username, newPassword, true); - OnValidatingPassword(args); - if (args.Cancel) - { - if (args.FailureInformation != null) - throw args.FailureInformation; - throw new MembershipPasswordException("Reset password canceled due to password validation failure."); - } - - var m = Member.GetMemberFromLoginName(username); + //TODO: This should be here - but how do we update failure count in this provider?? + //if (answer == null && RequiresQuestionAndAnswer) + //{ + // UpdateFailureCount(username, "passwordAnswer"); + + // throw new ProviderException("Password answer required for password reset."); + //} + + var newPassword = Membership.GeneratePassword(MinRequiredPasswordLength, MinRequiredNonAlphanumericCharacters); + + var args = new ValidatePasswordEventArgs(username, newPassword, true); + OnValidatingPassword(args); + if (args.Cancel) + { + if (args.FailureInformation != null) + throw args.FailureInformation; + throw new MembershipPasswordException("Reset password canceled due to password validation failure."); + } + + var m = Member.GetMemberFromLoginName(username); if (m == null) throw new MembershipPasswordException("The supplied user is not found"); - - if (RequiresQuestionAndAnswer) + + if (RequiresQuestionAndAnswer) { - // check if password answer property alias is set - if (string.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias) == false) + // check if password answer property alias is set + if (string.IsNullOrEmpty(_passwordRetrievalAnswerPropertyTypeAlias) == false) { - // check if user is locked out - if (string.IsNullOrEmpty(_lockPropertyTypeAlias) == false) + // check if user is locked out + if (string.IsNullOrEmpty(LockPropertyTypeAlias) == false) { - var isLockedOut = false; - bool.TryParse(GetMemberProperty(m, _lockPropertyTypeAlias, true), out isLockedOut); - if (isLockedOut) + var isLockedOut = false; + bool.TryParse(GetMemberProperty(m, LockPropertyTypeAlias, true), out isLockedOut); + if (isLockedOut) { - throw new MembershipPasswordException("The supplied user is locked out"); + throw new MembershipPasswordException("The supplied user is locked out"); } } - - // match password answer - if (GetMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, false) != answer) + + // match password answer + if (GetMemberProperty(m, _passwordRetrievalAnswerPropertyTypeAlias, false) != answer) { - throw new MembershipPasswordException("Incorrect password answer"); + throw new MembershipPasswordException("Incorrect password answer"); } } - else - { - throw new ProviderException("Password retrieval answer property alias is not set! To automatically support password question/answers you'll need to add references to the membertype properties in the 'Member' element in web.config by adding their aliases to the 'umbracoPasswordRetrievalQuestionPropertyTypeAlias' and 'umbracoPasswordRetrievalAnswerPropertyTypeAlias' attributes"); - } + else + { + throw new ProviderException("Password retrieval answer property alias is not set! To automatically support password question/answers you'll need to add references to the membertype properties in the 'Member' element in web.config by adding their aliases to the 'umbracoPasswordRetrievalQuestionPropertyTypeAlias' and 'umbracoPasswordRetrievalAnswerPropertyTypeAlias' attributes"); + } } - - string salt; - var encodedPassword = EncryptOrHashNewPassword(newPassword, out salt); - //set the password on the member - m.ChangePassword( + + string salt; + var encodedPassword = EncryptOrHashNewPassword(newPassword, out salt); + //set the password on the member + m.ChangePassword( FormatPasswordForStorage(encodedPassword, salt)); if (string.IsNullOrEmpty(_lastPasswordChangedPropertyTypeAlias) == false) @@ -627,9 +660,9 @@ namespace umbraco.providers.members UpdateMemberProperty(m, _lastPasswordChangedPropertyTypeAlias, DateTime.Now); } - m.Save(); - - return newPassword; + m.Save(); + + return newPassword; } /// @@ -641,18 +674,18 @@ namespace umbraco.providers.members /// public override bool UnlockUser(string userName) { - if (string.IsNullOrEmpty(_lockPropertyTypeAlias) == false) + if (string.IsNullOrEmpty(LockPropertyTypeAlias) == false) { - var m = Member.GetMemberFromLoginName(userName); + var m = Member.GetMemberFromLoginName(userName); if (m != null) { - UpdateMemberProperty(m, _lockPropertyTypeAlias, 0); - m.Save(); + UpdateMemberProperty(m, LockPropertyTypeAlias, 0); + m.Save(); return true; } - throw new Exception(String.Format("No member with the username '{0}' found", userName)); + throw new Exception(String.Format("No member with the username '{0}' found", userName)); } - throw new ProviderException("To enable lock/unlocking, you need to add a 'bool' property on your membertype and add the alias of the property in the 'umbracoLockPropertyTypeAlias' attribute of the membership element in the web.config."); + throw new ProviderException("To enable lock/unlocking, you need to add a 'bool' property on your membertype and add the alias of the property in the 'umbracoLockPropertyTypeAlias' attribute of the membership element in the web.config."); } /// @@ -661,28 +694,28 @@ namespace umbraco.providers.members /// A object that represents the user to update and the updated information for the user. public override void UpdateUser(MembershipUser user) { - var m = Member.GetMemberFromLoginName(user.UserName); + var m = Member.GetMemberFromLoginName(user.UserName); m.Email = user.Email; // if supported, update approve status - UpdateMemberProperty(m, _approvedPropertyTypeAlias, user.IsApproved ? 1 : 0); + UpdateMemberProperty(m, ApprovedPropertyTypeAlias, user.IsApproved ? 1 : 0); // if supported, update lock status - UpdateMemberProperty(m, _lockPropertyTypeAlias, user.IsLockedOut ? 1 : 0); + UpdateMemberProperty(m, LockPropertyTypeAlias, user.IsLockedOut ? 1 : 0); if (user.IsLockedOut) { UpdateMemberProperty(m, _lastLockedOutPropertyTypeAlias, DateTime.Now); - } + } // if supported, update comment - UpdateMemberProperty(m, _commentPropertyTypeAlias, user.Comment); + UpdateMemberProperty(m, CommentPropertyTypeAlias, user.Comment); m.Save(); } private static void UpdateMemberProperty(Member m, string propertyAlias, object propertyValue) { - if (string.IsNullOrEmpty(propertyAlias) == false) + if (string.IsNullOrEmpty(propertyAlias) == false) { if (m.getProperty(propertyAlias) != null) { @@ -693,7 +726,7 @@ namespace umbraco.providers.members private static string GetMemberProperty(Member m, string propertyAlias, bool isBool) { - if (string.IsNullOrEmpty(propertyAlias) == false) + if (string.IsNullOrEmpty(propertyAlias) == false) { if (m.getProperty(propertyAlias) != null && m.getProperty(propertyAlias).Value != null) @@ -709,26 +742,26 @@ namespace umbraco.providers.members return null; } - - private static string GetMemberProperty(IMember m, string propertyAlias, bool isBool) - { - if (string.IsNullOrEmpty(propertyAlias) == false) - { - if (m.Properties[propertyAlias] != null && - m.Properties[propertyAlias].Value != null) - { - if (isBool) - { - // Umbraco stored true as 1, which means it can be bool.tryParse'd - return m.Properties[propertyAlias].Value.ToString().Replace("1", "true").Replace("0", "false"); - } - return m.Properties[propertyAlias].Value.ToString(); - } - } - - return null; - } - + + private static string GetMemberProperty(IMember m, string propertyAlias, bool isBool) + { + if (string.IsNullOrEmpty(propertyAlias) == false) + { + if (m.Properties[propertyAlias] != null && + m.Properties[propertyAlias].Value != null) + { + if (isBool) + { + // Umbraco stored true as 1, which means it can be bool.tryParse'd + return m.Properties[propertyAlias].Value.ToString().Replace("1", "true").Replace("0", "false"); + } + return m.Properties[propertyAlias].Value.ToString(); + } + } + + return null; + } + /// /// Verifies that the specified user name and password exist in the data source. /// @@ -739,16 +772,16 @@ namespace umbraco.providers.members /// public override bool ValidateUser(string username, string password) { - var m = Member.GetMemberFromLoginAndEncodedPassword(username, EncryptOrHashExistingPassword(password)); + var m = Member.GetMemberFromLoginAndEncodedPassword(username, EncryptOrHashExistingPassword(password)); if (m != null) { // check for lock status. If locked, then set the member property to null - if (string.IsNullOrEmpty(_lockPropertyTypeAlias) == false) + if (string.IsNullOrEmpty(LockPropertyTypeAlias) == false) { - string lockedStatus = GetMemberProperty(m, _lockPropertyTypeAlias, true); - if (string.IsNullOrEmpty(lockedStatus) == false) + string lockedStatus = GetMemberProperty(m, LockPropertyTypeAlias, true); + if (string.IsNullOrEmpty(lockedStatus) == false) { - var isLocked = false; + var isLocked = false; if (bool.TryParse(lockedStatus, out isLocked)) { if (isLocked) @@ -759,44 +792,44 @@ namespace umbraco.providers.members } } - // check for approve status. If not approved, then set the member property to null - if (!CheckApproveStatus(m)) { + //check for approve status. If not approved, then set the member property to null + if (m != null && !CheckApproveStatus(m)) { m = null; } // maybe update login date - if (m != null && string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) + if (m != null && string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) { - UpdateMemberProperty(m, _lastLoginPropertyTypeAlias, DateTime.Now); + UpdateMemberProperty(m, _lastLoginPropertyTypeAlias, DateTime.Now); } // maybe reset password attempts - if (m != null && string.IsNullOrEmpty(_failedPasswordAttemptsPropertyTypeAlias) == false) + if (m != null && string.IsNullOrEmpty(_failedPasswordAttemptsPropertyTypeAlias) == false) { - UpdateMemberProperty(m, _failedPasswordAttemptsPropertyTypeAlias, 0); + UpdateMemberProperty(m, _failedPasswordAttemptsPropertyTypeAlias, 0); } // persist data if (m != null) m.Save(); } - else if (string.IsNullOrEmpty(_lockPropertyTypeAlias) == false - && string.IsNullOrEmpty(_failedPasswordAttemptsPropertyTypeAlias) == false) + else if (string.IsNullOrEmpty(LockPropertyTypeAlias) == false + && string.IsNullOrEmpty(_failedPasswordAttemptsPropertyTypeAlias) == false) { - var updateMemberDataObject = Member.GetMemberFromLoginName(username); + var updateMemberDataObject = Member.GetMemberFromLoginName(username); // update fail rate if it's approved if (updateMemberDataObject != null && CheckApproveStatus(updateMemberDataObject)) { int failedAttempts = 0; - int.TryParse(GetMemberProperty(updateMemberDataObject, _failedPasswordAttemptsPropertyTypeAlias, false), out failedAttempts); + int.TryParse(GetMemberProperty(updateMemberDataObject, _failedPasswordAttemptsPropertyTypeAlias, false), out failedAttempts); failedAttempts = failedAttempts+1; - UpdateMemberProperty(updateMemberDataObject, _failedPasswordAttemptsPropertyTypeAlias, failedAttempts); + UpdateMemberProperty(updateMemberDataObject, _failedPasswordAttemptsPropertyTypeAlias, failedAttempts); // lock user? if (failedAttempts >= MaxInvalidPasswordAttempts) { - UpdateMemberProperty(updateMemberDataObject, _lockPropertyTypeAlias, 1); - UpdateMemberProperty(updateMemberDataObject, _lastLockedOutPropertyTypeAlias, DateTime.Now); + UpdateMemberProperty(updateMemberDataObject, LockPropertyTypeAlias, 1); + UpdateMemberProperty(updateMemberDataObject, _lastLockedOutPropertyTypeAlias, DateTime.Now); } updateMemberDataObject.Save(); } @@ -807,13 +840,13 @@ namespace umbraco.providers.members private bool CheckApproveStatus(Member m) { - var isApproved = false; - if (string.IsNullOrEmpty(_approvedPropertyTypeAlias) == false) + var isApproved = false; + if (string.IsNullOrEmpty(ApprovedPropertyTypeAlias) == false) { if (m != null) { - var approveStatus = GetMemberProperty(m, _approvedPropertyTypeAlias, true); - if (string.IsNullOrEmpty(approveStatus) == false) + var approveStatus = GetMemberProperty(m, ApprovedPropertyTypeAlias, true); + if (string.IsNullOrEmpty(approveStatus) == false) { //try parsing as bool first (just in case) if (bool.TryParse(approveStatus, out isApproved) == false) @@ -826,6 +859,11 @@ namespace umbraco.providers.members } } } + else + { + //There is no property so we shouldn't use the approve status + isApproved = true; + } } } else { @@ -837,7 +875,7 @@ namespace umbraco.providers.members #endregion #region Helper Methods - + /// /// Checks the password. /// @@ -852,10 +890,10 @@ namespace umbraco.providers.members switch (PasswordFormat) { case MembershipPasswordFormat.Encrypted: - pass2 = DecodePassword(dbPassword); + pass2 = DecodePassword(dbPassword); break; case MembershipPasswordFormat.Hashed: - pass1 = EncryptOrHashExistingPassword(password); + pass1 = EncryptOrHashExistingPassword(password); break; default: break; @@ -869,10 +907,10 @@ namespace umbraco.providers.members /// /// The password. /// The encoded password. - [Obsolete("Do not use this, it is the legacy way to encode a password")] + [Obsolete("Do not use this, it is the legacy way to encode a password")] public string EncodePassword(string password) { - return LegacyEncodePassword(password); + return LegacyEncodePassword(password); } /// @@ -880,10 +918,10 @@ namespace umbraco.providers.members /// /// The encoded password. /// The unencoded password. - [Obsolete("Do not use this, it is the legacy way to decode a password")] + [Obsolete("Do not use this, it is the legacy way to decode a password")] public string UnEncodePassword(string encodedPassword) { - return LegacyUnEncodePassword(encodedPassword); + return LegacyUnEncodePassword(encodedPassword); } /// @@ -894,130 +932,100 @@ namespace umbraco.providers.members private MembershipUser ConvertToMembershipUser(Member m) { if (m == null) return null; - + var lastLogin = DateTime.Now; - var lastLocked = DateTime.MinValue; - var isApproved = true; - var isLocked = false; - var comment = ""; - var passwordQuestion = ""; - - // last login - if (string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) - { - DateTime.TryParse(GetMemberProperty(m, _lastLoginPropertyTypeAlias, false), out lastLogin); - } - // approved - if (string.IsNullOrEmpty(_approvedPropertyTypeAlias) == false) - { - bool.TryParse(GetMemberProperty(m, _approvedPropertyTypeAlias, true), out isApproved); - } - // locked - if (string.IsNullOrEmpty(_lockPropertyTypeAlias) == false) - { - bool.TryParse(GetMemberProperty(m, _lockPropertyTypeAlias, true), out isLocked); + var lastLocked = DateTime.MinValue; + var isApproved = true; + var isLocked = false; + var comment = ""; + var passwordQuestion = ""; + + // last login + if (string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) + { + DateTime.TryParse(GetMemberProperty(m, _lastLoginPropertyTypeAlias, false), out lastLogin); + } + // approved + if (string.IsNullOrEmpty(ApprovedPropertyTypeAlias) == false) + { + bool.TryParse(GetMemberProperty(m, ApprovedPropertyTypeAlias, true), out isApproved); + } + // locked + if (string.IsNullOrEmpty(LockPropertyTypeAlias) == false) + { + bool.TryParse(GetMemberProperty(m, LockPropertyTypeAlias, true), out isLocked); } // last locked if (string.IsNullOrEmpty(_lastLockedOutPropertyTypeAlias) == false) { DateTime.TryParse(GetMemberProperty(m, _lastLockedOutPropertyTypeAlias, false), out lastLocked); - } - // comment - if (string.IsNullOrEmpty(_commentPropertyTypeAlias) == false) - { - comment = GetMemberProperty(m, _commentPropertyTypeAlias, false); - } - // password question - if (string.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) == false) + } + // comment + if (string.IsNullOrEmpty(CommentPropertyTypeAlias) == false) { - passwordQuestion = GetMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, false); - } + comment = GetMemberProperty(m, CommentPropertyTypeAlias, false); + } + // password question + if (string.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) == false) + { + passwordQuestion = GetMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, false); + } return new MembershipUser(_providerName, m.LoginName, m.Id, m.Email, passwordQuestion, comment, isApproved, isLocked, m.CreateDateTime, lastLogin, - DateTime.Now, DateTime.Now, lastLocked); - } + DateTime.Now, DateTime.Now, lastLocked); + } + + /// + /// Converts to membership user. + /// + /// The m. + /// + private MembershipUser ConvertToMembershipUser(IMember m) + { + if (m == null) return null; - /// - /// Converts to membership user. - /// - /// The m. - /// - private MembershipUser ConvertToMembershipUser(IMember m) - { - if (m == null) return null; - var lastLogin = DateTime.Now; - var lastLocked = DateTime.MinValue; - var isApproved = true; - var isLocked = false; - var comment = ""; - var passwordQuestion = ""; - - // last login - if (string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) - { - DateTime.TryParse(GetMemberProperty(m, _lastLoginPropertyTypeAlias, false), out lastLogin); - } - // approved - if (string.IsNullOrEmpty(_approvedPropertyTypeAlias) == false) - { - bool.TryParse(GetMemberProperty(m, _approvedPropertyTypeAlias, true), out isApproved); - } - // locked - if (string.IsNullOrEmpty(_lockPropertyTypeAlias) == false) - { - bool.TryParse(GetMemberProperty(m, _lockPropertyTypeAlias, true), out isLocked); + var lastLocked = DateTime.MinValue; + var isApproved = true; + var isLocked = false; + var comment = ""; + var passwordQuestion = ""; + + // last login + if (string.IsNullOrEmpty(_lastLoginPropertyTypeAlias) == false) + { + DateTime.TryParse(GetMemberProperty(m, _lastLoginPropertyTypeAlias, false), out lastLogin); + } + // approved + if (string.IsNullOrEmpty(ApprovedPropertyTypeAlias) == false) + { + bool.TryParse(GetMemberProperty(m, ApprovedPropertyTypeAlias, true), out isApproved); + } + // locked + if (string.IsNullOrEmpty(LockPropertyTypeAlias) == false) + { + bool.TryParse(GetMemberProperty(m, LockPropertyTypeAlias, true), out isLocked); } // last locked if (string.IsNullOrEmpty(_lastLockedOutPropertyTypeAlias) == false) { DateTime.TryParse(GetMemberProperty(m, _lastLockedOutPropertyTypeAlias, false), out lastLocked); - } - // comment - if (string.IsNullOrEmpty(_commentPropertyTypeAlias) == false) - { - comment = GetMemberProperty(m, _commentPropertyTypeAlias, false); } - // password question - if (string.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) == false) - { - passwordQuestion = GetMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, false); - } - + // comment + if (string.IsNullOrEmpty(CommentPropertyTypeAlias) == false) + { + comment = GetMemberProperty(m, CommentPropertyTypeAlias, false); + } + // password question + if (string.IsNullOrEmpty(_passwordRetrievalQuestionPropertyTypeAlias) == false) + { + passwordQuestion = GetMemberProperty(m, _passwordRetrievalQuestionPropertyTypeAlias, false); + } + return new MembershipUser(_providerName, m.Username, m.Id, m.Email, passwordQuestion, comment, isApproved, isLocked, m.CreateDate, lastLogin, - DateTime.Now, DateTime.Now, lastLocked); + DateTime.Now, DateTime.Now, lastLocked); } #endregion } - - //TODO: We need to re-enable this in 6.2, but need to back port most of the membership provider changes (still in a custom branch atm) - - ///// - ///// Adds some event handling - ///// - //public class MembershipEventHandler : ApplicationEventHandler - //{ - // protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - // { - // Member.New += Member_New; - // } - - // void Member_New(Member sender, NewEventArgs e) - // { - // //This is a bit of a hack to ensure that the member is approved when created since many people will be using - // // this old api to create members on the front-end and they need to be approved - which is based on whether or not - // // the Umbraco membership provider is configured. - // var provider = Membership.Provider as UmbracoMembershipProvider; - // if (provider != null) - // { - // var approvedField = provider.ApprovedPropertyTypeAlias; - // var property = sender.getProperty(approvedField); - // if (property != null) - // { - // property.Value = 1; - // } - // } - // } - //} } diff --git a/src/umbraco.providers/members/MembershipEventHandler.cs b/src/umbraco.providers/members/MembershipEventHandler.cs new file mode 100644 index 0000000000..71330dd8e0 --- /dev/null +++ b/src/umbraco.providers/members/MembershipEventHandler.cs @@ -0,0 +1,35 @@ +using System.Web.Security; +using Umbraco.Core; +using umbraco.cms.businesslogic; +using umbraco.cms.businesslogic.member; + +namespace umbraco.providers.members +{ + /// + /// Adds some event handling + /// + public class MembershipEventHandler : ApplicationEventHandler + { + protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + Member.New += Member_New; + } + + void Member_New(Member sender, NewEventArgs e) + { + //This is a bit of a hack to ensure that the member is approved when created since many people will be using + // this old api to create members on the front-end and they need to be approved - which is based on whether or not + // the Umbraco membership provider is configured. + var provider = Membership.Provider as UmbracoMembershipProvider; + if (provider != null) + { + var approvedField = provider.ApprovedPropertyTypeAlias; + var property = sender.getProperty(approvedField); + if (property != null) + { + property.Value = 1; + } + } + } + } +} \ No newline at end of file diff --git a/src/umbraco.providers/umbraco.providers.csproj b/src/umbraco.providers/umbraco.providers.csproj index 2a8c4503be..de33276993 100644 --- a/src/umbraco.providers/umbraco.providers.csproj +++ b/src/umbraco.providers/umbraco.providers.csproj @@ -79,6 +79,7 @@ Properties\SolutionInfo.cs +