mirror of https://github.com/abpframework/abp.git
committed by
GitHub
46 changed files with 1966 additions and 121 deletions
@ -1,11 +1,8 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class IdentityErrorCodes |
|||
{ |
|||
public const string UserSelfDeletion = "Volo.Abp.Identity:010001"; |
|||
public const string MaxAllowedOuMembership = "Volo.Abp.Identity:010002"; |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class OrganizationUnitConsts |
|||
{ |
|||
/// <summary>
|
|||
/// Maximum length of the <see cref="DisplayName"/> property.
|
|||
/// </summary>
|
|||
public const int MaxDisplayNameLength = 128; |
|||
|
|||
/// <summary>
|
|||
/// Maximum depth of an OU hierarchy.
|
|||
/// </summary>
|
|||
public const int MaxDepth = 16; |
|||
|
|||
/// <summary>
|
|||
/// Length of a code unit between dots.
|
|||
/// </summary>
|
|||
public const int CodeUnitLength = 5; |
|||
|
|||
/// <summary>
|
|||
/// Maximum length of the <see cref="Code"/> property.
|
|||
/// </summary>
|
|||
public const int MaxCodeLength = MaxDepth * (CodeUnitLength + 1) - 1; |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public interface IOrganizationUnitRepository : IBasicRepository<OrganizationUnit, Guid> |
|||
{ |
|||
Task<List<OrganizationUnit>> GetChildrenAsync( |
|||
Guid? parentId, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<OrganizationUnit>> GetAllChildrenWithParentCodeAsync( |
|||
string code, |
|||
Guid? parentId, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<OrganizationUnit> GetAsync( |
|||
string displayName, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<OrganizationUnit>> GetListAsync( |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<OrganizationUnit>> GetListAsync( |
|||
IEnumerable<Guid> ids, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<IdentityRole>> GetRolesAsync( |
|||
OrganizationUnit organizationUnit, |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<int> GetRolesCountAsync( |
|||
OrganizationUnit organizationUnit, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
|
|||
Task<List<IdentityUser>> GetMembersAsync( |
|||
OrganizationUnit organizationUnit, |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
string filter = null, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
Task<int> GetMembersCountAsync( |
|||
OrganizationUnit organizationUnit, |
|||
CancellationToken cancellationToken = default |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents membership of a User to an OU.
|
|||
/// </summary>
|
|||
public class IdentityUserOrganizationUnit : CreationAuditedEntity, IMultiTenant |
|||
{ |
|||
/// <summary>
|
|||
/// TenantId of this entity.
|
|||
/// </summary>
|
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Id of the User.
|
|||
/// </summary>
|
|||
public virtual Guid UserId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Id of the related <see cref="OrganizationUnit"/>.
|
|||
/// </summary>
|
|||
public virtual Guid OrganizationUnitId { get; protected set; } |
|||
|
|||
protected IdentityUserOrganizationUnit() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public IdentityUserOrganizationUnit(Guid userId, Guid organizationUnitId, Guid? tenantId = null) |
|||
{ |
|||
UserId = userId; |
|||
OrganizationUnitId = organizationUnitId; |
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
public override object[] GetKeys() |
|||
{ |
|||
return new object[] { UserId, OrganizationUnitId }; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,212 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents an organization unit (OU).
|
|||
/// </summary>
|
|||
public class OrganizationUnit : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Parent <see cref="OrganizationUnit"/> Id.
|
|||
/// Null, if this OU is a root.
|
|||
/// </summary>
|
|||
public virtual Guid? ParentId { get; internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Hierarchical Code of this organization unit.
|
|||
/// Example: "00001.00042.00005".
|
|||
/// This is a unique code for a Tenant.
|
|||
/// It's changeable if OU hierarchy is changed.
|
|||
/// </summary>
|
|||
public virtual string Code { get; internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Display name of this role.
|
|||
/// </summary>
|
|||
public virtual string DisplayName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Roles of this OU.
|
|||
/// </summary>
|
|||
public virtual ICollection<OrganizationUnitRole> Roles { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="OrganizationUnit"/> class.
|
|||
/// </summary>
|
|||
public OrganizationUnit() |
|||
{ |
|||
|
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="OrganizationUnit"/> class.
|
|||
/// </summary>
|
|||
/// <param name="tenantId">Tenant's Id or null for host.</param>
|
|||
/// <param name="displayName">Display name.</param>
|
|||
/// <param name="parentId">Parent's Id or null if OU is a root.</param>
|
|||
public OrganizationUnit(Guid id, string displayName, Guid? parentId = null, Guid? tenantId = null) |
|||
{ |
|||
Id = id; |
|||
TenantId = tenantId; |
|||
DisplayName = displayName; |
|||
ParentId = parentId; |
|||
Roles = new Collection<OrganizationUnitRole>(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates code for given numbers.
|
|||
/// Example: if numbers are 4,2 then returns "00004.00002";
|
|||
/// </summary>
|
|||
/// <param name="numbers">Numbers</param>
|
|||
public static string CreateCode(params int[] numbers) |
|||
{ |
|||
if (numbers.IsNullOrEmpty()) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return numbers.Select(number => number.ToString(new string('0', OrganizationUnitConsts.CodeUnitLength))).JoinAsString("."); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Appends a child code to a parent code.
|
|||
/// Example: if parentCode = "00001", childCode = "00042" then returns "00001.00042".
|
|||
/// </summary>
|
|||
/// <param name="parentCode">Parent code. Can be null or empty if parent is a root.</param>
|
|||
/// <param name="childCode">Child code.</param>
|
|||
public static string AppendCode(string parentCode, string childCode) |
|||
{ |
|||
if (childCode.IsNullOrEmpty()) |
|||
{ |
|||
throw new ArgumentNullException(nameof(childCode), "childCode can not be null or empty."); |
|||
} |
|||
|
|||
if (parentCode.IsNullOrEmpty()) |
|||
{ |
|||
return childCode; |
|||
} |
|||
|
|||
return parentCode + "." + childCode; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets relative code to the parent.
|
|||
/// Example: if code = "00019.00055.00001" and parentCode = "00019" then returns "00055.00001".
|
|||
/// </summary>
|
|||
/// <param name="code">The code.</param>
|
|||
/// <param name="parentCode">The parent code.</param>
|
|||
public static string GetRelativeCode(string code, string parentCode) |
|||
{ |
|||
if (code.IsNullOrEmpty()) |
|||
{ |
|||
throw new ArgumentNullException(nameof(code), "code can not be null or empty."); |
|||
} |
|||
|
|||
if (parentCode.IsNullOrEmpty()) |
|||
{ |
|||
return code; |
|||
} |
|||
|
|||
if (code.Length == parentCode.Length) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return code.Substring(parentCode.Length + 1); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Calculates next code for given code.
|
|||
/// Example: if code = "00019.00055.00001" returns "00019.00055.00002".
|
|||
/// </summary>
|
|||
/// <param name="code">The code.</param>
|
|||
public static string CalculateNextCode(string code) |
|||
{ |
|||
if (code.IsNullOrEmpty()) |
|||
{ |
|||
throw new ArgumentNullException(nameof(code), "code can not be null or empty."); |
|||
} |
|||
|
|||
var parentCode = GetParentCode(code); |
|||
var lastUnitCode = GetLastUnitCode(code); |
|||
|
|||
return AppendCode(parentCode, CreateCode(Convert.ToInt32(lastUnitCode) + 1)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the last unit code.
|
|||
/// Example: if code = "00019.00055.00001" returns "00001".
|
|||
/// </summary>
|
|||
/// <param name="code">The code.</param>
|
|||
public static string GetLastUnitCode(string code) |
|||
{ |
|||
if (code.IsNullOrEmpty()) |
|||
{ |
|||
throw new ArgumentNullException(nameof(code), "code can not be null or empty."); |
|||
} |
|||
|
|||
var splittedCode = code.Split('.'); |
|||
return splittedCode[splittedCode.Length - 1]; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets parent code.
|
|||
/// Example: if code = "00019.00055.00001" returns "00019.00055".
|
|||
/// </summary>
|
|||
/// <param name="code">The code.</param>
|
|||
public static string GetParentCode(string code) |
|||
{ |
|||
if (code.IsNullOrEmpty()) |
|||
{ |
|||
throw new ArgumentNullException(nameof(code), "code can not be null or empty."); |
|||
} |
|||
|
|||
var splittedCode = code.Split('.'); |
|||
if (splittedCode.Length == 1) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return splittedCode.Take(splittedCode.Length - 1).JoinAsString("."); |
|||
} |
|||
|
|||
public virtual void AddRole(Guid roleId) |
|||
{ |
|||
Check.NotNull(roleId, nameof(roleId)); |
|||
|
|||
if (IsInRole(roleId)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
Roles.Add(new OrganizationUnitRole(roleId, Id, TenantId)); |
|||
} |
|||
|
|||
public virtual void RemoveRole(Guid roleId) |
|||
{ |
|||
Check.NotNull(roleId, nameof(roleId)); |
|||
|
|||
if (!IsInRole(roleId)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
Roles.RemoveAll(r => r.RoleId == roleId); |
|||
} |
|||
|
|||
public virtual bool IsInRole(Guid roleId) |
|||
{ |
|||
Check.NotNull(roleId, nameof(roleId)); |
|||
|
|||
return Roles.Any(r => r.RoleId == roleId); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,188 @@ |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Services; |
|||
using Volo.Abp.Identity.Localization; |
|||
using Volo.Abp.Threading; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Performs domain logic for Organization Units.
|
|||
/// </summary>
|
|||
public class OrganizationUnitManager : DomainService |
|||
{ |
|||
protected IOrganizationUnitRepository OrganizationUnitRepository { get; } |
|||
protected IStringLocalizer<IdentityResource> Localizer { get; } |
|||
protected IIdentityRoleRepository IdentityRoleRepository { get; } |
|||
protected ICancellationTokenProvider CancellationTokenProvider { get; } |
|||
|
|||
public OrganizationUnitManager( |
|||
IOrganizationUnitRepository organizationUnitRepository, |
|||
IStringLocalizer<IdentityResource> localizer, |
|||
IIdentityRoleRepository identityRoleRepository, |
|||
ICancellationTokenProvider cancellationTokenProvider) |
|||
{ |
|||
OrganizationUnitRepository = organizationUnitRepository; |
|||
Localizer = localizer; |
|||
IdentityRoleRepository = identityRoleRepository; |
|||
CancellationTokenProvider = cancellationTokenProvider; |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public virtual async Task CreateAsync(OrganizationUnit organizationUnit) |
|||
{ |
|||
organizationUnit.Code = await GetNextChildCodeAsync(organizationUnit.ParentId); |
|||
await ValidateOrganizationUnitAsync(organizationUnit); |
|||
await OrganizationUnitRepository.InsertAsync(organizationUnit); |
|||
} |
|||
|
|||
public virtual async Task UpdateAsync(OrganizationUnit organizationUnit) |
|||
{ |
|||
await ValidateOrganizationUnitAsync(organizationUnit); |
|||
await OrganizationUnitRepository.UpdateAsync(organizationUnit); |
|||
} |
|||
|
|||
public virtual async Task<string> GetNextChildCodeAsync(Guid? parentId) |
|||
{ |
|||
var lastChild = await GetLastChildOrNullAsync(parentId); |
|||
if (lastChild != null) |
|||
{ |
|||
return OrganizationUnit.CalculateNextCode(lastChild.Code); |
|||
} |
|||
|
|||
var parentCode = parentId != null |
|||
? await GetCodeOrDefaultAsync(parentId.Value) |
|||
: null; |
|||
|
|||
return OrganizationUnit.AppendCode( |
|||
parentCode, |
|||
OrganizationUnit.CreateCode(1) |
|||
); |
|||
} |
|||
|
|||
public virtual async Task<OrganizationUnit> GetLastChildOrNullAsync(Guid? parentId) |
|||
{ |
|||
var children = await OrganizationUnitRepository.GetChildrenAsync(parentId); |
|||
return children.OrderBy(c => c.Code).LastOrDefault(); |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public virtual async Task DeleteAsync(Guid id) |
|||
{ |
|||
var children = await FindChildrenAsync(id, true); |
|||
|
|||
foreach (var child in children) |
|||
{ |
|||
await OrganizationUnitRepository.DeleteAsync(child); |
|||
} |
|||
|
|||
await OrganizationUnitRepository.DeleteAsync(id); |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public virtual async Task MoveAsync(Guid id, Guid? parentId) |
|||
{ |
|||
var organizationUnit = await OrganizationUnitRepository.GetAsync(id); |
|||
if (organizationUnit.ParentId == parentId) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
//Should find children before Code change
|
|||
var children = await FindChildrenAsync(id, true); |
|||
|
|||
//Store old code of OU
|
|||
var oldCode = organizationUnit.Code; |
|||
|
|||
//Move OU
|
|||
organizationUnit.Code = await GetNextChildCodeAsync(parentId); |
|||
organizationUnit.ParentId = parentId; |
|||
|
|||
await ValidateOrganizationUnitAsync(organizationUnit); |
|||
|
|||
//Update Children Codes
|
|||
foreach (var child in children) |
|||
{ |
|||
child.Code = OrganizationUnit.AppendCode(organizationUnit.Code, OrganizationUnit.GetRelativeCode(child.Code, oldCode)); |
|||
} |
|||
} |
|||
|
|||
public virtual async Task<string> GetCodeOrDefaultAsync(Guid id) |
|||
{ |
|||
var ou = await OrganizationUnitRepository.GetAsync(id); |
|||
return ou?.Code; |
|||
} |
|||
|
|||
protected virtual async Task ValidateOrganizationUnitAsync(OrganizationUnit organizationUnit) |
|||
{ |
|||
var siblings = (await FindChildrenAsync(organizationUnit.ParentId)) |
|||
.Where(ou => ou.Id != organizationUnit.Id) |
|||
.ToList(); |
|||
|
|||
if (siblings.Any(ou => ou.DisplayName == organizationUnit.DisplayName)) |
|||
{ |
|||
throw new UserFriendlyException(Localizer["OrganizationUnitDuplicateDisplayNameWarning", organizationUnit.DisplayName]); |
|||
} |
|||
} |
|||
|
|||
public async Task<List<OrganizationUnit>> FindChildrenAsync(Guid? parentId, bool recursive = false) |
|||
{ |
|||
if (!recursive) |
|||
{ |
|||
return await OrganizationUnitRepository.GetChildrenAsync(parentId); |
|||
} |
|||
|
|||
if (!parentId.HasValue) |
|||
{ |
|||
return await OrganizationUnitRepository.GetListAsync(includeDetails: true); |
|||
} |
|||
|
|||
var code = await GetCodeOrDefaultAsync(parentId.Value); |
|||
|
|||
return await OrganizationUnitRepository.GetAllChildrenWithParentCodeAsync(code, parentId); |
|||
} |
|||
|
|||
public virtual Task<bool> IsInOrganizationUnitAsync(IdentityUser user, OrganizationUnit ou) |
|||
{ |
|||
return Task.FromResult(user.IsInOrganizationUnit(ou.Id)); |
|||
} |
|||
|
|||
public virtual async Task AddRoleToOrganizationUnitAsync(Guid roleId, Guid ouId) |
|||
{ |
|||
await AddRoleToOrganizationUnitAsync( |
|||
await IdentityRoleRepository.GetAsync(roleId), |
|||
await OrganizationUnitRepository.GetAsync(ouId, true) |
|||
); |
|||
} |
|||
|
|||
public virtual Task AddRoleToOrganizationUnitAsync(IdentityRole role, OrganizationUnit ou) |
|||
{ |
|||
var currentRoles = ou.Roles; |
|||
|
|||
if (currentRoles.Any(r => r.OrganizationUnitId == ou.Id && r.RoleId == role.Id)) |
|||
{ |
|||
return Task.FromResult(0); |
|||
} |
|||
ou.AddRole(role.Id); |
|||
return Task.FromResult(0); |
|||
} |
|||
|
|||
public virtual async Task RemoveRoleFromOrganizationUnitAsync(Guid roleId, Guid ouId) |
|||
{ |
|||
await RemoveRoleFromOrganizationUnitAsync( |
|||
await IdentityRoleRepository.GetAsync(roleId), |
|||
await OrganizationUnitRepository.GetAsync(ouId, true) |
|||
); |
|||
} |
|||
|
|||
public virtual Task RemoveRoleFromOrganizationUnitAsync(IdentityRole role, OrganizationUnit organizationUnit) |
|||
{ |
|||
organizationUnit.RemoveRole(role.Id); |
|||
return Task.FromResult(0); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Represents membership of a User to an OU.
|
|||
/// </summary>
|
|||
public class OrganizationUnitRole : CreationAuditedEntity, IMultiTenant |
|||
{ |
|||
/// <summary>
|
|||
/// TenantId of this entity.
|
|||
/// </summary>
|
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Id of the Role.
|
|||
/// </summary>
|
|||
public virtual Guid RoleId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Id of the <see cref="OrganizationUnit"/>.
|
|||
/// </summary>
|
|||
public virtual Guid OrganizationUnitId { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="OrganizationUnitRole"/> class.
|
|||
/// </summary>
|
|||
protected OrganizationUnitRole() |
|||
{ |
|||
|
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="OrganizationUnitRole"/> class.
|
|||
/// </summary>
|
|||
/// <param name="tenantId">TenantId</param>
|
|||
/// <param name="roleId">Id of the User.</param>
|
|||
/// <param name="organizationUnitId">Id of the <see cref="OrganizationUnit"/>.</param>
|
|||
public OrganizationUnitRole(Guid roleId, Guid organizationUnitId, Guid? tenantId = null) |
|||
{ |
|||
RoleId = roleId; |
|||
OrganizationUnitId = organizationUnitId; |
|||
TenantId = tenantId; |
|||
} |
|||
|
|||
public override object[] GetKeys() |
|||
{ |
|||
return new object[] { OrganizationUnitId, RoleId }; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,160 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Linq; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace Volo.Abp.Identity.EntityFrameworkCore |
|||
{ |
|||
public class EfCoreOrganizationUnitRepository |
|||
: EfCoreRepository<IIdentityDbContext, OrganizationUnit, Guid>, |
|||
IOrganizationUnitRepository |
|||
{ |
|||
public EfCoreOrganizationUnitRepository( |
|||
IDbContextProvider<IIdentityDbContext> dbContextProvider) |
|||
: base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationUnit>> GetChildrenAsync( |
|||
Guid? parentId, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await DbSet |
|||
.IncludeDetails(includeDetails) |
|||
.Where(x => x.ParentId == parentId) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationUnit>> GetAllChildrenWithParentCodeAsync( |
|||
string code, |
|||
Guid? parentId, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await DbSet |
|||
.IncludeDetails(includeDetails) |
|||
.Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationUnit>> GetListAsync( |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await DbSet |
|||
.IncludeDetails(includeDetails) |
|||
.OrderBy(sorting ?? nameof(OrganizationUnit.DisplayName)) |
|||
.PageBy(skipCount, maxResultCount) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
public virtual async Task<List<OrganizationUnit>> GetListAsync( |
|||
IEnumerable<Guid> ids, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await DbSet |
|||
.IncludeDetails(includeDetails) |
|||
.Where(t => ids.Contains(t.Id)) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<OrganizationUnit> GetAsync( |
|||
string displayName, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await DbSet |
|||
.IncludeDetails(includeDetails) |
|||
.FirstOrDefaultAsync( |
|||
ou => ou.DisplayName == displayName, |
|||
GetCancellationToken(cancellationToken) |
|||
); |
|||
} |
|||
|
|||
public virtual async Task<List<IdentityRole>> GetRolesAsync( |
|||
OrganizationUnit organizationUnit, |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var query = from organizationRole in DbContext.Set<OrganizationUnitRole>() |
|||
join role in DbContext.Roles.IncludeDetails(includeDetails) on organizationRole.RoleId equals role.Id |
|||
where organizationRole.OrganizationUnitId == organizationUnit.Id |
|||
select role; |
|||
query = query |
|||
.OrderBy(sorting ?? nameof(IdentityRole.Name)) |
|||
.PageBy(skipCount, maxResultCount); |
|||
|
|||
return await query.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<int> GetRolesCountAsync( |
|||
OrganizationUnit organizationUnit, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var query = from organizationRole in DbContext.Set<OrganizationUnitRole>() |
|||
join role in DbContext.Roles on organizationRole.RoleId equals role.Id |
|||
where organizationRole.OrganizationUnitId == organizationUnit.Id |
|||
select role; |
|||
|
|||
return await query.CountAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<List<IdentityUser>> GetMembersAsync( |
|||
OrganizationUnit organizationUnit, |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
string filter = null, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default |
|||
) |
|||
{ |
|||
var query = from userOu in DbContext.Set<IdentityUserOrganizationUnit>() |
|||
join user in DbContext.Users.IncludeDetails(includeDetails) on userOu.UserId equals user.Id |
|||
where userOu.OrganizationUnitId == organizationUnit.Id |
|||
select user; |
|||
|
|||
if (!filter.IsNullOrWhiteSpace()) |
|||
{ |
|||
query = query.Where(u => |
|||
u.UserName.Contains(filter) || |
|||
u.Email.Contains(filter) || |
|||
(u.PhoneNumber != null && u.PhoneNumber.Contains(filter)) |
|||
); |
|||
} |
|||
|
|||
return await query.OrderBy(sorting ?? nameof(IdentityUser.UserName)) |
|||
.PageBy(skipCount, maxResultCount) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<int> GetMembersCountAsync( |
|||
OrganizationUnit organizationUnit, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var query = from userOu in DbContext.Set<IdentityUserOrganizationUnit>() |
|||
join user in DbContext.Users on userOu.UserId equals user.Id |
|||
where userOu.OrganizationUnitId == organizationUnit.Id |
|||
select user; |
|||
|
|||
return await query.CountAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public override IQueryable<OrganizationUnit> WithDetails() |
|||
{ |
|||
return GetQueryable().IncludeDetails(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,138 @@ |
|||
using MongoDB.Driver; |
|||
using MongoDB.Driver.Linq; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Volo.Abp.Identity.MongoDB |
|||
{ |
|||
public class MongoOrganizationUnitRepository : MongoDbRepository<IAbpIdentityMongoDbContext, OrganizationUnit, Guid>, IOrganizationUnitRepository |
|||
{ |
|||
public MongoOrganizationUnitRepository( |
|||
IMongoDbContextProvider<IAbpIdentityMongoDbContext> dbContextProvider) |
|||
: base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationUnit>> GetChildrenAsync( |
|||
Guid? parentId, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await GetMongoQueryable() |
|||
.Where(ou => ou.ParentId == parentId) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationUnit>> GetAllChildrenWithParentCodeAsync( |
|||
string code, |
|||
Guid? parentId, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await GetMongoQueryable() |
|||
.Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationUnit>> GetListAsync( |
|||
IEnumerable<Guid> ids, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await GetMongoQueryable() |
|||
.Where(t => ids.Contains(t.Id)) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<List<OrganizationUnit>> GetListAsync( |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await GetMongoQueryable() |
|||
.OrderBy(sorting ?? nameof(OrganizationUnit.DisplayName)) |
|||
.As<IMongoQueryable<OrganizationUnit>>() |
|||
.PageBy<OrganizationUnit, IMongoQueryable<OrganizationUnit>>(skipCount, maxResultCount) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<OrganizationUnit> GetAsync( |
|||
string displayName, |
|||
bool includeDetails = true, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await GetMongoQueryable() |
|||
.FirstOrDefaultAsync( |
|||
ou => ou.DisplayName == displayName, |
|||
GetCancellationToken(cancellationToken) |
|||
); |
|||
} |
|||
|
|||
public virtual async Task<List<IdentityRole>> GetRolesAsync( |
|||
OrganizationUnit organizationUnit, |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray(); |
|||
return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)) |
|||
.OrderBy(sorting ?? nameof(IdentityRole.Name)) |
|||
.As<IMongoQueryable<IdentityRole>>() |
|||
.PageBy<IdentityRole, IMongoQueryable<IdentityRole>>(skipCount, maxResultCount) |
|||
.ToListAsync(cancellationToken); |
|||
} |
|||
|
|||
public virtual async Task<int> GetRolesCountAsync( |
|||
OrganizationUnit organizationUnit, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray(); |
|||
return await DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)) |
|||
.As<IMongoQueryable<IdentityRole>>() |
|||
.CountAsync(cancellationToken); |
|||
} |
|||
|
|||
public virtual async Task<List<IdentityUser>> GetMembersAsync( |
|||
OrganizationUnit organizationUnit, |
|||
string sorting = null, |
|||
int maxResultCount = int.MaxValue, |
|||
int skipCount = 0, |
|||
string filter = null, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await DbContext.Users.AsQueryable() |
|||
.Where(u => u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id)) |
|||
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>( |
|||
!filter.IsNullOrWhiteSpace(), |
|||
u => |
|||
u.UserName.Contains(filter) || |
|||
u.Email.Contains(filter) |
|||
) |
|||
.OrderBy(sorting ?? nameof(IdentityUser.UserName)) |
|||
.As<IMongoQueryable<IdentityUser>>() |
|||
.PageBy<IdentityUser, IMongoQueryable<IdentityUser>>(skipCount, maxResultCount) |
|||
.ToListAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
|
|||
public virtual async Task<int> GetMembersCountAsync( |
|||
OrganizationUnit organizationUnit, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
return await DbContext.Users.AsQueryable() |
|||
.Where(u => u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id)) |
|||
.As<IMongoQueryable<IdentityUser>>() |
|||
.CountAsync(GetCancellationToken(cancellationToken)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,121 @@ |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Shouldly; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.Uow; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class OrganizationUnitManager_Tests : AbpIdentityDomainTestBase |
|||
{ |
|||
private readonly OrganizationUnitManager _organizationUnitManager; |
|||
private readonly IOrganizationUnitRepository _organizationUnitRepository; |
|||
private readonly IdentityTestData _testData; |
|||
private readonly IIdentityRoleRepository _identityRoleRepository; |
|||
private readonly ILookupNormalizer _lookupNormalizer; |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
public OrganizationUnitManager_Tests() |
|||
{ |
|||
_organizationUnitManager = GetRequiredService<OrganizationUnitManager>(); |
|||
_organizationUnitRepository = GetRequiredService<IOrganizationUnitRepository>(); |
|||
_identityRoleRepository = GetRequiredService<IIdentityRoleRepository>(); |
|||
_lookupNormalizer = GetRequiredService<ILookupNormalizer>(); |
|||
_testData = GetRequiredService<IdentityTestData>(); |
|||
_unitOfWorkManager = GetRequiredService<IUnitOfWorkManager>(); |
|||
_guidGenerator = GetService<IGuidGenerator>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task CreateAsnyc() |
|||
{ |
|||
await _organizationUnitManager.CreateAsync(new OrganizationUnit(_guidGenerator.Create(), "Root 1")); |
|||
|
|||
var root1 = await _organizationUnitRepository.GetAsync("Root 1"); |
|||
root1.ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task UpdateAsync() |
|||
{ |
|||
var ou = await _organizationUnitRepository.GetAsync("OU111"); |
|||
ou.DisplayName = "OU111 Updated"; |
|||
await _organizationUnitManager.UpdateAsync(ou); |
|||
|
|||
var ouAfterChange = await _organizationUnitRepository.GetAsync("OU111 Updated"); |
|||
ouAfterChange.DisplayName.ShouldContain("OU111 Updated"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task DeleteAsync() |
|||
{ |
|||
var ou = await _organizationUnitRepository.GetAsync("OU11"); |
|||
await _organizationUnitManager.DeleteAsync(ou.Id); |
|||
|
|||
(await _organizationUnitRepository.GetAsync("OU11")).ShouldBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task MoveAsync() |
|||
{ |
|||
var ou1 = await _organizationUnitRepository.GetAsync("OU1"); |
|||
var ou2 = await _organizationUnitRepository.GetAsync("OU2"); |
|||
|
|||
await _organizationUnitManager.MoveAsync(ou1.Id, ou2.Id); |
|||
|
|||
ou1 = await _organizationUnitRepository.GetAsync("OU1"); |
|||
ou1.ParentId.ShouldBe(ou2.Id); |
|||
ou1.Code.ShouldBe(OrganizationUnit.CreateCode(2, 2)); |
|||
|
|||
var ou11 = await _organizationUnitRepository.GetAsync("OU11"); |
|||
ou11.ParentId.ShouldBe(ou1.Id); |
|||
ou11.Code.ShouldBe(OrganizationUnit.CreateCode(2, 2, 1)); |
|||
|
|||
var ou111 = await _organizationUnitRepository.GetAsync("OU111"); |
|||
ou111.ParentId.ShouldBe(ou11.Id); |
|||
ou111.Code.ShouldBe(OrganizationUnit.CreateCode(2, 2, 1, 1)); |
|||
|
|||
var ou112 = await _organizationUnitRepository.GetAsync("OU112"); |
|||
ou112.ParentId.ShouldBe(ou11.Id); |
|||
ou112.Code.ShouldBe(OrganizationUnit.CreateCode(2, 2, 1, 2)); |
|||
|
|||
var ou12 = await _organizationUnitRepository.GetAsync("OU12"); |
|||
ou12.ParentId.ShouldBe(ou1.Id); |
|||
ou12.Code.ShouldBe(OrganizationUnit.CreateCode(2, 2, 2)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task AddRoleToOrganizationUnitAsync() |
|||
{ |
|||
OrganizationUnit ou = null; |
|||
IdentityRole adminRole = null; |
|||
|
|||
using (var uow = _unitOfWorkManager.Begin()) |
|||
{ |
|||
ou = await _organizationUnitRepository.GetAsync("OU1", true); |
|||
adminRole = await _identityRoleRepository.FindByNormalizedNameAsync(_lookupNormalizer.NormalizeName("admin")); |
|||
await _organizationUnitManager.AddRoleToOrganizationUnitAsync(adminRole, ou); |
|||
await _organizationUnitRepository.UpdateAsync(ou); |
|||
|
|||
await uow.CompleteAsync(); |
|||
} |
|||
|
|||
ou = await _organizationUnitRepository.GetAsync("OU1", includeDetails: true); |
|||
ou.Roles.First().RoleId.ShouldBe(adminRole.Id); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task RemoveRoleFromOrganizationUnitAsync() |
|||
{ |
|||
var ou = await _organizationUnitRepository.GetAsync("OU1", true); |
|||
var adminRole = await _identityRoleRepository.FindByNormalizedNameAsync(_lookupNormalizer.NormalizeName("admin")); |
|||
await _organizationUnitManager.AddRoleToOrganizationUnitAsync(adminRole.Id, ou.Id); |
|||
|
|||
await _organizationUnitManager.RemoveRoleFromOrganizationUnitAsync(adminRole.Id, ou.Id); |
|||
ou = await _organizationUnitRepository.GetAsync("OU1", includeDetails: true); |
|||
ou.Roles.FirstOrDefault(r => r.RoleId == adminRole.Id).ShouldBeNull(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace Volo.Abp.Identity.EntityFrameworkCore |
|||
{ |
|||
public class OrganizationUnitRepository_Tests : OrganizationUnitRepository_Tests<AbpIdentityEntityFrameworkCoreTestModule> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Volo.Abp.Identity.MongoDB |
|||
{ |
|||
public class OrganizationUnitRepository_Tests : OrganizationUnitRepository_Tests<AbpIdentityMongoDbTestModule> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,155 @@ |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Shouldly; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
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 |
|||
{ |
|||
public abstract class OrganizationUnitRepository_Tests<TStartupModule> : AbpIdentityTestBase<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
private readonly IOrganizationUnitRepository _organizationUnitRepository; |
|||
private readonly ILookupNormalizer _lookupNormalizer; |
|||
private readonly IdentityTestData _testData; |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
private readonly OrganizationUnitManager _organizationUnitManager; |
|||
private readonly IIdentityRoleRepository _identityRoleRepository; |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
private readonly IIdentityUserRepository _identityUserRepository; |
|||
|
|||
public OrganizationUnitRepository_Tests() |
|||
{ |
|||
_organizationUnitRepository = ServiceProvider.GetRequiredService<IOrganizationUnitRepository>(); |
|||
_lookupNormalizer = ServiceProvider.GetRequiredService<ILookupNormalizer>(); |
|||
_testData = GetRequiredService<IdentityTestData>(); |
|||
_guidGenerator = GetRequiredService<IGuidGenerator>(); |
|||
_organizationUnitManager = GetRequiredService<OrganizationUnitManager>(); |
|||
_identityRoleRepository = GetRequiredService<IIdentityRoleRepository>(); |
|||
_unitOfWorkManager = GetRequiredService<IUnitOfWorkManager>(); |
|||
_identityUserRepository = GetRequiredService<IIdentityUserRepository>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetChildrenAsync() |
|||
{ |
|||
(await _organizationUnitRepository.GetChildrenAsync(_testData.RoleModeratorId)).ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetAllChildrenWithParentCodeAsync() |
|||
{ |
|||
(await _organizationUnitRepository.GetAllChildrenWithParentCodeAsync(OrganizationUnit.CreateCode(0), _guidGenerator.Create())).ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetListAsync() |
|||
{ |
|||
var ouIds = (await _organizationUnitRepository.GetListAsync(includeDetails: true)) |
|||
.Select(ou => ou.Id).Take(2); |
|||
var ous = await _organizationUnitRepository.GetListAsync(ouIds); |
|||
ous.Count.ShouldBe(2); |
|||
ous.ShouldContain(ou => ou.Id == ouIds.First()); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetOrganizationUnitAsync() |
|||
{ |
|||
var organizationUnit = await _organizationUnitRepository.GetAsync("OU111"); |
|||
organizationUnit.ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetCountAsync() |
|||
{ |
|||
(await _organizationUnitRepository.GetCountAsync()).ShouldBeGreaterThan(0); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Eager_Load_OrganizationUnit_Collections() |
|||
{ |
|||
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.GetAsync("OU111", includeDetails: true); |
|||
|
|||
var ou111Roles = await _organizationUnitRepository.GetRolesAsync(ou, includeDetails: true); |
|||
ou111Roles.Count.ShouldBe(2); |
|||
ou111Roles.ShouldContain(n => n.Name == "manager"); |
|||
ou111Roles.ShouldContain(n => n.Name == "moderator"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetOrganizationUnitRolesWithPagingAsync() |
|||
{ |
|||
OrganizationUnit ou = await _organizationUnitRepository.GetAsync("OU111", includeDetails: true); |
|||
|
|||
var ou111Roles = await _organizationUnitRepository.GetRolesAsync(ou, sorting: "name desc", maxResultCount: 1, includeDetails: true); |
|||
ou111Roles.Count.ShouldBe(1); |
|||
ou111Roles.ShouldContain(n => n.Name == "moderator"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetMembersInOrganizationUnitListAsync() |
|||
{ |
|||
OrganizationUnit ou1 = await _organizationUnitRepository.GetAsync("OU111", true); |
|||
OrganizationUnit ou2 = await _organizationUnitRepository.GetAsync("OU112", true); |
|||
var users = await _identityUserRepository.GetUsersInOrganizationsListAsync(new List<Guid> { ou1.Id, ou2.Id }); |
|||
users.Count.ShouldBeGreaterThan(0); |
|||
} |
|||
[Fact] |
|||
public async Task GetMembersInOrganizationUnitWithParamsAsync() |
|||
{ |
|||
OrganizationUnit ou = await _organizationUnitRepository.GetAsync("OU111", true); |
|||
var users = await _organizationUnitRepository.GetMembersAsync(ou, "UserName DESC", 5, 0, "n"); |
|||
|
|||
users.Count.ShouldBeGreaterThan(1); |
|||
users.Count.ShouldBeLessThanOrEqualTo(5); |
|||
|
|||
//Filter check
|
|||
users.ShouldAllBe(u => u.UserName.Contains("ne") || u.Email.Contains("n")); |
|||
|
|||
//Order check
|
|||
for (var i = 0; i < users.Count - 1; i++) |
|||
{ |
|||
string.Compare( |
|||
users[i].UserName, |
|||
users[i + 1].UserName, |
|||
StringComparison.OrdinalIgnoreCase |
|||
).ShouldBeGreaterThan(0); |
|||
} |
|||
|
|||
users = await _organizationUnitRepository.GetMembersAsync(ou, null, 999, 0, "undefined-username"); |
|||
users.Count.ShouldBe(0); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetMembersCountOfOrganizationUnit() |
|||
{ |
|||
OrganizationUnit ou = await _organizationUnitRepository.GetAsync("OU111", true); |
|||
var usersCount = await _organizationUnitRepository.GetMembersCountAsync(ou); |
|||
|
|||
usersCount.ShouldBeGreaterThan(1); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetRolesCountOfOrganizationUnit() |
|||
{ |
|||
OrganizationUnit ou = await _organizationUnitRepository.GetAsync("OU111", true); |
|||
var rolesCount = await _organizationUnitRepository.GetRolesCountAsync(ou); |
|||
|
|||
rolesCount.ShouldBeGreaterThan(1); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue