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

Revert "Use delegates to simplify mocking"

This reverts commit 4983e413e4.
This commit is contained in:
Thomas Rittson 2024-10-07 09:45:45 +10:00
parent 4983e413e4
commit 7b66fff98c
No known key found for this signature in database
GPG Key ID: CDDDA03861C35E27
6 changed files with 45 additions and 38 deletions

View File

@ -2,6 +2,7 @@
using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Enums;
using Bit.Core.Entities;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Policies; namespace Bit.Core.AdminConsole.OrganizationFeatures.Policies;
@ -25,7 +26,7 @@ public interface IPolicyDefinition
/// <param name="currentPolicy">The current policy, if any</param> /// <param name="currentPolicy">The current policy, if any</param>
/// <param name="modifiedPolicy">The modified policy to be saved</param> /// <param name="modifiedPolicy">The modified policy to be saved</param>
/// <returns>A sequence of validation errors if validation was unsuccessful</returns> /// <returns>A sequence of validation errors if validation was unsuccessful</returns>
public Func<Policy?, Policy, Task<string?>> Validate { get; } public Task<string?> ValidateAsync(Policy? currentPolicy, Policy modifiedPolicy);
/// <summary> /// <summary>
/// Optionally performs side effects after a policy is validated but before it is saved. /// Optionally performs side effects after a policy is validated but before it is saved.
@ -33,5 +34,5 @@ public interface IPolicyDefinition
/// </summary> /// </summary>
/// <param name="currentPolicy">The current policy, if any</param> /// <param name="currentPolicy">The current policy, if any</param>
/// <param name="modifiedPolicy">The modified policy to be saved</param> /// <param name="modifiedPolicy">The modified policy to be saved</param>
public Func<Policy?, Policy, Task> OnSaveSideEffects { get; } public Task OnSaveSideEffectsAsync(Policy? currentPolicy, Policy modifiedPolicy);
} }

View File

@ -1,10 +1,13 @@
#nullable enable #nullable enable
using System.ComponentModel;
using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Enums; using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Repositories; using Bit.Core.Auth.Repositories;
using Bit.Core.Context; using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Repositories; using Bit.Core.Repositories;
@ -37,27 +40,13 @@ public class SingleOrgPolicyDefinition : IPolicyDefinition
_currentContext = currentContext; _currentContext = currentContext;
} }
public Func<Policy?, Policy, Task<string?>> Validate => async (currentPolicy, modifiedPolicy) => public async Task OnSaveSideEffectsAsync(Policy? currentPolicy, Policy modifiedPolicy)
{
var organizationId = modifiedPolicy.OrganizationId;
// Do not allow this policy to be disabled if Key Connector is being used
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organizationId);
if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.KeyConnector)
{
return "Key Connector is enabled.";
}
return null;
};
public Func<Policy?, Policy, Task> OnSaveSideEffects => async (currentPolicy, modifiedPolicy) =>
{ {
if (currentPolicy is null or { Enabled: false } && modifiedPolicy is { Enabled: true }) if (currentPolicy is null or { Enabled: false } && modifiedPolicy is { Enabled: true })
{ {
await RemoveNonCompliantUsersAsync(modifiedPolicy.OrganizationId); await RemoveNonCompliantUsersAsync(modifiedPolicy.OrganizationId);
} }
}; }
private async Task RemoveNonCompliantUsersAsync(Guid organizationId) private async Task RemoveNonCompliantUsersAsync(Guid organizationId)
{ {
@ -96,4 +85,17 @@ public class SingleOrgPolicyDefinition : IPolicyDefinition
} }
} }
public async Task<string?> ValidateAsync(Policy? currentPolicy, Policy modifiedPolicy)
{
var organizationId = modifiedPolicy.OrganizationId;
// Do not allow this policy to be disabled if Key Connector is being used
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organizationId);
if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.KeyConnector)
{
return "Key Connector is enabled.";
}
return null;
}
} }

View File

@ -82,21 +82,21 @@ public class PolicyServicevNext : IPolicyServicevNext
.Where(otherPolicy => otherPolicy is { Enabled: true }) .Where(otherPolicy => otherPolicy is { Enabled: true })
.ToList(); .ToList();
if (dependentPolicies is { Count: > 0 }) if (dependentPolicies is { Count: > 0})
{ {
throw new BadRequestException("This policy is required by " + dependentPolicies.First() + ". Try disabling that policy first."); throw new BadRequestException("This policy is required by " + dependentPolicies.First() + ". Try disabling that policy first." );
} }
} }
// Run other validation // Run other validation
var validationError = await policyDefinition.Validate(currentPolicy, policy); var validationError = await policyDefinition.ValidateAsync(currentPolicy, policy);
if (validationError != null) if (validationError != null)
{ {
throw new BadRequestException(validationError); throw new BadRequestException(validationError);
} }
// Run side effects // Run side effects
await policyDefinition.OnSaveSideEffects(currentPolicy, policy); await policyDefinition.OnSaveSideEffectsAsync(currentPolicy, policy);
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
if (policy.Id == default) if (policy.Id == default)

View File

@ -1,9 +1,11 @@
#nullable enable #nullable enable
using System.Reflection; using System.Reflection;
using AutoFixture;
using AutoFixture.Kernel; using AutoFixture.Kernel;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies; using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using Bit.Core.AdminConsole.Services.Implementations; using Bit.Core.AdminConsole.Services.Implementations;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Core.Test.AdminConsole.AutoFixture; namespace Bit.Core.Test.AdminConsole.AutoFixture;

View File

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

View File

@ -10,9 +10,9 @@ using Bit.Core.Services;
using Bit.Core.Test.AdminConsole.AutoFixture; using Bit.Core.Test.AdminConsole.AutoFixture;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
using AdminConsoleFixtures = Bit.Core.Test.AdminConsole.AutoFixture;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
using AdminConsoleFixtures = Bit.Core.Test.AdminConsole.AutoFixture;
namespace Bit.Core.Test.AdminConsole.Services; namespace Bit.Core.Test.AdminConsole.Services;
@ -72,7 +72,7 @@ public class PolicyServicevNextTests
} }
[Theory, BitAutoData] [Theory, BitAutoData]
public async Task SaveAsync_PolicyDefinitionNotFound_Throws([Policy(PolicyType.SingleOrg)] Policy policy) public async Task SaveAsync_PolicyDefinitionNotFound_Throws([Policy(PolicyType.SingleOrg)]Policy policy)
{ {
var sutProvider = SutProviderFactory(); var sutProvider = SutProviderFactory();
ArrangeOrganization(sutProvider, policy); ArrangeOrganization(sutProvider, policy);
@ -91,7 +91,7 @@ public class PolicyServicevNextTests
public async Task SaveAsync_ThrowsOnValidationError([AdminConsoleFixtures.Policy(PolicyType.SingleOrg)] Policy policy) public async Task SaveAsync_ThrowsOnValidationError([AdminConsoleFixtures.Policy(PolicyType.SingleOrg)] Policy policy)
{ {
var fakePolicyDefinition = new FakeSingleOrgPolicyDefinition(); var fakePolicyDefinition = new FakeSingleOrgPolicyDefinition();
fakePolicyDefinition.Validate(null, policy).Returns("Validation error!"); fakePolicyDefinition.ValidateAsyncMock(null, policy).Returns("Validation error!");
var sutProvider = SutProviderFactory([fakePolicyDefinition]); var sutProvider = SutProviderFactory([fakePolicyDefinition]);
ArrangeOrganization(sutProvider, policy); ArrangeOrganization(sutProvider, policy);