From 99f23a51bc039d4de5d36d821476be73e8536175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 17 Mar 2020 19:30:12 +0300 Subject: [PATCH] Resolved #2977: Should set default roles for new external users --- .../Volo/Abp/Account/AccountAppService.cs | 10 +-- .../Pages/Account/Login.cshtml.cs | 1 + .../Volo/Abp/Identity/IdentityUserManager.cs | 23 +++++ .../Abp/Identity/IdentityUserManager_Tests.cs | 89 ++++++++++++++++++- 4 files changed, 113 insertions(+), 10 deletions(-) diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs index 31de74efde..35d812806f 100644 --- a/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs +++ b/modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs @@ -30,19 +30,11 @@ namespace Volo.Abp.Account (await UserManager.CreateAsync(user, input.Password)).CheckErrors(); await UserManager.SetEmailAsync(user,input.EmailAddress); - - await SetDefaultRolesAsync(user); + await UserManager.AddDefaultRolesAsync(user); return ObjectMapper.Map(user); } - protected virtual async Task SetDefaultRolesAsync(IdentityUser user) - { - var defaultRoles = await _roleRepository.GetDefaultOnesAsync(); - - await UserManager.SetRolesAsync(user, defaultRoles.Select(r => r.Name)); - } - protected virtual async Task CheckSelfRegistrationAsync() { if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled)) diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs index 7857537acb..7d92131eef 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs @@ -212,6 +212,7 @@ namespace Volo.Abp.Account.Web.Pages.Account CheckIdentityErrors(await UserManager.CreateAsync(user)); CheckIdentityErrors(await UserManager.SetEmailAsync(user, emailAddress)); CheckIdentityErrors(await UserManager.AddLoginAsync(user, info)); + CheckIdentityErrors(await UserManager.AddDefaultRolesAsync(user)); return user; } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs index 8723056452..b15d765a0c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Services; using Volo.Abp.Threading; @@ -15,12 +16,17 @@ namespace Volo.Abp.Identity { public class IdentityUserManager : UserManager, IDomainService { + protected IIdentityRoleRepository RoleRepository { get; } + protected IIdentityUserRepository UserRepository { get; } + protected override CancellationToken CancellationToken => _cancellationTokenProvider.Token; private readonly ICancellationTokenProvider _cancellationTokenProvider; public IdentityUserManager( IdentityUserStore store, + IIdentityRoleRepository roleRepository, + IIdentityUserRepository userRepository, IOptions optionsAccessor, IPasswordHasher passwordHasher, IEnumerable> userValidators, @@ -41,6 +47,8 @@ namespace Volo.Abp.Identity services, logger) { + RoleRepository = roleRepository; + UserRepository = userRepository; _cancellationTokenProvider = cancellationTokenProvider; } @@ -76,5 +84,20 @@ namespace Volo.Abp.Identity return IdentityResult.Success; } + + public virtual async Task AddDefaultRolesAsync([NotNull] IdentityUser user) + { + await UserRepository.EnsureCollectionLoadedAsync(user, u => u.Roles, CancellationToken); + + foreach (var role in await RoleRepository.GetDefaultOnesAsync(cancellationToken: CancellationToken)) + { + if (!user.IsInRole(role.Id)) + { + user.AddRole(role.Id); + } + } + + return await UpdateUserAsync(user); + } } } diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs index 761655deb2..32f344a32e 100644 --- a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Shouldly; +using Volo.Abp.Castle.DynamicProxy; using Volo.Abp.Uow; using Xunit; @@ -43,7 +45,9 @@ namespace Volo.Abp.Identity using (var uow = _unitOfWorkManager.Begin()) { var user = await _identityUserRepository.FindByNormalizedUserNameAsync( - _lookupNormalizer.NormalizeName("david")); + _lookupNormalizer.NormalizeName("david") + ); + user.ShouldNotBeNull(); var identityResult = await _identityUserManager.SetRolesAsync(user, new List() @@ -83,5 +87,88 @@ namespace Volo.Abp.Identity await uow.CompleteAsync(); } } + + [Fact] + public async Task AddDefaultRolesAsync_In_Same_Uow() + { + await CreateRandomDefaultRoleAsync(); + + using (var uow = _unitOfWorkManager.Begin()) + { + var user = CreateRandomUser(); + + (await _identityUserManager.CreateAsync(user)).CheckErrors(); + + user.Roles.Count.ShouldBe(0); + + await _identityUserManager.AddDefaultRolesAsync(user); + + user.Roles.Count.ShouldBeGreaterThan(0); + + foreach (var roleId in user.Roles.Select(r => r.RoleId)) + { + var role = await _identityRoleRepository.GetAsync(roleId); + role.IsDefault.ShouldBe(true); + } + + await uow.CompleteAsync(); + } + } + + [Fact] + public async Task AddDefaultRolesAsync_In_Different_Uow() + { + await CreateRandomDefaultRoleAsync(); + + Guid userId; + + using (var uow = _unitOfWorkManager.Begin()) + { + var user = CreateRandomUser(); + userId = user.Id; + + (await _identityUserManager.CreateAsync(user)).CheckErrors(); + user.Roles.Count.ShouldBe(0); + await uow.CompleteAsync(); + } + + using (var uow = _unitOfWorkManager.Begin()) + { + var user = await _identityUserManager.GetByIdAsync(userId); + + await _identityUserManager.AddDefaultRolesAsync(user); + user.Roles.Count.ShouldBeGreaterThan(0); + + foreach (var roleId in user.Roles.Select(r => r.RoleId)) + { + var role = await _identityRoleRepository.GetAsync(roleId); + role.IsDefault.ShouldBe(true); + } + + await uow.CompleteAsync(); + } + } + + private async Task CreateRandomDefaultRoleAsync() + { + await _identityRoleRepository.InsertAsync( + new IdentityRole( + Guid.NewGuid(), + Guid.NewGuid().ToString() + ) + { + IsDefault = true + } + ); + } + + private static IdentityUser CreateRandomUser() + { + return new IdentityUser( + Guid.NewGuid(), + Guid.NewGuid().ToString(), + Guid.NewGuid().ToString() + "@abp.io" + ); + } } }