Skip to content

Commit

Permalink
Remove dynamic claim cache when deleting organization's role.
Browse files Browse the repository at this point in the history
  • Loading branch information
maliming committed Nov 20, 2023
1 parent ba940d2 commit ee3377a
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ Task<List<OrganizationUnit>> GetListAsync(
CancellationToken cancellationToken = default
);

Task<List<OrganizationUnit>> GetListByRoleAsync(
Guid roleId,
bool includeDetails = false,
CancellationToken cancellationToken = default
);

Task<List<IdentityRole>> GetRolesAsync(
OrganizationUnit organizationUnit,
string sorting = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class IdentityRoleManager : RoleManager<IdentityRole>, IDomainService
protected IStringLocalizer<IdentityResource> Localizer { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
protected IIdentityUserRepository UserRepository { get; }
protected IOrganizationUnitRepository OrganizationUnitRepository { get; }
protected OrganizationUnitManager OrganizationUnitManager { get; }
protected IDistributedCache<AbpDynamicClaimCacheItem> DynamicClaimCache { get; }

public IdentityRoleManager(
Expand All @@ -33,6 +35,8 @@ public IdentityRoleManager(
IStringLocalizer<IdentityResource> localizer,
ICancellationTokenProvider cancellationTokenProvider,
IIdentityUserRepository userRepository,
IOrganizationUnitRepository organizationUnitRepository,
OrganizationUnitManager organizationUnitManager,
IDistributedCache<AbpDynamicClaimCacheItem> dynamicClaimCache)
: base(
store,
Expand All @@ -44,6 +48,8 @@ public IdentityRoleManager(
Localizer = localizer;
CancellationTokenProvider = cancellationTokenProvider;
UserRepository = userRepository;
OrganizationUnitRepository = organizationUnitRepository;
OrganizationUnitManager = organizationUnitManager;
DynamicClaimCache = dynamicClaimCache;
}

Expand Down Expand Up @@ -84,11 +90,16 @@ public async override Task<IdentityResult> DeleteAsync(IdentityRole role)
}

var userIdList = await UserRepository.GetUserIdListByRoleIdAsync(role.Id, cancellationToken: CancellationToken);
var orgList = await OrganizationUnitRepository.GetListByRoleAsync(role.Id, includeDetails: false, cancellationToken: CancellationToken);
var result = await base.DeleteAsync(role);
if (result.Succeeded)
{
Logger.LogDebug($"Remove dynamic claims cache for users of role: {role.Id}");
await DynamicClaimCache.RemoveManyAsync(userIdList.Select(userId => AbpDynamicClaimCacheItem.CalculateCacheKey(userId, role.TenantId)), token: CancellationToken);
foreach (var organizationUnit in orgList)
{
await OrganizationUnitManager.RemoveDynamicClaimCacheAsync(organizationUnit);
}
}

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public virtual async Task RemoveRoleFromOrganizationUnitAsync(IdentityRole role,
await OrganizationUnitRepository.UpdateAsync(organizationUnit);
}

protected virtual async Task RemoveDynamicClaimCacheAsync(OrganizationUnit organizationUnit)
public virtual async Task RemoveDynamicClaimCacheAsync(OrganizationUnit organizationUnit)
{
Logger.LogDebug($"Remove dynamic claims cache for users of organization: {organizationUnit.Id}");
var userIds = await OrganizationUnitRepository.GetMemberIdsAsync(organizationUnit.Id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ public virtual async Task<List<OrganizationUnit>> GetListAsync(
.ToListAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task<List<OrganizationUnit>> GetListByRoleAsync(
Guid roleId,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();

var query = from organizationRole in dbContext.Set<OrganizationUnitRole>()
join organizationUnit in dbContext.OrganizationUnits.IncludeDetails(includeDetails) on organizationRole.OrganizationUnitId equals organizationUnit.Id
where organizationRole.RoleId == roleId
select organizationUnit;

return await query.ToListAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task<OrganizationUnit> GetAsync(
string displayName,
bool includeDetails = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ public virtual async Task<List<OrganizationUnit>> GetListAsync(
.ToListAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task<List<OrganizationUnit>> GetListByRoleAsync(
Guid roleId,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.Roles.Any(r => r.RoleId == roleId))
.ToListAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task<List<OrganizationUnit>> GetListAsync(
string sorting = null,
int maxResultCount = int.MaxValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,63 @@ await UsingUowAsync(async () =>
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "moderator");
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "manager"); //manager role from OU111 is deleted.
}

[Fact]
public async Task Should_Get_Correct_Claims_After_User_Organization_Role_Or_Member_Changed()
{
ClaimsPrincipal claimsPrincipal = null;
await UsingUowAsync(async () =>
{
var user = await _identityUserManager.GetByIdAsync(_testData.UserBobId);
user.ShouldNotBeNull();
claimsPrincipal = await _abpUserClaimsPrincipalFactory.CreateAsync(user);
claimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "supporter");
claimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "moderator");
claimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "manager");
var dynamicClaimsPrincipal = await _abpClaimsPrincipalFactory.CreateDynamicAsync(claimsPrincipal);
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "supporter");
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "moderator");
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "manager");
var ou = await _organizationUnitRepository.GetAsync("OU111", true);
ou.ShouldNotBeNull();
ou.Roles.Count.ShouldBe(2);
ou.Roles.ShouldContain(x => x.RoleId == _testData.RoleModeratorId);
ou.Roles.ShouldContain(x => x.RoleId == _testData.RoleManagerId);
ou.AddRole(_testData.RoleSaleId);
await _identityUserManager.AddToOrganizationUnitAsync(user, ou);
await _organizationUnitManager.UpdateAsync(ou);
});
var dynamicClaimsPrincipal = await _abpClaimsPrincipalFactory.CreateDynamicAsync(claimsPrincipal);
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "supporter");
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "moderator");
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "manager");
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "sale");

