diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs index 6c2b6d9a3c..c7783cb949 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IOrganizationUnitRepository.cs @@ -32,5 +32,10 @@ namespace Volo.Abp.Identity bool includeDetails = false, CancellationToken cancellationToken = default ); + Task> GetOrganizationUnitRoles( + Guid organizationUnitId, + bool includeDetails = false, + CancellationToken cancellationToken = default + ); } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs index 5ddf1213df..46a5ef341a 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs @@ -39,9 +39,12 @@ namespace Volo.Abp.Identity.EntityFrameworkCore var query = from userRole in DbContext.Set() join role in DbContext.Roles on userRole.RoleId equals role.Id where userRole.UserId == id - select role.Name; - - return await query.ToListAsync(GetCancellationToken(cancellationToken)); + select role.Name; + var organizationUnitIds = DbContext.Set().Where(q => q.UserId == id).Select(q => q.OrganizationUnitId).ToArray(); + var organizationRoleIds = DbContext.Set().Where(our => organizationUnitIds.Contains(our.OrganizationUnitId)).Select(r => r.RoleId).ToArray(); + var orgUnitRoleNameQuery = DbContext.Roles.Where(r => organizationRoleIds.Contains(r.Id)).Select(n => n.Name); + var resultQuery = query.Union(orgUnitRoleNameQuery); + return await resultQuery.ToListAsync(GetCancellationToken(cancellationToken)); } public virtual async Task> GetRoleNamesInOrganizationUnitAsync( diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs index 1f8ecdb045..2de8cb3f52 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs @@ -54,8 +54,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore } public async Task GetOrganizationUnitAsync( - string displayName, - bool includeDetails = false, + string displayName, + bool includeDetails = false, CancellationToken cancellationToken = default) { return await DbSet @@ -64,6 +64,17 @@ namespace Volo.Abp.Identity.EntityFrameworkCore ou => ou.DisplayName == displayName, GetCancellationToken(cancellationToken) ); + } + public async Task> GetOrganizationUnitRoles( + Guid organizationUnitId, bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var query = from organizationRole in DbContext.Set() + join role in DbContext.Roles.IncludeDetails(includeDetails) on organizationRole.RoleId equals role.Id + where organizationRole.OrganizationUnitId == organizationUnitId + select role; + + return await query.ToListAsync(GetCancellationToken(cancellationToken)); } public override IQueryable WithDetails() diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs index 68a57962d9..e6469238ae 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs @@ -39,8 +39,17 @@ namespace Volo.Abp.Identity.MongoDB CancellationToken cancellationToken = default) { var user = await GetAsync(id, cancellationToken: GetCancellationToken(cancellationToken)); + var organizationUnitIds = user.OrganizationUnits + .Select(r => r.OrganizationUnitId) + .ToArray(); + var organizationUnits = DbContext.OrganizationUnits + .AsQueryable() + .Where(ou => organizationUnitIds.Contains(ou.Id)) + .ToArray(); + var orgUnitRoleIds = organizationUnits.SelectMany(x => x.Roles.Select(r => r.RoleId)).ToArray(); var roleIds = user.Roles.Select(r => r.RoleId).ToArray(); - return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)).Select(r => r.Name).ToListAsync(GetCancellationToken(cancellationToken)); + var allRoleIds = orgUnitRoleIds.Union(roleIds); + return await DbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).Select(r => r.Name).ToListAsync(GetCancellationToken(cancellationToken)); } public async Task> GetRoleNamesInOrganizationUnitAsync( @@ -140,8 +149,17 @@ namespace Volo.Abp.Identity.MongoDB CancellationToken cancellationToken = default) { var user = await GetAsync(id, cancellationToken: GetCancellationToken(cancellationToken)); + var organizationUnitIds = user.OrganizationUnits + .Select(r => r.OrganizationUnitId) + .ToArray(); + var organizationUnits = DbContext.OrganizationUnits + .AsQueryable() + .Where(ou => organizationUnitIds.Contains(ou.Id)) + .ToArray(); + var orgUnitRoleIds = organizationUnits.SelectMany(x => x.Roles.Select(r => r.RoleId)).ToArray(); var roleIds = user.Roles.Select(r => r.RoleId).ToArray(); - return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)).ToListAsync(GetCancellationToken(cancellationToken)); + var allRoleIds = orgUnitRoleIds.Union(roleIds); + return await DbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).ToListAsync(GetCancellationToken(cancellationToken)); } public async Task> GetOrganizationUnitsAsync( diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs index b9d3151017..a86bbc1194 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs @@ -59,6 +59,16 @@ namespace Volo.Abp.Identity.MongoDB ou => ou.DisplayName == displayName, GetCancellationToken(cancellationToken) ); - } + } + + public async Task> GetOrganizationUnitRoles( + Guid organizationUnitId, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var organizationUnit = await GetAsync(organizationUnitId, includeDetails, cancellationToken); + var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray(); + return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)).ToListAsync(cancellationToken); + } } } diff --git a/modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs b/modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs index 24807de7b7..a56631b2ae 100644 --- a/modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs @@ -215,9 +215,10 @@ namespace Volo.Abp.Identity //Assert var roleNames = await _userRepository.GetRoleNamesAsync(johnNash.Id); - roleNames.Count.ShouldBe(2); + roleNames.Count.ShouldBe(3); roleNames.ShouldContain("admin"); roleNames.ShouldContain("moderator"); + roleNames.ShouldContain("manager"); } private static string CreateRandomEmail() diff --git a/modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo/Abp/Identity/EntityFrameworkCore/OrganizationUnitRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo/Abp/Identity/EntityFrameworkCore/OrganizationUnitRepository_Tests.cs index 8fa9a14dba..3e8de4f511 100644 --- a/modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo/Abp/Identity/EntityFrameworkCore/OrganizationUnitRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo/Abp/Identity/EntityFrameworkCore/OrganizationUnitRepository_Tests.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Volo.Abp.Identity.EntityFrameworkCore +namespace Volo.Abp.Identity.EntityFrameworkCore { public class OrganizationUnitRepository_Tests : OrganizationUnitRepository_Tests { diff --git a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs index 59964ba28e..7aef8f6c87 100644 --- a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentityUserRepository_Tests.cs @@ -44,9 +44,10 @@ namespace Volo.Abp.Identity { var john = await UserRepository.FindByNormalizedUserNameAsync(LookupNormalizer.NormalizeName("john.nash")); var roles = await UserRepository.GetRoleNamesAsync(john.Id); - roles.Count.ShouldBe(2); + roles.Count.ShouldBe(3); roles.ShouldContain("moderator"); roles.ShouldContain("supporter"); + roles.ShouldContain("manager"); } [Fact] @@ -118,9 +119,10 @@ namespace Volo.Abp.Identity { var john = await UserRepository.FindByNormalizedUserNameAsync(LookupNormalizer.NormalizeName("john.nash")); var roles = await UserRepository.GetRolesAsync(john.Id); - roles.Count.ShouldBe(2); + roles.Count.ShouldBe(3); roles.ShouldContain(r => r.Name == "moderator"); roles.ShouldContain(r => r.Name == "supporter"); + roles.ShouldContain(r => r.Name == "manager"); } [Fact] diff --git a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs index b6b4cf746b..4e35a606b3 100644 --- a/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/OrganizationUnitRepository_Tests.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading.Tasks; using Volo.Abp.Guids; using Volo.Abp.Modularity; +using Volo.Abp.Uow; using Xunit; namespace Volo.Abp.Identity @@ -12,37 +13,43 @@ namespace Volo.Abp.Identity public abstract class OrganizationUnitRepository_Tests : AbpIdentityTestBase where TStartupModule : IAbpModule { - protected IOrganizationUnitRepository OrganizationUnitRepository { get; } - protected ILookupNormalizer LookupNormalizer { get; } + private readonly IOrganizationUnitRepository _organizationUnitRepository; + private readonly ILookupNormalizer _lookupNormalizer; private readonly IdentityTestData _testData; - private readonly IGuidGenerator _guidGenerator; + private readonly IGuidGenerator _guidGenerator; + private readonly OrganizationUnitManager _organizationUnitManager; + private readonly IIdentityRoleRepository _identityRoleRepository; + private readonly IUnitOfWorkManager _unitOfWorkManager; public OrganizationUnitRepository_Tests() { - OrganizationUnitRepository = ServiceProvider.GetRequiredService(); - LookupNormalizer = ServiceProvider.GetRequiredService(); + _organizationUnitRepository = ServiceProvider.GetRequiredService(); + _lookupNormalizer = ServiceProvider.GetRequiredService(); _testData = GetRequiredService(); _guidGenerator = GetRequiredService(); + _organizationUnitManager = GetRequiredService(); + _identityRoleRepository = GetRequiredService(); + _unitOfWorkManager = GetRequiredService(); } [Fact] public async Task GetChildrenAsync() { - (await OrganizationUnitRepository.GetChildrenAsync(_testData.RoleModeratorId)).ShouldNotBeNull(); + (await _organizationUnitRepository.GetChildrenAsync(_testData.RoleModeratorId)).ShouldNotBeNull(); } [Fact] public async Task GetAllChildrenWithParentCodeAsync() { - (await OrganizationUnitRepository.GetAllChildrenWithParentCodeAsync(OrganizationUnit.CreateCode(0), _guidGenerator.Create())).ShouldNotBeNull(); + (await _organizationUnitRepository.GetAllChildrenWithParentCodeAsync(OrganizationUnit.CreateCode(0), _guidGenerator.Create())).ShouldNotBeNull(); } [Fact] public async Task GetListAsync() { - var ouIds = (await OrganizationUnitRepository.GetListAsync(includeDetails: true)) + var ouIds = (await _organizationUnitRepository.GetListAsync(includeDetails: true)) .Select(ou => ou.Id).Take(2); - var ous = await OrganizationUnitRepository.GetListAsync(ouIds); + var ous = await _organizationUnitRepository.GetListAsync(ouIds); ous.Count.ShouldBe(2); ous.ShouldContain(ou => ou.Id == ouIds.First()); } @@ -50,23 +57,33 @@ namespace Volo.Abp.Identity [Fact] public async Task GetOrganizationUnitAsync() { - var organizationUnit = await OrganizationUnitRepository.GetOrganizationUnitAsync("OU111"); + var organizationUnit = await _organizationUnitRepository.GetOrganizationUnitAsync("OU111"); organizationUnit.ShouldNotBeNull(); } [Fact] public async Task GetCountAsync() { - (await OrganizationUnitRepository.GetCountAsync()).ShouldBeGreaterThan(0); + (await _organizationUnitRepository.GetCountAsync()).ShouldBeGreaterThan(0); } [Fact] public async Task Should_Eager_Load_OrganizationUnit_Collections() { - var ou = (await OrganizationUnitRepository.GetListAsync(includeDetails: true)) + var ou = (await _organizationUnitRepository.GetListAsync(includeDetails: true)) .FirstOrDefault(ou => ou.DisplayName == "OU111"); ou.Roles.ShouldNotBeNull(); ou.Roles.Any().ShouldBeTrue(); + } + [Fact] + public async Task GetOrganizationUnitRolesAsync() + { + OrganizationUnit ou = await _organizationUnitRepository.GetOrganizationUnitAsync("OU111", true); + + var ou111Roles = await _organizationUnitRepository.GetOrganizationUnitRoles(ou.Id, true); + ou111Roles.Count.ShouldBe(2); + ou111Roles.ShouldContain(n => n.Name == "manager"); + ou111Roles.ShouldContain(n => n.Name == "moderator"); } } }