diff --git a/src/Umbraco.Core/Security/PasswordSecurity.cs b/src/Umbraco.Core/Security/PasswordSecurity.cs
index b38e125a44..cedceecd3d 100644
--- a/src/Umbraco.Core/Security/PasswordSecurity.cs
+++ b/src/Umbraco.Core/Security/PasswordSecurity.cs
@@ -150,6 +150,10 @@ namespace Umbraco.Core.Security
public bool VerifyPassword(string password, string dbPassword)
{
if (string.IsNullOrWhiteSpace(dbPassword)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(dbPassword));
+
+ if (dbPassword.StartsWith(Constants.Security.EmptyPasswordPrefix))
+ return false;
+
var storedHashedPass = ParseStoredHashPassword(dbPassword, out var salt);
var hashed = HashPassword(password, salt);
return storedHashedPass == hashed;
diff --git a/src/Umbraco.Core/Services/Implement/MemberService.cs b/src/Umbraco.Core/Services/Implement/MemberService.cs
index 0dccca8a64..f29a11cd27 100644
--- a/src/Umbraco.Core/Services/Implement/MemberService.cs
+++ b/src/Umbraco.Core/Services/Implement/MemberService.cs
@@ -1120,77 +1120,6 @@ namespace Umbraco.Core.Services.Implement
#region Membership
- ///
- /// A helper method that will create a basic/generic member for use with a generic membership provider
- ///
- ///
- internal static IMember CreateGenericMembershipProviderMember(string name, string email, string username, string password)
- {
- var identity = int.MaxValue;
-
- var memType = new MemberType(-1);
- var propGroup = new PropertyGroup(MemberType.SupportsPublishingConst)
- {
- Name = "Membership",
- Id = --identity
- };
- propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Ntext, Constants.Conventions.Member.Comments)
- {
- Name = Constants.Conventions.Member.CommentsLabel,
- SortOrder = 0,
- Id = --identity,
- Key = identity.ToGuid()
- });
- propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.Aliases.Boolean, ValueStorageType.Integer, Constants.Conventions.Member.IsApproved)
- {
- Name = Constants.Conventions.Member.IsApprovedLabel,
- SortOrder = 3,
- Id = --identity,
- Key = identity.ToGuid()
- });
- propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.Aliases.Boolean, ValueStorageType.Integer, Constants.Conventions.Member.IsLockedOut)
- {
- Name = Constants.Conventions.Member.IsLockedOutLabel,
- SortOrder = 4,
- Id = --identity,
- Key = identity.ToGuid()
- });
- propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.Aliases.Label, ValueStorageType.Date, Constants.Conventions.Member.LastLockoutDate)
- {
- Name = Constants.Conventions.Member.LastLockoutDateLabel,
- SortOrder = 5,
- Id = --identity,
- Key = identity.ToGuid()
- });
- propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.Aliases.Label, ValueStorageType.Date, Constants.Conventions.Member.LastLoginDate)
- {
- Name = Constants.Conventions.Member.LastLoginDateLabel,
- SortOrder = 6,
- Id = --identity,
- Key = identity.ToGuid()
- });
- propGroup.PropertyTypes.Add(new PropertyType(Constants.PropertyEditors.Aliases.Label, ValueStorageType.Date, Constants.Conventions.Member.LastPasswordChangeDate)
- {
- Name = Constants.Conventions.Member.LastPasswordChangeDateLabel,
- SortOrder = 7,
- Id = --identity,
- Key = identity.ToGuid()
- });
-
- memType.PropertyGroups.Add(propGroup);
-
- // should we "create member"?
- var member = new Member(name, email, username, password, memType);
-
- //we've assigned ids to the property types and groups but we also need to assign fake ids to the properties themselves.
- foreach (var property in member.Properties)
- {
- property.Id = --identity;
- }
-
- return member;
- }
-
///
/// Exports a member.
///
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/users/changepassword.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/users/changepassword.directive.js
index 2dd319142b..0512abe579 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/users/changepassword.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/users/changepassword.directive.js
@@ -80,11 +80,7 @@
}));
unsubscribe.push($scope.$on("formSubmitting", function () {
- //if there was a previously generated password displaying, clear it
- if (vm.changing && vm.passwordValues) {
- vm.passwordValues.generatedPassword = null;
- }
- else if (!vm.changing) {
+ if (!vm.changing) {
//we are not changing, so the model needs to be null
vm.passwordValues = null;
}
@@ -105,8 +101,6 @@
function doChange() {
resetModel();
vm.changing = true;
- //if there was a previously generated password displaying, clear it
- vm.passwordValues.generatedPassword = null;
vm.passwordValues.confirm = null;
};
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
index a03a71febe..825b4d1d44 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
@@ -41,7 +41,7 @@
if (!model) {
return null;
}
- var trimmed = _.omit(model, ["confirm", "generatedPassword"]);
+ var trimmed = _.omit(model, ["confirm"]);
//ensure that the pass value is null if all child properties are null
var allNull = true;
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/user/user.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/user/user.controller.js
index 5e19235dce..060ef77a5d 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/user/user.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/user/user.controller.js
@@ -141,11 +141,6 @@ angular.module("umbraco")
//reset old data
clearPasswordFields();
- //if the password has been reset, then update our model
- if (data.value) {
- $scope.changePasswordModel.value.generatedPassword = data.value;
- }
-
formHelper.resetForm({ scope: $scope });
$scope.changePasswordButtonState = "success";
diff --git a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs
index 8cc34896ba..33e37adb2b 100644
--- a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs
+++ b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs
@@ -2,17 +2,12 @@
using System.Collections.Generic;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
-using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Models;
-using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using System.Linq;
-using Umbraco.Core.Models.Membership;
-using Umbraco.Core.Services.Implement;
using Umbraco.Web.Composing;
-using Umbraco.Web.Security;
namespace Umbraco.Web.Editors.Binders
{
diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs
index 18450f41ae..fe490e8699 100644
--- a/src/Umbraco.Web/Editors/ContentController.cs
+++ b/src/Umbraco.Web/Editors/ContentController.cs
@@ -8,7 +8,6 @@ using System.Text;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
-using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
diff --git a/src/Umbraco.Web/Editors/Filters/MemberSaveModelValidator.cs b/src/Umbraco.Web/Editors/Filters/MemberSaveModelValidator.cs
index f837253b4b..5b3aa3d7ee 100644
--- a/src/Umbraco.Web/Editors/Filters/MemberSaveModelValidator.cs
+++ b/src/Umbraco.Web/Editors/Filters/MemberSaveModelValidator.cs
@@ -5,7 +5,6 @@ using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
-using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -21,11 +20,13 @@ namespace Umbraco.Web.Editors.Filters
internal class MemberSaveModelValidator : ContentModelValidator>
{
private readonly IMemberTypeService _memberTypeService;
+ private readonly IMemberService _memberService;
- public MemberSaveModelValidator(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService)
+ public MemberSaveModelValidator(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService, IMemberService memberService)
: base(logger, umbracoContextAccessor)
{
_memberTypeService = memberTypeService;
+ _memberService = memberService;
}
///
@@ -55,7 +56,7 @@ namespace Umbraco.Web.Editors.Filters
//default provider!
var membershipProvider = MembershipProviderExtensions.GetMembersMembershipProvider();
- var validEmail = ValidateUniqueEmail(model, membershipProvider);
+ var validEmail = ValidateUniqueEmail(model);
if (validEmail == false)
{
modelState.AddPropertyError(
@@ -63,7 +64,7 @@ namespace Umbraco.Web.Editors.Filters
$"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}email");
}
- var validLogin = ValidateUniqueLogin(model, membershipProvider);
+ var validLogin = ValidateUniqueLogin(model);
if (validLogin == false)
{
modelState.AddPropertyError(
@@ -121,13 +122,11 @@ namespace Umbraco.Web.Editors.Filters
return ValidateProperties(propertiesToValidate, model.PersistedContent.Properties.ToList(), actionContext);
}
- internal bool ValidateUniqueLogin(MemberSave model, MembershipProvider membershipProvider)
+ internal bool ValidateUniqueLogin(MemberSave model)
{
if (model == null) throw new ArgumentNullException(nameof(model));
- if (membershipProvider == null) throw new ArgumentNullException(nameof(membershipProvider));
-
- int totalRecs;
- var existingByName = membershipProvider.FindUsersByName(model.Username.Trim(), 0, int.MaxValue, out totalRecs);
+
+ var existingByName = _memberService.GetByUsername(model.Username.Trim());
switch (model.Action)
{
case ContentSaveAction.Save:
@@ -136,8 +135,7 @@ namespace Umbraco.Web.Editors.Filters
if (model.PersistedContent.Username.InvariantEquals(model.Username.Trim()) == false)
{
//they are changing their login name
- if (existingByName.Cast().Select(x => x.UserName)
- .Any(x => x == model.Username.Trim()))
+ if (existingByName != null && existingByName.Username == model.Username.Trim())
{
//the user cannot use this login
return false;
@@ -146,8 +144,7 @@ namespace Umbraco.Web.Editors.Filters
break;
case ContentSaveAction.SaveNew:
//check if the user's login already exists
- if (existingByName.Cast().Select(x => x.UserName)
- .Any(x => x == model.Username.Trim()))
+ if (existingByName != null && existingByName.Username == model.Username.Trim())
{
//the user cannot use this login
return false;
@@ -161,18 +158,11 @@ namespace Umbraco.Web.Editors.Filters
return true;
}
- internal bool ValidateUniqueEmail(MemberSave model, MembershipProvider membershipProvider)
+ internal bool ValidateUniqueEmail(MemberSave model)
{
if (model == null) throw new ArgumentNullException(nameof(model));
- if (membershipProvider == null) throw new ArgumentNullException(nameof(membershipProvider));
- if (membershipProvider.RequiresUniqueEmail == false)
- {
- return true;
- }
-
- int totalRecs;
- var existingByEmail = membershipProvider.FindUsersByEmail(model.Email.Trim(), 0, int.MaxValue, out totalRecs);
+ var existingByEmail = _memberService.GetByEmail(model.Email.Trim());
switch (model.Action)
{
case ContentSaveAction.Save:
@@ -180,8 +170,7 @@ namespace Umbraco.Web.Editors.Filters
if (model.PersistedContent.Email.InvariantEquals(model.Email.Trim()) == false)
{
//they are changing their email
- if (existingByEmail.Cast().Select(x => x.Email)
- .Any(x => x.InvariantEquals(model.Email.Trim())))
+ if (existingByEmail != null && existingByEmail.Email.InvariantEquals(model.Email.Trim()))
{
//the user cannot use this email
return false;
@@ -190,8 +179,7 @@ namespace Umbraco.Web.Editors.Filters
break;
case ContentSaveAction.SaveNew:
//check if the user's email already exists
- if (existingByEmail.Cast().Select(x => x.Email)
- .Any(x => x.InvariantEquals(model.Email.Trim())))
+ if (existingByEmail != null && existingByEmail.Email.InvariantEquals(model.Email.Trim()))
{
//the user cannot use this email
return false;
diff --git a/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs b/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs
index 04b0112d56..14b48e8219 100644
--- a/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs
+++ b/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs
@@ -15,22 +15,24 @@ namespace Umbraco.Web.Editors.Filters
private readonly ILogger _logger;
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IMemberTypeService _memberTypeService;
+ private readonly IMemberService _memberService;
public MemberSaveValidationAttribute()
- : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.MemberTypeService)
+ : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.MemberTypeService, Current.Services.MemberService)
{ }
- public MemberSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService)
+ public MemberSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService, IMemberService memberService)
{
_logger = logger;
_umbracoContextAccessor = umbracoContextAccessor;
_memberTypeService = memberTypeService;
+ _memberService = memberService;
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
var model = (MemberSave)actionContext.ActionArguments["contentItem"];
- var contentItemValidator = new MemberSaveModelValidator(_logger, _umbracoContextAccessor, _memberTypeService);
+ var contentItemValidator = new MemberSaveModelValidator(_logger, _umbracoContextAccessor, _memberTypeService, _memberService);
//now do each validation step
if (contentItemValidator.ValidateExistingContent(model, actionContext))
if (contentItemValidator.ValidateProperties(model, model, actionContext))
diff --git a/src/Umbraco.Web/Editors/MemberGroupController.cs b/src/Umbraco.Web/Editors/MemberGroupController.cs
index 89041fb512..d06c45aad6 100644
--- a/src/Umbraco.Web/Editors/MemberGroupController.cs
+++ b/src/Umbraco.Web/Editors/MemberGroupController.cs
@@ -3,14 +3,10 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
-using System.Web.Security;
-using Umbraco.Core;
using Umbraco.Core.Models;
-using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
-using Umbraco.Web.Security;
using Umbraco.Web.WebApi.Filters;
using Constants = Umbraco.Core.Constants;
diff --git a/src/Umbraco.Web/Editors/MemberTypeController.cs b/src/Umbraco.Web/Editors/MemberTypeController.cs
index 9600b96f92..fd34eaf300 100644
--- a/src/Umbraco.Web/Editors/MemberTypeController.cs
+++ b/src/Umbraco.Web/Editors/MemberTypeController.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
-using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
@@ -12,11 +11,9 @@ using Umbraco.Core.Dictionary;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
-using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
-using Umbraco.Web.Security;
using Umbraco.Web.WebApi.Filters;
using Constants = Umbraco.Core.Constants;
diff --git a/src/Umbraco.Web/Editors/PasswordChanger.cs b/src/Umbraco.Web/Editors/PasswordChanger.cs
index c16a743dd7..6b4227557b 100644
--- a/src/Umbraco.Web/Editors/PasswordChanger.cs
+++ b/src/Umbraco.Web/Editors/PasswordChanger.cs
@@ -1,9 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
-using System.Web.Security;
using Umbraco.Core;
-using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Identity;
@@ -111,62 +109,6 @@ namespace Umbraco.Web.Editors
return passwordSecurity.HashPasswordForStorage(passwordModel.NewPassword);
}
- ///
- /// Changes password for a member/user given the membership provider and the password change model
- ///
- /// The username of the user having their password changed
- ///
- ///
- ///
- public Attempt 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));
- var userId = -1;
-
-
- //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" }) });
- }
-
- if (membershipProvider.EnablePasswordRetrieval)
- {
- return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Membership providers using encrypted passwords and password retrieval are not supported", new[] { "value" }) });
- }
-
- //without being able to retrieve the original password
- if (passwordModel.OldPassword.IsNullOrWhiteSpace())
- {
- //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 an old password is supplied 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[] { "oldPassword" }) })
- : Attempt.Succeed(new PasswordChangedModel());
- }
- catch (Exception ex)
- {
- _logger.Warn(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" }) });
- }
-
- }
+
}
}
diff --git a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs
index 98f958c844..9bdade968c 100644
--- a/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs
+++ b/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs
@@ -4,7 +4,6 @@ using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
-using System.Web.Security;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Composing;
@@ -14,7 +13,6 @@ using Umbraco.Core.Models.Identity;
using Umbraco.Core.Services;
using Umbraco.Web.Install.Models;
using Umbraco.Web.Security;
-using System.Web;
namespace Umbraco.Web.Install.InstallSteps
{
diff --git a/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs
index 435d349aa3..9b17ac9d70 100644
--- a/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs
+++ b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
@@ -32,43 +31,11 @@ namespace Umbraco.Web.Models.Mapping
public void DefineMaps(UmbracoMapper mapper)
{
- mapper.Define((source, context) => new MemberDisplay(), Map);
- mapper.Define((source, context) => MemberService.CreateGenericMembershipProviderMember(source.UserName, source.Email, source.UserName, ""), Map);
mapper.Define((source, context) => new MemberDisplay(), Map);
mapper.Define((source, context) => new MemberBasic(), Map);
- mapper.Define((source, context) => new MemberBasic(), Map);
mapper.Define((source, context) => new MemberGroupDisplay(), Map);
mapper.Define((source, context) => new ContentPropertyCollectionDto(), Map);
- }
-
- private void Map(MembershipUser source, MemberDisplay target, MapperContext context)
- {
- //first convert to IMember
- var member = context.Map(source);
- //then convert to MemberDisplay
- context.Map(member);
- }
-
- // TODO: SD: I can't remember why this mapping is here?
- // Umbraco.Code.MapAll -Properties -CreatorId -Level -Name -CultureInfos -ParentId
- // Umbraco.Code.MapAll -Path -SortOrder -DeleteDate -WriterId -VersionId -PasswordQuestion
- // Umbraco.Code.MapAll -RawPasswordAnswerValue -FailedPasswordAttempts
- private void Map(MembershipUser source, IMember target, MapperContext context)
- {
- target.Comments = source.Comment;
- target.CreateDate = source.CreationDate;
- target.Email = source.Email;
- target.Id = int.MaxValue;
- target.IsApproved = source.IsApproved;
- target.IsLockedOut = source.IsLockedOut;
- target.Key = source.ProviderUserKey.TryConvertTo().Result;
- target.LastLockoutDate = source.LastLockoutDate;
- target.LastLoginDate = source.LastLoginDate;
- target.LastPasswordChangeDate = source.LastPasswordChangedDate;
- target.RawPasswordValue = source.CreationDate > DateTime.MinValue ? Guid.NewGuid().ToString("N") : "";
- target.UpdateDate = source.LastActivityDate;
- target.Username = source.UserName;
- }
+ }
// Umbraco.Code.MapAll -Properties -Errors -Edited -Updater -Alias -IsChildOfListView
// Umbraco.Code.MapAll -Trashed -IsContainer -VariesByCulture
@@ -118,23 +85,6 @@ namespace Umbraco.Web.Models.Mapping
target.Username = source.Username;
}
- //TODO: SD: I can't remember why this mapping is here?
- // Umbraco.Code.MapAll -Udi -Properties -ParentId -Path -SortOrder -Edited -Updater
- // Umbraco.Code.MapAll -Trashed -Alias -ContentTypeId -ContentTypeAlias -VariesByCulture
- private void Map(MembershipUser source, MemberBasic target, MapperContext context)
- {
- target.CreateDate = source.CreationDate;
- target.Email = source.Email;
- target.Icon = Constants.Icons.Member;
- target.Id = int.MaxValue;
- target.Key = source.ProviderUserKey.TryConvertTo().Result;
- target.Name = source.UserName;
- target.Owner = new UserProfile { Name = "Admin", UserId = -1 };
- target.State = ContentSavedState.Draft;
- target.UpdateDate = source.LastActivityDate;
- target.Username = source.UserName;
-}
-
// Umbraco.Code.MapAll -Icon -Trashed -ParentId -Alias
private void Map(IMemberGroup source, MemberGroupDisplay target, MapperContext context)
{
diff --git a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs
index 67694d3ea8..1a52816d14 100644
--- a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Mapping;
using Umbraco.Core.Composing;
@@ -29,15 +28,17 @@ namespace Umbraco.Web.Models.Mapping
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly ILocalizedTextService _localizedTextService;
private readonly IMemberTypeService _memberTypeService;
- private readonly IUserService _userService;
+ private readonly IMemberService _memberService;
+ private readonly IMemberGroupService _memberGroupService;
- public MemberTabsAndPropertiesMapper(ICultureDictionary cultureDictionary, IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IUserService userService, IMemberTypeService memberTypeService)
+ public MemberTabsAndPropertiesMapper(ICultureDictionary cultureDictionary, IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IMemberTypeService memberTypeService, IMemberService memberService, IMemberGroupService memberGroupService)
: base(cultureDictionary, localizedTextService)
{
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
_localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService));
- _userService = userService ?? throw new ArgumentNullException(nameof(userService));
_memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService));
+ _memberService = memberService ?? throw new ArgumentNullException(nameof(memberService));
+ _memberGroupService = memberGroupService ?? throw new ArgumentNullException(nameof(memberGroupService));
}
///
@@ -127,12 +128,10 @@ namespace Umbraco.Web.Models.Mapping
{
Alias = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}password",
Label = _localizedTextService.Localize("password"),
- // NOTE: The value here is a json value - but the only property we care about is the generatedPassword one if it exists, the newPassword exists
- // only when creating a new member and we want to have a generated password pre-filled.
+
Value = new Dictionary
{
- // TODO: why ignoreCase, what are we doing here?!
- {"generatedPassword", member.GetAdditionalDataValueIgnoreCase("GeneratedPassword", null)},
+ // TODO: why ignoreCase, what are we doing here?!
{"newPassword", member.GetAdditionalDataValueIgnoreCase("NewPassword", null)},
},
// TODO: Hard coding this because the changepassword doesn't necessarily need to be a resolvable (real) property editor
@@ -231,12 +230,13 @@ namespace Umbraco.Web.Models.Mapping
return prop;
}
- internal static IDictionary GetMemberGroupValue(string username)
+ internal IDictionary GetMemberGroupValue(string username)
{
- var userRoles = username.IsNullOrWhiteSpace() ? null : Roles.GetRolesForUser(username);
+ var userRoles = username.IsNullOrWhiteSpace() ? null : _memberService.GetAllRoles(username);
// create a dictionary of all roles (except internal roles) + "false"
- var result = Roles.GetAllRoles().Distinct()
+ var result = _memberGroupService.GetAll()
+ .Select(x => x.Name)
// if a role starts with __umbracoRole we won't show it as it's an internal role used for public access
.Where(x => x.StartsWith(Constants.Conventions.Member.InternalRolePrefix) == false)
.OrderBy(x => x, StringComparer.OrdinalIgnoreCase)
diff --git a/src/Umbraco.Web/Routing/PublishedRouter.cs b/src/Umbraco.Web/Routing/PublishedRouter.cs
index 91fc903ba8..30076ee2b0 100644
--- a/src/Umbraco.Web/Routing/PublishedRouter.cs
+++ b/src/Umbraco.Web/Routing/PublishedRouter.cs
@@ -1,15 +1,11 @@
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Globalization;
using System.IO;
-using System.Web.Security;
using Umbraco.Core;
-using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
-using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
diff --git a/src/Umbraco.Web/Security/BackOfficeUserManager.cs b/src/Umbraco.Web/Security/BackOfficeUserManager.cs
index 4476edbd10..cca08318f4 100644
--- a/src/Umbraco.Web/Security/BackOfficeUserManager.cs
+++ b/src/Umbraco.Web/Security/BackOfficeUserManager.cs
@@ -1,9 +1,7 @@
using System;
-using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
-using System.Web.Security;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security.DataProtection;
diff --git a/src/Umbraco.Web/Security/MembershipHelper.cs b/src/Umbraco.Web/Security/MembershipHelper.cs
index da6e846020..c9a507494c 100644
--- a/src/Umbraco.Web/Security/MembershipHelper.cs
+++ b/src/Umbraco.Web/Security/MembershipHelper.cs
@@ -16,6 +16,7 @@ using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
using Umbraco.Web.Editors;
using Umbraco.Web.Security.Providers;
+using System.ComponentModel.DataAnnotations;
namespace Umbraco.Web.Security
{
@@ -643,7 +644,7 @@ namespace Umbraco.Web.Security
public virtual Attempt ChangePassword(string username, ChangingPasswordModel passwordModel, MembershipProvider membershipProvider)
{
var passwordChanger = new PasswordChanger(_logger);
- return passwordChanger.ChangePasswordWithMembershipProvider(username, passwordModel, membershipProvider);
+ return ChangePasswordWithMembershipProvider(username, passwordModel, membershipProvider);
}
///
@@ -732,5 +733,63 @@ namespace Umbraco.Web.Security
return sb.ToString();
}
+ ///
+ /// Changes password for a member/user given the membership provider and the password change model
+ ///
+ /// The username of the user having their password changed
+ ///
+ ///
+ ///
+ private Attempt 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));
+ var userId = -1;
+
+
+ //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" }) });
+ }
+
+ if (membershipProvider.EnablePasswordRetrieval)
+ {
+ return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Membership providers using encrypted passwords and password retrieval are not supported", new[] { "value" }) });
+ }
+
+ //without being able to retrieve the original password
+ if (passwordModel.OldPassword.IsNullOrWhiteSpace())
+ {
+ //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 an old password is supplied 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[] { "oldPassword" }) })
+ : Attempt.Succeed(new PasswordChangedModel());
+ }
+ catch (Exception ex)
+ {
+ _logger.Warn(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" }) });
+ }
+
+ }
+
}
}
diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs
index 7c97873a2c..84909d5fda 100644
--- a/src/Umbraco.Web/Trees/MemberTreeController.cs
+++ b/src/Umbraco.Web/Trees/MemberTreeController.cs
@@ -6,7 +6,6 @@ using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Http.ModelBinding;
-using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
@@ -37,11 +36,9 @@ namespace Umbraco.Web.Trees
public MemberTreeController(UmbracoTreeSearcher treeSearcher)
{
_treeSearcher = treeSearcher;
- _provider = MembershipProviderExtensions.GetMembersMembershipProvider();
}
private readonly UmbracoTreeSearcher _treeSearcher;
- private readonly MembershipProvider _provider;
///
/// Gets an individual tree node