1
0
mirror of https://github.com/bitwarden/server synced 2025-12-06 00:03:34 +00:00
Files
server/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/Repositories/AccessPolicyRepository.cs
Thomas Avery 53ba2eeb18 [SM-390] Project Access Policies (#2507)
The purpose of this PR is to create server endpoints for creating, reading, updating, and deleting access policies for projects.
2023-01-19 17:31:19 -06:00

172 lines
7.2 KiB
C#

using AutoMapper;
using Bit.Core.Repositories;
using Bit.Infrastructure.EntityFramework.Models;
using Bit.Infrastructure.EntityFramework.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace Bit.Commercial.Infrastructure.EntityFramework.Repositories;
public class AccessPolicyRepository : BaseEntityFrameworkRepository, IAccessPolicyRepository
{
public AccessPolicyRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) : base(serviceScopeFactory,
mapper)
{
}
public async Task<List<Core.Entities.BaseAccessPolicy>> CreateManyAsync(List<Core.Entities.BaseAccessPolicy> baseAccessPolicies)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
foreach (var baseAccessPolicy in baseAccessPolicies)
{
baseAccessPolicy.SetNewId();
switch (baseAccessPolicy)
{
case Core.Entities.UserProjectAccessPolicy accessPolicy:
{
var entity =
Mapper.Map<UserProjectAccessPolicy>(accessPolicy);
await dbContext.AddAsync(entity);
break;
}
case Core.Entities.GroupProjectAccessPolicy accessPolicy:
{
var entity = Mapper.Map<GroupProjectAccessPolicy>(accessPolicy);
await dbContext.AddAsync(entity);
break;
}
case Core.Entities.ServiceAccountProjectAccessPolicy accessPolicy:
{
var entity = Mapper.Map<ServiceAccountProjectAccessPolicy>(accessPolicy);
await dbContext.AddAsync(entity);
break;
}
}
}
await dbContext.SaveChangesAsync();
return baseAccessPolicies;
}
}
public async Task<bool> AccessPolicyExists(Core.Entities.BaseAccessPolicy baseAccessPolicy)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
switch (baseAccessPolicy)
{
case Core.Entities.UserProjectAccessPolicy accessPolicy:
{
var policy = await dbContext.UserProjectAccessPolicy
.Where(c => c.OrganizationUserId == accessPolicy.OrganizationUserId &&
c.GrantedProjectId == accessPolicy.GrantedProjectId)
.FirstOrDefaultAsync();
return policy != null;
}
case Core.Entities.GroupProjectAccessPolicy accessPolicy:
{
var policy = await dbContext.GroupProjectAccessPolicy
.Where(c => c.GroupId == accessPolicy.GroupId &&
c.GrantedProjectId == accessPolicy.GrantedProjectId)
.FirstOrDefaultAsync();
return policy != null;
}
case Core.Entities.ServiceAccountProjectAccessPolicy accessPolicy:
{
var policy = await dbContext.ServiceAccountProjectAccessPolicy
.Where(c => c.ServiceAccountId == accessPolicy.ServiceAccountId &&
c.GrantedProjectId == accessPolicy.GrantedProjectId)
.FirstOrDefaultAsync();
return policy != null;
}
default:
throw new ArgumentException("Unsupported access policy type provided.", nameof(baseAccessPolicy));
}
}
}
public async Task<Core.Entities.BaseAccessPolicy?> GetByIdAsync(Guid id)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var entity = await dbContext.AccessPolicies.Where(ap => ap.Id == id)
.Include(ap => ((UserProjectAccessPolicy)ap).OrganizationUser.User)
.Include(ap => ((GroupProjectAccessPolicy)ap).Group)
.Include(ap => ((ServiceAccountProjectAccessPolicy)ap).ServiceAccount)
.FirstOrDefaultAsync();
if (entity == null)
{
return null;
}
return MapToCore(entity);
}
}
public async Task ReplaceAsync(Core.Entities.BaseAccessPolicy baseAccessPolicy)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var entity = await dbContext.AccessPolicies.FindAsync(baseAccessPolicy.Id);
if (entity != null)
{
dbContext.AccessPolicies.Attach(entity);
entity.Write = baseAccessPolicy.Write;
entity.Read = baseAccessPolicy.Read;
entity.RevisionDate = baseAccessPolicy.RevisionDate;
await dbContext.SaveChangesAsync();
}
}
}
public async Task<IEnumerable<Core.Entities.BaseAccessPolicy>?> GetManyByProjectId(Guid id)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var entities = await dbContext.AccessPolicies.Where(ap =>
((UserProjectAccessPolicy)ap).GrantedProjectId == id ||
((GroupProjectAccessPolicy)ap).GrantedProjectId == id ||
((ServiceAccountProjectAccessPolicy)ap).GrantedProjectId == id)
.Include(ap => ((UserProjectAccessPolicy)ap).OrganizationUser.User)
.Include(ap => ((GroupProjectAccessPolicy)ap).Group)
.Include(ap => ((ServiceAccountProjectAccessPolicy)ap).ServiceAccount)
.ToListAsync();
return !entities.Any() ? null : entities.Select(MapToCore);
}
}
public async Task DeleteAsync(Guid id)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var entity = await dbContext.AccessPolicies.FindAsync(id);
if (entity != null)
{
dbContext.Remove(entity);
await dbContext.SaveChangesAsync();
}
}
}
private Core.Entities.BaseAccessPolicy MapToCore(BaseAccessPolicy baseAccessPolicyEntity)
{
return baseAccessPolicyEntity switch
{
UserProjectAccessPolicy ap => Mapper.Map<Core.Entities.UserProjectAccessPolicy>(ap),
GroupProjectAccessPolicy ap => Mapper.Map<Core.Entities.GroupProjectAccessPolicy>(ap),
ServiceAccountProjectAccessPolicy ap => Mapper.Map<Core.Entities.ServiceAccountProjectAccessPolicy>(ap),
_ => throw new ArgumentException("Unsupported access policy type")
};
}
}