From 9c3b7202e40d54f79629db33a71784bd0c83d0c2 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Mon, 24 Feb 2025 15:47:15 +0000 Subject: [PATCH 01/11] Add PersonalOwnershipPolicyRequirement for managing personal ownership policy --- .../PersonalOwnershipPolicyRequirement.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs diff --git a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs new file mode 100644 index 000000000000..e967a4e89093 --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs @@ -0,0 +1,39 @@ +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.Enums; + +namespace Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; + +/// +/// Policy requirements for the Disable Personal Ownership policy. +/// +public class PersonalOwnershipPolicyRequirement : IPolicyRequirement +{ + /// + /// Indicates whether Personal Ownership is disabled for the user. If true, members are required to save items to an organization. + /// + public bool DisablePersonalOwnership { get; init; } + + /// + /// Creates a new PersonalOwnershipPolicyRequirement. + /// + /// All PolicyDetails relating to the user. + /// + /// This is a for the PersonalOwnershipPolicyRequirement. + /// + public static PersonalOwnershipPolicyRequirement Create(IEnumerable policyDetails) + { + var filteredPolicies = policyDetails + .ExemptRoles([OrganizationUserType.Owner, OrganizationUserType.Admin]) + .ExemptStatus([OrganizationUserStatusType.Invited, OrganizationUserStatusType.Revoked]) + .ExemptProviders() + .ToList(); + + var result = new PersonalOwnershipPolicyRequirement + { + DisablePersonalOwnership = filteredPolicies.GetPolicyType(PolicyType.PersonalOwnership).Any() + }; + + return result; + } +} From 595fbab1302574c3c79282b8b5ca707c7ac2af2f Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Mon, 24 Feb 2025 15:47:50 +0000 Subject: [PATCH 02/11] Add tests for PersonalOwnershipPolicyRequirement --- ...PersonalOwnershipPolicyRequirementTests.cs | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs new file mode 100644 index 000000000000..d0fb1cd83f43 --- /dev/null +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs @@ -0,0 +1,65 @@ +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 PersonalOwnershipPolicyRequirementTests +{ + [Theory, AutoData] + public void DisablePersonalOwnership_IsFalse_IfNoPersonalOwnershipPolicies( + [PolicyDetails(PolicyType.RequireSso)] PolicyDetails otherPolicy1, + [PolicyDetails(PolicyType.SendOptions)] PolicyDetails otherPolicy2) + { + var actual = PersonalOwnershipPolicyRequirement.Create([otherPolicy1, otherPolicy2]); + + Assert.False(actual.DisablePersonalOwnership); + } + + [Theory] + [InlineAutoData(OrganizationUserType.Owner, false)] + [InlineAutoData(OrganizationUserType.Admin, false)] + [InlineAutoData(OrganizationUserType.User, true)] + [InlineAutoData(OrganizationUserType.Custom, true)] + public void DisablePersonalOwnership_TestRoles( + OrganizationUserType userType, + bool shouldBeEnforced, + [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails) + { + policyDetails.OrganizationUserType = userType; + + var actual = PersonalOwnershipPolicyRequirement.Create([policyDetails]); + + Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); + } + + [Theory, AutoData] + public void DisablePersonalOwnership_Not_EnforcedAgainstProviders( + [PolicyDetails(PolicyType.PersonalOwnership, isProvider: true)] PolicyDetails policyDetails) + { + var actual = PersonalOwnershipPolicyRequirement.Create([policyDetails]); + + Assert.False(actual.DisablePersonalOwnership); + } + + [Theory] + [InlineAutoData(OrganizationUserStatusType.Confirmed, true)] + [InlineAutoData(OrganizationUserStatusType.Accepted, true)] + [InlineAutoData(OrganizationUserStatusType.Invited, false)] + [InlineAutoData(OrganizationUserStatusType.Revoked, false)] + public void DisablePersonalOwnership_TestStatuses( + OrganizationUserStatusType userStatus, + bool shouldBeEnforced, + [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails) + { + policyDetails.OrganizationUserStatus = userStatus; + + var actual = PersonalOwnershipPolicyRequirement.Create([policyDetails]); + + Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); + } +} From de9615e0880c9702d517b59d6330aee10f52d262 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Mon, 24 Feb 2025 15:48:21 +0000 Subject: [PATCH 03/11] Register PersonalOwnershipPolicyRequirement in policy requirement factory --- .../Policies/PolicyServiceCollectionExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs index 7bc8a7b5a327..1fc4289ed290 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs @@ -33,6 +33,7 @@ private static void AddPolicyRequirements(this IServiceCollection services) { // Register policy requirement factories here services.AddPolicyRequirement(SendPolicyRequirement.Create); + services.AddPolicyRequirement(PersonalOwnershipPolicyRequirement.Create); } /// From 26ddc8af33a6c625e1c2de3df6024fffe8fcada5 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Mon, 24 Feb 2025 15:55:59 +0000 Subject: [PATCH 04/11] Update ImportCiphersCommand to check PersonalOwnershipPolicyRequirement if the PolicyRequirements flag is enabled Update unit tests --- .../ImportFeatures/ImportCiphersCommand.cs | 20 +++++-- .../ImportCiphersAsyncCommandTests.cs | 60 ++++++++++++++++++- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs b/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs index 646121db52cb..88b4b1e43f55 100644 --- a/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs +++ b/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs @@ -1,10 +1,13 @@ using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; using Bit.Core.AdminConsole.Services; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Exceptions; using Bit.Core.Platform.Push; using Bit.Core.Repositories; +using Bit.Core.Services; using Bit.Core.Tools.Enums; using Bit.Core.Tools.ImportFeatures.Interfaces; using Bit.Core.Tools.Models.Business; @@ -26,7 +29,8 @@ public class ImportCiphersCommand : IImportCiphersCommand private readonly ICollectionRepository _collectionRepository; private readonly IReferenceEventService _referenceEventService; private readonly ICurrentContext _currentContext; - + private readonly IPolicyRequirementQuery _policyRequirementQuery; + private readonly IFeatureService _featureService; public ImportCiphersCommand( ICipherRepository cipherRepository, @@ -37,7 +41,9 @@ public ImportCiphersCommand( IPushNotificationService pushService, IPolicyService policyService, IReferenceEventService referenceEventService, - ICurrentContext currentContext) + ICurrentContext currentContext, + IPolicyRequirementQuery policyRequirementQuery, + IFeatureService featureService) { _cipherRepository = cipherRepository; _folderRepository = folderRepository; @@ -48,9 +54,10 @@ public ImportCiphersCommand( _policyService = policyService; _referenceEventService = referenceEventService; _currentContext = currentContext; + _policyRequirementQuery = policyRequirementQuery; + _featureService = featureService; } - public async Task ImportIntoIndividualVaultAsync( List folders, List ciphers, @@ -59,8 +66,11 @@ public async Task ImportIntoIndividualVaultAsync( var userId = folders.FirstOrDefault()?.UserId ?? ciphers.FirstOrDefault()?.UserId; // Make sure the user can save new ciphers to their personal vault - var anyPersonalOwnershipPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(userId.Value, PolicyType.PersonalOwnership); - if (anyPersonalOwnershipPolicies) + var isPersonalVaultRestricted = _featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements) + ? (await _policyRequirementQuery.GetAsync(userId.Value)).DisablePersonalOwnership + : await _policyService.AnyPoliciesApplicableToUserAsync(userId.Value, PolicyType.PersonalOwnership); + + if (isPersonalVaultRestricted) { throw new BadRequestException("You cannot import items into your personal vault because you are " + "a member of an organization which forbids it."); diff --git a/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs b/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs index 1e978562817b..36bf20bf7734 100644 --- a/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs +++ b/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs @@ -1,10 +1,13 @@ using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Enums; +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; using Bit.Core.Platform.Push; using Bit.Core.Repositories; +using Bit.Core.Services; using Bit.Core.Test.AutoFixture.CipherFixtures; using Bit.Core.Tools.Enums; using Bit.Core.Tools.ImportFeatures; @@ -18,7 +21,6 @@ using NSubstitute; using Xunit; - namespace Bit.Core.Test.Tools.ImportFeatures; [UserCipherCustomize] @@ -51,6 +53,36 @@ public async Task ImportIntoIndividualVaultAsync_Success( await sutProvider.GetDependency().Received(1).PushSyncVaultAsync(importingUserId); } + [Theory, BitAutoData] + public async Task ImportIntoIndividualVaultAsync_WithPolicyRequirementsEnabled_WithDisablePersonalOwnershipPolicyDisabled_Success( + Guid importingUserId, + List ciphers, + SutProvider sutProvider) + { + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PolicyRequirements) + .Returns(true); + + sutProvider.GetDependency() + .GetAsync(importingUserId) + .Returns(new PersonalOwnershipPolicyRequirement { DisablePersonalOwnership = false }); + + sutProvider.GetDependency() + .GetManyByUserIdAsync(importingUserId) + .Returns(new List()); + + var folders = new List { new Folder { UserId = importingUserId } }; + + var folderRelationships = new List>(); + + // Act + await sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships); + + // Assert + await sutProvider.GetDependency().Received(1).CreateAsync(ciphers, Arg.Any>()); + await sutProvider.GetDependency().Received(1).PushSyncVaultAsync(importingUserId); + } + [Theory, BitAutoData] public async Task ImportIntoIndividualVaultAsync_ThrowsBadRequestException( List folders, @@ -73,6 +105,32 @@ public async Task ImportIntoIndividualVaultAsync_ThrowsBadRequestException( Assert.Equal("You cannot import items into your personal vault because you are a member of an organization which forbids it.", exception.Message); } + [Theory, BitAutoData] + public async Task ImportIntoIndividualVaultAsync_WithPolicyRequirementsEnabled_WithDisablePersonalOwnershipPolicyEnabled_ThrowsBadRequestException( + List folders, + List ciphers, + SutProvider sutProvider) + { + var userId = Guid.NewGuid(); + folders.ForEach(f => f.UserId = userId); + ciphers.ForEach(c => c.UserId = userId); + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PolicyRequirements) + .Returns(true); + + sutProvider.GetDependency() + .GetAsync(userId) + .Returns(new PersonalOwnershipPolicyRequirement { DisablePersonalOwnership = true }); + + var folderRelationships = new List>(); + + var exception = await Assert.ThrowsAsync(() => + sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships)); + + Assert.Equal("You cannot import items into your personal vault because you are a member of an organization which forbids it.", exception.Message); + } + [Theory, BitAutoData] public async Task ImportIntoOrganizationalVaultAsync_Success( Organization organization, From fd488c97cd8a3bdfe169e338dabaf66a7ce5ee70 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Mon, 24 Feb 2025 15:56:39 +0000 Subject: [PATCH 05/11] Update CipherService to support PersonalOwnershipPolicyRequirement with feature flag - Add support for checking personal ownership policy using PolicyRequirementQuery when feature flag is enabled - Update CipherService constructor to inject new dependencies - Add tests for personal vault restrictions with and without feature flag --- .../Services/Implementations/CipherService.cs | 17 ++- .../Vault/Services/CipherServiceTests.cs | 106 ++++++++++++++++++ 2 files changed, 120 insertions(+), 3 deletions(-) diff --git a/src/Core/Vault/Services/Implementations/CipherService.cs b/src/Core/Vault/Services/Implementations/CipherService.cs index 90c03df90b0a..733425905848 100644 --- a/src/Core/Vault/Services/Implementations/CipherService.cs +++ b/src/Core/Vault/Services/Implementations/CipherService.cs @@ -1,5 +1,7 @@ using System.Text.Json; using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; using Bit.Core.AdminConsole.Services; using Bit.Core.Context; using Bit.Core.Enums; @@ -38,6 +40,8 @@ public class CipherService : ICipherService private const long _fileSizeLeeway = 1024L * 1024L; // 1MB private readonly IReferenceEventService _referenceEventService; private readonly ICurrentContext _currentContext; + private readonly IPolicyRequirementQuery _policyRequirementQuery; + private readonly IFeatureService _featureService; public CipherService( ICipherRepository cipherRepository, @@ -54,7 +58,9 @@ public CipherService( IPolicyService policyService, GlobalSettings globalSettings, IReferenceEventService referenceEventService, - ICurrentContext currentContext) + ICurrentContext currentContext, + IPolicyRequirementQuery policyRequirementQuery, + IFeatureService featureService) { _cipherRepository = cipherRepository; _folderRepository = folderRepository; @@ -71,6 +77,8 @@ public CipherService( _globalSettings = globalSettings; _referenceEventService = referenceEventService; _currentContext = currentContext; + _policyRequirementQuery = policyRequirementQuery; + _featureService = featureService; } public async Task SaveAsync(Cipher cipher, Guid savingUserId, DateTime? lastKnownRevisionDate, @@ -139,8 +147,11 @@ public async Task SaveDetailsAsync(CipherDetails cipher, Guid savingUserId, Date else { // Make sure the user can save new ciphers to their personal vault - var anyPersonalOwnershipPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(savingUserId, PolicyType.PersonalOwnership); - if (anyPersonalOwnershipPolicies) + var isPersonalVaultRestricted = _featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements) + ? (await _policyRequirementQuery.GetAsync(savingUserId)).DisablePersonalOwnership + : await _policyService.AnyPoliciesApplicableToUserAsync(savingUserId, PolicyType.PersonalOwnership); + + if (isPersonalVaultRestricted) { throw new BadRequestException("Due to an Enterprise Policy, you are restricted from saving items to your personal vault."); } diff --git a/test/Core.Test/Vault/Services/CipherServiceTests.cs b/test/Core.Test/Vault/Services/CipherServiceTests.cs index 4f02d94c9ccd..5b30c880ffa1 100644 --- a/test/Core.Test/Vault/Services/CipherServiceTests.cs +++ b/test/Core.Test/Vault/Services/CipherServiceTests.cs @@ -1,4 +1,8 @@ using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies; +using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; +using Bit.Core.AdminConsole.Services; using Bit.Core.Billing.Enums; using Bit.Core.Entities; using Bit.Core.Enums; @@ -725,6 +729,108 @@ await sutProvider.GetDependency().Received(1).UpdateCiphersAs Arg.Is>(arg => !arg.Except(ciphers).Any())); } + [Theory] + [BitAutoData] + public async Task SaveDetailsAsync_PersonalVault_WithDisablePersonalOwnershipPolicyEnabled_Throws( + SutProvider sutProvider, + CipherDetails cipher, + Guid savingUserId) + { + // Arrange + cipher.Id = default; + cipher.UserId = savingUserId; + cipher.OrganizationId = null; + + sutProvider.GetDependency() + .AnyPoliciesApplicableToUserAsync(savingUserId, PolicyType.PersonalOwnership) + .Returns(true); + + // Act & Assert + var exception = await Assert.ThrowsAsync( + () => sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null)); + Assert.Contains("restricted from saving items to your personal vault", exception.Message); + } + + [Theory] + [BitAutoData] + public async Task SaveDetailsAsync_PersonalVault_WithDisablePersonalOwnershipPolicyDisabled_Succeeds( + SutProvider sutProvider, + CipherDetails cipher, + Guid savingUserId) + { + // Arrange + cipher.Id = default; + cipher.UserId = savingUserId; + cipher.OrganizationId = null; + + sutProvider.GetDependency() + .AnyPoliciesApplicableToUserAsync(savingUserId, PolicyType.PersonalOwnership) + .Returns(false); + + // Act + await sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null); + + // Assert + await sutProvider.GetDependency() + .Received(1) + .CreateAsync(cipher); + } + + [Theory] + [BitAutoData] + public async Task SaveDetailsAsync_PersonalVault_WithPolicyRequirementsEnabled_WithDisablePersonalOwnershipPolicyEnabled_Throws( + SutProvider sutProvider, + CipherDetails cipher, + Guid savingUserId) + { + // Arrange + cipher.Id = default; + cipher.UserId = savingUserId; + cipher.OrganizationId = null; + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PolicyRequirements) + .Returns(true); + + sutProvider.GetDependency() + .GetAsync(savingUserId) + .Returns(new PersonalOwnershipPolicyRequirement { DisablePersonalOwnership = true }); + + // Act & Assert + var exception = await Assert.ThrowsAsync( + () => sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null)); + Assert.Contains("restricted from saving items to your personal vault", exception.Message); + } + + [Theory] + [BitAutoData] + public async Task SaveDetailsAsync_PersonalVault_WithPolicyRequirementsEnabled_WithDisablePersonalOwnershipPolicyDisabled_Succeeds( + SutProvider sutProvider, + CipherDetails cipher, + Guid savingUserId) + { + // Arrange + cipher.Id = default; + cipher.UserId = savingUserId; + cipher.OrganizationId = null; + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PolicyRequirements) + .Returns(true); + + sutProvider.GetDependency() + .GetAsync(savingUserId) + .Returns(new PersonalOwnershipPolicyRequirement { DisablePersonalOwnership = false }); + + // Act + await sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null); + + // Assert + await sutProvider.GetDependency() + .Received(1) + .CreateAsync(cipher); + } + private async Task AssertNoActionsAsync(SutProvider sutProvider) { await sutProvider.GetDependency().DidNotReceiveWithAnyArgs().GetManyOrganizationDetailsByOrganizationIdAsync(default); From 27876d6b445b25476bdc6795e2674bb5e82a81b0 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Tue, 25 Feb 2025 15:28:17 +0000 Subject: [PATCH 06/11] Clean up redundant "Arrange", "Act", and "Assert" comments in test methods --- .../ImportFeatures/ImportCiphersAsyncCommandTests.cs | 2 -- test/Core.Test/Vault/Services/CipherServiceTests.cs | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs b/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs index 36bf20bf7734..e0c4f5a5c0f8 100644 --- a/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs +++ b/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs @@ -75,10 +75,8 @@ public async Task ImportIntoIndividualVaultAsync_WithPolicyRequirementsEnabled_W var folderRelationships = new List>(); - // Act await sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships); - // Assert await sutProvider.GetDependency().Received(1).CreateAsync(ciphers, Arg.Any>()); await sutProvider.GetDependency().Received(1).PushSyncVaultAsync(importingUserId); } diff --git a/test/Core.Test/Vault/Services/CipherServiceTests.cs b/test/Core.Test/Vault/Services/CipherServiceTests.cs index 5b30c880ffa1..ba1693b1a5a0 100644 --- a/test/Core.Test/Vault/Services/CipherServiceTests.cs +++ b/test/Core.Test/Vault/Services/CipherServiceTests.cs @@ -736,7 +736,6 @@ public async Task SaveDetailsAsync_PersonalVault_WithDisablePersonalOwnershipPol CipherDetails cipher, Guid savingUserId) { - // Arrange cipher.Id = default; cipher.UserId = savingUserId; cipher.OrganizationId = null; @@ -745,7 +744,6 @@ public async Task SaveDetailsAsync_PersonalVault_WithDisablePersonalOwnershipPol .AnyPoliciesApplicableToUserAsync(savingUserId, PolicyType.PersonalOwnership) .Returns(true); - // Act & Assert var exception = await Assert.ThrowsAsync( () => sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null)); Assert.Contains("restricted from saving items to your personal vault", exception.Message); @@ -758,7 +756,6 @@ public async Task SaveDetailsAsync_PersonalVault_WithDisablePersonalOwnershipPol CipherDetails cipher, Guid savingUserId) { - // Arrange cipher.Id = default; cipher.UserId = savingUserId; cipher.OrganizationId = null; @@ -767,10 +764,8 @@ public async Task SaveDetailsAsync_PersonalVault_WithDisablePersonalOwnershipPol .AnyPoliciesApplicableToUserAsync(savingUserId, PolicyType.PersonalOwnership) .Returns(false); - // Act await sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null); - // Assert await sutProvider.GetDependency() .Received(1) .CreateAsync(cipher); @@ -783,7 +778,6 @@ public async Task SaveDetailsAsync_PersonalVault_WithPolicyRequirementsEnabled_W CipherDetails cipher, Guid savingUserId) { - // Arrange cipher.Id = default; cipher.UserId = savingUserId; cipher.OrganizationId = null; @@ -796,7 +790,6 @@ public async Task SaveDetailsAsync_PersonalVault_WithPolicyRequirementsEnabled_W .GetAsync(savingUserId) .Returns(new PersonalOwnershipPolicyRequirement { DisablePersonalOwnership = true }); - // Act & Assert var exception = await Assert.ThrowsAsync( () => sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null)); Assert.Contains("restricted from saving items to your personal vault", exception.Message); @@ -809,7 +802,6 @@ public async Task SaveDetailsAsync_PersonalVault_WithPolicyRequirementsEnabled_W CipherDetails cipher, Guid savingUserId) { - // Arrange cipher.Id = default; cipher.UserId = savingUserId; cipher.OrganizationId = null; @@ -822,10 +814,8 @@ public async Task SaveDetailsAsync_PersonalVault_WithPolicyRequirementsEnabled_W .GetAsync(savingUserId) .Returns(new PersonalOwnershipPolicyRequirement { DisablePersonalOwnership = false }); - // Act await sutProvider.Sut.SaveDetailsAsync(cipher, savingUserId, null); - // Assert await sutProvider.GetDependency() .Received(1) .CreateAsync(cipher); From 43a2ba0d2c2be6e75ca72ad4c01cb34b24d7959e Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Wed, 26 Feb 2025 11:00:03 +0000 Subject: [PATCH 07/11] Refactor PersonalOwnershipPolicyRequirementTests method names for clarity - Improve test method names to better describe their purpose and behavior - Rename methods to follow a more descriptive naming convention - No functional changes to the test logic --- .../PersonalOwnershipPolicyRequirementTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs index d0fb1cd83f43..c271418e7594 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs @@ -11,7 +11,7 @@ namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.Policies.PolicyRequire public class PersonalOwnershipPolicyRequirementTests { [Theory, AutoData] - public void DisablePersonalOwnership_IsFalse_IfNoPersonalOwnershipPolicies( + public void Create_WithNonPersonalOwnershipPolicies_ReturnsDisablePersonalOwnershipFalse( [PolicyDetails(PolicyType.RequireSso)] PolicyDetails otherPolicy1, [PolicyDetails(PolicyType.SendOptions)] PolicyDetails otherPolicy2) { @@ -25,7 +25,7 @@ public void DisablePersonalOwnership_IsFalse_IfNoPersonalOwnershipPolicies( [InlineAutoData(OrganizationUserType.Admin, false)] [InlineAutoData(OrganizationUserType.User, true)] [InlineAutoData(OrganizationUserType.Custom, true)] - public void DisablePersonalOwnership_TestRoles( + public void Create_WithDifferentOrganizationUserTypes_ReturnsExpectedEnforcement( OrganizationUserType userType, bool shouldBeEnforced, [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails) @@ -38,7 +38,7 @@ public void DisablePersonalOwnership_TestRoles( } [Theory, AutoData] - public void DisablePersonalOwnership_Not_EnforcedAgainstProviders( + public void Create_WithProviderPolicyDetails_ReturnsDisablePersonalOwnershipFalse( [PolicyDetails(PolicyType.PersonalOwnership, isProvider: true)] PolicyDetails policyDetails) { var actual = PersonalOwnershipPolicyRequirement.Create([policyDetails]); @@ -51,7 +51,7 @@ public void DisablePersonalOwnership_Not_EnforcedAgainstProviders( [InlineAutoData(OrganizationUserStatusType.Accepted, true)] [InlineAutoData(OrganizationUserStatusType.Invited, false)] [InlineAutoData(OrganizationUserStatusType.Revoked, false)] - public void DisablePersonalOwnership_TestStatuses( + public void Create_WithDifferentOrganizationUserStatuses_ReturnsExpectedEnforcement( OrganizationUserStatusType userStatus, bool shouldBeEnforced, [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails) From 99e4e06ac5130fa916b48c4d499620346b5f6a28 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Wed, 26 Feb 2025 11:15:37 +0000 Subject: [PATCH 08/11] Remove commented code explaining policy check --- src/Core/Vault/Services/Implementations/CipherService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/Vault/Services/Implementations/CipherService.cs b/src/Core/Vault/Services/Implementations/CipherService.cs index 733425905848..61d22aa406e2 100644 --- a/src/Core/Vault/Services/Implementations/CipherService.cs +++ b/src/Core/Vault/Services/Implementations/CipherService.cs @@ -146,7 +146,6 @@ public async Task SaveDetailsAsync(CipherDetails cipher, Guid savingUserId, Date } else { - // Make sure the user can save new ciphers to their personal vault var isPersonalVaultRestricted = _featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements) ? (await _policyRequirementQuery.GetAsync(savingUserId)).DisablePersonalOwnership : await _policyService.AnyPoliciesApplicableToUserAsync(savingUserId, PolicyType.PersonalOwnership); From 245f781362d12304d6b28b34761f3dc8fb199a48 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Tue, 11 Mar 2025 15:16:21 +0000 Subject: [PATCH 09/11] Refactor PersonalOwnership Policy Requirement implementation - Add PersonalOwnershipPolicyRequirementFactory to replace static Create method - Simplify policy requirement creation logic - Update PolicyServiceCollectionExtensions to register new factory - Update ImportCiphersCommand to use correct user ID parameter - Remove redundant PersonalOwnershipPolicyRequirementTests --- .../PersonalOwnershipPolicyRequirement.cs | 27 ++---- .../PolicyServiceCollectionExtensions.cs | 1 + .../ImportFeatures/ImportCiphersCommand.cs | 4 +- ...lOwnershipPolicyRequirementFactoryTests.cs | 90 +++++++++++++++++++ ...PersonalOwnershipPolicyRequirementTests.cs | 66 +------------- .../ImportCiphersAsyncCommandTests.cs | 4 +- 6 files changed, 103 insertions(+), 89 deletions(-) create mode 100644 test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs diff --git a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs index e967a4e89093..6f3f017bb99f 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirement.cs @@ -1,6 +1,5 @@ using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; -using Bit.Core.Enums; namespace Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; @@ -13,27 +12,15 @@ public class PersonalOwnershipPolicyRequirement : IPolicyRequirement /// Indicates whether Personal Ownership is disabled for the user. If true, members are required to save items to an organization. /// public bool DisablePersonalOwnership { get; init; } +} - /// - /// Creates a new PersonalOwnershipPolicyRequirement. - /// - /// All PolicyDetails relating to the user. - /// - /// This is a for the PersonalOwnershipPolicyRequirement. - /// - public static PersonalOwnershipPolicyRequirement Create(IEnumerable policyDetails) - { - var filteredPolicies = policyDetails - .ExemptRoles([OrganizationUserType.Owner, OrganizationUserType.Admin]) - .ExemptStatus([OrganizationUserStatusType.Invited, OrganizationUserStatusType.Revoked]) - .ExemptProviders() - .ToList(); - - var result = new PersonalOwnershipPolicyRequirement - { - DisablePersonalOwnership = filteredPolicies.GetPolicyType(PolicyType.PersonalOwnership).Any() - }; +public class PersonalOwnershipPolicyRequirementFactory : BasePolicyRequirementFactory +{ + public override PolicyType PolicyType => PolicyType.PersonalOwnership; + public override PersonalOwnershipPolicyRequirement Create(IEnumerable policyDetails) + { + var result = new PersonalOwnershipPolicyRequirement { DisablePersonalOwnership = policyDetails.Any() }; return result; } } diff --git a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs index 6c698f9ffcaf..a5ad8aa6def2 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs @@ -33,5 +33,6 @@ private static void AddPolicyRequirements(this IServiceCollection services) { services.AddScoped, DisableSendPolicyRequirementFactory>(); services.AddScoped, SendOptionsPolicyRequirementFactory>(); + services.AddScoped, PersonalOwnershipPolicyRequirementFactory>(); } } diff --git a/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs b/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs index c0465a13ad84..3c58dca183bb 100644 --- a/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs +++ b/src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs @@ -66,8 +66,8 @@ public async Task ImportIntoIndividualVaultAsync( { // Make sure the user can save new ciphers to their personal vault var isPersonalVaultRestricted = _featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements) - ? (await _policyRequirementQuery.GetAsync(userId.Value)).DisablePersonalOwnership - : await _policyService.AnyPoliciesApplicableToUserAsync(userId.Value, PolicyType.PersonalOwnership); + ? (await _policyRequirementQuery.GetAsync(importingUserId)).DisablePersonalOwnership + : await _policyService.AnyPoliciesApplicableToUserAsync(importingUserId, PolicyType.PersonalOwnership); if (isPersonalVaultRestricted) { diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs new file mode 100644 index 000000000000..e7ef9f9bbfd8 --- /dev/null +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs @@ -0,0 +1,90 @@ +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 Bit.Test.Common.AutoFixture; +using Bit.Test.Common.AutoFixture.Attributes; +using Xunit; + +namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements; + +[SutProviderCustomize] +public class PersonalOwnershipPolicyRequirementFactoryTests +{ + [Theory, BitAutoData] + public void DisablePersonalOwnership_WithNoPolicies_ReturnsFalse(SutProvider sutProvider) + { + var actual = sutProvider.Sut.Create([]); + + Assert.False(actual.DisablePersonalOwnership); + } + + [Theory, BitAutoData] + public void DisablePersonalOwnership_WithNonPersonalOwnershipPolicies_ReturnsFalse( + [PolicyDetails(PolicyType.RequireSso)] PolicyDetails otherPolicy1, + [PolicyDetails(PolicyType.SendOptions)] PolicyDetails otherPolicy2, + SutProvider sutProvider) + { + var actual = sutProvider.Sut.Create([otherPolicy1, otherPolicy2]); + + Assert.False(actual.DisablePersonalOwnership); + } + + [Theory, BitAutoData] + public void DisablePersonalOwnership_WithPersonalOwnershipPolicies_ReturnsTrue( + [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails[] policies, + SutProvider sutProvider + ) + { + var actual = sutProvider.Sut.Create(policies); + + Assert.True(actual.DisablePersonalOwnership); + } + + [Theory, BitAutoData] + public void DisablePersonalOwnership_WithProviderUserParameter_ReturnsFalse( + [PolicyDetails(PolicyType.PersonalOwnership, isProvider: true)] PolicyDetails policyDetails, + SutProvider sutProvider) + { + var actual = sutProvider.Sut.Create([policyDetails]); + + Assert.False(actual.DisablePersonalOwnership); + } + + [Theory] + [BitAutoData(OrganizationUserType.Owner, false)] + [BitAutoData(OrganizationUserType.Admin, false)] + [BitAutoData(OrganizationUserType.User, true)] + [BitAutoData(OrganizationUserType.Custom, true)] + public void DisablePersonalOwnership_RespectsExemptRoles( + OrganizationUserType userType, + bool shouldBeEnforced, + [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails, + SutProvider sutProvider) + { + policyDetails.OrganizationUserType = userType; + + var actual = sutProvider.Sut.Create([policyDetails]); + + Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); + } + + [Theory] + [BitAutoData(OrganizationUserStatusType.Confirmed, true)] + [BitAutoData(OrganizationUserStatusType.Accepted, true)] + [BitAutoData(OrganizationUserStatusType.Invited, false)] + [BitAutoData(OrganizationUserStatusType.Revoked, false)] + public void DisablePersonalOwnership_RespectsExemptStatuses( + OrganizationUserStatusType userStatus, + bool shouldBeEnforced, + [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails, + SutProvider sutProvider) + { + policyDetails.OrganizationUserStatus = userStatus; + + var actual = sutProvider.Sut.Create([policyDetails]); + + Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); + } +} diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs index c271418e7594..5f282702bb03 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs @@ -1,65 +1 @@ -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 PersonalOwnershipPolicyRequirementTests -{ - [Theory, AutoData] - public void Create_WithNonPersonalOwnershipPolicies_ReturnsDisablePersonalOwnershipFalse( - [PolicyDetails(PolicyType.RequireSso)] PolicyDetails otherPolicy1, - [PolicyDetails(PolicyType.SendOptions)] PolicyDetails otherPolicy2) - { - var actual = PersonalOwnershipPolicyRequirement.Create([otherPolicy1, otherPolicy2]); - - Assert.False(actual.DisablePersonalOwnership); - } - - [Theory] - [InlineAutoData(OrganizationUserType.Owner, false)] - [InlineAutoData(OrganizationUserType.Admin, false)] - [InlineAutoData(OrganizationUserType.User, true)] - [InlineAutoData(OrganizationUserType.Custom, true)] - public void Create_WithDifferentOrganizationUserTypes_ReturnsExpectedEnforcement( - OrganizationUserType userType, - bool shouldBeEnforced, - [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails) - { - policyDetails.OrganizationUserType = userType; - - var actual = PersonalOwnershipPolicyRequirement.Create([policyDetails]); - - Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); - } - - [Theory, AutoData] - public void Create_WithProviderPolicyDetails_ReturnsDisablePersonalOwnershipFalse( - [PolicyDetails(PolicyType.PersonalOwnership, isProvider: true)] PolicyDetails policyDetails) - { - var actual = PersonalOwnershipPolicyRequirement.Create([policyDetails]); - - Assert.False(actual.DisablePersonalOwnership); - } - - [Theory] - [InlineAutoData(OrganizationUserStatusType.Confirmed, true)] - [InlineAutoData(OrganizationUserStatusType.Accepted, true)] - [InlineAutoData(OrganizationUserStatusType.Invited, false)] - [InlineAutoData(OrganizationUserStatusType.Revoked, false)] - public void Create_WithDifferentOrganizationUserStatuses_ReturnsExpectedEnforcement( - OrganizationUserStatusType userStatus, - bool shouldBeEnforced, - [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails) - { - policyDetails.OrganizationUserStatus = userStatus; - - var actual = PersonalOwnershipPolicyRequirement.Create([policyDetails]); - - Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); - } -} + \ No newline at end of file diff --git a/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs b/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs index 4fd196797f37..89e6d152cc95 100644 --- a/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs +++ b/test/Core.Test/Tools/ImportFeatures/ImportCiphersAsyncCommandTests.cs @@ -75,7 +75,7 @@ public async Task ImportIntoIndividualVaultAsync_WithPolicyRequirementsEnabled_W var folderRelationships = new List>(); - await sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships); + await sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships, importingUserId); await sutProvider.GetDependency().Received(1).CreateAsync(ciphers, Arg.Any>()); await sutProvider.GetDependency().Received(1).PushSyncVaultAsync(importingUserId); @@ -124,7 +124,7 @@ public async Task ImportIntoIndividualVaultAsync_WithPolicyRequirementsEnabled_W var folderRelationships = new List>(); var exception = await Assert.ThrowsAsync(() => - sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships)); + sutProvider.Sut.ImportIntoIndividualVaultAsync(folders, ciphers, folderRelationships, userId)); Assert.Equal("You cannot import items into your personal vault because you are a member of an organization which forbids it.", exception.Message); } From a9211f94c36db99e56b407dfe93aac4184dc1f6f Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Tue, 11 Mar 2025 15:23:17 +0000 Subject: [PATCH 10/11] Remove redundant PersonalOwnershipPolicyRequirementTests --- .../PersonalOwnershipPolicyRequirementTests.cs | 1 - 1 file changed, 1 deletion(-) delete mode 100644 test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs deleted file mode 100644 index 5f282702bb03..000000000000 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementTests.cs +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 439a13a665c678cc454d654bb9442915732fb088 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Tue, 11 Mar 2025 15:42:30 +0000 Subject: [PATCH 11/11] Remove unnecessary tests from PersonalOwnershipPolicyRequirementFactoryTests --- ...lOwnershipPolicyRequirementFactoryTests.cs | 61 +------------------ 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs index e7ef9f9bbfd8..2ce75ca61e8c 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/PersonalOwnershipPolicyRequirementFactoryTests.cs @@ -1,7 +1,6 @@ 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 Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; @@ -20,71 +19,13 @@ public void DisablePersonalOwnership_WithNoPolicies_ReturnsFalse(SutProvider sutProvider) - { - var actual = sutProvider.Sut.Create([otherPolicy1, otherPolicy2]); - - Assert.False(actual.DisablePersonalOwnership); - } - [Theory, BitAutoData] public void DisablePersonalOwnership_WithPersonalOwnershipPolicies_ReturnsTrue( [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails[] policies, - SutProvider sutProvider - ) + SutProvider sutProvider) { var actual = sutProvider.Sut.Create(policies); Assert.True(actual.DisablePersonalOwnership); } - - [Theory, BitAutoData] - public void DisablePersonalOwnership_WithProviderUserParameter_ReturnsFalse( - [PolicyDetails(PolicyType.PersonalOwnership, isProvider: true)] PolicyDetails policyDetails, - SutProvider sutProvider) - { - var actual = sutProvider.Sut.Create([policyDetails]); - - Assert.False(actual.DisablePersonalOwnership); - } - - [Theory] - [BitAutoData(OrganizationUserType.Owner, false)] - [BitAutoData(OrganizationUserType.Admin, false)] - [BitAutoData(OrganizationUserType.User, true)] - [BitAutoData(OrganizationUserType.Custom, true)] - public void DisablePersonalOwnership_RespectsExemptRoles( - OrganizationUserType userType, - bool shouldBeEnforced, - [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails, - SutProvider sutProvider) - { - policyDetails.OrganizationUserType = userType; - - var actual = sutProvider.Sut.Create([policyDetails]); - - Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); - } - - [Theory] - [BitAutoData(OrganizationUserStatusType.Confirmed, true)] - [BitAutoData(OrganizationUserStatusType.Accepted, true)] - [BitAutoData(OrganizationUserStatusType.Invited, false)] - [BitAutoData(OrganizationUserStatusType.Revoked, false)] - public void DisablePersonalOwnership_RespectsExemptStatuses( - OrganizationUserStatusType userStatus, - bool shouldBeEnforced, - [PolicyDetails(PolicyType.PersonalOwnership)] PolicyDetails policyDetails, - SutProvider sutProvider) - { - policyDetails.OrganizationUserStatus = userStatus; - - var actual = sutProvider.Sut.Create([policyDetails]); - - Assert.Equal(shouldBeEnforced, actual.DisablePersonalOwnership); - } }