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 0a91959f86..75ff06afe9 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 @@ -61,7 +61,7 @@ public class EfCoreIdentityUserRepository : EfCoreRepository() + var userRoles = await (from userRole in dbContext.Set() join role in dbContext.Roles on userRole.RoleId equals role.Id where userIds.Contains(userRole.UserId) group new @@ -73,7 +73,24 @@ public class EfCoreIdentityUserRepository : EfCoreRepository x.Name).ToArray() - }).ToListAsync(GetCancellationToken(cancellationToken)); + }).ToListAsync(cancellationToken: cancellationToken); + + var orgUnitRoles = await (from userOu in dbContext.Set() + join roleOu in dbContext.Set() on userOu.OrganizationUnitId equals roleOu.OrganizationUnitId + join role in dbContext.Roles on roleOu.RoleId equals role.Id + where userIds.Contains(userOu.UserId) + group new + { + userOu.UserId, + role.Name + } by userOu.UserId + into gp + select new IdentityUserIdWithRoleNames + { + Id = gp.Key, RoleNames = gp.Select(x => x.Name).ToArray() + }).ToListAsync(cancellationToken: cancellationToken); + + return userRoles.Concat(orgUnitRoles).GroupBy(x => x.Id).Select(x => new IdentityUserIdWithRoleNames {Id = x.Key, RoleNames = x.SelectMany(y => y.RoleNames).Distinct().ToArray()}).ToList(); } public virtual async Task> GetRoleNamesInOrganizationUnitAsync( 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 935367c5c3..f93586ed79 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 @@ -377,26 +377,47 @@ public class MongoIdentityUserRepository : MongoDbRepository userIds, CancellationToken cancellationToken = default) { - cancellationToken = GetCancellationToken(cancellationToken); - - var userAndRoleIds = (await GetMongoQueryableAsync(cancellationToken)) - .Where(u => userIds.Contains(u.Id)) - .SelectMany(u => u.Roles) - .Select(userRole => new - { - userRole.UserId, - userRole.RoleId - }).GroupBy(x => x.UserId).ToDictionary(x => x.Key, x => x.Select(r => r.RoleId).ToList()); - + var users = await GetListByIdsAsync(userIds, cancellationToken: cancellationToken); + + var userAndRoleIds = users.SelectMany(u => u.Roles) + .Select(userRole => new { userRole.UserId, userRole.RoleId }) + .GroupBy(x => x.UserId).ToDictionary(x => x.Key, x => x.Select(r => r.RoleId).ToList()); + var userAndOrganizationUnitIds = users.SelectMany(u => u.OrganizationUnits) + .Select(userOrganizationUnit => new { userOrganizationUnit.UserId, userOrganizationUnit.OrganizationUnitId }) + .GroupBy(x => x.UserId).ToDictionary(x => x.Key, x => x.Select(r => r.OrganizationUnitId).ToList()); + + var organizationUnitIds = userAndOrganizationUnitIds.SelectMany(x => x.Value); var roleIds = userAndRoleIds.SelectMany(x => x.Value); - var roles = await (await GetMongoQueryableAsync(cancellationToken)).Where(r => roleIds.Contains(r.Id)).Select(r => new + + var organizationUnitAndRoleIds = await (await GetMongoQueryableAsync(cancellationToken)).Where(ou => organizationUnitIds.Contains(ou.Id)) + .Select(userOrganizationUnit => new + { + userOrganizationUnit.Id, + userOrganizationUnit.Roles + }).ToListAsync(cancellationToken: cancellationToken); + var allOrganizationUnitRoleIds = organizationUnitAndRoleIds.SelectMany(x => x.Roles.Select(r => r.RoleId)).ToList(); + var allRoleIds = roleIds.Union(allOrganizationUnitRoleIds); + + var roles = await (await GetMongoQueryableAsync(cancellationToken)).Where(r => allRoleIds.Contains(r.Id)).Select(r => new{ r.Id, r.Name }).ToListAsync(cancellationToken); + var userRoles = userAndRoleIds.ToDictionary(x => x.Key, x => roles.Where(r => x.Value.Contains(r.Id)).Select(r => r.Name).ToArray()); + + var result = userRoles.Select(x => new IdentityUserIdWithRoleNames { Id = x.Key, RoleNames = x.Value }).ToList(); + + foreach (var userAndOrganizationUnitId in userAndOrganizationUnitIds) { - r.Id, - r.Name - }).ToListAsync(cancellationToken); - - var result = userAndRoleIds.ToDictionary(x => x.Key, x => roles.Where(r => x.Value.Contains(r.Id)).Select(r => r.Name).ToArray()); + var user = result.FirstOrDefault(x => x.Id == userAndOrganizationUnitId.Key); + var organizationUnitRoleIds = organizationUnitAndRoleIds.Where(x => userAndOrganizationUnitId.Value.Contains(x.Id)).SelectMany(x => x.Roles.Select(r => r.RoleId)).ToList(); + var roleNames = roles.Where(x => organizationUnitRoleIds.Contains(x.Id)).Select(r => r.Name).ToArray(); + if (user != null && roleNames.Any()) + { + user.RoleNames = user.RoleNames.Union(roleNames).ToArray(); + } + else if(roleNames.Any()) + { + result.Add(new IdentityUserIdWithRoleNames { Id = userAndOrganizationUnitId.Key, RoleNames = roleNames}); + } + } - return result.Select(x => new IdentityUserIdWithRoleNames() { Id = x.Key, RoleNames = x.Value }).ToList(); + return result; } } 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 9132a1e023..2516e0c09b 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 @@ -73,15 +73,16 @@ public abstract class IdentityUserRepository_Tests : AbpIdentity userBob.RoleNames[0].ShouldBe("manager"); var userJohn = userRoleNames.First(x => x.Id == TestData.UserJohnId); - userJohn.RoleNames.Length.ShouldBe(2); + userJohn.RoleNames.Length.ShouldBe(3); userJohn.RoleNames.ShouldContain("moderator"); userJohn.RoleNames.ShouldContain("supporter"); + userJohn.RoleNames.ShouldContain("manager"); var userNeo = userRoleNames.First(x => x.Id == TestData.UserNeoId); - userNeo.RoleNames.Length.ShouldBe(1); - userNeo.RoleNames[0].ShouldBe("supporter"); - - userRoleNames.ShouldNotContain(x => x.Id == TestData.UserDavidId); + userNeo.RoleNames.Length.ShouldBe(3); + userNeo.RoleNames.ShouldContain("supporter"); + userJohn.RoleNames.ShouldContain("moderator"); + userJohn.RoleNames.ShouldContain("manager"); } [Fact]