From 6d089d3c26a143083d5f461922dcbb354f0c5737 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Fri, 23 Feb 2024 10:01:14 -0800 Subject: [PATCH] [AC-2195] Fixes for FC V1 for Custom Users (#3837) * [AC-2195] Ensure Custom users with EditAnyCollection can always access all ciphers * [AC-2195] Ensure FC V1 logic is not used for non-migrated organizations --- .../Vault/Controllers/CiphersController.cs | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Api/Vault/Controllers/CiphersController.cs b/src/Api/Vault/Controllers/CiphersController.cs index aef4f7819..90e7d2ed1 100644 --- a/src/Api/Vault/Controllers/CiphersController.cs +++ b/src/Api/Vault/Controllers/CiphersController.cs @@ -44,13 +44,11 @@ public class CiphersController : Controller private readonly Version _cipherKeyEncryptionMinimumVersion = new Version(Constants.CipherKeyEncryptionMinimumVersion); private readonly IFeatureService _featureService; private readonly IOrganizationCiphersQuery _organizationCiphersQuery; + private readonly IApplicationCacheService _applicationCacheService; private bool UseFlexibleCollections => _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollections); - private bool UseFlexibleCollectionsV1 => - _featureService.IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1); - public CiphersController( ICipherRepository cipherRepository, ICollectionCipherRepository collectionCipherRepository, @@ -62,7 +60,8 @@ public class CiphersController : Controller ILogger logger, GlobalSettings globalSettings, IFeatureService featureService, - IOrganizationCiphersQuery organizationCiphersQuery) + IOrganizationCiphersQuery organizationCiphersQuery, + IApplicationCacheService applicationCacheService) { _cipherRepository = cipherRepository; _collectionCipherRepository = collectionCipherRepository; @@ -75,6 +74,7 @@ public class CiphersController : Controller _globalSettings = globalSettings; _featureService = featureService; _organizationCiphersQuery = organizationCiphersQuery; + _applicationCacheService = applicationCacheService; } [HttpGet("{id}")] @@ -241,7 +241,7 @@ public class CiphersController : Controller public async Task> GetOrganizationCiphers(Guid organizationId) { // Flexible Collections Logic - if (UseFlexibleCollectionsV1) + if (await UseFlexibleCollectionsV1Async(organizationId)) { return await GetAllOrganizationCiphersAsync(organizationId); } @@ -266,7 +266,7 @@ public class CiphersController : Controller [HttpGet("organization-details/assigned")] public async Task> GetAssignedOrganizationCiphers(Guid organizationId) { - if (!UseFlexibleCollectionsV1) + if (!await UseFlexibleCollectionsV1Async(organizationId)) { throw new FeatureUnavailableException(); } @@ -322,9 +322,13 @@ public class CiphersController : Controller { var org = _currentContext.GetOrganization(organizationId); + // We do NOT need to check the organization collection management setting here because Owners/Admins can + // ALWAYS access all ciphers in order to export them. Additionally, custom users with AccessImportExport or + // EditAnyCollection permissions can also always access all ciphers. if (org is { Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or - { Permissions.AccessImportExport: true }) + { Permissions.AccessImportExport: true } or + { Permissions.EditAnyCollection: true }) { return true; } @@ -974,4 +978,15 @@ public class CiphersController : Controller { return await _cipherRepository.GetByIdAsync(cipherId, userId, UseFlexibleCollections); } + + private async Task UseFlexibleCollectionsV1Async(Guid organizationId) + { + if (!_featureService.IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1)) + { + return false; + } + + var organizationAbility = await _applicationCacheService.GetOrganizationAbilityAsync(organizationId); + return organizationAbility?.FlexibleCollections ?? false; + } }