diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js index 9f60d300cd..00d2776510 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js @@ -6,6 +6,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.ChangePasswordCont //based on the membership provider cannot always be ported to js from .net directly. /* { + hasPassword: true/false, requiresQuestionAnswer: true/false, enableReset: true/false, minPasswordLength: 10 @@ -13,6 +14,9 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.ChangePasswordCont */ //set defaults if they are not available + if (!$scope.model.config || !$scope.model.config.hasPassword) { + $scope.model.config.hasPassword = false; + } if (!$scope.model.config || !$scope.model.config.requiresQuestionAnswer) { $scope.model.config.requiresQuestionAnswer = false; } @@ -20,15 +24,12 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.ChangePasswordCont $scope.model.config.enableReset = true; } if (!$scope.model.config || !$scope.model.config.minPasswordLength) { - $scope.model.config.minPasswordLength = 7; + $scope.model.config.minPasswordLength = 0; } - $scope.confirm = ""; - $scope.hasPassword = $scope.model.value !== undefined && $scope.model.value !== null && $scope.model.value !== ""; - - $scope.changing = !$scope.hasPassword; + $scope.changing = !$scope.model.config.hasPassword; $scope.doChange = function() { $scope.changing = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.html index c624a81cc2..b15fced660 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.html @@ -1,9 +1,6 @@ 
- -
- Password changing or resetting is currently not supported -
+ Change password
@@ -28,6 +25,6 @@ Passwords must match
- + Cancel
\ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 9784c9e309..3b98328238 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -2167,7 +2167,6 @@ - Web.Template.config Designer diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index a17817ced4..8ac0d6bdc6 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -11,6 +11,8 @@ using System.Web.Security; using AutoMapper; using Examine.LuceneEngine.SearchCriteria; using Examine.SearchCriteria; +using Umbraco.Core; +using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; using Umbraco.Web.WebApi; @@ -21,7 +23,6 @@ using Umbraco.Web.WebApi.Filters; using umbraco; using Constants = Umbraco.Core.Constants; using Examine; -using Member = umbraco.cms.businesslogic.member.Member; namespace Umbraco.Web.Editors { @@ -57,7 +58,7 @@ namespace Umbraco.Web.Editors /// public MemberDisplay GetByKey(Guid key) { - if (Member.InUmbracoMemberMode()) + if (Membership.Provider.Name == Constants.Conventions.Member.UmbracoMemberProviderName) { var foundMember = Services.MemberService.GetByKey(key); if (foundMember == null) @@ -135,7 +136,7 @@ namespace Umbraco.Web.Editors switch (contentItem.Action) { case ContentSaveAction.Save: - //TODO: Update with the provider! - change password, etc... + UpdateWithMembershipProvider(contentItem); break; case ContentSaveAction.SaveNew: MembershipCreateStatus status; @@ -196,6 +197,40 @@ namespace Umbraco.Web.Editors base.MapPropertyValues(contentItem); } + /// + /// Update the membership user using the membership provider (for things like email, etc...) + /// + /// + private void UpdateWithMembershipProvider(MemberSave contentItem) + { + //Get the member from the provider + var membershipUser = Membership.Provider.GetUser(contentItem.PersistedContent.Username, false); + if (membershipUser == null) + { + //This should never happen! so we'll let it YSOD if it does. + throw new InvalidOperationException("Could not get member from membership provider " + Membership.Provider.Name + " with username " + contentItem.PersistedContent.Username); + } + + //ok, first thing to do is check if they've changed their email + //TODO: When we support the other membership provider data then we'll check if any of that's changed too. + if (contentItem.Email.Trim().InvariantEquals(membershipUser.Email)) + { + membershipUser.Email = contentItem.Email.Trim(); + + try + { + Membership.Provider.UpdateUser(membershipUser); + } + catch (Exception ex) + { + LogHelper.WarnWithException("Could not update member, the provider returned an error", ex); + ModelState.AddPropertyError( + //specify 'default' just so that it shows up as a notification - is not assigned to a property + new ValidationResult("Could not update member, the provider returned an error: " + ex.Message + " (see log for full details)"), "default"); + } + } + } + /// /// This is going to create the user with the membership provider and check for validation /// diff --git a/src/Umbraco.Web/Editors/MembershipProviderValidationFilterAttribute.cs b/src/Umbraco.Web/Editors/MembershipProviderValidationFilterAttribute.cs index 8fbd226f0f..71943baea2 100644 --- a/src/Umbraco.Web/Editors/MembershipProviderValidationFilterAttribute.cs +++ b/src/Umbraco.Web/Editors/MembershipProviderValidationFilterAttribute.cs @@ -57,7 +57,7 @@ namespace Umbraco.Web.Editors { //they are changing their login name if (existingByEmail.Cast().Select(x => x.UserName) - .Any(x => x.InvariantEquals(contentItem.Username.Trim()))) + .Any(x => x == contentItem.Username.Trim())) { //the user cannot use this login return false; @@ -67,7 +67,7 @@ namespace Umbraco.Web.Editors case ContentSaveAction.SaveNew: //check if the user's login already exists if (existingByEmail.Cast().Select(x => x.UserName) - .Any(x => x.InvariantEquals(contentItem.Username.Trim()))) + .Any(x => x == contentItem.Username.Trim())) { //the user cannot use this login return false; diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs index 37690321c9..ba9108a73e 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Web.Security; using AutoMapper; using Umbraco.Core; using Umbraco.Core.Models; @@ -66,6 +67,8 @@ namespace Umbraco.Web.Models.Mapping /// private static void MapGenericCustomProperties(IMember member, MemberDisplay display) { + var membershipProvider = Membership.Provider; + TabsAndPropertiesResolver.MapGenericProperties( member, display, new ContentPropertyDisplay @@ -81,7 +84,16 @@ namespace Umbraco.Web.Models.Mapping Alias = string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix), Label = ui.Text("password"), Value = "", - View = "changepassword" //TODO: Hard coding this because the templatepicker doesn't necessarily need to be a resolvable (real) property editor + View = "changepassword",//TODO: Hard coding this because the templatepicker doesn't necessarily need to be a resolvable (real) property editor + Config = new Dictionary + { + //the password change toggle will only be displayed if there is already a password assigned. + { "hasPassword", member.Password.IsNullOrWhiteSpace() == false }, + { "minPasswordLength", membershipProvider.MinRequiredPasswordLength }, + { "enableReset", membershipProvider.EnablePasswordReset }, + { "requiresQuestionAnswer", membershipProvider.RequiresQuestionAndAnswer } + //TODO: Inject the other parameters in here to change the behavior of this control - based on the membership provider settings. + } }, new ContentPropertyDisplay {