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

[SM-706] Extract Authorization From Create/Update Secret Commands (#2896)

* Extract authorization from commands

* Swap to request model validation.

* Swap to pattern detection
This commit is contained in:
Thomas Avery
2023-06-08 16:40:35 -05:00
committed by GitHub
parent 6a9e7a1d0a
commit 05f11a8ee1
15 changed files with 674 additions and 231 deletions

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.SecretsFixture;
@ -18,61 +14,15 @@ namespace Bit.Commercial.Core.Test.SecretsManager.Commands.Secrets;
public class CreateSecretCommandTests
{
[Theory]
[BitAutoData(PermissionType.RunAsAdmin)]
[BitAutoData(PermissionType.RunAsUserWithPermission)]
public async Task CreateAsync_Success(PermissionType permissionType, Secret data,
SutProvider<CreateSecretCommand> sutProvider, Guid userId, Project mockProject)
[BitAutoData]
public async Task CreateAsync_Success(Secret data,
SutProvider<CreateSecretCommand> sutProvider, Project mockProject)
{
sutProvider.GetDependency<IProjectRepository>().ProjectsAreInOrganization(default, default).ReturnsForAnyArgs(true);
mockProject.OrganizationId = data.OrganizationId;
data.Projects = new List<Project>() { mockProject };
if (permissionType == PermissionType.RunAsAdmin)
{
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(data.OrganizationId).Returns(true);
sutProvider.GetDependency<IProjectRepository>().AccessToProjectAsync((Guid)data.Projects?.First().Id, userId, AccessClientType.NoAccessCheck)
.Returns((true, true));
}
else
{
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(data.OrganizationId).Returns(false);
sutProvider.GetDependency<IProjectRepository>().AccessToProjectAsync((Guid)data.Projects?.First().Id, userId, AccessClientType.User)
.Returns((true, true));
}
await sutProvider.Sut.CreateAsync(data, userId);
await sutProvider.Sut.CreateAsync(data);
await sutProvider.GetDependency<ISecretRepository>().Received(1)
.CreateAsync(data);
}
[Theory]
[BitAutoData]
public async Task CreateAsync_UserWithoutPermission_ThrowsNotFound(Secret data,
SutProvider<CreateSecretCommand> sutProvider, Guid userId, Project mockProject)
{
data.Projects = new List<Project>() { mockProject };
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(data.OrganizationId).Returns(false);
sutProvider.GetDependency<IProjectRepository>().AccessToProjectAsync((Guid)data.Projects?.First().Id, userId, AccessClientType.User)
.Returns((false, false));
await Assert.ThrowsAsync<NotFoundException>(() =>
sutProvider.Sut.CreateAsync(data, userId));
}
[Theory]
[BitAutoData]
public async Task CreateAsync_NoProjects_User_ThrowsNotFound(Secret data,
SutProvider<CreateSecretCommand> sutProvider, Guid userId)
{
data.Projects = null;
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(data.OrganizationId).Returns(false);
await Assert.ThrowsAsync<NotFoundException>(() =>
sutProvider.Sut.CreateAsync(data, userId));
}
}

View File

@ -1,7 +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;
@ -24,36 +21,20 @@ public class UpdateSecretCommandTests
[BitAutoData]
public async Task UpdateAsync_SecretDoesNotExist_ThrowsNotFound(Secret data, SutProvider<UpdateSecretCommand> sutProvider)
{
var exception = await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(data, default));
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(data));
await sutProvider.GetDependency<ISecretRepository>().DidNotReceiveWithAnyArgs().UpdateAsync(default);
}
[Theory]
[BitAutoData(PermissionType.RunAsAdmin)]
[BitAutoData(PermissionType.RunAsUserWithPermission)]
public async Task UpdateAsync_Success(PermissionType permissionType, Secret data, SutProvider<UpdateSecretCommand> sutProvider, Guid userId, Project mockProject)
[BitAutoData]
public async Task UpdateAsync_Success(Secret existingSecret, Secret data, SutProvider<UpdateSecretCommand> sutProvider, Project mockProject)
{
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(data.OrganizationId).Returns(true);
sutProvider.GetDependency<IProjectRepository>().ProjectsAreInOrganization(default, default).ReturnsForAnyArgs(true);
mockProject.OrganizationId = data.OrganizationId;
sutProvider.GetDependency<ISecretRepository>().GetByIdAsync(existingSecret.Id).Returns(existingSecret);
data.Projects = new List<Project>() { mockProject };
if (permissionType == PermissionType.RunAsAdmin)
{
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(data.OrganizationId).Returns(true);
}
else
{
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(data.OrganizationId).Returns(false);
sutProvider.GetDependency<IProjectRepository>()
.AccessToProjectAsync((Guid)data.Projects?.First().Id, userId, AccessClientType.User)
.Returns((true, true));
}
sutProvider.GetDependency<ISecretRepository>().GetByIdAsync(data.Id).Returns(data);
await sutProvider.Sut.UpdateAsync(data, userId);
await sutProvider.Sut.UpdateAsync(data);
await sutProvider.GetDependency<ISecretRepository>().Received(1)
.UpdateAsync(data);
@ -61,13 +42,10 @@ public class UpdateSecretCommandTests
[Theory]
[BitAutoData]
public async Task UpdateAsync_DoesNotModifyOrganizationId(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider, Guid userId)
public async Task UpdateAsync_DoesNotModifyOrganizationId(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider)
{
var updatedOrgId = Guid.NewGuid();
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(existingSecret.OrganizationId).Returns(true);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(existingSecret.OrganizationId).Returns(true);
sutProvider.GetDependency<ISecretRepository>().GetByIdAsync(existingSecret.Id).Returns(existingSecret);
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(updatedOrgId).Returns(true);
var secretUpdate = new Secret()
{
@ -76,7 +54,7 @@ public class UpdateSecretCommandTests
Key = existingSecret.Key,
};
var result = await sutProvider.Sut.UpdateAsync(secretUpdate, userId);
var result = await sutProvider.Sut.UpdateAsync(secretUpdate);
Assert.Equal(existingSecret.OrganizationId, result.OrganizationId);
Assert.NotEqual(existingSecret.OrganizationId, updatedOrgId);
@ -84,11 +62,9 @@ public class UpdateSecretCommandTests
[Theory]
[BitAutoData]
public async Task UpdateAsync_DoesNotModifyCreationDate(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider, Guid userId)
public async Task UpdateAsync_DoesNotModifyCreationDate(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider)
{
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(existingSecret.OrganizationId).Returns(true);
sutProvider.GetDependency<ISecretRepository>().GetByIdAsync(existingSecret.Id).Returns(existingSecret);
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(existingSecret.OrganizationId).Returns(true);
var updatedCreationDate = DateTime.UtcNow;
var secretUpdate = new Secret()
@ -99,7 +75,7 @@ public class UpdateSecretCommandTests
OrganizationId = existingSecret.OrganizationId
};
var result = await sutProvider.Sut.UpdateAsync(secretUpdate, userId);
var result = await sutProvider.Sut.UpdateAsync(secretUpdate);
Assert.Equal(existingSecret.CreationDate, result.CreationDate);
Assert.NotEqual(existingSecret.CreationDate, updatedCreationDate);
@ -107,11 +83,9 @@ public class UpdateSecretCommandTests
[Theory]
[BitAutoData]
public async Task UpdateAsync_DoesNotModifyDeletionDate(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider, Guid userId)
public async Task UpdateAsync_DoesNotModifyDeletionDate(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider)
{
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(existingSecret.OrganizationId).Returns(true);
sutProvider.GetDependency<ISecretRepository>().GetByIdAsync(existingSecret.Id).Returns(existingSecret);
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(existingSecret.OrganizationId).Returns(true);
var updatedDeletionDate = DateTime.UtcNow;
var secretUpdate = new Secret()
@ -122,7 +96,7 @@ public class UpdateSecretCommandTests
OrganizationId = existingSecret.OrganizationId
};
var result = await sutProvider.Sut.UpdateAsync(secretUpdate, userId);
var result = await sutProvider.Sut.UpdateAsync(secretUpdate);
Assert.Equal(existingSecret.DeletedDate, result.DeletedDate);
Assert.NotEqual(existingSecret.DeletedDate, updatedDeletionDate);
@ -131,12 +105,9 @@ public class UpdateSecretCommandTests
[Theory]
[BitAutoData]
public async Task UpdateAsync_RevisionDateIsUpdatedToUtcNow(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider, Guid userId)
public async Task UpdateAsync_RevisionDateIsUpdatedToUtcNow(Secret existingSecret, SutProvider<UpdateSecretCommand> sutProvider)
{
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(existingSecret.OrganizationId).Returns(true);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(existingSecret.OrganizationId).Returns(true);
sutProvider.GetDependency<ISecretRepository>().GetByIdAsync(existingSecret.Id).Returns(existingSecret);
sutProvider.GetDependency<ICurrentContext>().OrganizationAdmin(existingSecret.OrganizationId).Returns(true);
var updatedRevisionDate = DateTime.UtcNow.AddDays(10);
var secretUpdate = new Secret()
@ -147,7 +118,7 @@ public class UpdateSecretCommandTests
OrganizationId = existingSecret.OrganizationId
};
var result = await sutProvider.Sut.UpdateAsync(secretUpdate, userId);
var result = await sutProvider.Sut.UpdateAsync(secretUpdate);
Assert.NotEqual(secretUpdate.RevisionDate, result.RevisionDate);
AssertHelper.AssertRecent(result.RevisionDate);