1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-25 12:45:18 +01:00

[PM-1270] Throw error when removing master password reset policy with TDE enabled (#2964)

* [PM-1270] Updated PolicyService to throw an exception in case TDE is enabled and the user is trying to turn off the master password reset policy or tries to remove auto-enrollment

* [PM-1270] Added unit tests around the checks for turning off the master password reset policy or removing auto-enrollment

* [PM-1270] Fixed existing unit test SaveAsync_NewPolicy_Created

* [PM-1270] Removed unused method mock on unit test
This commit is contained in:
Rui Tomé 2023-06-07 09:56:31 +01:00 committed by GitHub
parent 90a28ad87f
commit 746dec6496
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 1 deletions

View File

@ -75,6 +75,13 @@ public class PolicyService : IPolicyService
} }
break; break;
case PolicyType.ResetPassword:
if (!policy.Enabled || policy.GetDataModel<ResetPasswordDataModel>()?.AutoEnrollEnabled == false)
{
await RequiredBySsoTrustedDeviceEncryptionAsync(org);
}
break;
case PolicyType.MaximumVaultTimeout: case PolicyType.MaximumVaultTimeout:
if (policy.Enabled) if (policy.Enabled)
{ {
@ -230,7 +237,6 @@ public class PolicyService : IPolicyService
private async Task RequiredByKeyConnectorAsync(Organization org) private async Task RequiredByKeyConnectorAsync(Organization org)
{ {
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(org.Id); var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(org.Id);
if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.KeyConnector) if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.KeyConnector)
{ {
@ -254,4 +260,13 @@ public class PolicyService : IPolicyService
throw new BadRequestException("This policy is only available to 2020 Enterprise plans."); throw new BadRequestException("This policy is only available to 2020 Enterprise plans.");
} }
} }
private async Task RequiredBySsoTrustedDeviceEncryptionAsync(Organization org)
{
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(org.Id);
if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.TrustedDeviceEncryption)
{
throw new BadRequestException("Trusted device encryption is on and requires this policy.");
}
}
} }

View File

@ -6,6 +6,7 @@ using Bit.Core.Entities;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.Models.Data.Organizations.OrganizationUsers;
using Bit.Core.Models.Data.Organizations.Policies;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
@ -208,6 +209,7 @@ public class PolicyServiceTests
[PolicyFixtures.Policy(PolicyType.ResetPassword)] Policy policy, SutProvider<PolicyService> sutProvider) [PolicyFixtures.Policy(PolicyType.ResetPassword)] Policy policy, SutProvider<PolicyService> sutProvider)
{ {
policy.Id = default; policy.Id = default;
policy.Data = null;
SetupOrg(sutProvider, policy.OrganizationId, new Organization SetupOrg(sutProvider, policy.OrganizationId, new Organization
{ {
@ -396,6 +398,52 @@ public class PolicyServiceTests
Assert.True(policy.RevisionDate - utcNow < TimeSpan.FromSeconds(1)); Assert.True(policy.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
} }
[Theory]
[BitAutoData(true, false)]
[BitAutoData(false, true)]
[BitAutoData(false, false)]
public async Task SaveAsync_PolicyRequiredByTrustedDeviceEncryption_DisablePolicyOrDisableAutomaticEnrollment_ThrowsBadRequest(
bool policyEnabled,
bool autoEnrollEnabled,
[PolicyFixtures.Policy(PolicyType.ResetPassword)] Policy policy,
SutProvider<PolicyService> sutProvider)
{
policy.Enabled = policyEnabled;
policy.SetDataModel(new ResetPasswordDataModel
{
AutoEnrollEnabled = autoEnrollEnabled
});
SetupOrg(sutProvider, policy.OrganizationId, new Organization
{
Id = policy.OrganizationId,
UsePolicies = true,
});
var ssoConfig = new SsoConfig { Enabled = true };
ssoConfig.SetData(new SsoConfigurationData { MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption });
sutProvider.GetDependency<ISsoConfigRepository>()
.GetByOrganizationIdAsync(policy.OrganizationId)
.Returns(ssoConfig);
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SaveAsync(policy,
Substitute.For<IUserService>(),
Substitute.For<IOrganizationService>(),
Guid.NewGuid()));
Assert.Contains("Trusted device encryption is on and requires this policy.", badRequestException.Message, StringComparison.OrdinalIgnoreCase);
await sutProvider.GetDependency<IPolicyRepository>()
.DidNotReceiveWithAnyArgs()
.UpsertAsync(default);
await sutProvider.GetDependency<IEventService>()
.DidNotReceiveWithAnyArgs()
.LogPolicyEventAsync(default, default, default);
}
[Theory, BitAutoData] [Theory, BitAutoData]
public async Task GetPoliciesApplicableToUserAsync_WithRequireSsoTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsNoPolicies(Guid userId, SutProvider<PolicyService> sutProvider) public async Task GetPoliciesApplicableToUserAsync_WithRequireSsoTypeFilter_WithDefaultOrganizationUserStatusFilter_ReturnsNoPolicies(Guid userId, SutProvider<PolicyService> sutProvider)
{ {