mirror of
https://github.com/bitwarden/server
synced 2025-12-14 15:23:42 +00:00
[PM-18239] Master password policy requirement (#5936)
* wip * initial implementation * add tests * more tests, fix policy Enabled * remove exempt statuses * test EnforcedOptions is populated * clean up, add test * fix test, add json attributes for deserialization * fix attribute casing * fix test --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
using Bit.Core.Test.AdminConsole.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
|
||||
[SutProviderCustomize]
|
||||
public class MasterPasswordPolicyRequirementFactoryTests
|
||||
{
|
||||
[Theory, BitAutoData]
|
||||
public void MasterPasswordPolicyData_CombineWith_Joins_Policy_Options(SutProvider<MasterPasswordPolicyRequirementFactory> sutProvider)
|
||||
{
|
||||
var mpd1 = JsonSerializer.Serialize(new MasterPasswordPolicyData { MinLength = 20, RequireLower = false, RequireSpecial = false });
|
||||
var mpd2 = JsonSerializer.Serialize(new MasterPasswordPolicyData { RequireLower = true });
|
||||
var mpd3 = JsonSerializer.Serialize(new MasterPasswordPolicyData { RequireSpecial = true });
|
||||
|
||||
var policyDetails1 = new PolicyDetails
|
||||
{
|
||||
PolicyType = PolicyType.MasterPassword,
|
||||
PolicyData = mpd1
|
||||
};
|
||||
|
||||
var policyDetails2 = new PolicyDetails
|
||||
{
|
||||
PolicyType = PolicyType.MasterPassword,
|
||||
PolicyData = mpd2
|
||||
};
|
||||
var policyDetails3 = new PolicyDetails
|
||||
{
|
||||
PolicyType = PolicyType.MasterPassword,
|
||||
PolicyData = mpd3
|
||||
};
|
||||
|
||||
|
||||
var actual = sutProvider.Sut.Create([policyDetails1, policyDetails2, policyDetails3]);
|
||||
|
||||
Assert.NotNull(actual);
|
||||
Assert.True(actual.Enabled);
|
||||
Assert.True(actual.EnforcedOptions.RequireLower);
|
||||
Assert.True(actual.EnforcedOptions.RequireSpecial);
|
||||
Assert.Equal(20, actual.EnforcedOptions.MinLength);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void MasterPassword_IsFalse_IfNoPolicies(SutProvider<MasterPasswordPolicyRequirementFactory> sutProvider)
|
||||
{
|
||||
var actual = sutProvider.Sut.Create([]);
|
||||
|
||||
Assert.False(actual.Enabled);
|
||||
Assert.Null(actual.EnforcedOptions);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public void MasterPassword_IsTrue_IfAnyDisableSendPolicies(
|
||||
[PolicyDetails(PolicyType.MasterPassword)] PolicyDetails[] policies,
|
||||
SutProvider<MasterPasswordPolicyRequirementFactory> sutProvider)
|
||||
{
|
||||
var actual = sutProvider.Sut.Create(policies);
|
||||
|
||||
Assert.True(actual.Enabled);
|
||||
Assert.NotNull(actual.EnforcedOptions);
|
||||
Assert.NotNull(actual.EnforcedOptions.EnforceOnLogin);
|
||||
Assert.NotNull(actual.EnforcedOptions.RequireLower);
|
||||
Assert.NotNull(actual.EnforcedOptions.RequireNumbers);
|
||||
Assert.NotNull(actual.EnforcedOptions.RequireSpecial);
|
||||
Assert.NotNull(actual.EnforcedOptions.RequireUpper);
|
||||
Assert.Null(actual.EnforcedOptions.MinComplexity);
|
||||
Assert.Null(actual.EnforcedOptions.MinLength);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,15 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.AdminConsole.Services.Implementations;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
@@ -117,6 +123,38 @@ public class PolicyServiceTests
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetMasterPasswordPolicyForUserAsync_WithFeatureFlagEnabled_EvaluatesPolicyRequirement(User user, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(user.Id, sutProvider);
|
||||
var policyRequirement = new MasterPasswordPolicyRequirement
|
||||
{
|
||||
Enabled = true,
|
||||
EnforcedOptions = new MasterPasswordPolicyData()
|
||||
};
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
sutProvider.GetDependency<IPolicyRequirementQuery>().GetAsync<MasterPasswordPolicyRequirement>(user.Id).Returns(policyRequirement);
|
||||
|
||||
var result = await sutProvider.Sut.GetMasterPasswordPolicyForUserAsync(user);
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>().Received(1).IsEnabled(FeatureFlagKeys.PolicyRequirements);
|
||||
await sutProvider.GetDependency<IPolicyRepository>().DidNotReceive().GetManyByUserIdAsync(user.Id);
|
||||
await sutProvider.GetDependency<IPolicyRequirementQuery>().Received(1).GetAsync<MasterPasswordPolicyRequirement>(user.Id);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetMasterPasswordPolicyForUserAsync_WithFeatureFlagDisabled_EvaluatesPolicyDetails(User user, SutProvider<PolicyService> sutProvider)
|
||||
{
|
||||
SetupUserPolicies(user.Id, sutProvider);
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(false);
|
||||
|
||||
var result = await sutProvider.Sut.GetMasterPasswordPolicyForUserAsync(user);
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>().Received(1).IsEnabled(FeatureFlagKeys.PolicyRequirements);
|
||||
await sutProvider.GetDependency<IPolicyRepository>().Received(1).GetManyByUserIdAsync(user.Id);
|
||||
await sutProvider.GetDependency<IPolicyRequirementQuery>().DidNotReceive().GetAsync<MasterPasswordPolicyRequirement>(user.Id);
|
||||
}
|
||||
|
||||
private static void SetupOrg(SutProvider<PolicyService> sutProvider, Guid organizationId, Organization organization)
|
||||
{
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
|
||||
Reference in New Issue
Block a user