1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 08:32:50 -05:00

[SM-788] Extract authorization from secret delete command (#3003)

* Extract authorization from secret delete command
This commit is contained in:
Thomas Avery
2023-06-27 13:12:34 -05:00
committed by GitHub
parent c1723d9e90
commit d020c49c0e
9 changed files with 287 additions and 196 deletions

View File

@ -374,4 +374,83 @@ public class SecretAuthorizationHandlerTests
Assert.True(authzContext.HasSucceeded);
}
[Theory]
[BitAutoData]
public async Task CanDeleteSecret_AccessToSecretsManagerFalse_DoesNotSucceed(
SutProvider<SecretAuthorizationHandler> sutProvider, Secret secret,
ClaimsPrincipal claimsPrincipal)
{
var requirement = SecretOperations.Delete;
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(secret.OrganizationId)
.Returns(false);
var authzContext = new AuthorizationHandlerContext(new List<IAuthorizationRequirement> { requirement },
claimsPrincipal, secret);
await sutProvider.Sut.HandleAsync(authzContext);
Assert.False(authzContext.HasSucceeded);
}
[Theory]
[BitAutoData]
public async Task CanDeleteSecret_NullResource_DoesNotSucceed(
SutProvider<SecretAuthorizationHandler> sutProvider, Secret secret,
ClaimsPrincipal claimsPrincipal,
Guid userId)
{
var requirement = SecretOperations.Delete;
SetupPermission(sutProvider, PermissionType.RunAsAdmin, secret.OrganizationId, userId);
var authzContext = new AuthorizationHandlerContext(new List<IAuthorizationRequirement> { requirement },
claimsPrincipal, null);
await sutProvider.Sut.HandleAsync(authzContext);
Assert.False(authzContext.HasSucceeded);
}
[Theory]
[BitAutoData]
public async Task CanDeleteSecret_ServiceAccountClient_DoesNotSucceed(
SutProvider<SecretAuthorizationHandler> sutProvider, Secret secret, Guid userId,
ClaimsPrincipal claimsPrincipal)
{
var requirement = SecretOperations.Delete;
SetupPermission(sutProvider, PermissionType.RunAsUserWithPermission, secret.OrganizationId, userId,
AccessClientType.ServiceAccount);
sutProvider.GetDependency<ISecretRepository>()
.AccessToSecretAsync(secret.Id, userId, Arg.Any<AccessClientType>())
.Returns((true, true));
var authzContext = new AuthorizationHandlerContext(new List<IAuthorizationRequirement> { requirement },
claimsPrincipal, secret);
await sutProvider.Sut.HandleAsync(authzContext);
Assert.False(authzContext.HasSucceeded);
}
[Theory]
[BitAutoData(PermissionType.RunAsAdmin, true, true, true)]
[BitAutoData(PermissionType.RunAsUserWithPermission, false, false, false)]
[BitAutoData(PermissionType.RunAsUserWithPermission, false, true, true)]
[BitAutoData(PermissionType.RunAsUserWithPermission, true, false, false)]
[BitAutoData(PermissionType.RunAsUserWithPermission, true, true, true)]
public async Task CanDeleteProject_AccessCheck(PermissionType permissionType, bool read, bool write,
bool expected,
SutProvider<SecretAuthorizationHandler> sutProvider, Secret secret,
ClaimsPrincipal claimsPrincipal,
Guid userId)
{
var requirement = SecretOperations.Delete;
SetupPermission(sutProvider, permissionType, secret.OrganizationId, userId);
sutProvider.GetDependency<ISecretRepository>()
.AccessToSecretAsync(secret.Id, userId, Arg.Any<AccessClientType>())
.Returns((read, write));
var authzContext = new AuthorizationHandlerContext(new List<IAuthorizationRequirement> { requirement },
claimsPrincipal, secret);
await sutProvider.Sut.HandleAsync(authzContext);
Assert.Equal(expected, authzContext.HasSucceeded);
}
}

View File

@ -1,8 +1,4 @@
using Bit.Commercial.Core.SecretsManager.Commands.Secrets;
using Bit.Commercial.Core.Test.SecretsManager.Enums;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.SecretsManager.Entities;
using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Test.SecretsManager.AutoFixture.ProjectsFixture;
@ -20,75 +16,12 @@ public class DeleteSecretCommandTests
{
[Theory]
[BitAutoData]
public async Task DeleteSecrets_Throws_NotFoundException(List<Guid> data,
SutProvider<DeleteSecretCommand> sutProvider)
public async Task DeleteSecrets_Success(SutProvider<DeleteSecretCommand> sutProvider, List<Secret> data)
{
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(data).Returns(new List<Secret>());
var exception = await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.DeleteSecrets(data, default));
await sutProvider.GetDependency<ISecretRepository>().DidNotReceiveWithAnyArgs().SoftDeleteManyByIdAsync(default);
}
[Theory]
[BitAutoData]
public async Task DeleteSecrets_OneIdNotFound_Throws_NotFoundException(List<Guid> data,
SutProvider<DeleteSecretCommand> sutProvider)
{
var secret = new Secret()
{
Id = Guid.NewGuid()
};
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(data).Returns(new List<Secret>() { secret });
var exception = await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.DeleteSecrets(data, default));
await sutProvider.GetDependency<ISecretRepository>().DidNotReceiveWithAnyArgs().SoftDeleteManyByIdAsync(default);
}
[Theory]
[BitAutoData(PermissionType.RunAsAdmin)]
[BitAutoData(PermissionType.RunAsUserWithPermission)]
public async Task DeleteSecrets_Success(PermissionType permissionType, List<Guid> data,
SutProvider<DeleteSecretCommand> sutProvider, Guid userId, Guid organizationId, Project mockProject)
{
List<Project> projects = null;
if (permissionType == PermissionType.RunAsAdmin)
{
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(organizationId).Returns(true);
}
else
{
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(organizationId).Returns(false);
sutProvider.GetDependency<IProjectRepository>().AccessToProjectAsync(mockProject.Id, userId, AccessClientType.User)
.Returns((true, true));
projects = new List<Project>() { mockProject };
}
var secrets = new List<Secret>();
foreach (Guid id in data)
{
var secret = new Secret()
{
Id = id,
OrganizationId = organizationId,
Projects = projects
};
secrets.Add(secret);
}
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(data).Returns(secrets);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(default).ReturnsForAnyArgs(true);
var results = await sutProvider.Sut.DeleteSecrets(data, userId);
await sutProvider.GetDependency<ISecretRepository>().Received(1).SoftDeleteManyByIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(data)));
foreach (var result in results)
{
Assert.Equal("", result.Item2);
}
await sutProvider.Sut.DeleteSecrets(data);
await sutProvider.GetDependency<ISecretRepository>()
.Received(1)
.SoftDeleteManyByIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(data.Select(d => d.Id))));
}
}