1
0
mirror of https://github.com/bitwarden/server synced 2026-01-05 10:03:23 +00:00

[SM-1030] Cleanup old access policy management code (#4015)

* Remove access selector code

* Cleanup integration tests
This commit is contained in:
Thomas Avery
2024-05-06 14:56:58 -05:00
committed by GitHub
parent 3715d7d426
commit cd3a45c8c6
26 changed files with 500 additions and 3026 deletions

View File

@@ -1,184 +0,0 @@
#nullable enable
using System.ComponentModel.DataAnnotations;
using Bit.Core.Exceptions;
using Bit.Core.SecretsManager.Entities;
namespace Bit.Api.SecretsManager.Models.Request;
public class AccessPoliciesCreateRequest
{
private static void CheckForDistinctAccessPolicies(IReadOnlyCollection<BaseAccessPolicy> accessPolicies)
{
var distinctAccessPolicies = accessPolicies.DistinctBy(baseAccessPolicy =>
{
return baseAccessPolicy switch
{
UserProjectAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.OrganizationUserId, ap.GrantedProjectId),
GroupProjectAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.GroupId, ap.GrantedProjectId),
ServiceAccountProjectAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.ServiceAccountId,
ap.GrantedProjectId),
UserServiceAccountAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.OrganizationUserId,
ap.GrantedServiceAccountId),
GroupServiceAccountAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.GroupId, ap.GrantedServiceAccountId),
_ => throw new ArgumentException("Unsupported access policy type provided.", nameof(baseAccessPolicy)),
};
}).ToList();
if (accessPolicies.Count != distinctAccessPolicies.Count)
{
throw new BadRequestException("Resources must be unique");
}
}
public IEnumerable<AccessPolicyRequest>? UserAccessPolicyRequests { get; set; }
public IEnumerable<AccessPolicyRequest>? GroupAccessPolicyRequests { get; set; }
public IEnumerable<AccessPolicyRequest>? ServiceAccountAccessPolicyRequests { get; set; }
public List<BaseAccessPolicy> ToBaseAccessPoliciesForProject(Guid grantedProjectId, Guid organizationId)
{
if (UserAccessPolicyRequests == null && GroupAccessPolicyRequests == null && ServiceAccountAccessPolicyRequests == null)
{
throw new BadRequestException("No creation requests provided.");
}
var userAccessPolicies = UserAccessPolicyRequests?
.Select(x => x.ToUserProjectAccessPolicy(grantedProjectId, organizationId)).ToList();
var groupAccessPolicies = GroupAccessPolicyRequests?
.Select(x => x.ToGroupProjectAccessPolicy(grantedProjectId, organizationId)).ToList();
var serviceAccountAccessPolicies = ServiceAccountAccessPolicyRequests?
.Select(x => x.ToServiceAccountProjectAccessPolicy(grantedProjectId, organizationId)).ToList();
var policies = new List<BaseAccessPolicy>();
if (userAccessPolicies != null)
{
policies.AddRange(userAccessPolicies);
}
if (groupAccessPolicies != null)
{
policies.AddRange(groupAccessPolicies);
}
if (serviceAccountAccessPolicies != null)
{
policies.AddRange(serviceAccountAccessPolicies);
}
CheckForDistinctAccessPolicies(policies);
return policies;
}
public List<BaseAccessPolicy> ToBaseAccessPoliciesForServiceAccount(Guid grantedServiceAccountId, Guid organizationId)
{
if (UserAccessPolicyRequests == null && GroupAccessPolicyRequests == null)
{
throw new BadRequestException("No creation requests provided.");
}
var userAccessPolicies = UserAccessPolicyRequests?
.Select(x => x.ToUserServiceAccountAccessPolicy(grantedServiceAccountId, organizationId)).ToList();
var groupAccessPolicies = GroupAccessPolicyRequests?
.Select(x => x.ToGroupServiceAccountAccessPolicy(grantedServiceAccountId, organizationId)).ToList();
var policies = new List<BaseAccessPolicy>();
if (userAccessPolicies != null)
{
policies.AddRange(userAccessPolicies);
}
if (groupAccessPolicies != null)
{
policies.AddRange(groupAccessPolicies);
}
CheckForDistinctAccessPolicies(policies);
return policies;
}
public int Count()
{
var total = 0;
if (UserAccessPolicyRequests != null)
{
total += UserAccessPolicyRequests.Count();
}
if (GroupAccessPolicyRequests != null)
{
total += GroupAccessPolicyRequests.Count();
}
if (ServiceAccountAccessPolicyRequests != null)
{
total += ServiceAccountAccessPolicyRequests.Count();
}
return total;
}
}
public class AccessPolicyRequest
{
[Required]
public Guid GranteeId { get; set; }
[Required]
public bool Read { get; set; }
[Required]
public bool Write { get; set; }
public UserProjectAccessPolicy ToUserProjectAccessPolicy(Guid projectId, Guid organizationId) =>
new()
{
OrganizationUserId = GranteeId,
GrantedProjectId = projectId,
GrantedProject = new Project { OrganizationId = organizationId, Id = projectId },
Read = Read,
Write = Write
};
public GroupProjectAccessPolicy ToGroupProjectAccessPolicy(Guid projectId, Guid organizationId) =>
new()
{
GroupId = GranteeId,
GrantedProjectId = projectId,
GrantedProject = new Project { OrganizationId = organizationId, Id = projectId },
Read = Read,
Write = Write
};
public ServiceAccountProjectAccessPolicy ToServiceAccountProjectAccessPolicy(Guid projectId, Guid organizationId) =>
new()
{
ServiceAccountId = GranteeId,
GrantedProjectId = projectId,
GrantedProject = new Project { OrganizationId = organizationId, Id = projectId },
Read = Read,
Write = Write
};
public UserServiceAccountAccessPolicy ToUserServiceAccountAccessPolicy(Guid id, Guid organizationId) =>
new()
{
OrganizationUserId = GranteeId,
GrantedServiceAccountId = id,
GrantedServiceAccount = new ServiceAccount() { OrganizationId = organizationId, Id = id },
Read = Read,
Write = Write
};
public GroupServiceAccountAccessPolicy ToGroupServiceAccountAccessPolicy(Guid id, Guid organizationId) =>
new()
{
GroupId = GranteeId,
GrantedServiceAccountId = id,
GrantedServiceAccount = new ServiceAccount() { OrganizationId = organizationId, Id = id },
Read = Read,
Write = Write
};
}

