diff --git a/src/Admin/AdminConsole/Views/Organizations/_ViewInformation.cshtml b/src/Admin/AdminConsole/Views/Organizations/_ViewInformation.cshtml index db2e2c601a70..f3853e16a93e 100644 --- a/src/Admin/AdminConsole/Views/Organizations/_ViewInformation.cshtml +++ b/src/Admin/AdminConsole/Views/Organizations/_ViewInformation.cshtml @@ -1,4 +1,6 @@ -@model OrganizationViewModel +@inject Bit.Core.Services.IFeatureService FeatureService +@model OrganizationViewModel +
Id
@Model.Organization.Id
@@ -53,8 +55,19 @@
Administrators manage all collections
@(Model.Organization.AllowAdminAccessToAllCollectionItems ? "On" : "Off")
-
Limit collection creation to administrators
-
@(Model.Organization.LimitCollectionCreationDeletion ? "On" : "Off")
+ @if (!FeatureService.IsEnabled(Bit.Core.FeatureFlagKeys.LimitCollectionCreationDeletionSplit)) + { +
Limit collection creation to administrators
+
@(Model.Organization.LimitCollectionCreationDeletion ? "On" : "Off")
+ } + else + { +
Limit collection creation to administrators
+
@(Model.Organization.LimitCollectionCreation ? "On" : "Off")
+ +
Limit collection deletion to administrators
+
@(Model.Organization.LimitCollectionDeletion ? "On" : "Off")
+ }

Secrets Manager

