1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 23:52:50 -05:00

[SM-702] Extract access policy checks from create/update project commands (#2842)

* Move to access query for project commands

* Swap to hasAccess method per action

* Swap to authorization handler pattern

* Move ProjectOperationRequirement to Core

* Add default throw + tests

* Swap to reflection for testing switch
This commit is contained in:
Thomas Avery
2023-05-03 09:40:24 -05:00
committed by GitHub
parent 7be19b53f4
commit 5474d3da18
28 changed files with 490 additions and 166 deletions

View File

@ -4,6 +4,7 @@ using Bit.Api.SecretsManager.Models.Response;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.SecretsManager.AuthorizationRequirements;
using Bit.Core.SecretsManager.Commands.Projects.Interfaces;
using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Services;
@ -22,6 +23,7 @@ public class ProjectsController : Controller
private readonly ICreateProjectCommand _createProjectCommand;
private readonly IUpdateProjectCommand _updateProjectCommand;
private readonly IDeleteProjectCommand _deleteProjectCommand;
private readonly IAuthorizationService _authorizationService;
public ProjectsController(
ICurrentContext currentContext,
@ -29,7 +31,8 @@ public class ProjectsController : Controller
IProjectRepository projectRepository,
ICreateProjectCommand createProjectCommand,
IUpdateProjectCommand updateProjectCommand,
IDeleteProjectCommand deleteProjectCommand)
IDeleteProjectCommand deleteProjectCommand,
IAuthorizationService authorizationService)
{
_currentContext = currentContext;
_userService = userService;
@ -37,6 +40,7 @@ public class ProjectsController : Controller
_createProjectCommand = createProjectCommand;
_updateProjectCommand = updateProjectCommand;
_deleteProjectCommand = deleteProjectCommand;
_authorizationService = authorizationService;
}
[HttpGet("organizations/{organizationId}/projects")]
@ -58,26 +62,37 @@ public class ProjectsController : Controller
}
[HttpPost("organizations/{organizationId}/projects")]
public async Task<ProjectResponseModel> CreateAsync([FromRoute] Guid organizationId, [FromBody] ProjectCreateRequestModel createRequest)
public async Task<ProjectResponseModel> CreateAsync([FromRoute] Guid organizationId,
[FromBody] ProjectCreateRequestModel createRequest)
{
if (!_currentContext.AccessSecretsManager(organizationId))
var project = createRequest.ToProject(organizationId);
var authorizationResult =
await _authorizationService.AuthorizeAsync(User, project, ProjectOperations.Create);
if (!authorizationResult.Succeeded)
{
throw new NotFoundException();
}
var userId = _userService.GetProperUserId(User).Value;
var result = await _createProjectCommand.CreateAsync(createRequest.ToProject(organizationId), userId);
var result = await _createProjectCommand.CreateAsync(project, userId);
// Creating a project means you have read & write permission.
return new ProjectResponseModel(result, true, true);
}
[HttpPut("projects/{id}")]
public async Task<ProjectResponseModel> UpdateAsync([FromRoute] Guid id, [FromBody] ProjectUpdateRequestModel updateRequest)
public async Task<ProjectResponseModel> UpdateAsync([FromRoute] Guid id,
[FromBody] ProjectUpdateRequestModel updateRequest)
{
var userId = _userService.GetProperUserId(User).Value;
var project = await _projectRepository.GetByIdAsync(id);
var authorizationResult =
await _authorizationService.AuthorizeAsync(User, project, ProjectOperations.Update);
if (!authorizationResult.Succeeded)
{
throw new NotFoundException();
}
var result = await _updateProjectCommand.UpdateAsync(updateRequest.ToProject(id), userId);
var result = await _updateProjectCommand.UpdateAsync(updateRequest.ToProject(id));
// Updating a project means you have read & write permission.
return new ProjectResponseModel(result, true, true);

View File

@ -12,7 +12,7 @@ public class ProjectCreateRequestModel
public Project ToProject(Guid organizationId)
{
return new Project()
return new Project
{
OrganizationId = organizationId,
Name = Name,

View File

@ -12,11 +12,10 @@ public class ProjectUpdateRequestModel
public Project ToProject(Guid id)
{
return new Project()
return new Project
{
Id = id,
Name = Name,
};
}
}