View File

@@ -0,0 +1,67 @@
#nullable enable
using System.ComponentModel.DataAnnotations;
using Bit.Core.SecretsManager.Entities;
namespace Bit.Api.SecretsManager.Models.Request;
public class AccessPolicyRequest
{
[Required]
public Guid GranteeId { get; set; }
[Required]
public bool Read { get; set; }
[Required]
public bool Write { get; set; }
public UserProjectAccessPolicy ToUserProjectAccessPolicy(Guid projectId, Guid organizationId) =>
new()
{
OrganizationUserId = GranteeId,
GrantedProjectId = projectId,
GrantedProject = new Project { OrganizationId = organizationId, Id = projectId },
Read = Read,
Write = Write
};
public GroupProjectAccessPolicy ToGroupProjectAccessPolicy(Guid projectId, Guid organizationId) =>
new()
{
GroupId = GranteeId,
GrantedProjectId = projectId,
GrantedProject = new Project { OrganizationId = organizationId, Id = projectId },
Read = Read,
Write = Write
};
public ServiceAccountProjectAccessPolicy ToServiceAccountProjectAccessPolicy(Guid projectId, Guid organizationId) =>
new()
{
ServiceAccountId = GranteeId,
GrantedProjectId = projectId,
GrantedProject = new Project { OrganizationId = organizationId, Id = projectId },
Read = Read,
Write = Write
};
public UserServiceAccountAccessPolicy ToUserServiceAccountAccessPolicy(Guid id, Guid organizationId) =>
new()
{
OrganizationUserId = GranteeId,
GrantedServiceAccountId = id,
GrantedServiceAccount = new ServiceAccount() { OrganizationId = organizationId, Id = id },
Read = Read,
Write = Write
};
public GroupServiceAccountAccessPolicy ToGroupServiceAccountAccessPolicy(Guid id, Guid organizationId) =>
new()
{
GroupId = GranteeId,
GrantedServiceAccountId = id,
GrantedServiceAccount = new ServiceAccount() { OrganizationId = organizationId, Id = id },
Read = Read,
Write = Write
};
}

View File

@@ -1,12 +0,0 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Api.SecretsManager.Models.Request;
public class AccessPolicyUpdateRequest
{
[Required]
public bool Read { get; set; }
[Required]
public bool Write { get; set; }
}

View File

