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

@ -248,26 +248,107 @@ public class ProjectsControllerTests
[Theory]
[BitAutoData]
public async void BulkDeleteProjects_Success(SutProvider<ProjectsController> sutProvider, List<Project> data)
public async void BulkDeleteProjects_NoProjectsFound_ThrowsNotFound(
SutProvider<ProjectsController> sutProvider, List<Project> data)
{
sutProvider.GetDependency<IUserService>().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid());
var ids = data.Select(project => project.Id).ToList();
var mockResult = data.Select(project => new Tuple<Project, string>(project, "")).ToList();
sutProvider.GetDependency<IDeleteProjectCommand>().DeleteProjects(ids, default).ReturnsForAnyArgs(mockResult);
var results = await sutProvider.Sut.BulkDeleteAsync(ids);
await sutProvider.GetDependency<IDeleteProjectCommand>().Received(1)
.DeleteProjects(Arg.Is(ids), Arg.Any<Guid>());
Assert.Equal(data.Count, results.Data.Count());
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(new List<Project>());
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.BulkDeleteAsync(ids));
}
[Theory]
[BitAutoData]
public async void BulkDeleteProjects_NoGuids_ThrowsArgumentNullException(
SutProvider<ProjectsController> sutProvider)
public async void BulkDeleteProjects_ProjectsFoundMisMatch_ThrowsNotFound(
SutProvider<ProjectsController> sutProvider, List<Project> data, Project mockProject)
{
sutProvider.GetDependency<IUserService>().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid());
await Assert.ThrowsAsync<ArgumentNullException>(() => sutProvider.Sut.BulkDeleteAsync(new List<Guid>()));
data.Add(mockProject);
var ids = data.Select(project => project.Id).ToList();
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(new List<Project> { mockProject });
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.BulkDeleteAsync(ids));
}
[Theory]
[BitAutoData]
public async void BulkDeleteProjects_OrganizationMistMatch_ThrowsNotFound(
SutProvider<ProjectsController> sutProvider, List<Project> data)
{
var ids = data.Select(project => project.Id).ToList();
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.BulkDeleteAsync(ids));
}
[Theory]
[BitAutoData]
public async void BulkDeleteProjects_NoAccessToSecretsManager_ThrowsNotFound(
SutProvider<ProjectsController> sutProvider, List<Project> data)
{
var ids = data.Select(project => project.Id).ToList();
var organizationId = data.First().OrganizationId;
foreach (var project in data)
{
project.OrganizationId = organizationId;
}
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId)).ReturnsForAnyArgs(false);
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.BulkDeleteAsync(ids));
}
[Theory]
[BitAutoData]
public async void BulkDeleteProjects_ReturnsAccessDeniedForProjectsWithoutAccess_Success(
SutProvider<ProjectsController> sutProvider, List<Project> data)
{
var ids = data.Select(project => project.Id).ToList();
var organizationId = data.First().OrganizationId;
foreach (var project in data)
{
project.OrganizationId = organizationId;
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), project,
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).ReturnsForAnyArgs(AuthorizationResult.Success());
}
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), data.First(),
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).Returns(AuthorizationResult.Failed());
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId)).ReturnsForAnyArgs(true);
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
var results = await sutProvider.Sut.BulkDeleteAsync(ids);
Assert.Equal(data.Count, results.Data.Count());
Assert.Equal("access denied", results.Data.First().Error);
data.Remove(data.First());
await sutProvider.GetDependency<IDeleteProjectCommand>().Received(1)
.DeleteProjects(Arg.Is(AssertHelper.AssertPropertyEqual(data)));
}
[Theory]
[BitAutoData]
public async void BulkDeleteProjects_Success(SutProvider<ProjectsController> sutProvider, List<Project> data)
{
var ids = data.Select(project => project.Id).ToList();
var organizationId = data.First().OrganizationId;
foreach (var project in data)
{
project.OrganizationId = organizationId;
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), project,
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).ReturnsForAnyArgs(AuthorizationResult.Success());
}
sutProvider.GetDependency<IProjectRepository>().GetManyWithSecretsByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId)).ReturnsForAnyArgs(true);
var results = await sutProvider.Sut.BulkDeleteAsync(ids);
await sutProvider.GetDependency<IDeleteProjectCommand>().Received(1)
.DeleteProjects(Arg.Is(AssertHelper.AssertPropertyEqual(data)));
Assert.Equal(data.Count, results.Data.Count());
foreach (var result in results.Data)
{
Assert.Null(result.Error);
}
}
}