diff --git a/src/Api/AdminConsole/Models/Response/Organizations/OrganizationResponseModel.cs b/src/Api/AdminConsole/Models/Response/Organizations/OrganizationResponseModel.cs index 08b4e4b0638c..935bf120bcd0 100644 --- a/src/Api/AdminConsole/Models/Response/Organizations/OrganizationResponseModel.cs +++ b/src/Api/AdminConsole/Models/Response/Organizations/OrganizationResponseModel.cs @@ -55,6 +55,9 @@ public OrganizationResponseModel(Organization organization, string obj = "organi SmServiceAccounts = organization.SmServiceAccounts; MaxAutoscaleSmSeats = organization.MaxAutoscaleSmSeats; MaxAutoscaleSmServiceAccounts = organization.MaxAutoscaleSmServiceAccounts; + LimitCollectionCreation = organization.LimitCollectionCreation; + LimitCollectionDeletion = organization.LimitCollectionDeletion; + // Deperectated: https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = organization.LimitCollectionCreationDeletion; AllowAdminAccessToAllCollectionItems = organization.AllowAdminAccessToAllCollectionItems; } @@ -98,6 +101,9 @@ public OrganizationResponseModel(Organization organization, string obj = "organi public int? SmServiceAccounts { get; set; } public int? MaxAutoscaleSmSeats { get; set; } public int? MaxAutoscaleSmServiceAccounts { get; set; } + public bool LimitCollectionCreation { get; set; } + public bool LimitCollectionDeletion { get; set; } + // Deperectated: https://bitwarden.atlassian.net/browse/PM-10863 public bool LimitCollectionCreationDeletion { get; set; } public bool AllowAdminAccessToAllCollectionItems { get; set; } } diff --git a/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs b/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs index 17ebfc095e28..40489fc60256 100644 --- a/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs +++ b/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs @@ -62,6 +62,9 @@ public ProfileOrganizationResponseModel(OrganizationUserOrganizationDetails orga FamilySponsorshipToDelete = organization.FamilySponsorshipToDelete; FamilySponsorshipValidUntil = organization.FamilySponsorshipValidUntil; AccessSecretsManager = organization.AccessSecretsManager; + LimitCollectionCreation = organization.LimitCollectionCreation; + LimitCollectionDeletion = organization.LimitCollectionDeletion; + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = organization.LimitCollectionCreationDeletion; AllowAdminAccessToAllCollectionItems = organization.AllowAdminAccessToAllCollectionItems; @@ -120,6 +123,9 @@ public ProfileOrganizationResponseModel(OrganizationUserOrganizationDetails orga public DateTime? FamilySponsorshipValidUntil { get; set; } public bool? FamilySponsorshipToDelete { get; set; } public bool AccessSecretsManager { get; set; } + public bool LimitCollectionCreation { get; set; } + public bool LimitCollectionDeletion { get; set; } + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 public bool LimitCollectionCreationDeletion { get; set; } public bool AllowAdminAccessToAllCollectionItems { get; set; } } diff --git a/src/Api/AdminConsole/Models/Response/ProfileProviderOrganizationResponseModel.cs b/src/Api/AdminConsole/Models/Response/ProfileProviderOrganizationResponseModel.cs index 46819f886964..92498834db05 100644 --- a/src/Api/AdminConsole/Models/Response/ProfileProviderOrganizationResponseModel.cs +++ b/src/Api/AdminConsole/Models/Response/ProfileProviderOrganizationResponseModel.cs @@ -44,6 +44,9 @@ public ProfileProviderOrganizationResponseModel(ProviderUserOrganizationDetails ProviderId = organization.ProviderId; ProviderName = organization.ProviderName; ProductTierType = StaticStore.GetPlan(organization.PlanType).ProductTier; + LimitCollectionCreation = organization.LimitCollectionCreation; + LimitCollectionDeletion = organization.LimitCollectionDeletion; + // https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = organization.LimitCollectionCreationDeletion; AllowAdminAccessToAllCollectionItems = organization.AllowAdminAccessToAllCollectionItems; } diff --git a/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs b/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs index 68e87b522b33..f016b1206781 100644 --- a/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs +++ b/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs @@ -4,11 +4,17 @@ namespace Bit.Api.Models.Request.Organizations; public class OrganizationCollectionManagementUpdateRequestModel { + public bool LimitCollectionCreation { get; set; } + public bool LimitCollectionDeletion { get; set; } + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 public bool LimitCreateDeleteOwnerAdmin { get; set; } public bool AllowAdminAccessToAllCollectionItems { get; set; } public virtual Organization ToOrganization(Organization existingOrganization) { + existingOrganization.LimitCollectionCreation = LimitCollectionCreation; + existingOrganization.LimitCollectionDeletion = LimitCollectionDeletion; + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 existingOrganization.LimitCollectionCreationDeletion = LimitCreateDeleteOwnerAdmin; existingOrganization.AllowAdminAccessToAllCollectionItems = AllowAdminAccessToAllCollectionItems; return existingOrganization; diff --git a/src/Api/Vault/AuthorizationHandlers/Collections/BulkCollectionAuthorizationHandler.cs b/src/Api/Vault/AuthorizationHandlers/Collections/BulkCollectionAuthorizationHandler.cs index 5d11b39ead25..7c1369c47ce6 100644 --- a/src/Api/Vault/AuthorizationHandlers/Collections/BulkCollectionAuthorizationHandler.cs +++ b/src/Api/Vault/AuthorizationHandlers/Collections/BulkCollectionAuthorizationHandler.cs @@ -1,5 +1,6 @@ #nullable enable using System.Diagnostics; +using Bit.Core; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Enums; @@ -101,7 +102,7 @@ protected override async Task HandleRequirementAsync(AuthorizationHandlerContext break; case null: - // requirement isn't actually nullable but since we use the + // requirement isn't actually nullable but since we use the // not null when trick it makes the compiler think that requirement // could actually be nullable. throw new UnreachableException(); @@ -123,8 +124,14 @@ private async Task CanCreateAsync(CurrentContextOrganization? org) return true; } + var organizationAbility = await GetOrganizationAbilityAsync(org); + + var limitCollectionCreationEnabled = !(_featureService.IsEnabled(FeatureFlagKeys.LimitCollectionCreationDeletionSplit) + ? organizationAbility is { LimitCollectionCreation: false } + : organizationAbility is { LimitCollectionCreationDeletion: false }); + // If the limit collection management setting is disabled, allow any user to create collections - if (await GetOrganizationAbilityAsync(org) is { LimitCollectionCreationDeletion: false }) + if (!limitCollectionCreationEnabled) { return true; } @@ -256,8 +263,15 @@ private async Task CanDeleteAsync(ICollection resources, Curre // Ensure acting user has manage permissions for all collections being deleted // If LimitCollectionCreationDeletion is true, only Owners and Admins can delete collections they manage var organizationAbility = await GetOrganizationAbilityAsync(org); - var canDeleteManagedCollections = organizationAbility is { LimitCollectionCreationDeletion: false } || - org is { Type: OrganizationUserType.Owner or OrganizationUserType.Admin }; + + var limitCollectionDeletionEnabled = !(_featureService.IsEnabled(FeatureFlagKeys.LimitCollectionCreationDeletionSplit) + ? organizationAbility is { LimitCollectionDeletion: false } + : organizationAbility is { LimitCollectionCreationDeletion: false }); + + var canDeleteManagedCollections = + !limitCollectionDeletionEnabled || + org is { Type: OrganizationUserType.Owner or OrganizationUserType.Admin }; + if (canDeleteManagedCollections && await CanManageCollectionsAsync(resources, org)) { return true; diff --git a/src/Core/AdminConsole/Entities/Organization.cs b/src/Core/AdminConsole/Entities/Organization.cs index 34fe157c6ecb..1718be902af3 100644 --- a/src/Core/AdminConsole/Entities/Organization.cs +++ b/src/Core/AdminConsole/Entities/Organization.cs @@ -313,7 +313,6 @@ public void UpdateFromLicense(OrganizationLicense license) UseSecretsManager = license.UseSecretsManager; SmSeats = license.SmSeats; SmServiceAccounts = license.SmServiceAccounts; - LimitCollectionCreationDeletion = license.LimitCollectionCreationDeletion; AllowAdminAccessToAllCollectionItems = license.AllowAdminAccessToAllCollectionItems; } } diff --git a/src/Core/AdminConsole/Models/Data/Organizations/OrganizationAbility.cs b/src/Core/AdminConsole/Models/Data/Organizations/OrganizationAbility.cs index 07db80d433ff..a91b960839c3 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/OrganizationAbility.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/OrganizationAbility.cs @@ -21,6 +21,9 @@ public OrganizationAbility(Organization organization) UseResetPassword = organization.UseResetPassword; UseCustomPermissions = organization.UseCustomPermissions; UsePolicies = organization.UsePolicies; + LimitCollectionCreation = organization.LimitCollectionCreation; + LimitCollectionDeletion = organization.LimitCollectionDeletion; + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = organization.LimitCollectionCreationDeletion; AllowAdminAccessToAllCollectionItems = organization.AllowAdminAccessToAllCollectionItems; } @@ -37,6 +40,9 @@ public OrganizationAbility(Organization organization) public bool UseResetPassword { get; set; } public bool UseCustomPermissions { get; set; } public bool UsePolicies { get; set; } + public bool LimitCollectionCreation { get; set; } + public bool LimitCollectionDeletion { get; set; } + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 public bool LimitCollectionCreationDeletion { get; set; } public bool AllowAdminAccessToAllCollectionItems { get; set; } } diff --git a/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserOrganizationDetails.cs b/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserOrganizationDetails.cs index cdd73cba7125..435369e77afc 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserOrganizationDetails.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserOrganizationDetails.cs @@ -54,6 +54,9 @@ public class OrganizationUserOrganizationDetails public bool UsePasswordManager { get; set; } public int? SmSeats { get; set; } public int? SmServiceAccounts { get; set; } + public bool LimitCollectionCreation { get; set; } + public bool LimitCollectionDeletion { get; set; } + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 public bool LimitCollectionCreationDeletion { get; set; } public bool AllowAdminAccessToAllCollectionItems { get; set; } } diff --git a/src/Core/AdminConsole/Models/Data/Organizations/SelfHostedOrganizationDetails.cs b/src/Core/AdminConsole/Models/Data/Organizations/SelfHostedOrganizationDetails.cs index d21ba9183019..1fa547d98b87 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/SelfHostedOrganizationDetails.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/SelfHostedOrganizationDetails.cs @@ -144,6 +144,9 @@ public Organization ToOrganization() RevisionDate = RevisionDate, MaxAutoscaleSeats = MaxAutoscaleSeats, OwnersNotifiedOfAutoscaling = OwnersNotifiedOfAutoscaling, + LimitCollectionCreation = LimitCollectionCreation, + LimitCollectionDeletion = LimitCollectionDeletion, + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = LimitCollectionCreationDeletion, AllowAdminAccessToAllCollectionItems = AllowAdminAccessToAllCollectionItems, Status = Status diff --git a/src/Core/AdminConsole/Models/Data/Provider/ProviderUserOrganizationDetails.cs b/src/Core/AdminConsole/Models/Data/Provider/ProviderUserOrganizationDetails.cs index d3d831f5187d..a2ac6225390a 100644 --- a/src/Core/AdminConsole/Models/Data/Provider/ProviderUserOrganizationDetails.cs +++ b/src/Core/AdminConsole/Models/Data/Provider/ProviderUserOrganizationDetails.cs @@ -40,6 +40,8 @@ public class ProviderUserOrganizationDetails [JsonConverter(typeof(HtmlEncodingStringConverter))] public string ProviderName { get; set; } public PlanType PlanType { get; set; } + public bool LimitCollectionCreation { get; set; } + public bool LimitCollectionDeletion { get; set; } public bool LimitCollectionCreationDeletion { get; set; } public bool AllowAdminAccessToAllCollectionItems { get; set; } } diff --git a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs index 5c3f81cee2e1..a09e79f2f09b 100644 --- a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs +++ b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs @@ -705,10 +705,16 @@ private async Task ValidateSignUpPoliciesAsync(Guid ownerId) UseSecretsManager = license.UseSecretsManager, SmSeats = license.SmSeats, SmServiceAccounts = license.SmServiceAccounts, - LimitCollectionCreationDeletion = license.LimitCollectionCreationDeletion, - AllowAdminAccessToAllCollectionItems = license.AllowAdminAccessToAllCollectionItems, }; + // These fields are being removed from consideration when processing + // licenses. + if (!_featureService.IsEnabled(FeatureFlagKeys.LimitCollectionCreationDeletionSplit)) + { + organization.LimitCollectionCreationDeletion = license.LimitCollectionCreationDeletion; + organization.AllowAdminAccessToAllCollectionItems = license.AllowAdminAccessToAllCollectionItems; + } + var result = await SignUpAsync(organization, owner.Id, ownerKey, collectionName, false); var dir = $"{_globalSettings.LicenseDirectory}/organization"; diff --git a/src/Core/Models/Business/OrganizationLicense.cs b/src/Core/Models/Business/OrganizationLicense.cs index ebc1a083f9f1..796bf6b97484 100644 --- a/src/Core/Models/Business/OrganizationLicense.cs +++ b/src/Core/Models/Business/OrganizationLicense.cs @@ -53,8 +53,11 @@ public OrganizationLicense(Organization org, SubscriptionInfo subscriptionInfo, UseSecretsManager = org.UseSecretsManager; SmSeats = org.SmSeats; SmServiceAccounts = org.SmServiceAccounts; + + // Deprecated. Left for backwards compatibility with old license versions. LimitCollectionCreationDeletion = org.LimitCollectionCreationDeletion; AllowAdminAccessToAllCollectionItems = org.AllowAdminAccessToAllCollectionItems; + // if (subscriptionInfo?.Subscription == null) { @@ -138,8 +141,12 @@ public OrganizationLicense(Organization org, SubscriptionInfo subscriptionInfo, public bool UseSecretsManager { get; set; } public int? SmSeats { get; set; } public int? SmServiceAccounts { get; set; } + + // Deprecated. Left for backwards compatibility with old license versions. public bool LimitCollectionCreationDeletion { get; set; } = true; public bool AllowAdminAccessToAllCollectionItems { get; set; } = true; + // + public bool Trial { get; set; } public LicenseType? LicenseType { get; set; } public string Hash { get; set; } @@ -150,7 +157,14 @@ public OrganizationLicense(Organization org, SubscriptionInfo subscriptionInfo, /// Represents the current version of the license format. Should be updated whenever new fields are added. /// /// Intentionally set one version behind to allow self hosted users some time to update before - /// getting out of date license errors + /// getting out of date license errors + /// + /// + /// ⚠ This is important! We are on this license version because of new + /// properties that were added for versions 14 and 15. These properties + /// were later removed! When you increment to version 16 please delete + /// this comment. + /// public const int CurrentLicenseFileVersion = 14; private bool ValidLicenseVersion { @@ -367,12 +381,6 @@ to the Organization object. It's validated as part of the hash but does not need organization.SmServiceAccounts == SmServiceAccounts; } - /* - * Version 14 added LimitCollectionCreationDeletion and Version 15 added AllowAdminAccessToAllCollectionItems, - * however these are just user settings and it is not worth failing validation if they mismatch. - * They are intentionally excluded. - */ - return valid; } diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Models/Organization.cs b/src/Infrastructure.EntityFramework/AdminConsole/Models/Organization.cs index d134bdb67ec2..d7f83d829db4 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Models/Organization.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Models/Organization.cs @@ -38,9 +38,6 @@ public OrganizationMapperProfile() .ForMember(org => org.ApiKeys, opt => opt.Ignore()) .ForMember(org => org.Connections, opt => opt.Ignore()) .ForMember(org => org.Domains, opt => opt.Ignore()) - // Shadow properties - to be introduced by https://bitwarden.atlassian.net/browse/PM-10863 - .ForMember(org => org.LimitCollectionCreation, opt => opt.Ignore()) - .ForMember(org => org.LimitCollectionDeletion, opt => opt.Ignore()) .ReverseMap(); CreateProjection() diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationRepository.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationRepository.cs index 96c9a912e1ee..de1fadcb58b9 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationRepository.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationRepository.cs @@ -99,6 +99,9 @@ public async Task> GetManyAbilitiesAsync() UseScim = e.UseScim, UseCustomPermissions = e.UseCustomPermissions, UsePolicies = e.UsePolicies, + LimitCollectionCreation = e.LimitCollectionCreation, + LimitCollectionDeletion = e.LimitCollectionDeletion, + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = e.LimitCollectionCreationDeletion, AllowAdminAccessToAllCollectionItems = e.AllowAdminAccessToAllCollectionItems }).ToListAsync(); diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs index 1584b26f01de..ba278fc915e3 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs @@ -66,6 +66,9 @@ from os in os_g.DefaultIfEmpty() UsePasswordManager = o.UsePasswordManager, SmSeats = o.SmSeats, SmServiceAccounts = o.SmServiceAccounts, + LimitCollectionCreation = o.LimitCollectionCreation, + LimitCollectionDeletion = o.LimitCollectionDeletion, + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = o.LimitCollectionCreationDeletion, AllowAdminAccessToAllCollectionItems = o.AllowAdminAccessToAllCollectionItems, }; diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/ProviderUserOrganizationDetailsViewQuery.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/ProviderUserOrganizationDetailsViewQuery.cs index 30a20806d8fa..1a9f8e347d96 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/ProviderUserOrganizationDetailsViewQuery.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/ProviderUserOrganizationDetailsViewQuery.cs @@ -44,6 +44,9 @@ join p in dbContext.Providers on pu.ProviderId equals p.Id ProviderId = x.p.Id, ProviderName = x.p.Name, PlanType = x.o.PlanType, + LimitCollectionCreation = x.o.LimitCollectionCreation, + LimitCollectionDeletion = x.o.LimitCollectionDeletion, + // Deprecated: https://bitwarden.atlassian.net/browse/PM-10863 LimitCollectionCreationDeletion = x.o.LimitCollectionCreationDeletion, AllowAdminAccessToAllCollectionItems = x.o.AllowAdminAccessToAllCollectionItems, }); diff --git a/test/Api.Test/Vault/AuthorizationHandlers/BulkCollectionAuthorizationHandlerTests.cs b/test/Api.Test/Vault/AuthorizationHandlers/BulkCollectionAuthorizationHandlerTests.cs index b94162be8e23..bd380129a386 100644 --- a/test/Api.Test/Vault/AuthorizationHandlers/BulkCollectionAuthorizationHandlerTests.cs +++ b/test/Api.Test/Vault/AuthorizationHandlers/BulkCollectionAuthorizationHandlerTests.cs @@ -32,7 +32,7 @@ public async Task CanCreateAsync_WhenAdminOrOwner_Success( organization.Type = userType; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, true); + ArrangeOrganizationAbility(sutProvider, organization, true, true); var context = new AuthorizationHandlerContext( new[] { BulkCollectionOperations.Create }, @@ -48,7 +48,7 @@ public async Task CanCreateAsync_WhenAdminOrOwner_Success( } [Theory, BitAutoData, CollectionCustomization] - public async Task CanCreateAsync_WhenUser_WithLimitCollectionCreationDeletionFalse_Success( + public async Task CanCreateAsync_WhenUser_WithLimitCollectionCreationFalse_Success( SutProvider sutProvider, ICollection collections, CurrentContextOrganization organization) @@ -57,7 +57,7 @@ public async Task CanCreateAsync_WhenUser_WithLimitCollectionCreationDeletionFal organization.Type = OrganizationUserType.User; - ArrangeOrganizationAbility(sutProvider, organization, false); + ArrangeOrganizationAbility(sutProvider, organization, false, false); var context = new AuthorizationHandlerContext( new[] { BulkCollectionOperations.Create }, @@ -92,7 +92,7 @@ public async Task CanCreateAsync_WhenMissingPermissions_NoSuccess( ManageUsers = false }; - ArrangeOrganizationAbility(sutProvider, organization, true); + ArrangeOrganizationAbility(sutProvider, organization, true, true); var context = new AuthorizationHandlerContext( new[] { BulkCollectionOperations.Create }, @@ -116,7 +116,7 @@ public async Task CanCreateAsync_WhenMissingOrgAccess_NoSuccess( SutProvider sutProvider) { collections.ForEach(c => c.OrganizationId = organization.Id); - ArrangeOrganizationAbility(sutProvider, organization, true); + ArrangeOrganizationAbility(sutProvider, organization, true, true); var context = new AuthorizationHandlerContext( new[] { BulkCollectionOperations.Create }, @@ -904,7 +904,7 @@ public async Task CanDeleteAsync_WithDeleteAnyCollectionPermission_Success( DeleteAnyCollection = true }; - ArrangeOrganizationAbility(sutProvider, organization, true); + ArrangeOrganizationAbility(sutProvider, organization, true, true); var context = new AuthorizationHandlerContext( new[] { BulkCollectionOperations.Delete }, @@ -931,7 +931,7 @@ public async Task CanDeleteAsync_WhenAdminOrOwner_AllowAdminAccessToAllCollectio organization.Type = userType; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, true); + ArrangeOrganizationAbility(sutProvider, organization, true, true); var context = new AuthorizationHandlerContext( new[] { BulkCollectionOperations.Delete }, @@ -947,7 +947,7 @@ public async Task CanDeleteAsync_WhenAdminOrOwner_AllowAdminAccessToAllCollectio } [Theory, BitAutoData, CollectionCustomization] - public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionFalse_WithCanManagePermission_Success( + public async Task CanDeleteAsync_WhenUser_LimitCollectionDeletionFalse_WithCanManagePermission_Success( SutProvider sutProvider, ICollection collections, CurrentContextOrganization organization) @@ -957,7 +957,7 @@ public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionFalse_W organization.Type = OrganizationUserType.User; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, false); + ArrangeOrganizationAbility(sutProvider, organization, false, false); sutProvider.GetDependency().UserId.Returns(actingUserId); sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); @@ -982,7 +982,7 @@ public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionFalse_W [BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Owner)] [BitAutoData(OrganizationUserType.User)] - public async Task CanDeleteAsync_LimitCollectionCreationDeletionFalse_AllowAdminAccessToAllCollectionItemsFalse_WithCanManagePermission_Success( + public async Task CanDeleteAsync_LimitCollectionDeletionFalse_AllowAdminAccessToAllCollectionItemsFalse_WithCanManagePermission_Success( OrganizationUserType userType, SutProvider sutProvider, ICollection collections, @@ -993,7 +993,7 @@ public async Task CanDeleteAsync_LimitCollectionCreationDeletionFalse_AllowAdmin organization.Type = userType; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, false, false); + ArrangeOrganizationAbility(sutProvider, organization, false, false, false); sutProvider.GetDependency().UserId.Returns(actingUserId); sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); @@ -1017,7 +1017,7 @@ public async Task CanDeleteAsync_LimitCollectionCreationDeletionFalse_AllowAdmin [Theory, CollectionCustomization] [BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Owner)] - public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionCreationDeletionTrue_AllowAdminAccessToAllCollectionItemsFalse_WithCanManagePermission_Success( + public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionDeletionTrue_AllowAdminAccessToAllCollectionItemsFalse_WithCanManagePermission_Success( OrganizationUserType userType, SutProvider sutProvider, ICollection collections, @@ -1028,7 +1028,7 @@ public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionCreationDeletio organization.Type = userType; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, true, false); + ArrangeOrganizationAbility(sutProvider, organization, true, true, false); sutProvider.GetDependency().UserId.Returns(actingUserId); sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); @@ -1052,7 +1052,7 @@ public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionCreationDeletio [Theory, CollectionCustomization] [BitAutoData(OrganizationUserType.Admin)] [BitAutoData(OrganizationUserType.Owner)] - public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionCreationDeletionTrue_AllowAdminAccessToAllCollectionItemsFalse_WithoutCanManagePermission_Failure( + public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionDeletionTrue_AllowAdminAccessToAllCollectionItemsFalse_WithoutCanManagePermission_Failure( OrganizationUserType userType, SutProvider sutProvider, ICollection collections, @@ -1063,7 +1063,7 @@ public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionCreationDeletio organization.Type = userType; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, true, false); + ArrangeOrganizationAbility(sutProvider, organization, true, true, false); sutProvider.GetDependency().UserId.Returns(actingUserId); sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); @@ -1086,7 +1086,7 @@ public async Task CanDeleteAsync_WhenAdminOrOwner_LimitCollectionCreationDeletio } [Theory, BitAutoData, CollectionCustomization] - public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionTrue_AllowAdminAccessToAllCollectionItemsTrue_Failure( + public async Task CanDeleteAsync_WhenUser_LimitCollectionDeletionTrue_AllowAdminAccessToAllCollectionItemsTrue_Failure( SutProvider sutProvider, ICollection collections, CurrentContextOrganization organization) @@ -1096,7 +1096,7 @@ public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionTrue_Al organization.Type = OrganizationUserType.User; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, true); + ArrangeOrganizationAbility(sutProvider, organization, true, true); sutProvider.GetDependency().UserId.Returns(actingUserId); sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); @@ -1119,7 +1119,7 @@ public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionTrue_Al } [Theory, BitAutoData, CollectionCustomization] - public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionTrue_AllowAdminAccessToAllCollectionItemsFalse_Failure( + public async Task CanDeleteAsync_WhenUser_LimitCollectionDeletionTrue_AllowAdminAccessToAllCollectionItemsFalse_Failure( SutProvider sutProvider, ICollection collections, CurrentContextOrganization organization) @@ -1129,7 +1129,7 @@ public async Task CanDeleteAsync_WhenUser_LimitCollectionCreationDeletionTrue_Al organization.Type = OrganizationUserType.User; organization.Permissions = new Permissions(); - ArrangeOrganizationAbility(sutProvider, organization, true, false); + ArrangeOrganizationAbility(sutProvider, organization, true, true, false); sutProvider.GetDependency().UserId.Returns(actingUserId); sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); @@ -1171,7 +1171,7 @@ public async Task CanDeleteAsync_WhenMissingPermissions_NoSuccess( ManageUsers = false }; - ArrangeOrganizationAbility(sutProvider, organization, true); + ArrangeOrganizationAbility(sutProvider, organization, true, true); var context = new AuthorizationHandlerContext( new[] { BulkCollectionOperations.Delete }, @@ -1262,6 +1262,8 @@ public async Task HandleRequirementAsync_Provider_Success( { collections.First().OrganizationId, new OrganizationAbility { + LimitCollectionCreation = true, + LimitCollectionDeletion = true, LimitCollectionCreationDeletion = true, AllowAdminAccessToAllCollectionItems = true } @@ -1338,14 +1340,20 @@ public async Task CachesCollectionsWithCanManagePermissions( private static void ArrangeOrganizationAbility( SutProvider sutProvider, - CurrentContextOrganization organization, bool limitCollectionCreationDeletion, + CurrentContextOrganization organization, + bool limitCollectionCreation, + bool limitCollectionDeletion, bool allowAdminAccessToAllCollectionItems = true) { var organizationAbility = new OrganizationAbility(); organizationAbility.Id = organization.Id; - organizationAbility.LimitCollectionCreationDeletion = limitCollectionCreationDeletion; + organizationAbility.LimitCollectionCreation = limitCollectionCreation; + organizationAbility.LimitCollectionDeletion = limitCollectionDeletion; + // Deprecated: remove with https://bitwarden.atlassian.net/browse/PM-10863 + organizationAbility.LimitCollectionCreationDeletion = limitCollectionCreation || limitCollectionDeletion; organizationAbility.AllowAdminAccessToAllCollectionItems = allowAdminAccessToAllCollectionItems; + sutProvider.GetDependency().GetOrganizationAbilityAsync(organizationAbility.Id) .Returns(organizationAbility); } diff --git a/test/Core.Test/Models/Business/OrganizationLicenseFileFixtures.cs b/test/Core.Test/Models/Business/OrganizationLicenseFileFixtures.cs index 500c4475a97f..98866282f474 100644 --- a/test/Core.Test/Models/Business/OrganizationLicenseFileFixtures.cs +++ b/test/Core.Test/Models/Business/OrganizationLicenseFileFixtures.cs @@ -111,7 +111,5 @@ public static Organization OrganizationFactory() => SmServiceAccounts = 8, MaxAutoscaleSmSeats = 101, MaxAutoscaleSmServiceAccounts = 102, - LimitCollectionCreationDeletion = true, - AllowAdminAccessToAllCollectionItems = true, }; } diff --git a/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/OrganizationUserRepositoryTests.cs b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/OrganizationUserRepositoryTests.cs index 3b102c7881d5..77586e98223e 100644 --- a/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/OrganizationUserRepositoryTests.cs +++ b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/OrganizationUserRepositoryTests.cs @@ -253,7 +253,8 @@ public async Task GetManyDetailsByUserAsync_Works(IUserRepository userRepository Assert.Equal(orgUser1.Permissions, result.Permissions); Assert.Equal(organization.SmSeats, result.SmSeats); Assert.Equal(organization.SmServiceAccounts, result.SmServiceAccounts); - Assert.Equal(organization.LimitCollectionCreationDeletion, result.LimitCollectionCreationDeletion); + Assert.Equal(organization.LimitCollectionCreation, result.LimitCollectionCreation); + Assert.Equal(organization.LimitCollectionDeletion, result.LimitCollectionDeletion); Assert.Equal(organization.AllowAdminAccessToAllCollectionItems, result.AllowAdminAccessToAllCollectionItems); }