mirror of
https://github.com/bitwarden/server.git
synced 2025-07-03 00:52:49 -05:00
[SM-707] Refactor authorization for Access Policy Commands (#2905)
* Extract authorization from access policy commands * Use auto mapper to ignore unwanted properties ---------
This commit is contained in:
@ -5,6 +5,7 @@ using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.SecretsManager.AuthorizationRequirements;
|
||||
using Bit.Core.SecretsManager.Commands.AccessPolicies.Interfaces;
|
||||
using Bit.Core.SecretsManager.Entities;
|
||||
using Bit.Core.SecretsManager.Repositories;
|
||||
@ -31,8 +32,10 @@ public class AccessPoliciesController : Controller
|
||||
private readonly IServiceAccountRepository _serviceAccountRepository;
|
||||
private readonly IUpdateAccessPolicyCommand _updateAccessPolicyCommand;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
public AccessPoliciesController(
|
||||
IAuthorizationService authorizationService,
|
||||
IUserService userService,
|
||||
ICurrentContext currentContext,
|
||||
IAccessPolicyRepository accessPolicyRepository,
|
||||
@ -44,6 +47,7 @@ public class AccessPoliciesController : Controller
|
||||
IDeleteAccessPolicyCommand deleteAccessPolicyCommand,
|
||||
IUpdateAccessPolicyCommand updateAccessPolicyCommand)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_userService = userService;
|
||||
_currentContext = currentContext;
|
||||
_serviceAccountRepository = serviceAccountRepository;
|
||||
@ -71,9 +75,17 @@ public class AccessPoliciesController : Controller
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var (accessClient, userId) = await GetAccessClientTypeAsync(project.OrganizationId);
|
||||
var policies = request.ToBaseAccessPoliciesForProject(id);
|
||||
var results = await _createAccessPoliciesCommand.CreateManyAsync(policies, userId, accessClient);
|
||||
var policies = request.ToBaseAccessPoliciesForProject(id, project.OrganizationId);
|
||||
foreach (var policy in policies)
|
||||
{
|
||||
var authorizationResult = await _authorizationService.AuthorizeAsync(User, policy, AccessPolicyOperations.Create);
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
var results = await _createAccessPoliciesCommand.CreateManyAsync(policies);
|
||||
return new ProjectAccessPoliciesResponseModel(results);
|
||||
}
|
||||
|
||||
@ -102,9 +114,17 @@ public class AccessPoliciesController : Controller
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var (accessClient, userId) = await GetAccessClientTypeAsync(serviceAccount.OrganizationId);
|
||||
var policies = request.ToBaseAccessPoliciesForServiceAccount(id);
|
||||
var results = await _createAccessPoliciesCommand.CreateManyAsync(policies, userId, accessClient);
|
||||
var policies = request.ToBaseAccessPoliciesForServiceAccount(id, serviceAccount.OrganizationId);
|
||||
foreach (var policy in policies)
|
||||
{
|
||||
var authorizationResult = await _authorizationService.AuthorizeAsync(User, policy, AccessPolicyOperations.Create);
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
var results = await _createAccessPoliciesCommand.CreateManyAsync(policies);
|
||||
return new ServiceAccountAccessPoliciesResponseModel(results);
|
||||
}
|
||||
|
||||
@ -128,17 +148,29 @@ public class AccessPoliciesController : Controller
|
||||
throw new BadRequestException($"Can process no more than {_maxBulkCreation} creation requests at once.");
|
||||
}
|
||||
|
||||
if (requests.Count != requests.DistinctBy(request => request.GrantedId).Count())
|
||||
{
|
||||
throw new BadRequestException("Resources must be unique");
|
||||
}
|
||||
|
||||
var serviceAccount = await _serviceAccountRepository.GetByIdAsync(id);
|
||||
if (serviceAccount == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var (accessClient, userId) = await GetAccessClientTypeAsync(serviceAccount.OrganizationId);
|
||||
var policies = requests.Select(request => request.ToServiceAccountProjectAccessPolicy(id));
|
||||
var policies = requests.Select(request => request.ToServiceAccountProjectAccessPolicy(id, serviceAccount.OrganizationId)).ToList();
|
||||
foreach (var policy in policies)
|
||||
{
|
||||
var authorizationResult = await _authorizationService.AuthorizeAsync(User, policy, AccessPolicyOperations.Create);
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
var results =
|
||||
await _createAccessPoliciesCommand.CreateManyAsync(new List<BaseAccessPolicy>(policies), userId,
|
||||
accessClient);
|
||||
await _createAccessPoliciesCommand.CreateManyAsync(new List<BaseAccessPolicy>(policies));
|
||||
var responses = results.Select(ap =>
|
||||
new ServiceAccountProjectAccessPolicyResponseModel((ServiceAccountProjectAccessPolicy)ap));
|
||||
return new ListResponseModel<ServiceAccountProjectAccessPolicyResponseModel>(responses);
|
||||
@ -165,8 +197,15 @@ public class AccessPoliciesController : Controller
|
||||
public async Task<BaseAccessPolicyResponseModel> UpdateAccessPolicyAsync([FromRoute] Guid id,
|
||||
[FromBody] AccessPolicyUpdateRequest request)
|
||||
{
|
||||
var userId = _userService.GetProperUserId(User).Value;
|
||||
var result = await _updateAccessPolicyCommand.UpdateAsync(id, request.Read, request.Write, userId);
|
||||
var ap = await _accessPolicyRepository.GetByIdAsync(id);
|
||||
var authorizationResult =
|
||||
await _authorizationService.AuthorizeAsync(User, ap, AccessPolicyOperations.Update);
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
var result = await _updateAccessPolicyCommand.UpdateAsync(id, request.Read, request.Write);
|
||||
|
||||
return result switch
|
||||
{
|
||||
@ -185,8 +224,15 @@ public class AccessPoliciesController : Controller
|
||||
[HttpDelete("{id}")]
|
||||
public async Task DeleteAccessPolicyAsync([FromRoute] Guid id)
|
||||
{
|
||||
var userId = _userService.GetProperUserId(User).Value;
|
||||
await _deleteAccessPolicyCommand.DeleteAsync(id, userId);
|
||||
var ap = await _accessPolicyRepository.GetByIdAsync(id);
|
||||
var authorizationResult =
|
||||
await _authorizationService.AuthorizeAsync(User, ap, AccessPolicyOperations.Delete);
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
await _deleteAccessPolicyCommand.DeleteAsync(id);
|
||||
}
|
||||
|
||||
[HttpGet("/organizations/{id}/access-policies/people/potential-grantees")]
|
||||
|
Reference in New Issue
Block a user