await UsingUowAsync(async () =>
{
var saleRole = await _identityRoleRepository.GetAsync(_testData.RoleSaleId);
await _identityRoleManager.DeleteAsync(saleRole);
});

dynamicClaimsPrincipal = await _abpClaimsPrincipalFactory.CreateDynamicAsync(claimsPrincipal);
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "supporter");
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "moderator");
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "manager");
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "sale");

await UsingUowAsync(async () =>
{
var user = await _identityUserManager.GetByIdAsync(_testData.UserBobId);
user.ShouldNotBeNull();
var ou = await _organizationUnitRepository.GetAsync("OU111", true);
ou.ShouldNotBeNull();
await _identityUserManager.RemoveFromOrganizationUnitAsync(user.Id, ou.Id);
});

dynamicClaimsPrincipal = await _abpClaimsPrincipalFactory.CreateDynamicAsync(claimsPrincipal);
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "supporter");
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "moderator");
dynamicClaimsPrincipal.Claims.ShouldContain(x => x.Type == ClaimTypes.Role && x.Value == "manager");
dynamicClaimsPrincipal.Claims.ShouldNotContain(x => x.Type == ClaimTypes.Role && x.Value == "sale");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ private async Task AddOrganizationUnits()
_ou111.AddRole(_moderatorRole.Id);
_ou111.AddRole(_managerRole.Id);
await _organizationUnitRepository.InsertAsync(_ou111);

var _ou222 = new OrganizationUnit(_guidGenerator.Create(), "OU222");
_ou222.Code = OrganizationUnit.CreateCode(1, 1, 1);
_ou222.AddRole(_moderatorRole.Id);
_ou222.AddRole(_managerRole.Id);
await _organizationUnitRepository.InsertAsync(_ou222);
}

private async Task AddUsers()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ public async Task GetListAsync()
ous.ShouldContain(ou => ou.Id == ouIds.First());
}

[Fact]
public async Task GetListByRoleAsync()
{
var ous = await _organizationUnitRepository.GetListByRoleAsync(_testData.RoleManagerId);
ous.Count.ShouldBe(2);
ous.ShouldContain(ou => ou.DisplayName == "OU111");
ous.ShouldContain(ou => ou.DisplayName == "OU222");

ous = await _organizationUnitRepository.GetListByRoleAsync(_testData.RoleModeratorId);
ous.Count.ShouldBe(2);
ous.ShouldContain(ou => ou.DisplayName == "OU111");
ous.ShouldContain(ou => ou.DisplayName == "OU222");

ous = await _organizationUnitRepository.GetListByRoleAsync(_testData.RoleSaleId);
ous.Count.ShouldBe(0);
}

[Fact]
public async Task AddMemberToOrganizationUnit()
{
Expand Down

0 comments on commit ee3377a

Please sign in to comment.