Skip to content

Commit

Permalink
Merge pull request #19853 from abpframework/RemoveClaimFromAllUsers
Browse files Browse the repository at this point in the history
Add `RemoveClaimFromAllUsersAsync` to `IIdentityUserRepository`.
  • Loading branch information
oykuermann authored May 17, 2024
2 parents 2ab4946 + f253c33 commit 6aa243f
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Task<List<IdentityRoleWithUserCount>> GetListWithUserCountAsync(
bool includeDetails = false,
CancellationToken cancellationToken = default
);

Task<List<IdentityRole>> GetListAsync(
string sorting = null,
int maxResultCount = int.MaxValue,
Expand All @@ -45,4 +45,10 @@ Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default
);

Task RemoveClaimFromAllRolesAsync(
string claimType,
bool autoSave = false,
CancellationToken cancellationToken = default
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ Task<List<IdentityUser>> GetListByClaimAsync(
CancellationToken cancellationToken = default
);

Task RemoveClaimFromAllUsersAsync(
string claimType,
bool autoSave = false,
CancellationToken cancellationToken = default
);

Task<List<IdentityUser>> GetListByNormalizedRoleNameAsync(
string normalizedRoleName,
bool includeDetails = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;

namespace Volo.Abp.Identity;

public class IdentityClaimTypeManager : DomainService
{
protected IIdentityClaimTypeRepository IdentityClaimTypeRepository { get; }
protected IIdentityUserRepository IdentityUserRepository { get; }
protected IIdentityRoleRepository IdentityRoleRepository { get; }

public IdentityClaimTypeManager(IIdentityClaimTypeRepository identityClaimTypeRepository)
public IdentityClaimTypeManager(
IIdentityClaimTypeRepository identityClaimTypeRepository,
IIdentityUserRepository identityUserRepository,
IIdentityRoleRepository identityRoleRepository)
{
IdentityClaimTypeRepository = identityClaimTypeRepository;
IdentityUserRepository = identityUserRepository;
IdentityRoleRepository = identityRoleRepository;
}

public virtual async Task<IdentityClaimType> CreateAsync(IdentityClaimType claimType)
Expand All @@ -34,7 +43,21 @@ public virtual async Task<IdentityClaimType> UpdateAsync(IdentityClaimType claim
throw new AbpException($"Can not update a static ClaimType.");
}


return await IdentityClaimTypeRepository.UpdateAsync(claimType);
}

public virtual async Task DeleteAsync(Guid id)
{
var claimType = await IdentityClaimTypeRepository.GetAsync(id);
if (claimType.IsStatic)
{
throw new AbpException($"Can not delete a static ClaimType.");
}

//Remove claim of this type from all users and roles
await IdentityUserRepository.RemoveClaimFromAllUsersAsync(claimType.Name);
await IdentityRoleRepository.RemoveClaimFromAllRolesAsync(claimType.Name);

await IdentityClaimTypeRepository.DeleteAsync(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,26 @@ public virtual async Task<IdentityRole> FindByNormalizedNameAsync(
}

public virtual async Task<List<IdentityRoleWithUserCount>> GetListWithUserCountAsync(
string sorting = null,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
string filter = null,
bool includeDetails = false,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var roles = await GetListInternalAsync(sorting, maxResultCount, skipCount, filter, includeDetails, cancellationToken: cancellationToken);

var roleIds = roles.Select(x => x.Id).ToList();
var userCount = await (await GetDbContextAsync()).Set<IdentityUserRole>()
.Where(userRole => roleIds.Contains(userRole.RoleId))
.GroupBy(userRole => userRole.RoleId)
.Select(x => new
.Select(x => new
{
RoleId = x.Key,
Count = x.Count()
})
.ToListAsync(GetCancellationToken(cancellationToken));

return roles.Select(role => new IdentityRoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList();
}

Expand Down Expand Up @@ -92,6 +92,20 @@ public virtual async Task<long> GetCountAsync(
.LongCountAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task RemoveClaimFromAllRolesAsync(string claimType, bool autoSave = false, CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
var roleClaims = await dbContext.Set<IdentityRoleClaim>().Where(uc => uc.ClaimType == claimType).ToListAsync(cancellationToken: cancellationToken);
if (roleClaims.Any())
{
(await GetDbContextAsync()).Set<IdentityRoleClaim>().RemoveRange(roleClaims);
if (autoSave)
{
await dbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
}

protected virtual async Task<List<IdentityRole>> GetListInternalAsync(
string sorting = null,
int maxResultCount = int.MaxValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ into gp
{
Id = gp.Key, RoleNames = gp.Select(x => x.Name).ToArray()
}).ToListAsync(cancellationToken: cancellationToken);

var orgUnitRoles = await (from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join roleOu in dbContext.Set<OrganizationUnitRole>() on userOu.OrganizationUnitId equals roleOu.OrganizationUnitId
join role in dbContext.Roles on roleOu.RoleId equals role.Id
Expand All @@ -89,7 +89,7 @@ into gp
{
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();
}

Expand Down Expand Up @@ -145,6 +145,20 @@ public virtual async Task<List<IdentityUser>> GetListByClaimAsync(
.ToListAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task RemoveClaimFromAllUsersAsync(string claimType, bool autoSave, CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
var userClaims = await dbContext.Set<IdentityUserClaim>().Where(uc => uc.ClaimType == claimType).ToListAsync(cancellationToken: cancellationToken);
if (userClaims.Any())
{
(await GetDbContextAsync()).Set<IdentityUserClaim>().RemoveRange(userClaims);
if (autoSave)
{
await dbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
}

public virtual async Task<List<IdentityUser>> GetListByNormalizedRoleNameAsync(
string normalizedRoleName,
bool includeDetails = false,
Expand Down Expand Up @@ -216,7 +230,7 @@ public virtual async Task<List<IdentityUser>> GetListAsync(
minModifitionTime,
cancellationToken
);

return await query.IncludeDetails(includeDetails)
.OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityUser.UserName) : sorting)
.PageBy(skipCount, maxResultCount)
Expand Down Expand Up @@ -437,14 +451,14 @@ protected virtual async Task<IQueryable<IdentityUser>> GetFilteredQueryableAsync
{
var upperFilter = filter?.ToUpperInvariant();
var query = await GetQueryableAsync();

if (roleId.HasValue)
{
var dbContext = await GetDbContextAsync();
var organizationUnitIds = await dbContext.Set<OrganizationUnitRole>().Where(q => q.RoleId == roleId.Value).Select(q => q.OrganizationUnitId).ToArrayAsync(cancellationToken: cancellationToken);
query = query.Where(identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value) || identityUser.OrganizationUnits.Any(x => organizationUnitIds.Contains(x.OrganizationUnitId)));
}

return query
.WhereIf(
!filter.IsNullOrWhiteSpace(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ public virtual async Task<List<IdentityRoleWithUserCount>> GetListWithUserCountA
.Where(user => user.Roles.Any(role => roleIds.Contains(role.RoleId)))
.SelectMany(user => user.Roles)
.GroupBy(userRole => userRole.RoleId)
.Select(x => new
.Select(x => new
{
RoleId = x.Key,
Count = x.Count()
})
.ToListAsync(GetCancellationToken(cancellationToken));

return roles.Select(role => new IdentityRoleWithUserCount(role, userCount.FirstOrDefault(x => x.RoleId == role.Id)?.Count ?? 0)).ToList();
}

Expand Down Expand Up @@ -99,6 +99,20 @@ public virtual async Task<long> GetCountAsync(
.LongCountAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task RemoveClaimFromAllRolesAsync(string claimType, bool autoSave = false, CancellationToken cancellationToken = default)
{
var roles = await (await GetMongoQueryableAsync(cancellationToken))
.Where(r => r.Claims.Any(c => c.ClaimType == claimType))
.ToListAsync(GetCancellationToken(cancellationToken));

foreach (var role in roles)
{
role.Claims.RemoveAll(c => c.ClaimType == claimType);
}

await UpdateManyAsync(roles, cancellationToken: cancellationToken);
}

protected virtual async Task<List<IdentityRole>> GetListInternalAsync(
string sorting = null,
int maxResultCount = int.MaxValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ public virtual async Task<List<IdentityUser>> GetListByClaimAsync(
.ToListAsync(GetCancellationToken(cancellationToken));
}

public virtual async Task RemoveClaimFromAllUsersAsync(string claimType, bool autoSave, CancellationToken cancellationToken = default)
{
var users = await (await GetMongoQueryableAsync(cancellationToken))
.Where(u => u.Claims.Any(c => c.ClaimType == claimType))
.ToListAsync(GetCancellationToken(cancellationToken));

foreach (var user in users)
{
user.Claims.RemoveAll(c => c.ClaimType == claimType);
}

await UpdateManyAsync(users, cancellationToken: cancellationToken);
}

public virtual async Task<List<IdentityUser>> GetListByNormalizedRoleNameAsync(
string normalizedRoleName,
bool includeDetails = false,
Expand Down Expand Up @@ -164,7 +178,7 @@ public virtual async Task<List<IdentityUser>> GetListAsync(
DateTime? maxModifitionTime = null,
DateTime? minModifitionTime = null,
CancellationToken cancellationToken = default)
{
{
var query = await GetFilteredQueryableAsync(
filter,
roleId,
Expand All @@ -184,7 +198,7 @@ public virtual async Task<List<IdentityUser>> GetListAsync(
minModifitionTime,
cancellationToken
);

return await query
.OrderBy(sorting.IsNullOrWhiteSpace() ? nameof(IdentityUser.UserName) : sorting)
.As<IMongoQueryable<IdentityUser>>()
Expand Down Expand Up @@ -365,17 +379,17 @@ public virtual async Task<List<IdentityUserIdWithRoleNames>> GetRoleNamesAsync(
CancellationToken cancellationToken = default)
{
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 organizationUnitAndRoleIds = await (await GetMongoQueryableAsync<OrganizationUnit>(cancellationToken)).Where(ou => organizationUnitIds.Contains(ou.Id))
.Select(userOrganizationUnit => new
{
Expand All @@ -384,10 +398,10 @@ public virtual async Task<List<IdentityUserIdWithRoleNames>> GetRoleNamesAsync(
}).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<IdentityRole>(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)
Expand Down Expand Up @@ -429,17 +443,17 @@ protected virtual async Task<IMongoQueryable<IdentityUser>> GetFilteredQueryable
{
var upperFilter = filter?.ToUpperInvariant();
var query = await GetMongoQueryableAsync(cancellationToken);

if (roleId.HasValue)
{
var organizationUnitIds = (await GetMongoQueryableAsync<OrganizationUnit>(cancellationToken))
.Where(ou => ou.Roles.Any(r => r.RoleId == roleId.Value))
.Select(userOrganizationUnit => userOrganizationUnit.Id)
.ToArray();

query = query.Where(identityUser => identityUser.Roles.Any(x => x.RoleId == roleId.Value) || identityUser.OrganizationUnits.Any(x => organizationUnitIds.Contains(x.OrganizationUnitId)));
}

return query
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(
!filter.IsNullOrWhiteSpace(),
Expand Down
Loading

0 comments on commit 6aa243f

Please sign in to comment.