diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs index f5e7c14d37..04ff5c2e5f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs @@ -22,6 +22,10 @@ namespace Volo.Abp.Identity CancellationToken cancellationToken = default ); + Task> GetRoleNamesInOrganizationUnitAsync( + Guid id, + CancellationToken cancellationToken = default); + Task FindByLoginAsync( [NotNull] string loginProvider, [NotNull] string providerKey, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs index cb03869ae6..cbec7144d2 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs @@ -366,7 +366,11 @@ namespace Volo.Abp.Identity Check.NotNull(user, nameof(user)); - return await _userRepository.GetRoleNamesAsync(user.Id, cancellationToken: cancellationToken); + var userRoles = await _userRepository.GetRoleNamesAsync(user.Id, cancellationToken: cancellationToken); + + var userOrganizationUnitRoles = await _userRepository.GetRoleNamesInOrganizationUnitAsync(user.Id, cancellationToken: cancellationToken); + + return userRoles.Union(userOrganizationUnitRoles).ToList(); } /// diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/IOrganizationUnitRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/IOrganizationUnitRepository.cs index 9774534bfc..fad8b044f8 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/IOrganizationUnitRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/IOrganizationUnitRepository.cs @@ -8,18 +8,18 @@ namespace Volo.Abp.Identity.Organizations { public interface IOrganizationUnitRepository : IBasicRepository { - Task> GetChildrenAsync(Guid? parentId); + Task> GetChildrenAsync(Guid? parentId, CancellationToken cancellationToken = default); - Task> GetAllChildrenWithParentCodeAsync(string code, Guid? parentId); + Task> GetAllChildrenWithParentCodeAsync(string code, Guid? parentId, CancellationToken cancellationToken = default); - Task> GetListAsync(IEnumerable ids); + Task> GetListAsync(IEnumerable ids, CancellationToken cancellationToken = default); - Task> GetListAsync(bool includeDetails = true); + Task> GetListAsync(bool includeDetails = true, CancellationToken cancellationToken = default); Task GetOrganizationUnit(string displayName, bool includeDetails = false, CancellationToken cancellationToken = default); - Task AddRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId); + Task AddRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId, CancellationToken cancellationToken = default); - Task RemoveRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId); + Task RemoveRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId, CancellationToken cancellationToken = default); } } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnitManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnitManager.cs index dbf6f44cef..356201aef9 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnitManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnitManager.cs @@ -151,8 +151,8 @@ namespace Volo.Abp.Identity.Organizations public virtual async Task AddRoleToOrganizationUnitAsync(Guid roleId, Guid ouId) { await AddRoleToOrganizationUnitAsync( - await _identityRoleRepository.GetAsync(roleId), - await _organizationUnitRepository.GetAsync(ouId) + await _identityRoleRepository.GetAsync(roleId).ConfigureAwait(false), + await _organizationUnitRepository.GetAsync(ouId, true).ConfigureAwait(false) ); } @@ -162,7 +162,7 @@ namespace Volo.Abp.Identity.Organizations if (currentRoles.Any(r => r.Id == role.Id)) { - return; + return ; } ou.AddRole(role.Id); await _organizationUnitRepository.AddRole(ou, role, ou.TenantId); 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 f27ece7b25..587c2043ac 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 @@ -44,6 +44,19 @@ namespace Volo.Abp.Identity.EntityFrameworkCore return await query.ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); } + public virtual async Task> GetRoleNamesInOrganizationUnitAsync( + Guid id, + CancellationToken cancellationToken = default) + { + var query = from userOu in DbContext.Set() + join roleOu in DbContext.Set() on userOu.OrganizationUnitId equals roleOu.OrganizationUnitId + join userOuRoles in DbContext.Roles on roleOu.RoleId equals userOuRoles.Id + where userOu.UserId == id + select userOuRoles.Name; + + return await query.ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); + } + public virtual async Task FindByLoginAsync( string loginProvider, string providerKey, 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 b90d600c94..2519efc617 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 @@ -18,28 +18,28 @@ namespace Volo.Abp.Identity.EntityFrameworkCore { } - public async Task> GetChildrenAsync(Guid? parentId) + public async Task> GetChildrenAsync(Guid? parentId, CancellationToken cancellationToken = default) { return await DbSet.Where(x => x.ParentId == parentId) - .ToListAsync(); + .ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); } - public async Task> GetAllChildrenWithParentCodeAsync(string code, Guid? parentId) + public async Task> GetAllChildrenWithParentCodeAsync(string code, Guid? parentId, CancellationToken cancellationToken = default) { return await DbSet.Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value) - .ToListAsync(); + .ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); } - public async Task> GetListAsync(IEnumerable ids) + public async Task> GetListAsync(IEnumerable ids, CancellationToken cancellationToken = default) { - return await DbSet.Where(t => ids.Contains(t.Id)).ToListAsync(); + return await DbSet.Where(t => ids.Contains(t.Id)).ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); } - public async Task> GetListAsync(bool includeDetails = true) + public override async Task> GetListAsync(bool includeDetails = true, CancellationToken cancellationToken = default) { return await DbSet .IncludeDetails(includeDetails) - .ToListAsync(); + .ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); } public async Task GetOrganizationUnit(string displayName, bool includeDetails = false, CancellationToken cancellationToken = default) @@ -52,14 +52,14 @@ namespace Volo.Abp.Identity.EntityFrameworkCore ).ConfigureAwait(false); } - public async Task AddRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId) + public Task AddRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId, CancellationToken cancellationToken = default) { var our = new OrganizationUnitRole(tenantId, role.Id, ou.Id); DbContext.Set().Add(our); - await DbContext.SaveChangesAsync(); + return Task.FromResult(0); } - public async Task RemoveRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId) + public async Task RemoveRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId, CancellationToken cancellationToken = default) { var context = DbContext.Set(); var our = await context.FirstOrDefaultAsync(our => @@ -68,12 +68,12 @@ namespace Volo.Abp.Identity.EntityFrameworkCore our.TenantId == tenantId ); DbContext.Set().Remove(our); - await DbContext.SaveChangesAsync(); } public override IQueryable WithDetails() { return GetQueryable().IncludeDetails(); } + } } diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs index 3db35866f5..a78dca0d0f 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs @@ -1,5 +1,6 @@ using MongoDB.Driver; using Volo.Abp.Data; +using Volo.Abp.Identity.Organizations; using Volo.Abp.MongoDB; namespace Volo.Abp.Identity.MongoDB @@ -13,6 +14,8 @@ namespace Volo.Abp.Identity.MongoDB public IMongoCollection ClaimTypes => Collection(); + public IMongoCollection OrganizationUnits => Collection(); + protected override void CreateModel(IMongoModelBuilder modelBuilder) { base.CreateModel(modelBuilder); diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs index dd0cc8d42e..f6bf256576 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs @@ -1,4 +1,5 @@ using System; +using Volo.Abp.Identity.Organizations; using Volo.Abp.MongoDB; namespace Volo.Abp.Identity.MongoDB @@ -31,6 +32,11 @@ namespace Volo.Abp.Identity.MongoDB { b.CollectionName = options.CollectionPrefix + "ClaimTypes"; }); + + builder.Entity(b => + { + b.CollectionName = options.CollectionPrefix + "OrganizationUnit"; + }); } } } \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs index cfbc10adba..16a400a772 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Identity.Organizations; using Volo.Abp.Modularity; using Volo.Abp.Users.MongoDB; @@ -17,6 +18,7 @@ namespace Volo.Abp.Identity.MongoDB options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs index 36cdcbec3e..38a38cc828 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs @@ -1,5 +1,6 @@ using MongoDB.Driver; using Volo.Abp.Data; +using Volo.Abp.Identity.Organizations; using Volo.Abp.MongoDB; namespace Volo.Abp.Identity.MongoDB @@ -12,5 +13,7 @@ namespace Volo.Abp.Identity.MongoDB IMongoCollection Roles { get; } IMongoCollection ClaimTypes { get; } + + IMongoCollection OrganizationUnits { get; } } } \ No newline at end of file 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 9c3b8bcd0e..f309cdcf7d 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 @@ -9,6 +9,7 @@ using MongoDB.Driver; using MongoDB.Driver.Linq; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Guids; +using Volo.Abp.Identity.Organizations; using Volo.Abp.MongoDB; namespace Volo.Abp.Identity.MongoDB @@ -17,14 +18,14 @@ namespace Volo.Abp.Identity.MongoDB { private readonly IGuidGenerator _guidGenerator; - public MongoIdentityUserRepository(IMongoDbContextProvider dbContextProvider, IGuidGenerator guidGenerator) + public MongoIdentityUserRepository(IMongoDbContextProvider dbContextProvider, IGuidGenerator guidGenerator) : base(dbContextProvider) { _guidGenerator = guidGenerator; } public async Task FindByNormalizedUserNameAsync( - string normalizedUserName, + string normalizedUserName, bool includeDetails = true, CancellationToken cancellationToken = default) { @@ -36,7 +37,7 @@ namespace Volo.Abp.Identity.MongoDB } public async Task> GetRoleNamesAsync( - Guid id, + Guid id, CancellationToken cancellationToken = default) { var user = await GetAsync(id, cancellationToken: GetCancellationToken(cancellationToken)).ConfigureAwait(false); @@ -44,9 +45,20 @@ namespace Volo.Abp.Identity.MongoDB return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)).Select(r => r.Name).ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); } + public async Task> GetRoleNamesInOrganizationUnitAsync( + Guid id, + CancellationToken cancellationToken = default) + { + var user = await GetAsync(id, cancellationToken: GetCancellationToken(cancellationToken)).ConfigureAwait(false); + var organizationUnitIds = user.OrganizationUnits.Select(r => r.OrganizationUnitId); + var organizationUnits = DbContext.OrganizationUnits.AsQueryable().Where(ou => organizationUnitIds.Contains(ou.Id)); + var roleIds = organizationUnits.SelectMany(x => x.Roles.Select(r => r.Id)); + return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)).Select(r => r.Name).ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); + } + public async Task FindByLoginAsync( - string loginProvider, - string providerKey, + string loginProvider, + string providerKey, bool includeDetails = true, CancellationToken cancellationToken = default) { @@ -74,7 +86,7 @@ namespace Volo.Abp.Identity.MongoDB } public async Task> GetListByNormalizedRoleNameAsync( - string normalizedRoleName, + string normalizedRoleName, bool includeDetails = false, CancellationToken cancellationToken = default) { @@ -92,9 +104,9 @@ namespace Volo.Abp.Identity.MongoDB public async Task> GetListAsync( string sorting = null, - int maxResultCount = int.MaxValue, - int skipCount = 0, - string filter = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + string filter = null, bool includeDetails = false, CancellationToken cancellationToken = default) { @@ -121,6 +133,16 @@ namespace Volo.Abp.Identity.MongoDB return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)).ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); } + public async Task> GetOrganizationUnitsAsync( + Guid id, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var user = await GetAsync(id, cancellationToken: GetCancellationToken(cancellationToken)).ConfigureAwait(false); + var organizationUnitIds = user.OrganizationUnits.Select(r => r.OrganizationUnitId); + return await DbContext.OrganizationUnits.AsQueryable().Where(ou => organizationUnitIds.Contains(ou.Id)).ToListAsync().ConfigureAwait(false); + } + public async Task GetCountAsync( string filter = null, CancellationToken cancellationToken = default) 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 new file mode 100644 index 0000000000..8e904b2c5b --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs @@ -0,0 +1,66 @@ +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.Guids; +using Volo.Abp.Identity.Organizations; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.Identity.MongoDB +{ + public class MongoOrganizationUnitRepository : MongoDbRepository, IOrganizationUnitRepository + { + private readonly IGuidGenerator _guidGenerator; + + public MongoOrganizationUnitRepository( + IMongoDbContextProvider dbContextProvider, + IGuidGenerator guidGenerator) + : base(dbContextProvider) + { + _guidGenerator = guidGenerator; + } + + public async Task> GetChildrenAsync(Guid? parentId, CancellationToken cancellationToken = default) + { + return await DbContext.OrganizationUnits.AsQueryable().Where(ou => ou.ParentId == parentId) + .ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); + } + + public async Task> GetAllChildrenWithParentCodeAsync(string code, Guid? parentId, CancellationToken cancellationToken = default) + { + return await DbContext.OrganizationUnits.AsQueryable() + .Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value) + .ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); + } + + public async Task> GetListAsync(IEnumerable ids, CancellationToken cancellationToken = default) + { + return await DbContext.OrganizationUnits.AsQueryable() + .Where(t => ids.Contains(t.Id)).ToListAsync(GetCancellationToken(cancellationToken)).ConfigureAwait(false); + } + + public async Task GetOrganizationUnit(string displayName, bool includeDetails = false, CancellationToken cancellationToken = default) + { + return await DbContext.OrganizationUnits.AsQueryable() + .FirstOrDefaultAsync( + ou => ou.DisplayName == displayName, + GetCancellationToken(cancellationToken) + ).ConfigureAwait(false); + } + + public Task AddRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task RemoveRole(OrganizationUnit ou, IdentityRole role, Guid? tenantId, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + } +} diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/OrganizationUnitManager_Tests.cs b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/OrganizationUnitManager_Tests.cs index f19716b8ee..5be4c7d517 100644 --- a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/OrganizationUnitManager_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/OrganizationUnitManager_Tests.cs @@ -89,9 +89,9 @@ namespace Volo.Abp.Identity { var ou = await _organizationUnitRepository.GetOrganizationUnit("OU1", true).ConfigureAwait(false); var adminRole = await _identityRoleRepository.FindByNormalizedNameAsync(_lookupNormalizer.NormalizeName("admin")).ConfigureAwait(false); - await _organizationUnitManager.AddRoleToOrganizationUnitAsync(adminRole.Id, ou.Id); + await _organizationUnitManager.AddRoleToOrganizationUnitAsync(adminRole, ou); - //TODO: This method has a bug: includeDetails not work + //TODO: This method has a bug: includeDetails not work or add role not work ou = await _organizationUnitRepository.GetOrganizationUnit("OU1", includeDetails: true).ConfigureAwait(false); ou.Roles.FirstOrDefault().Id.ShouldBe(adminRole.Id); } diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs new file mode 100644 index 0000000000..d60611b2b6 --- /dev/null +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Volo.Abp.Identity.MongoDB +{ + public class OrganizationUnitRepository_Tests : OrganizationUnitRepository_Tests + { + } +}