mirror of
https://github.com/bitwarden/server
synced 2025-12-25 04:33:26 +00:00
[PM-25126] Add Bulk Policy Details (#6256)
* Added new bulk get for policy details * Query improvements to avoid unnecessary look-ups.
This commit is contained in:
@@ -183,4 +183,94 @@ public class PolicyRepository : Repository<AdminConsoleEntities.Policy, Policy,
|
||||
|
||||
return await policyWithAffectedUsers.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<OrganizationPolicyDetails>> GetPolicyDetailsByUserIdsAndPolicyType(
|
||||
IEnumerable<Guid> userIds, PolicyType policyType)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(userIds);
|
||||
|
||||
var userIdsList = userIds.Where(id => id != Guid.Empty).ToList();
|
||||
|
||||
if (userIdsList.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
await using var dbContext = GetDatabaseContext(scope);
|
||||
|
||||
// Get provider relationships
|
||||
var providerLookup = await (from pu in dbContext.ProviderUsers
|
||||
join po in dbContext.ProviderOrganizations on pu.ProviderId equals po.ProviderId
|
||||
where pu.UserId != null && userIdsList.Contains(pu.UserId.Value)
|
||||
select new { pu.UserId, po.OrganizationId })
|
||||
.ToListAsync();
|
||||
|
||||
// Hashset for lookup
|
||||
var providerSet = new HashSet<(Guid UserId, Guid OrganizationId)>(
|
||||
providerLookup.Select(p => (p.UserId!.Value, p.OrganizationId)));
|
||||
|
||||
// Branch 1: Accepted users
|
||||
var acceptedUsers = await (from p in dbContext.Policies
|
||||
join ou in dbContext.OrganizationUsers on p.OrganizationId equals ou.OrganizationId
|
||||
join o in dbContext.Organizations on p.OrganizationId equals o.Id
|
||||
where p.Enabled
|
||||
&& p.Type == policyType
|
||||
&& o.Enabled
|
||||
&& o.UsePolicies
|
||||
&& ou.Status != OrganizationUserStatusType.Invited
|
||||
&& ou.UserId != null
|
||||
&& userIdsList.Contains(ou.UserId.Value)
|
||||
select new
|
||||
{
|
||||
OrganizationUserId = ou.Id,
|
||||
OrganizationId = p.OrganizationId,
|
||||
PolicyType = p.Type,
|
||||
PolicyData = p.Data,
|
||||
OrganizationUserType = ou.Type,
|
||||
OrganizationUserStatus = ou.Status,
|
||||
OrganizationUserPermissionsData = ou.Permissions,
|
||||
UserId = ou.UserId.Value
|
||||
}).ToListAsync();
|
||||
|
||||
// Branch 2: Invited users
|
||||
var invitedUsers = await (from p in dbContext.Policies
|
||||
join ou in dbContext.OrganizationUsers on p.OrganizationId equals ou.OrganizationId
|
||||
join o in dbContext.Organizations on p.OrganizationId equals o.Id
|
||||
join u in dbContext.Users on ou.Email equals u.Email
|
||||
where p.Enabled
|
||||
&& o.Enabled
|
||||
&& o.UsePolicies
|
||||
&& ou.Status == OrganizationUserStatusType.Invited
|
||||
&& userIdsList.Contains(u.Id)
|
||||
&& p.Type == policyType
|
||||
select new
|
||||
{
|
||||
OrganizationUserId = ou.Id,
|
||||
OrganizationId = p.OrganizationId,
|
||||
PolicyType = p.Type,
|
||||
PolicyData = p.Data,
|
||||
OrganizationUserType = ou.Type,
|
||||
OrganizationUserStatus = ou.Status,
|
||||
OrganizationUserPermissionsData = ou.Permissions,
|
||||
UserId = u.Id
|
||||
}).ToListAsync();
|
||||
|
||||
// Combine results with provder lookup
|
||||
var allResults = acceptedUsers.Concat(invitedUsers)
|
||||
.Select(item => new OrganizationPolicyDetails
|
||||
{
|
||||
OrganizationUserId = item.OrganizationUserId,
|
||||
OrganizationId = item.OrganizationId,
|
||||
PolicyType = item.PolicyType,
|
||||
PolicyData = item.PolicyData,
|
||||
OrganizationUserType = item.OrganizationUserType,
|
||||
OrganizationUserStatus = item.OrganizationUserStatus,
|
||||
OrganizationUserPermissionsData = item.OrganizationUserPermissionsData,
|
||||
UserId = item.UserId,
|
||||
IsProvider = providerSet.Contains((item.UserId, item.OrganizationId))
|
||||
});
|
||||
|
||||
return allResults.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user