1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-01 13:43:23 +01:00

Tests for required policies

This commit is contained in:
Thomas Rittson 2024-10-07 09:52:14 +10:00
parent 7b66fff98c
commit 9459c31663
No known key found for this signature in database
GPG Key ID: CDDDA03861C35E27
4 changed files with 105 additions and 11 deletions

View File

@ -90,7 +90,7 @@ public class PolicyServicevNext : IPolicyServicevNext
// Run other validation
var validationError = await policyDefinition.ValidateAsync(currentPolicy, policy);
if (validationError != null)
if (!string.IsNullOrEmpty(validationError))
{
throw new BadRequestException(validationError);
}

View File

@ -9,10 +9,12 @@ namespace Bit.Core.Test.AdminConsole.AutoFixture;
internal class PolicyCustomization : ICustomization
{
public PolicyType Type { get; set; }
public bool Enabled { get; set; }
public PolicyCustomization(PolicyType type)
public PolicyCustomization(PolicyType type, bool enabled)
{
Type = type;
Enabled = enabled;
}
public void Customize(IFixture fixture)
@ -20,21 +22,23 @@ internal class PolicyCustomization : ICustomization
fixture.Customize<Policy>(composer => composer
.With(o => o.OrganizationId, Guid.NewGuid())
.With(o => o.Type, Type)
.With(o => o.Enabled, true));
.With(o => o.Enabled, Enabled));
}
}
public class PolicyAttribute : CustomizeAttribute
{
private readonly PolicyType _type;
private readonly bool _enabled;
public PolicyAttribute(PolicyType type)
public PolicyAttribute(PolicyType type, bool enabled = true)
{
_type = type;
_enabled = enabled;
}
public override ICustomization GetCustomization(ParameterInfo parameter)
{
return new PolicyCustomization(_type);
return new PolicyCustomization(_type, _enabled);
}
}

View File

@ -1,8 +1,9 @@
using Bit.Core.AdminConsole.Entities;
#nullable enable
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
namespace Bit.Core.Test.AdminConsole.Services;
@ -11,10 +12,10 @@ public class FakeSingleOrgPolicyDefinition : IPolicyDefinition
public PolicyType Type => PolicyType.SingleOrg;
public IEnumerable<PolicyType> RequiredPolicies => Array.Empty<PolicyType>();
public readonly Func<Policy?, Policy, Task<string?>> ValidateAsyncMock = Substitute.For<Func<Policy, Policy, Task<string>>>();
public readonly Action<Policy?, Policy> OnSaveSideEffectsAsyncMock = Substitute.For<Action<Policy, Policy>>();
public readonly Func<Policy?, Policy, Task<string?>> ValidateAsyncMock = Substitute.For<Func<Policy?, Policy, Task<string?>>>();
public readonly Action<Policy?, Policy> OnSaveSideEffectsAsyncMock = Substitute.For<Action<Policy?, Policy>>();
public Task<string>? ValidateAsync(Policy? currentPolicy, Policy modifiedPolicy)
public Task<string?> ValidateAsync(Policy? currentPolicy, Policy modifiedPolicy)
{
return ValidateAsyncMock(currentPolicy, modifiedPolicy);
}
@ -25,3 +26,18 @@ public class FakeSingleOrgPolicyDefinition : IPolicyDefinition
return Task.FromResult(0);
}
}
public class FakeRequireSsoPolicyDefinition : IPolicyDefinition
{
public PolicyType Type => PolicyType.RequireSso;
public IEnumerable<PolicyType> RequiredPolicies => [PolicyType.SingleOrg];
public Task<string?> ValidateAsync(Policy? currentPolicy, Policy modifiedPolicy)
{
return Task.FromResult((string)null);
}
public Task OnSaveSideEffectsAsync(Policy? currentPolicy, Policy modifiedPolicy)
{
return Task.FromResult(0);
}
}

View File

@ -1,4 +1,6 @@
using AutoFixture;
#nullable enable
using AutoFixture;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
@ -107,6 +109,78 @@ public class PolicyServicevNextTests
await AssertPolicyNotSavedAsync(sutProvider);
}
[Theory, BitAutoData]
public async Task SaveAsync_RequiredPolicyIsNull_Throws(
[Policy(PolicyType.RequireSso)] Policy policy)
{
var sutProvider = SutProviderFactory([
new FakeRequireSsoPolicyDefinition(),
new FakeSingleOrgPolicyDefinition()
]);
ArrangeOrganization(sutProvider, policy);
sutProvider.GetDependency<IPolicyRepository>()
.GetManyByOrganizationIdAsync(policy.OrganizationId)
.Returns([]);
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SaveAsync(policy,
Substitute.For<IUserService>(),
Substitute.For<IOrganizationService>(),
Guid.NewGuid()));
Assert.Contains("Policy requires PolicyType SingleOrg to be enabled", badRequestException.Message, StringComparison.OrdinalIgnoreCase);
await AssertPolicyNotSavedAsync(sutProvider);
}
[Theory, BitAutoData]
public async Task SaveAsync_RequiredPolicyNotEnabled_Throws(
[Policy(PolicyType.SingleOrg, false)] Policy singleOrgPolicy,
[Policy(PolicyType.RequireSso)] Policy policy)
{
var sutProvider = SutProviderFactory([
new FakeRequireSsoPolicyDefinition(),
new FakeSingleOrgPolicyDefinition()
]);
ArrangeOrganization(sutProvider, policy);
sutProvider.GetDependency<IPolicyRepository>()
.GetManyByOrganizationIdAsync(policy.OrganizationId)
.Returns([singleOrgPolicy]);
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SaveAsync(policy,
Substitute.For<IUserService>(),
Substitute.For<IOrganizationService>(),
Guid.NewGuid()));
Assert.Contains("Policy requires PolicyType SingleOrg to be enabled", badRequestException.Message, StringComparison.OrdinalIgnoreCase);
await AssertPolicyNotSavedAsync(sutProvider);
}
[Theory, BitAutoData]
public async Task SaveAsync_RequiredPolicyEnabled_Success(
[Policy(PolicyType.SingleOrg, true)] Policy singleOrgPolicy,
[Policy(PolicyType.RequireSso)] Policy policy)
{
var sutProvider = SutProviderFactory([
new FakeRequireSsoPolicyDefinition(),
new FakeSingleOrgPolicyDefinition()
]);
ArrangeOrganization(sutProvider, policy);
sutProvider.GetDependency<IPolicyRepository>()
.GetManyByOrganizationIdAsync(policy.OrganizationId)
.Returns([singleOrgPolicy]);
await sutProvider.Sut.SaveAsync(policy,
Substitute.For<IUserService>(),
Substitute.For<IOrganizationService>(),
Guid.NewGuid());
await sutProvider.GetDependency<IPolicyRepository>().Received(1).UpsertAsync(policy);
}
/// <summary>
/// Returns a new SutProvider with the PolicyDefinitions registered in the Sut.
/// </summary>