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

[SM-787] Extract authorization from project delete command (#2987)

* Extract authorization from project delete command

* Support service account write access

---------

Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
This commit is contained in:
Thomas Avery
2023-07-11 15:15:18 -05:00
committed by GitHub
parent 4dea376aa3
commit b629c31de9
11 changed files with 269 additions and 213 deletions

View File

@ -6,6 +6,7 @@ using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.SecretsManager.AuthorizationRequirements;
using Bit.Core.SecretsManager.Commands.Projects.Interfaces;
using Bit.Core.SecretsManager.Entities;
using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Services;
using Bit.Core.Utilities;
@ -127,11 +128,44 @@ public class ProjectsController : Controller
}
[HttpPost("projects/delete")]
public async Task<ListResponseModel<BulkDeleteResponseModel>> BulkDeleteAsync([FromBody] List<Guid> ids)
public async Task<ListResponseModel<BulkDeleteResponseModel>> BulkDeleteAsync(
[FromBody] List<Guid> ids)
{
var userId = _userService.GetProperUserId(User).Value;
var results = await _deleteProjectCommand.DeleteProjects(ids, userId);
var responses = results.Select(r => new BulkDeleteResponseModel(r.Item1.Id, r.Item2));
var projects = (await _projectRepository.GetManyWithSecretsByIds(ids)).ToList();
if (!projects.Any() || projects.Count != ids.Count)
{
throw new NotFoundException();
}
// Ensure all projects belongs to the same organization
var organizationId = projects.First().OrganizationId;
if (projects.Any(p => p.OrganizationId != organizationId) ||
!_currentContext.AccessSecretsManager(organizationId))
{
throw new NotFoundException();
}
var projectsToDelete = new List<Project>();
var results = new List<(Project Project, string Error)>();
foreach (var project in projects)
{
var authorizationResult =
await _authorizationService.AuthorizeAsync(User, project, ProjectOperations.Delete);
if (authorizationResult.Succeeded)
{
projectsToDelete.Add(project);
results.Add((project, ""));
}
else
{
results.Add((project, "access denied"));
}
}
await _deleteProjectCommand.DeleteProjects(projectsToDelete);
var responses = results.Select(r => new BulkDeleteResponseModel(r.Project.Id, r.Error));
return new ListResponseModel<BulkDeleteResponseModel>(responses);
}
}