From 0245efe3cb107d7742e107ab9657f06e225c045b Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 7 Jan 2014 17:01:22 +1100 Subject: [PATCH] Fixes the change password dashboard to work properly. Fixes the EditUser to property save the member and the user. Adds new (probably temporary) MembershipHelper which is used to update a MembershipUser. Updates the User model to ignore the membership properties that we currently cannot persist. Ensures the legacy User membership provider still looks for a typed membership user (which should never have happened). Fixes small issue with underlying membership provider trying to encrypt an empty string. --- src/Umbraco.Core/Models/Membership/User.cs | 58 ++--- .../umbraco/dashboard/ChangePassword.ascx | 10 +- src/Umbraco.Web/Security/MembershipHelper.cs | 59 ++++++ .../UmbracoServiceMembershipProvider.cs | 5 + src/Umbraco.Web/Umbraco.Web.csproj | 12 +- .../umbraco/dashboard/ChangePassword.ascx | 68 ------ .../umbraco/dashboard/ChangePassword.ascx.cs | 199 +++++++++++++++--- .../dashboard/ChangePassword.ascx.designer.cs | 168 --------------- .../umbraco/users/EditUser.aspx.cs | 72 +++---- src/umbraco.businesslogic/User.cs | 16 ++ .../UsersMembershipProvider.cs | 22 +- 11 files changed, 323 insertions(+), 366 deletions(-) create mode 100644 src/Umbraco.Web/Security/MembershipHelper.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.designer.cs diff --git a/src/Umbraco.Core/Models/Membership/User.cs b/src/Umbraco.Core/Models/Membership/User.cs index bd06d0f99d..74bb463746 100644 --- a/src/Umbraco.Core/Models/Membership/User.cs +++ b/src/Umbraco.Core/Models/Membership/User.cs @@ -241,61 +241,27 @@ namespace Umbraco.Core.Models.Membership } } - //TODO: Figure out how to support all of this! + //TODO: Figure out how to support all of this! - we cannot have NotImplementedExceptions because these get used by the IMembershipMemberService service so + // we'll just have them as generic get/set which don't interact with the db. + [IgnoreDataMember] - public string PasswordQuestion - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public string PasswordQuestion { get; set; } [IgnoreDataMember] - public string PasswordAnswer - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public string PasswordAnswer { get; set; } [IgnoreDataMember] - public string Comments - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public string Comments { get; set; } [IgnoreDataMember] - public DateTime CreateDate - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public DateTime CreateDate { get; set; } [IgnoreDataMember] - public DateTime UpdateDate - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public DateTime UpdateDate { get; set; } [IgnoreDataMember] - public DateTime LastLoginDate - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public DateTime LastLoginDate { get; set; } [IgnoreDataMember] - public DateTime LastPasswordChangeDate - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public DateTime LastPasswordChangeDate { get; set; } [IgnoreDataMember] - public DateTime LastLockoutDate - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public DateTime LastLockoutDate { get; set; } [IgnoreDataMember] - public int FailedPasswordAttempts - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } + public int FailedPasswordAttempts { get; set; } #endregion diff --git a/src/Umbraco.Web.UI/umbraco/dashboard/ChangePassword.ascx b/src/Umbraco.Web.UI/umbraco/dashboard/ChangePassword.ascx index c169b273c7..e4d70bff76 100644 --- a/src/Umbraco.Web.UI/umbraco/dashboard/ChangePassword.ascx +++ b/src/Umbraco.Web.UI/umbraco/dashboard/ChangePassword.ascx @@ -12,6 +12,7 @@ goodPass: "success", strongPass: "success", baseStyle: "passtestresult", + minLength: <%=Provider.MinRequiredPasswordLength %>, userid: "<%=umbraco.BusinessLogic.User.GetCurrent().Name%>", messageloc: 1 }); @@ -47,19 +48,24 @@ <%=umbraco.ui.Text("passwordEnterNew") %>: * +
  • <%=umbraco.ui.Text("passwordConfirm") %>: - * <%=umbraco.ui.Text("passwordMismatch") %>
  • - +

    diff --git a/src/Umbraco.Web/Security/MembershipHelper.cs b/src/Umbraco.Web/Security/MembershipHelper.cs new file mode 100644 index 0000000000..c43ef623a5 --- /dev/null +++ b/src/Umbraco.Web/Security/MembershipHelper.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.Security; + +namespace Umbraco.Web.Security +{ + internal class MembershipHelper + { + + public MembershipUser UpdateMember(MembershipUser member, MembershipProvider provider, + string email = null, + bool? isApproved = null, + bool? isLocked = null, + DateTime? lastLoginDate = null, + DateTime? lastActivityDate = null, + string comment = null) + { + //set the writable properties + if (email != null) + { + member.Email = email; + } + if (isApproved.HasValue) + { + member.IsApproved = isApproved.Value; + } + if (lastLoginDate.HasValue) + { + member.LastLoginDate = lastLoginDate.Value; + } + if (lastActivityDate.HasValue) + { + member.LastActivityDate = lastActivityDate.Value; + } + if (comment != null) + { + member.Comment = comment; + } + + if (isLocked.HasValue) + { + //there is no 'setter' on IsLockedOut but you can ctor a new membership user with it set, so i guess that's what we'll do, + // this does mean however if it was a typed membership user object that it will no longer be typed + //membershipUser.IsLockedOut = true; + member = new MembershipUser(member.ProviderName, member.UserName, + member.ProviderUserKey, member.Email, member.PasswordQuestion, member.Comment, member.IsApproved, + isLocked.Value, //new value + member.CreationDate, member.LastLoginDate, member.LastActivityDate, member.LastPasswordChangedDate, member.LastLockoutDate); + } + + provider.UpdateUser(member); + + return member; + } + + } +} diff --git a/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs index e35e8267f0..20e3091d70 100644 --- a/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UmbracoServiceMembershipProvider.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Web.Configuration; using System.Web.Security; +using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence.Querying; @@ -296,6 +297,10 @@ namespace Umbraco.Web.Security.Providers internal string EncryptString(string str) { + if (str.IsNullOrWhiteSpace()) + { + return ""; + } var bytes = Encoding.Unicode.GetBytes(str); var password = new byte[bytes.Length]; Buffer.BlockCopy(bytes, 0, password, 0, bytes.Length); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 658ff1b993..cd2c67c8c8 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -314,6 +314,7 @@ + @@ -413,6 +414,9 @@ ASPXCodeBehind + + ASPXCodeBehind + ASPXCodeBehind @@ -912,13 +916,6 @@ - - ChangePassword.ascx - ASPXCodeBehind - - - ChangePassword.ascx - DesktopMediaUploader.ascx ASPXCodeBehind @@ -1796,7 +1793,6 @@ - diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx deleted file mode 100644 index c169b273c7..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx +++ /dev/null @@ -1,68 +0,0 @@ -<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ChangePassword.ascx.cs" Inherits="umbraco.presentation.umbraco.dashboard.ChangePassword" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - - - -
    -

    <%=umbraco.ui.Text("changePassword") %>

    - Users - -

    <%=umbraco.ui.Text("changePasswordDescription") %>

    - -
    -

    -
    -
    -
      -
    1. - - <%=umbraco.ui.Text("username") %>: - <%=umbraco.BusinessLogic.User.GetCurrent().Name%> - -
    2. -
    3. - - <%=umbraco.ui.Text("passwordCurrent") %>: - - * - -
    4. -
    5. - - <%=umbraco.ui.Text("passwordEnterNew") %>: - - * - -
    6. -
    7. - - <%=umbraco.ui.Text("passwordConfirm") %>: - - * - <%=umbraco.ui.Text("passwordMismatch") %> - -
    8. -
    -

    - -

    -
    - -

    <%=umbraco.ui.Text("passwordChanged") %>!

    -
    -
    diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.cs index 47960ae2b8..f288762cfb 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.cs @@ -11,43 +11,33 @@ namespace umbraco.presentation.umbraco.dashboard { public partial class ChangePassword : System.Web.UI.UserControl { - protected void Page_Load(object sender, EventArgs e) + protected MembershipProvider Provider { + get { return Membership.Providers[UmbracoSettings.DefaultBackofficeProvider]; } + } + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + DataBind(); } protected void changePassword_Click(object sender, EventArgs e) { - User u = User.GetCurrent(); - MembershipProvider provider = Membership.Providers[UmbracoSettings.DefaultBackofficeProvider]; - MembershipUser user = provider.GetUser(u.LoginName, true); + if (Page.IsValid == false) return; + var u = User.GetCurrent(); - string newPass = password.Text; - string oldPass = currentpassword.Text; - if (!string.IsNullOrEmpty(oldPass) && provider.ValidateUser(u.LoginName, oldPass)) + var newPass = password.Text; + var oldPass = currentpassword.Text; + + var success = Provider.ChangePassword(u.LoginName, oldPass, newPass); + if (success) { - if (!string.IsNullOrEmpty(newPass.Trim())) - { - if (newPass == confirmpassword.Text) - { - // make sure password is not empty - user.ChangePassword(u.Password, newPass); - changeForm.Visible = false; - errorPane.Visible = false; - passwordChanged.Visible = true; - } - else - { - errorPane.Visible = true; - errorMessage.Text = ui.Text("passwordIsDifferent"); - } - } - else - { - errorPane.Visible = true; - errorMessage.Text = ui.Text("passwordIsBlank"); - } + changeForm.Visible = false; + errorPane.Visible = false; + passwordChanged.Visible = true; } else { @@ -56,5 +46,158 @@ namespace umbraco.presentation.umbraco.dashboard } } + + /// + /// JsInclude2 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; + + /// + /// changeForm control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel changeForm; + + /// + /// errorPane control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel errorPane; + + /// + /// errorMessage control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal errorMessage; + + /// + /// Label1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label Label1; + + /// + /// Label2 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label Label2; + + /// + /// currentpassword control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox currentpassword; + + /// + /// RequiredFieldValidator1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1; + + /// + /// passwordLabel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label passwordLabel; + + /// + /// password control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox password; + + /// + /// passwordvalidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator passwordvalidator; + + /// + /// confirmpasswordlabel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label confirmpasswordlabel; + + /// + /// confirmpassword control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox confirmpassword; + + /// + /// NewPasswordLengthValidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RegularExpressionValidator NewPasswordLengthValidator; + + /// + /// CompareValidator1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.CompareValidator CompareValidator1; + + /// + /// changePassword control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button changePassword; + + /// + /// passwordChanged control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Panel passwordChanged; } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.designer.cs deleted file mode 100644 index cce2ab1ee8..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/ChangePassword.ascx.designer.cs +++ /dev/null @@ -1,168 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.presentation.umbraco.dashboard { - - - public partial class ChangePassword { - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// changeForm control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel changeForm; - - /// - /// errorPane control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel errorPane; - - /// - /// errorMessage control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal errorMessage; - - /// - /// Label1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label Label1; - - /// - /// Label2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label Label2; - - /// - /// currentpassword control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.TextBox currentpassword; - - /// - /// RequiredFieldValidator1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1; - - /// - /// passwordLabel control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label passwordLabel; - - /// - /// password control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.TextBox password; - - /// - /// passwordvalidator control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.RequiredFieldValidator passwordvalidator; - - /// - /// confirmpasswordlabel control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label confirmpasswordlabel; - - /// - /// confirmpassword control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.TextBox confirmpassword; - - /// - /// confirmpasswordvalidator control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.RequiredFieldValidator confirmpasswordvalidator; - - /// - /// CompareValidator1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.CompareValidator CompareValidator1; - - /// - /// changePassword control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button changePassword; - - /// - /// passwordChanged control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel passwordChanged; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs index fca93d6b0c..07674bca96 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs @@ -12,6 +12,7 @@ using System.Xml; using Umbraco.Core.Logging; using Umbraco.Web; using Umbraco.Web.Models; +using Umbraco.Web.Security; using umbraco.BasePages; using umbraco.BusinessLogic; using umbraco.businesslogic.Exceptions; @@ -490,41 +491,23 @@ namespace umbraco.cms.presentation.user //perform the changing password logic ChangePassword(passwordChangerControl, membershipUser, passwordChangerValidator); - - // Is it using the default membership provider - if (BackOfficeProvider is UsersMembershipProvider) - { - // Save user in membership provider - UsersMembershipUser umbracoUser = membershipUser as UsersMembershipUser; - umbracoUser.FullName = uname.Text.Trim(); - umbracoUser.Language = userLanguage.SelectedValue; - umbracoUser.UserType = UserType.GetUserType(int.Parse(userType.SelectedValue)); - BackOfficeProvider.UpdateUser(umbracoUser); - - // Save user details - u.Email = email.Text.Trim(); - u.Language = userLanguage.SelectedValue; - } - else - { - u.Name = uname.Text.Trim(); - u.Language = userLanguage.SelectedValue; - u.UserType = UserType.GetUserType(int.Parse(userType.SelectedValue)); - //SD: This check must be here for some reason but apparently we don't want to try to - // update when the AD provider is active. - if ((BackOfficeProvider is ActiveDirectoryMembershipProvider) == false) - { - BackOfficeProvider.UpdateUser(membershipUser); - } - } + //update the membership provider + UpdateMembershipProvider(membershipUser); + //update the Umbraco user properties - even though we are updating some of these properties in the membership provider that is + // ok since the membership provider might be storing these details someplace totally different! But we want to keep our UI in sync. + u.Name = uname.Text.Trim(); + u.Language = userLanguage.SelectedValue; + u.UserType = UserType.GetUserType(int.Parse(userType.SelectedValue)); + u.Email = email.Text.Trim(); u.LoginName = lname.Text; - //u.StartNodeId = int.Parse(startNode.Value); - + u.Disabled = Disabled.Checked; + u.DefaultToLiveEditing = DefaultToLiveEditing.Checked; + u.NoConsole = NoConsole.Checked; int startNode; - if (!int.TryParse(contentPicker.Value, out startNode)) + if (int.TryParse(contentPicker.Value, out startNode) == false) { //set to default if nothing is choosen if (u.StartNodeId > 0) @@ -532,17 +515,10 @@ namespace umbraco.cms.presentation.user else startNode = -1; } - u.StartNodeId = startNode; - - - u.Disabled = Disabled.Checked; - u.DefaultToLiveEditing = DefaultToLiveEditing.Checked; - u.NoConsole = NoConsole.Checked; - //u.StartMediaId = int.Parse(mediaStartNode.Value); - - + u.StartNodeId = startNode; + int mstartNode; - if (!int.TryParse(mediaPicker.Value, out mstartNode)) + if (int.TryParse(mediaPicker.Value, out mstartNode) == false) { //set to default if nothing is choosen if (u.StartMediaId > 0) @@ -553,7 +529,6 @@ namespace umbraco.cms.presentation.user u.StartMediaId = mstartNode; u.clearApplications(); - foreach (ListItem li in lapps.Items) { if (li.Selected) u.addApplication(li.Value); @@ -607,6 +582,21 @@ namespace umbraco.cms.presentation.user } } + private void UpdateMembershipProvider(MembershipUser membershipUser) + { + //SD: This check must be here for some reason but apparently we don't want to try to + // update when the AD provider is active. + if ((BackOfficeProvider is ActiveDirectoryMembershipProvider) == false) + { + var membershipHelper = new MembershipHelper(); + //set the writable properties that we are editing + membershipHelper.UpdateMember(membershipUser, BackOfficeProvider, + email.Text.Trim(), + Disabled.Checked == false, + NoConsole.Checked); + } + } + /// /// UserTabs control. /// diff --git a/src/umbraco.businesslogic/User.cs b/src/umbraco.businesslogic/User.cs index 3d0f2f3fe7..365a02e7bb 100644 --- a/src/umbraco.businesslogic/User.cs +++ b/src/umbraco.businesslogic/User.cs @@ -584,6 +584,22 @@ namespace umbraco.BusinessLogic SqlHelper.CreateParameter("@id", id)); } + public static void Update(int id, string name, string lname, string email, bool disabled, bool noConsole, UserType ut) + { + if (!ensureUniqueLoginName(lname, User.GetUser(id))) + throw new Exception(String.Format("A user with the login '{0}' already exists", lname)); + + + SqlHelper.ExecuteNonQuery(@"Update umbracoUser set userName=@name, userLogin=@lname, userEmail=@email, UserType=@type, userDisabled=@disabled, userNoConsole=@noconsole where id = @id", + SqlHelper.CreateParameter("@name", name), + SqlHelper.CreateParameter("@lname", lname), + SqlHelper.CreateParameter("@email", email), + SqlHelper.CreateParameter("@type", ut.Id), + SqlHelper.CreateParameter("@disabled", disabled), + SqlHelper.CreateParameter("@noconsole", noConsole), + SqlHelper.CreateParameter("@id", id)); + } + /// /// Updates the membership provider properties /// diff --git a/src/umbraco.providers/UsersMembershipProvider.cs b/src/umbraco.providers/UsersMembershipProvider.cs index 423a48707b..8a8fd1e212 100644 --- a/src/umbraco.providers/UsersMembershipProvider.cs +++ b/src/umbraco.providers/UsersMembershipProvider.cs @@ -443,11 +443,23 @@ namespace umbraco.providers var m = found.First(); - // update approve status - // update lock status - // TODO: Update last lockout time - // TODO: update comment - User.Update(m.Id, user.Email, user.IsApproved == false, user.IsLockedOut); + + var typedUser = user as UsersMembershipUser; + if (typedUser == null) + { + // update approve status + // update lock status + // TODO: Update last lockout time + // TODO: update comment + User.Update(m.Id, user.Email, user.IsApproved == false, user.IsLockedOut); + } + else + { + //This keeps compatibility - even though this logic to update name and user type should not exist here + User.Update(m.Id, typedUser.FullName.Trim(), typedUser.UserName, typedUser.Email, user.IsApproved == false, user.IsLockedOut, typedUser.UserType); + } + + m.Save(); }