1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-06 10:32:49 -05:00

Refactor policy checks (#1536)

* Move policy checking logic inside PolicyService

* Refactor to use currentContext.ManagePolicies

* Make orgUser status check more semantic

* Fix single org user checks

* Use CoreHelper implementation to deserialize json

* Refactor policy checks to use db query

* Use new db query for enforcing 2FA Policy

* Add Policy_ReadByTypeApplicableToUser

* Stub out EF implementations

* Refactor: use PolicyRepository only

* Refactor tests

* Copy SQL queries to proj and update sqlproj file

* Refactor importCiphersAsync to use new method

* Add EF implementations and tests

* Refactor SQL to remove unnecessary operations
This commit is contained in:
Thomas Rittson
2021-09-28 06:54:28 +10:00
committed by GitHub
parent fbf3e0dcdc
commit 66629b2f1c
18 changed files with 505 additions and 197 deletions

View File

@ -54,5 +54,30 @@ namespace Bit.Core.Repositories.EntityFramework
return Mapper.Map<List<TableModel.Policy>>(results);
}
}
public async Task<ICollection<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<TableModel.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

@ -0,0 +1,45 @@
using System.Collections.Generic;
using System.Linq;
using Bit.Core.Enums;
using Bit.Core.Models.EntityFramework;
using System;
namespace Bit.Core.Repositories.EntityFramework.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;
var query = from p in dbContext.Policies
join ou in dbContext.OrganizationUsers
on p.OrganizationId equals ou.OrganizationId
where ou.UserId == _userId &&
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;
}
}
}

View File

@ -11,5 +11,9 @@ namespace Bit.Core.Repositories
Task<Policy> GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type);
Task<ICollection<Policy>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Policy>> GetManyByUserIdAsync(Guid userId);
Task<ICollection<Policy>> GetManyByTypeApplicableToUserIdAsync(Guid userId, PolicyType policyType,
OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted);
Task<int> GetCountByTypeApplicableToUserIdAsync(Guid userId, PolicyType policyType,
OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted);
}
}

View File

@ -58,5 +58,33 @@ namespace Bit.Core.Repositories.SqlServer
return results.ToList();
}
}
public async Task<ICollection<Policy>> GetManyByTypeApplicableToUserIdAsync(Guid userId, PolicyType policyType,
OrganizationUserStatusType minStatus)
{
using (var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<Policy>(
$"[{Schema}].[{Table}_ReadByTypeApplicableToUser]",
new { UserId = userId, PolicyType = policyType, MinimumStatus = minStatus },
commandType: CommandType.StoredProcedure);
return results.ToList();
}
}
public async Task<int> GetCountByTypeApplicableToUserIdAsync(Guid userId, PolicyType policyType,
OrganizationUserStatusType minStatus)
{
using (var connection = new SqlConnection(ConnectionString))
{
var result = await connection.ExecuteScalarAsync<int>(
$"[{Schema}].[{Table}_CountByTypeApplicableToUser]",
new { UserId = userId, PolicyType = policyType, MinimumStatus = minStatus },
commandType: CommandType.StoredProcedure);
return result;
}
}
}
}