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 acb6b56dae..f5a54bf961 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 @@ -106,7 +106,7 @@ namespace Volo.Abp.Identity public virtual async Task AddToOrganizationUnitAsync(Guid userId, Guid ouId) { await AddToOrganizationUnitAsync( - await GetByIdAsync(userId), + await _identityUserRepository.GetAsync(userId, true), await _organizationUnitRepository.GetAsync(ouId) ); } @@ -130,7 +130,7 @@ namespace Volo.Abp.Identity public virtual async Task RemoveFromOrganizationUnitAsync(Guid userId, Guid ouId) { await RemoveFromOrganizationUnitAsync( - await GetByIdAsync(userId), + await _identityUserRepository.GetAsync(userId, true), await _organizationUnitRepository.GetAsync(ouId) ); } @@ -145,7 +145,7 @@ namespace Volo.Abp.Identity public virtual async Task SetOrganizationUnitsAsync(Guid userId, params Guid[] organizationUnitIds) { await SetOrganizationUnitsAsync( - await GetByIdAsync(userId), + await _identityUserRepository.GetAsync(userId, true), organizationUnitIds ); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnit.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnit.cs index 0955aa248a..2a48337e45 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnit.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Organizations/OrganizationUnit.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; @@ -37,6 +38,11 @@ namespace Volo.Abp.Identity.Organizations /// public virtual ICollection Children { get; set; } + /// + /// Roles of this OU. + /// + public virtual ICollection Roles { get; protected set; } + /// /// Initializes a new instance of the class. /// @@ -56,6 +62,8 @@ namespace Volo.Abp.Identity.Organizations TenantId = tenantId; DisplayName = displayName; ParentId = parentId; + + Roles = new Collection(); } /// @@ -174,5 +182,36 @@ namespace Volo.Abp.Identity.Organizations 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(TenantId, roleId, Id)); + } + + 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); + } } } 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 88aad4d66a..66861a9027 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 @@ -4,8 +4,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Services; using Volo.Abp.Identity.Localization; +using Volo.Abp.Threading; using Volo.Abp.Uow; namespace Volo.Abp.Identity.Organizations @@ -18,13 +20,19 @@ namespace Volo.Abp.Identity.Organizations protected IOrganizationUnitRepository _organizationUnitRepository { get; private set; } private readonly IStringLocalizer _localizer; + private readonly IIdentityRoleRepository _identityRoleRepository; + private readonly ICancellationTokenProvider _cancellationTokenProvider; public OrganizationUnitManager( IOrganizationUnitRepository organizationUnitRepository, - IStringLocalizer localizer) + IStringLocalizer localizer, + IIdentityRoleRepository identityRoleRepository, + ICancellationTokenProvider cancellationTokenProvider) { _organizationUnitRepository = organizationUnitRepository; _localizer = localizer; + _identityRoleRepository = identityRoleRepository; + _cancellationTokenProvider = cancellationTokenProvider; } [UnitOfWork] @@ -134,5 +142,45 @@ namespace Volo.Abp.Identity.Organizations return await _organizationUnitRepository.GetAllChildrenWithParentCodeAsync(code, parentId); } + + public virtual Task 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) + ); + } + + public virtual Task AddRoleToOrganizationUnitAsync(IdentityRole role, OrganizationUnit ou) + { + var currentRoles = ou.Roles; + + if (currentRoles.Any(r => r.Id == 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 async Task RemoveRoleFromOrganizationUnitAsync(IdentityRole role, OrganizationUnit organizationUnit) + { + await _organizationUnitRepository.EnsureCollectionLoadedAsync(organizationUnit, ou => ou.Roles, _cancellationTokenProvider.Token).ConfigureAwait(false); + + organizationUnit.RemoveRole(role.Id); + } } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs index b16f1e4234..6203233dcc 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs @@ -1,5 +1,6 @@ using System.Linq; using Microsoft.EntityFrameworkCore; +using Volo.Abp.Identity.Organizations; namespace Volo.Abp.Identity.EntityFrameworkCore { @@ -30,5 +31,16 @@ namespace Volo.Abp.Identity.EntityFrameworkCore return queryable .Include(x => x.Claims); } + + public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true) + { + if (!include) + { + return queryable; + } + + return queryable + .Include(x => x.Roles); + } } } \ No newline at end of file