mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05:00
[PM-18234] Add SendPolicyRequirement (#5409)
This commit is contained in:
@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using AutoFixture;
|
||||
using AutoFixture.Xunit2;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Core.Test.AdminConsole.AutoFixture;
|
||||
|
||||
internal class PolicyDetailsCustomization(
|
||||
PolicyType policyType,
|
||||
OrganizationUserType userType,
|
||||
bool isProvider,
|
||||
OrganizationUserStatusType userStatus) : ICustomization
|
||||
{
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customize<PolicyDetails>(composer => composer
|
||||
.With(o => o.PolicyType, policyType)
|
||||
.With(o => o.OrganizationUserType, userType)
|
||||
.With(o => o.IsProvider, isProvider)
|
||||
.With(o => o.OrganizationUserStatus, userStatus)
|
||||
.Without(o => o.PolicyData)); // avoid autogenerating invalid json data
|
||||
}
|
||||
}
|
||||
|
||||
public class PolicyDetailsAttribute(
|
||||
PolicyType policyType,
|
||||
OrganizationUserType userType = OrganizationUserType.User,
|
||||
bool isProvider = false,
|
||||
OrganizationUserStatusType userStatus = OrganizationUserStatusType.Confirmed) : CustomizeAttribute
|
||||
{
|
||||
public override ICustomization GetCustomization(ParameterInfo parameter)
|
||||
=> new PolicyDetailsCustomization(policyType, userType, isProvider, userStatus);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
|
||||
public static class PolicyDetailsTestExtensions
|
||||
{
|
||||
public static void SetDataModel<T>(this PolicyDetails policyDetails, T data) where T : IPolicyDataModel
|
||||
=> policyDetails.PolicyData = CoreHelpers.ClassToJsonData(data);
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
using AutoFixture.Xunit2;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Test.AdminConsole.AutoFixture;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
|
||||
public class SendPolicyRequirementTests
|
||||
{
|
||||
[Theory, AutoData]
|
||||
public void DisableSend_IsFalse_IfNoDisableSendPolicies(
|
||||
[PolicyDetails(PolicyType.RequireSso)] PolicyDetails otherPolicy1,
|
||||
[PolicyDetails(PolicyType.SendOptions)] PolicyDetails otherPolicy2)
|
||||
{
|
||||
EnableDisableHideEmail(otherPolicy2);
|
||||
|
||||
var actual = SendPolicyRequirement.Create([otherPolicy1, otherPolicy2]);
|
||||
|
||||
Assert.False(actual.DisableSend);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineAutoData(OrganizationUserType.Owner, false)]
|
||||
[InlineAutoData(OrganizationUserType.Admin, false)]
|
||||
[InlineAutoData(OrganizationUserType.User, true)]
|
||||
[InlineAutoData(OrganizationUserType.Custom, true)]
|
||||
public void DisableSend_TestRoles(
|
||||
OrganizationUserType userType,
|
||||
bool shouldBeEnforced,
|
||||
[PolicyDetails(PolicyType.DisableSend)] PolicyDetails policyDetails)
|
||||
{
|
||||
policyDetails.OrganizationUserType = userType;
|
||||
|
||||
var actual = SendPolicyRequirement.Create([policyDetails]);
|
||||
|
||||
Assert.Equal(shouldBeEnforced, actual.DisableSend);
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void DisableSend_Not_EnforcedAgainstProviders(
|
||||
[PolicyDetails(PolicyType.DisableSend, isProvider: true)] PolicyDetails policyDetails)
|
||||
{
|
||||
var actual = SendPolicyRequirement.Create([policyDetails]);
|
||||
|
||||
Assert.False(actual.DisableSend);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineAutoData(OrganizationUserStatusType.Confirmed, true)]
|
||||
[InlineAutoData(OrganizationUserStatusType.Accepted, true)]
|
||||
[InlineAutoData(OrganizationUserStatusType.Invited, false)]
|
||||
[InlineAutoData(OrganizationUserStatusType.Revoked, false)]
|
||||
public void DisableSend_TestStatuses(
|
||||
OrganizationUserStatusType userStatus,
|
||||
bool shouldBeEnforced,
|
||||
[PolicyDetails(PolicyType.DisableSend)] PolicyDetails policyDetails)
|
||||
{
|
||||
policyDetails.OrganizationUserStatus = userStatus;
|
||||
|
||||
var actual = SendPolicyRequirement.Create([policyDetails]);
|
||||
|
||||
Assert.Equal(shouldBeEnforced, actual.DisableSend);
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void DisableHideEmail_IsFalse_IfNoSendOptionsPolicies(
|
||||
[PolicyDetails(PolicyType.RequireSso)] PolicyDetails otherPolicy1,
|
||||
[PolicyDetails(PolicyType.DisableSend)] PolicyDetails otherPolicy2)
|
||||
{
|
||||
var actual = SendPolicyRequirement.Create([otherPolicy1, otherPolicy2]);
|
||||
|
||||
Assert.False(actual.DisableHideEmail);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineAutoData(OrganizationUserType.Owner, false)]
|
||||
[InlineAutoData(OrganizationUserType.Admin, false)]
|
||||
[InlineAutoData(OrganizationUserType.User, true)]
|
||||
[InlineAutoData(OrganizationUserType.Custom, true)]
|
||||
public void DisableHideEmail_TestRoles(
|
||||
OrganizationUserType userType,
|
||||
bool shouldBeEnforced,
|
||||
[PolicyDetails(PolicyType.SendOptions)] PolicyDetails policyDetails)
|
||||
{
|
||||
EnableDisableHideEmail(policyDetails);
|
||||
policyDetails.OrganizationUserType = userType;
|
||||
|
||||
var actual = SendPolicyRequirement.Create([policyDetails]);
|
||||
|
||||
Assert.Equal(shouldBeEnforced, actual.DisableHideEmail);
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void DisableHideEmail_Not_EnforcedAgainstProviders(
|
||||
[PolicyDetails(PolicyType.SendOptions, isProvider: true)] PolicyDetails policyDetails)
|
||||
{
|
||||
EnableDisableHideEmail(policyDetails);
|
||||
|
||||
var actual = SendPolicyRequirement.Create([policyDetails]);
|
||||
|
||||
Assert.False(actual.DisableHideEmail);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineAutoData(OrganizationUserStatusType.Confirmed, true)]
|
||||
[InlineAutoData(OrganizationUserStatusType.Accepted, true)]
|
||||
[InlineAutoData(OrganizationUserStatusType.Invited, false)]
|
||||
[InlineAutoData(OrganizationUserStatusType.Revoked, false)]
|
||||
public void DisableHideEmail_TestStatuses(
|
||||
OrganizationUserStatusType userStatus,
|
||||
bool shouldBeEnforced,
|
||||
[PolicyDetails(PolicyType.SendOptions)] PolicyDetails policyDetails)
|
||||
{
|
||||
EnableDisableHideEmail(policyDetails);
|
||||
policyDetails.OrganizationUserStatus = userStatus;
|
||||
|
||||
var actual = SendPolicyRequirement.Create([policyDetails]);
|
||||
|
||||
Assert.Equal(shouldBeEnforced, actual.DisableHideEmail);
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public void DisableHideEmail_HandlesNullData(
|
||||
[PolicyDetails(PolicyType.SendOptions)] PolicyDetails policyDetails)
|
||||
{
|
||||
policyDetails.PolicyData = null;
|
||||
|
||||
var actual = SendPolicyRequirement.Create([policyDetails]);
|
||||
|
||||
Assert.False(actual.DisableHideEmail);
|
||||
}
|
||||
|
||||
private static void EnableDisableHideEmail(PolicyDetails policyDetails)
|
||||
=> policyDetails.SetDataModel(new SendOptionsPolicyData { DisableHideEmail = true });
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
using AutoFixture;
|
||||
using System.Reflection;
|
||||
using AutoFixture;
|
||||
using AutoFixture.Xunit2;
|
||||
using Bit.Core.Tools.Entities;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
|
||||
@ -19,3 +21,20 @@ internal class UserSendCustomizeAttribute : BitCustomizeAttribute
|
||||
{
|
||||
public override ICustomization GetCustomization() => new UserSend();
|
||||
}
|
||||
|
||||
internal class NewUserSend : ICustomization
|
||||
{
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customize<Send>(composer => composer
|
||||
.With(s => s.Id, Guid.Empty)
|
||||
.Without(s => s.OrganizationId));
|
||||
}
|
||||
}
|
||||
|
||||
internal class NewUserSendCustomizeAttribute : CustomizeAttribute
|
||||
{
|
||||
public override ICustomization GetCustomization(ParameterInfo parameterInfo)
|
||||
=> new NewUserSend();
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ using System.Text.Json;
|
||||
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.Services;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Exceptions;
|
||||
@ -22,6 +24,7 @@ using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using NSubstitute;
|
||||
using NSubstitute.ExceptionExtensions;
|
||||
using Xunit;
|
||||
|
||||
using GlobalSettings = Bit.Core.Settings.GlobalSettings;
|
||||
@ -118,6 +121,93 @@ public class SendServiceTests
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
// Disable Send policy check - vNext
|
||||
private void SaveSendAsync_Setup_vNext(SutProvider<SendService> sutProvider, Send send,
|
||||
SendPolicyRequirement sendPolicyRequirement)
|
||||
{
|
||||
sutProvider.GetDependency<IPolicyRequirementQuery>().GetAsync<SendPolicyRequirement>(send.UserId!.Value)
|
||||
.Returns(sendPolicyRequirement);
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
|
||||
// Should not be called in these tests
|
||||
sutProvider.GetDependency<IPolicyService>().AnyPoliciesApplicableToUserAsync(
|
||||
Arg.Any<Guid>(), Arg.Any<PolicyType>()).ThrowsAsync<Exception>();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableSend_Applies_Throws_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new SendPolicyRequirement { DisableSend = true });
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.SaveSendAsync(send));
|
||||
Assert.Contains("Due to an Enterprise Policy, you are only able to delete an existing Send.",
|
||||
exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableSend_DoesntApply_Success_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new SendPolicyRequirement());
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
// Send Options Policy - Disable Hide Email check
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_Applies_Throws_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new SendPolicyRequirement { DisableHideEmail = true });
|
||||
send.HideEmail = true;
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.SaveSendAsync(send));
|
||||
Assert.Contains("Due to an Enterprise Policy, you are not allowed to hide your email address from recipients when creating or editing a Send.", exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_Applies_ButEmailNotHidden_Success_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new SendPolicyRequirement { DisableHideEmail = true });
|
||||
send.HideEmail = false;
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(SendType.File)]
|
||||
[BitAutoData(SendType.Text)]
|
||||
public async Task SaveSendAsync_DisableHideEmail_DoesntApply_Success_vNext(SendType sendType,
|
||||
SutProvider<SendService> sutProvider, [NewUserSendCustomize] Send send)
|
||||
{
|
||||
send.Type = sendType;
|
||||
SaveSendAsync_Setup_vNext(sutProvider, send, new SendPolicyRequirement());
|
||||
send.HideEmail = true;
|
||||
|
||||
await sutProvider.Sut.SaveSendAsync(send);
|
||||
|
||||
await sutProvider.GetDependency<ISendRepository>().Received(1).CreateAsync(send);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SaveSendAsync_ExistingSend_Updates(SutProvider<SendService> sutProvider,
|
||||
|
Reference in New Issue
Block a user