1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-03 17:12:49 -05:00

[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537)

* [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails

* [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync

* [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user

* [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data

* [EC-787] Returning PolicyData on stored procedures

* [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection

* [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync

* [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync

* [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync

* [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync

* [EC-787] Changed integration test to check for single result

* [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete

* [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails

* [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser

* [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync

* [EC-787] Removed 'OrganizationUserType' parameter from queries

* [EC-787] Formatted OrganizationUserPolicyDetailsCompare

* [EC-787] Renamed SQL migration files

* [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json

* [EC-787] Refactored excluded user types for each Policy

* [EC-787] Updated dates on dbo_future files

* [EC-787] Remove dbo_future files from sql proj

* [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync

* [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType

* Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>

---------

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
This commit is contained in:
Rui Tomé
2023-05-12 08:22:19 +01:00
committed by GitHub
parent 99b0953acd
commit 8d3fe12170
26 changed files with 560 additions and 319 deletions

View File

@ -587,4 +587,38 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
await dbContext.SaveChangesAsync();
}
}
public async Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId, PolicyType policyType)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var providerOrganizations = from pu in dbContext.ProviderUsers
where pu.UserId == userId
join po in dbContext.ProviderOrganizations
on pu.ProviderId equals po.ProviderId
select po;
var query = from p in dbContext.Policies
join ou in dbContext.OrganizationUsers
on p.OrganizationId equals ou.OrganizationId
let email = dbContext.Users.Find(userId).Email // Invited orgUsers do not have a UserId associated with them, so we have to match up their email
where p.Type == policyType &&
(ou.UserId == userId || ou.Email == email)
select new OrganizationUserPolicyDetails
{
OrganizationUserId = ou.Id,
OrganizationId = p.OrganizationId,
PolicyType = p.Type,
PolicyEnabled = p.Enabled,
PolicyData = p.Data,
OrganizationUserType = ou.Type,
OrganizationUserStatus = ou.Status,
OrganizationUserPermissionsData = ou.Permissions,
IsProvider = providerOrganizations.Any(po => po.OrganizationId == p.OrganizationId)
};
return await query.ToListAsync();
}
}
}

View File

@ -48,29 +48,4 @@ public class PolicyRepository : Repository<Core.Entities.Policy, Policy, Guid>,
return Mapper.Map<List<Core.Entities.Policy>>(results);
}
}
public async Task<ICollection<Core.Entities.Policy>> GetManyByTypeApplicableToUserIdAsync(Guid userId, PolicyType policyType,
OrganizationUserStatusType minStatus)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var query = new PolicyReadByTypeApplicableToUserQuery(userId, policyType, minStatus);
var results = await query.Run(dbContext).ToListAsync();
return Mapper.Map<List<Core.Entities.Policy>>(results);
}
}
public async Task<int> GetCountByTypeApplicableToUserIdAsync(Guid userId, PolicyType policyType,
OrganizationUserStatusType minStatus)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var query = new PolicyReadByTypeApplicableToUserQuery(userId, policyType, minStatus);
return await GetCountFromQuery(query);
}
}
}

View File

@ -1,50 +0,0 @@
using Bit.Core.Enums;
using Bit.Infrastructure.EntityFramework.Models;
namespace Bit.Infrastructure.EntityFramework.Repositories.Queries;
public class PolicyReadByTypeApplicableToUserQuery : IQuery<Policy>
{
private readonly Guid _userId;
private readonly PolicyType _policyType;
private readonly OrganizationUserStatusType _minimumStatus;
public PolicyReadByTypeApplicableToUserQuery(Guid userId, PolicyType policyType, OrganizationUserStatusType minimumStatus)
{
_userId = userId;
_policyType = policyType;
_minimumStatus = minimumStatus;
}
public IQueryable<Policy> Run(DatabaseContext dbContext)
{
var providerOrganizations = from pu in dbContext.ProviderUsers
where pu.UserId == _userId
join po in dbContext.ProviderOrganizations
on pu.ProviderId equals po.ProviderId
select po;
string userEmail = null;
if (_minimumStatus == OrganizationUserStatusType.Invited)
{
// Invited orgUsers do not have a UserId associated with them, so we have to match up their email
userEmail = dbContext.Users.Find(_userId)?.Email;
}
var query = from p in dbContext.Policies
join ou in dbContext.OrganizationUsers
on p.OrganizationId equals ou.OrganizationId
where
((_minimumStatus > OrganizationUserStatusType.Invited && ou.UserId == _userId) ||
(_minimumStatus == OrganizationUserStatusType.Invited && ou.Email == userEmail)) &&
p.Type == _policyType &&
p.Enabled &&
ou.Status >= _minimumStatus &&
ou.Type >= OrganizationUserType.User &&
(ou.Permissions == null ||
ou.Permissions.Contains($"\"managePolicies\":false")) &&
!providerOrganizations.Any(po => po.OrganizationId == p.OrganizationId)
select p;
return query;
}
}