@@ -1,4 +1,5 @@
using Bit.Core.Exceptions;
using Bit.Api.SecretsManager.Utilities;
using Bit.Core.Exceptions;
using Bit.Core.SecretsManager.Entities;
using Bit.Core.SecretsManager.Models.Data;
@@ -10,29 +11,6 @@ public class PeopleAccessPoliciesRequestModel
public IEnumerable<AccessPolicyRequest> GroupAccessPolicyRequests { get; set; }
private static void CheckForDistinctAccessPolicies(IReadOnlyCollection<BaseAccessPolicy> accessPolicies)
{
var distinctAccessPolicies = accessPolicies.DistinctBy(baseAccessPolicy =>
{
return baseAccessPolicy switch
{
UserProjectAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.OrganizationUserId, ap.GrantedProjectId),
GroupProjectAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.GroupId, ap.GrantedProjectId),
ServiceAccountProjectAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.ServiceAccountId,
ap.GrantedProjectId),
UserServiceAccountAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.OrganizationUserId,
ap.GrantedServiceAccountId),
GroupServiceAccountAccessPolicy ap => new Tuple<Guid?, Guid?>(ap.GroupId, ap.GrantedServiceAccountId),
_ => throw new ArgumentException("Unsupported access policy type provided.", nameof(baseAccessPolicy))
};
}).ToList();
if (accessPolicies.Count != distinctAccessPolicies.Count)
{
throw new BadRequestException("Resources must be unique");
}
}
public ProjectPeopleAccessPolicies ToProjectPeopleAccessPolicies(Guid grantedProjectId, Guid organizationId)
{
var userAccessPolicies = UserAccessPolicyRequests?
@@ -51,7 +29,8 @@ public class PeopleAccessPoliciesRequestModel
policies.AddRange(groupAccessPolicies);
}
CheckForDistinctAccessPolicies(policies);
AccessPolicyHelpers.CheckForDistinctAccessPolicies(policies);
AccessPolicyHelpers.CheckAccessPoliciesHaveReadPermission(policies);
return new ProjectPeopleAccessPolicies
{
@@ -62,7 +41,8 @@ public class PeopleAccessPoliciesRequestModel
};
}
public ServiceAccountPeopleAccessPolicies ToServiceAccountPeopleAccessPolicies(Guid grantedServiceAccountId, Guid organizationId)
public ServiceAccountPeopleAccessPolicies ToServiceAccountPeopleAccessPolicies(Guid grantedServiceAccountId,
Guid organizationId)
{
var userAccessPolicies = UserAccessPolicyRequests?
.Select(x => x.ToUserServiceAccountAccessPolicy(grantedServiceAccountId, organizationId)).ToList();
@@ -81,7 +61,7 @@ public class PeopleAccessPoliciesRequestModel
policies.AddRange(groupAccessPolicies);
}
CheckForDistinctAccessPolicies(policies);
AccessPolicyHelpers.CheckForDistinctAccessPolicies(policies);
if (!policies.All(ap => ap.Read && ap.Write))
{

View File

@@ -1,40 +0,0 @@
using Bit.Core.Models.Api;
using Bit.Core.SecretsManager.Entities;
namespace Bit.Api.SecretsManager.Models.Response;
public class ProjectAccessPoliciesResponseModel : ResponseModel
{
private const string _objectName = "projectAccessPolicies";
public ProjectAccessPoliciesResponseModel(IEnumerable<BaseAccessPolicy> baseAccessPolicies)
: base(_objectName)
{
foreach (var baseAccessPolicy in baseAccessPolicies)
{
switch (baseAccessPolicy)
{
case UserProjectAccessPolicy accessPolicy:
UserAccessPolicies.Add(new UserProjectAccessPolicyResponseModel(accessPolicy));
break;
case GroupProjectAccessPolicy accessPolicy:
GroupAccessPolicies.Add(new GroupProjectAccessPolicyResponseModel(accessPolicy));
break;
case ServiceAccountProjectAccessPolicy accessPolicy:
ServiceAccountAccessPolicies.Add(
new ServiceAccountProjectAccessPolicyResponseModel(accessPolicy));
break;
}
}
}
public ProjectAccessPoliciesResponseModel() : base(_objectName)
{
}
public List<UserProjectAccessPolicyResponseModel> UserAccessPolicies { get; set; } = new();
public List<GroupProjectAccessPolicyResponseModel> GroupAccessPolicies { get; set; } = new();
public List<ServiceAccountProjectAccessPolicyResponseModel> ServiceAccountAccessPolicies { get; set; } = new();
}