diff --git a/src/Umbraco.Core/Services/IMemberGroupService.cs b/src/Umbraco.Core/Services/IMemberGroupService.cs index e584537ab1..16028ded3f 100644 --- a/src/Umbraco.Core/Services/IMemberGroupService.cs +++ b/src/Umbraco.Core/Services/IMemberGroupService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Umbraco.Cms.Core.Models; diff --git a/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs b/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs index 399da9aec0..0b91237af9 100644 --- a/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs +++ b/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; @@ -13,35 +10,27 @@ namespace Umbraco.Cms.Core.Security /// /// A custom user store that uses Umbraco member data /// - public class MemberRoleStore : RoleStoreBase, string, IdentityUserRole, IdentityRoleClaim> + public class MemberRoleStore : IRoleStore where TRole : IdentityRole { private readonly IMemberGroupService _memberGroupService; + private bool _disposed; - public MemberRoleStore(IMemberGroupService memberGroupService, IdentityErrorDescriber describer) - : base(describer) => _memberGroupService = memberGroupService ?? throw new ArgumentNullException(nameof(memberGroupService)); - - /// - public override IQueryable> Roles + public MemberRoleStore(IMemberGroupService memberGroupService, IdentityErrorDescriber errorDescriber) { - get - { - IEnumerable memberGroups = _memberGroupService.GetAll(); - var identityRoles = new List>(); - foreach (IMemberGroup group in memberGroups) - { - IdentityRole identityRole = MapFromMemberGroup(group); - identityRoles.Add(identityRole); - } - - return identityRoles.AsQueryable(); - } + _memberGroupService = memberGroupService ?? throw new ArgumentNullException(nameof(memberGroupService)); + ErrorDescriber = errorDescriber ?? throw new ArgumentNullException(nameof(errorDescriber)); } + /// + /// Gets or sets the for any error that occurred with the current operation. + /// + public IdentityErrorDescriber ErrorDescriber { get; set; } + /// - public override Task CreateAsync( - IdentityRole role, - CancellationToken cancellationToken = new CancellationToken()) + public Task CreateAsync(TRole role, CancellationToken cancellationToken = new CancellationToken()) { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); @@ -61,9 +50,10 @@ namespace Umbraco.Cms.Core.Security /// - public override Task UpdateAsync(IdentityRole role, - CancellationToken cancellationToken = new CancellationToken()) + public Task UpdateAsync(TRole role, CancellationToken cancellationToken = new CancellationToken()) { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); @@ -93,9 +83,10 @@ namespace Umbraco.Cms.Core.Security } /// - public override Task DeleteAsync(IdentityRole role, - CancellationToken cancellationToken = new CancellationToken()) + public Task DeleteAsync(TRole role, CancellationToken cancellationToken = new CancellationToken()) { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); @@ -122,9 +113,60 @@ namespace Umbraco.Cms.Core.Security } /// - public override Task> FindByIdAsync(string id, - CancellationToken cancellationToken = new CancellationToken()) + + public Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + if (role == null) + { + throw new ArgumentNullException(nameof(role)); + } + + return Task.FromResult(role.Id); + } + + public Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + + if (!int.TryParse(role.Id, out int roleId)) + { + return null; + } + + IMemberGroup memberGroup = _memberGroupService.GetById(roleId); + + return Task.FromResult(memberGroup?.Name); + } + + public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + return null; + } + + public Task GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + return null; + } + + public Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + return null; + } + + /// + public Task FindByIdAsync(string id, CancellationToken cancellationToken = new CancellationToken()) + { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); if (!int.TryParse(id, out int roleId)) { return null; @@ -136,39 +178,34 @@ namespace Umbraco.Cms.Core.Security } /// - public override Task> FindByNameAsync(string normalizedName, - CancellationToken cancellationToken = new CancellationToken()) + public Task FindByNameAsync(string name, CancellationToken cancellationToken = new CancellationToken()) { - IMemberGroup memberGroup = _memberGroupService.GetByName(normalizedName); + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + if (name == null) + { + throw new ArgumentNullException(nameof(name)); + } + IMemberGroup memberGroup = _memberGroupService.GetByName(name); return Task.FromResult(memberGroup == null ? null : MapFromMemberGroup(memberGroup)); } - ///TODO: are we implementing these claims methods? - - /// - public override Task> GetClaimsAsync(IdentityRole role, CancellationToken cancellationToken = new CancellationToken()) => throw new System.NotImplementedException(); - - /// - public override Task AddClaimAsync(IdentityRole role, Claim claim, CancellationToken cancellationToken = new CancellationToken()) => throw new System.NotImplementedException(); - - /// - public override Task RemoveClaimAsync(IdentityRole role, Claim claim, CancellationToken cancellationToken = new CancellationToken()) => throw new System.NotImplementedException(); - /// /// Maps a member group to an identity role /// /// /// - private IdentityRole MapFromMemberGroup(IMemberGroup memberGroup) + private TRole MapFromMemberGroup(IMemberGroup memberGroup) { var result = new IdentityRole { Id = memberGroup.Id.ToString(), Name = memberGroup.Name + //TODO: Are we interested in NormalizedRoleName? }; - return result; + return result as TRole; } /// @@ -177,7 +214,7 @@ namespace Umbraco.Cms.Core.Security /// /// /// - private bool MapToMemberGroup(IdentityRole role, IMemberGroup memberGroup) + private bool MapToMemberGroup(TRole role, IMemberGroup memberGroup) { var anythingChanged = false; @@ -189,5 +226,21 @@ namespace Umbraco.Cms.Core.Security return anythingChanged; } + + public void Dispose() + { + //TODO: is any dispose action necessary here or is this all managed by the IOC container? + } + + /// + /// Throws if this class has been disposed. + /// + protected void ThrowIfDisposed() + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name); + } + } } } diff --git a/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs b/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs index 5e6138980a..1f6d4743be 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/MemberGroupService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; @@ -130,6 +130,25 @@ namespace Umbraco.Cms.Core.Services.Implement } } + + public void GetByRole(IMemberGroup memberGroup) + { + using (var scope = ScopeProvider.CreateScope()) + { + var deleteEventArgs = new DeleteEventArgs(memberGroup); + if (scope.Events.DispatchCancelable(Deleting, this, deleteEventArgs)) + { + scope.Complete(); + return; + } + + _memberGroupRepository.Delete(memberGroup); + scope.Complete(); + deleteEventArgs.CanCancel = false; + scope.Events.Dispatch(Deleted, this, deleteEventArgs); + } + } + /// /// Occurs before Delete of a member group /// diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs index f74b6cef94..ed77c63afc 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberRoleStoreTests.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -7,7 +6,6 @@ using Microsoft.AspNetCore.Identity; using Moq; using NUnit.Framework; using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; @@ -19,19 +17,19 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security private Mock _mockMemberGroupService; private IdentityErrorDescriber ErrorDescriber => new IdentityErrorDescriber(); - public MemberRoleStore CreateSut() + public MemberRoleStore CreateSut() { _mockMemberGroupService = new Mock(); - return new MemberRoleStore( + return new MemberRoleStore( _mockMemberGroupService.Object, ErrorDescriber); } [Test] - public void GivenICreateAMemberRole_AndTheGroupIsNull_ThenIShouldGetAFailedResultAsync() + public void GivenICreateAMemberRole_AndTheGroupIsNull_ThenIShouldGetAnArgumentException() { // arrange - MemberRoleStore sut = CreateSut(); + MemberRoleStore sut = CreateSut(); CancellationToken fakeCancellationToken = new CancellationToken() { }; // act @@ -46,8 +44,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security public async Task GivenICreateAMemberRole_AndTheGroupIsPopulatedCorrectly_ThenIShouldGetASuccessResultAsync() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "777", Name = "testname" @@ -74,8 +72,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security public async Task GivenIUpdateAMemberRole_AndTheGroupExistsWithTheSameName_ThenIShouldGetASuccessResultAsyncButNoUpdatesMade() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "777", Name = "fakeGroupName" @@ -103,8 +101,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security public async Task GivenIUpdateAMemberRole_AndTheGroupExistsWithADifferentSameName_ThenIShouldGetASuccessResultAsyncWithUpdatesMade() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "777", Name = "fakeGroup777" @@ -133,8 +131,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security public async Task GivenIUpdateAMemberRole_AndTheGroupDoesntExist_ThenIShouldGetAFailureResultAsync() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "777", Name = "testname" @@ -157,31 +155,29 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security public async Task GivenIUpdateAMemberRole_AndTheIdCannotBeParsedToAnInt_ThenIShouldGetAFailureResultAsync() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "7a77", Name = "testname" }; var fakeCancellationToken = new CancellationToken() { }; - - bool raiseEvents = false; - - + // act IdentityResult identityResult = await sut.UpdateAsync(fakeRole, fakeCancellationToken); // assert Assert.IsTrue(identityResult.Succeeded == false); Assert.IsTrue(identityResult.Errors.Any(x => x.Code == "DefaultError" && x.Description == "An unknown failure has occurred.")); + _mockMemberGroupService.VerifyNoOtherCalls(); } [Test] public async Task GivenIDeleteAMemberRole_AndItExists_ThenTheMemberGroupShouldBeDeleted_AndIShouldGetASuccessResultAsync() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "777", Name = "testname" @@ -201,14 +197,15 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security Assert.IsTrue(!identityResult.Errors.Any()); _mockMemberGroupService.Verify(x => x.GetById(777)); _mockMemberGroupService.Verify(x => x.Delete(mockMemberGroup)); + _mockMemberGroupService.VerifyNoOtherCalls(); } [Test] public async Task GivenIDeleteAMemberRole_AndTheIdCannotBeParsedToAnInt_ThenTheMemberGroupShouldNotBeDeleted_AndIShouldGetAFailResultAsync() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "7a77", Name = "testname" @@ -225,6 +222,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security // assert Assert.IsTrue(identityResult.Succeeded == false); Assert.IsTrue(identityResult.Errors.Any(x => x.Code == "DefaultError" && x.Description == "An unknown failure has occurred.")); + _mockMemberGroupService.VerifyNoOtherCalls(); } @@ -232,8 +230,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security public async Task GivenIDeleteAMemberRole_AndItDoesntExist_ThenTheMemberGroupShouldNotBeDeleted_AndIShouldGetAFailResultAsync() { // arrange - MemberRoleStore sut = CreateSut(); - var fakeRole = new IdentityRole() + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { Id = "777", Name = "testname" @@ -251,43 +249,142 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security Assert.IsTrue(identityResult.Succeeded == false); Assert.IsTrue(identityResult.Errors.Any(x=>x.Code == "InvalidRoleName" && x.Description == "Role name 'testname' is invalid.")); _mockMemberGroupService.Verify(x => x.GetById(777)); + _mockMemberGroupService.VerifyNoOtherCalls(); } [Test] - public async Task GivenIGetAllMemberRoles_ThenIShouldGetAllMemberGroups_AndASuccessResultAsync() + public async Task GivenIFindAMemberRoleByRoleId_AndRoleIdExists_ThenIShouldGetASuccessResultAsync() { // arrange - MemberRoleStore sut = CreateSut(); + MemberRoleStore sut = CreateSut(); var fakeRole = new IdentityRole("fakeGroupName") { Id = "777" }; - IEnumerable> expected = new List>() + int fakeRoleId = 777; + + IMemberGroup mockMemberGroup = Mock.Of(m => + m.Name == "fakeGroupName" && + m.CreatorId == 123 && + m.Id == 777); + + var fakeCancellationToken = new CancellationToken() { }; + + _mockMemberGroupService.Setup(x => x.GetById(fakeRoleId)).Returns(mockMemberGroup); + + // act + IdentityRole actual = await sut.FindByIdAsync(fakeRole.Id, fakeCancellationToken); + + // assert + Assert.AreEqual(fakeRole.Name, actual.Name); + Assert.AreEqual(fakeRole.Id, actual.Id); + _mockMemberGroupService.Verify(x => x.GetById(fakeRoleId)); + _mockMemberGroupService.VerifyNoOtherCalls(); + } + + [Test] + public void GivenIFindAMemberRoleByRoleId_AndIdCannotBeParsedToAnInt_ThenIShouldGetAFailureResultAsync() + { + // arrange + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole { - fakeRole + Id = "7a77", + Name = "testname" + }; + var fakeCancellationToken = new CancellationToken() { }; + + // act + Task actual = sut.FindByIdAsync(fakeRole.Id, fakeCancellationToken); + + // assert + Assert.IsNull(actual); + _mockMemberGroupService.VerifyNoOtherCalls(); + } + + [Test] + public async Task GivenIFindAMemberRoleByRoleName_AndRoleNameExists_ThenIShouldGetASuccessResultAsync() + { + // arrange + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole("fakeGroupName") + { + Id = "777" }; IMemberGroup mockMemberGroup = Mock.Of(m => - m.Name == "fakeGroupName" && m.CreatorId == 123 && m.Id == 777); + m.Name == "fakeGroupName" && + m.CreatorId == 123 && + m.Id == 777); - IEnumerable fakeMemberGroups = new List() - { - mockMemberGroup - }; - _mockMemberGroupService.Setup(x => x.GetAll()).Returns(fakeMemberGroups); + _mockMemberGroupService.Setup(x => x.GetByName(fakeRole.Name)).Returns(mockMemberGroup); // act - IQueryable> actual = sut.Roles; + IdentityRole actual = await sut.FindByNameAsync(fakeRole.Name); // assert - Assert.AreEqual(expected.AsQueryable().First().Id, actual.First().Id); - Assert.AreEqual(expected.AsQueryable().First().Name, actual.First().Name); - //Always null: - //Assert.AreEqual(expected.AsQueryable().First().NormalizedName, actual.First().NormalizedName); - //Always different: - //Assert.AreEqual(expected.AsQueryable().First().ConcurrencyStamp, actual.First().ConcurrencyStamp); - _mockMemberGroupService.Verify(x => x.GetAll()); + Assert.AreEqual(fakeRole.Name, actual.Name); + Assert.AreEqual(fakeRole.Id, actual.Id); + _mockMemberGroupService.Verify(x => x.GetByName(fakeRole.Name)); + } + + [Test] + public void GivenIFindAMemberRoleByRoleName_AndTheNameIsNull_ThenIShouldGetAnArgumentException() + { + // arrange + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole + { + Id = "777" + }; + var fakeCancellationToken = new CancellationToken() { }; + + // act + Action actual = () => sut.FindByNameAsync(fakeRole.Name, fakeCancellationToken); + + // assert + Assert.That(actual, Throws.ArgumentNullException); + _mockMemberGroupService.VerifyNoOtherCalls(); + + } + + [Test] + public void GivenIGetAMemberRoleId_AndTheRoleIsNull_ThenIShouldGetAnArgumentException() + { + // arrange + MemberRoleStore sut = CreateSut(); + var fakeCancellationToken = new CancellationToken() { }; + + // act + Action actual = () => sut.GetRoleIdAsync(null, fakeCancellationToken); + + // assert + Assert.That(actual, Throws.ArgumentNullException); + } + + [Test] + public void GivenIGetAMemberRoleId_AndTheRoleIsNotNull_ThenIShouldGetTheMemberRole() + { + // arrange + MemberRoleStore sut = CreateSut(); + var fakeRole = new IdentityRole("fakeGroupName") + { + Id = "777" + }; + string fakeRoleId = fakeRole.Id; + + var fakeCancellationToken = new CancellationToken(); + + // act + Task actual = sut.GetRoleIdAsync(fakeRole, fakeCancellationToken); + + // assert + Assert.That(actual, Throws.ArgumentNullException); + + + // assert + Assert.AreEqual(fakeRoleId, actual.Result); } } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj index bcb4022ec7..a85b158810 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj @@ -38,4 +38,10 @@ + + + ..\Umbraco.Web\bin\Debug\Umbraco.Infrastructure.dll + + + diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs index 3ea1d615b8..df76736de9 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MemberGroupController.cs @@ -28,13 +28,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers private readonly IMemberGroupService _memberGroupService; private readonly UmbracoMapper _umbracoMapper; private readonly ILocalizedTextService _localizedTextService; - private readonly RoleManager> _roleManager; + private readonly RoleManager _roleManager; public MemberGroupController( IMemberGroupService memberGroupService, UmbracoMapper umbracoMapper, ILocalizedTextService localizedTextService, - RoleManager> roleManager + RoleManager roleManager ) { _memberGroupService = memberGroupService ?? throw new ArgumentNullException(nameof(memberGroupService)); @@ -105,7 +105,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers foreach (int id in ids) { - Task> role = _roleManager.FindByIdAsync(id.ToString()); + Task role = _roleManager.FindByIdAsync(id.ToString()); roles.Add(role.Result); } diff --git a/src/Umbraco.Web.Common/DependencyInjection/ServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/DependencyInjection/ServiceCollectionExtensions.cs index 39a6b2906d..b123a659c5 100644 --- a/src/Umbraco.Web.Common/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/DependencyInjection/ServiceCollectionExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Web.Caching; using SixLabors.ImageSharp.Web.Commands; @@ -62,12 +63,23 @@ namespace Umbraco.Extensions /// /// Adds the services required for using Members Identity /// - public static void AddMembersIdentity(this IServiceCollection services) => + public static void AddMembersIdentity(this IServiceCollection services) + { services.BuildMembersIdentity() .AddDefaultTokenProviders() + .AddMemberManager() + //.AddRoles() .AddUserStore() - .AddMembersManager(); + .AddRoleStore>() + .AddRoleValidator>() + .AddRoleManager>(); + //services.AddScoped>( + // s => new UserClaimsPrincipalFactory( + // s.GetService(), + // s.GetService>(), + // s.GetService>())); + } private static MemberIdentityBuilder BuildMembersIdentity(this IServiceCollection services) { @@ -75,7 +87,7 @@ namespace Umbraco.Extensions services.TryAddScoped, UserValidator>(); services.TryAddScoped, PasswordValidator>(); services.TryAddScoped, PasswordHasher>(); - return new MemberIdentityBuilder(services); + return new MemberIdentityBuilder(typeof(IdentityRole), services); } private static void RemoveIntParamenterIfValueGreatherThen(IDictionary commands, string parameter, int maxValue) diff --git a/src/Umbraco.Web.Common/Extensions/IdentityBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/IdentityBuilderExtensions.cs index b1c2944565..6940221518 100644 --- a/src/Umbraco.Web.Common/Extensions/IdentityBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/IdentityBuilderExtensions.cs @@ -12,10 +12,10 @@ namespace Umbraco.Extensions /// /// Adds a for the . /// - /// The usermanager interface - /// The usermanager type + /// The member manager interface + /// The member manager type /// The current instance. - public static IdentityBuilder AddMembersManager(this IdentityBuilder identityBuilder) + public static IdentityBuilder AddMemberManager(this IdentityBuilder identityBuilder) where TUserManager : UserManager, TInterface { identityBuilder.Services.AddScoped(typeof(TInterface), typeof(TUserManager)); diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj index 2bcf4a3e55..3dc8575dd7 100644 --- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj +++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj @@ -22,6 +22,7 @@ +