From 72736db4b6d43407f8fd47b6a12ca801b649d33f Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:21:48 -0600 Subject: [PATCH 1/7] [PM-13839][PM-13840] Admin Console Collections (#4922) * add collectionIds to the response of `{id}/admin` - They're now needed in the admin console when add/editing a cipher. - Prior to this there was no way to edit collection when editing a cipher. Assigning collections was a separate workflow * return cipher from collections endpoint --- src/Api/Vault/Controllers/CiphersController.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Api/Vault/Controllers/CiphersController.cs b/src/Api/Vault/Controllers/CiphersController.cs index 09ade4d0d47d..59984683e556 100644 --- a/src/Api/Vault/Controllers/CiphersController.cs +++ b/src/Api/Vault/Controllers/CiphersController.cs @@ -99,7 +99,10 @@ public async Task GetAdmin(string id) throw new NotFoundException(); } - return new CipherMiniResponseModel(cipher, _globalSettings, cipher.OrganizationUseTotp); + var collectionCiphers = await _collectionCipherRepository.GetManyByOrganizationIdAsync(cipher.OrganizationId.Value); + var collectionCiphersGroupDict = collectionCiphers.GroupBy(c => c.CipherId).ToDictionary(s => s.Key); + + return new CipherMiniDetailsResponseModel(cipher, _globalSettings, collectionCiphersGroupDict, cipher.OrganizationUseTotp); } [HttpGet("{id}/full-details")] @@ -600,10 +603,10 @@ await _cipherService.SaveCollectionsAsync(cipher, [HttpPut("{id}/collections-admin")] [HttpPost("{id}/collections-admin")] - public async Task PutCollectionsAdmin(string id, [FromBody] CipherCollectionsRequestModel model) + public async Task PutCollectionsAdmin(string id, [FromBody] CipherCollectionsRequestModel model) { var userId = _userService.GetProperUserId(User).Value; - var cipher = await _cipherRepository.GetByIdAsync(new Guid(id)); + var cipher = await _cipherRepository.GetOrganizationDetailsByIdAsync(new Guid(id)); if (cipher == null || !cipher.OrganizationId.HasValue || !await CanEditCipherAsAdminAsync(cipher.OrganizationId.Value, new[] { cipher.Id })) @@ -621,6 +624,11 @@ public async Task PutCollectionsAdmin(string id, [FromBody] CipherCollectionsReq } await _cipherService.SaveCollectionsAsync(cipher, collectionIds, userId, true); + + var collectionCiphers = await _collectionCipherRepository.GetManyByOrganizationIdAsync(cipher.OrganizationId.Value); + var collectionCiphersGroupDict = collectionCiphers.GroupBy(c => c.CipherId).ToDictionary(s => s.Key); + + return new CipherMiniDetailsResponseModel(cipher, _globalSettings, collectionCiphersGroupDict, cipher.OrganizationUseTotp); } [HttpPost("bulk-collections")] From 82cd1a8b1a38f24174a2be1dbbd93c2f958a161d Mon Sep 17 00:00:00 2001 From: Brandon Treston Date: Thu, 7 Nov 2024 11:30:26 -0500 Subject: [PATCH 2/7] add feature flag (#4987) --- src/Core/Constants.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 0bc6393d3cce..e152966e52d9 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -151,6 +151,7 @@ public static class FeatureFlagKeys public const string GeneratorToolsModernization = "generator-tools-modernization"; public const string NewDeviceVerification = "new-device-verification"; public const string RiskInsightsCriticalApplication = "pm-14466-risk-insights-critical-application"; + public const string IntegrationPage = "pm-14505-admin-console-integration-page"; public static List GetAllKeys() { From 4adcecb80a980f9f9690c5f19e22072e61f5038d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:51:39 -0500 Subject: [PATCH 3/7] [deps]: Update Microsoft.NET.Test.Sdk to 17.11.1 (#4830) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../Infrastructure.Dapper.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Infrastructure.Dapper.Test/Infrastructure.Dapper.Test.csproj b/test/Infrastructure.Dapper.Test/Infrastructure.Dapper.Test.csproj index db5913d729be..dfc8951cc38b 100644 --- a/test/Infrastructure.Dapper.Test/Infrastructure.Dapper.Test.csproj +++ b/test/Infrastructure.Dapper.Test/Infrastructure.Dapper.Test.csproj @@ -10,7 +10,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From 15bc5060c6893987d14cbbda7c238c159036b191 Mon Sep 17 00:00:00 2001 From: Brandon Treston Date: Thu, 7 Nov 2024 14:10:00 -0500 Subject: [PATCH 4/7] [PM-11409] prevent managed user from leaving managing organization (#4995) * prevent managed user from leaving managing organization * fix org check to be specific to single org * simplify logic --- .../Controllers/OrganizationsController.cs | 6 ++++ .../OrganizationsControllerTests.cs | 36 +++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Api/AdminConsole/Controllers/OrganizationsController.cs b/src/Api/AdminConsole/Controllers/OrganizationsController.cs index 0b3811618712..e134adc042c1 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationsController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationsController.cs @@ -252,6 +252,12 @@ public async Task Leave(Guid id) throw new BadRequestException("Your organization's Single Sign-On settings prevent you from leaving."); } + if (_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning) + && (await _userService.GetOrganizationsManagingUserAsync(user.Id)).Any(x => x.Id == id)) + { + throw new BadRequestException("Managed user account cannot leave managing organization. Contact your organization administrator for additional details."); + } + await _removeOrganizationUserCommand.RemoveUserAsync(id, user.Id); } diff --git a/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs b/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs index 25227fec7bed..13826888d797 100644 --- a/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs +++ b/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs @@ -51,7 +51,6 @@ public class OrganizationsControllerTests : IDisposable private readonly IProviderBillingService _providerBillingService; private readonly IDataProtectorTokenFactory _orgDeleteTokenDataFactory; private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand; - private readonly OrganizationsController _sut; public OrganizationsControllerTests() @@ -123,7 +122,8 @@ public async Task OrganizationsController_UserCannotLeaveOrganizationThatProvide _currentContext.OrganizationUser(orgId).Returns(true); _ssoConfigRepository.GetByOrganizationIdAsync(orgId).Returns(ssoConfig); _userService.GetUserByPrincipalAsync(Arg.Any()).Returns(user); - + _featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true); + _userService.GetOrganizationsManagingUserAsync(user.Id).Returns(new List { null }); var exception = await Assert.ThrowsAsync(() => _sut.Leave(orgId)); Assert.Contains("Your organization's Single Sign-On settings prevent you from leaving.", @@ -132,6 +132,36 @@ public async Task OrganizationsController_UserCannotLeaveOrganizationThatProvide await _removeOrganizationUserCommand.DidNotReceiveWithAnyArgs().RemoveUserAsync(default, default); } + [Theory, AutoData] + public async Task OrganizationsController_UserCannotLeaveOrganizationThatManagesUser( + Guid orgId, User user) + { + var ssoConfig = new SsoConfig + { + Id = default, + Data = new SsoConfigurationData + { + MemberDecryptionType = MemberDecryptionType.KeyConnector + }.Serialize(), + Enabled = true, + OrganizationId = orgId, + }; + var foundOrg = new Organization(); + foundOrg.Id = orgId; + + _currentContext.OrganizationUser(orgId).Returns(true); + _ssoConfigRepository.GetByOrganizationIdAsync(orgId).Returns(ssoConfig); + _userService.GetUserByPrincipalAsync(Arg.Any()).Returns(user); + _featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true); + _userService.GetOrganizationsManagingUserAsync(user.Id).Returns(new List { { foundOrg } }); + var exception = await Assert.ThrowsAsync(() => _sut.Leave(orgId)); + + Assert.Contains("Managed user account cannot leave managing organization. Contact your organization administrator for additional details.", + exception.Message); + + await _removeOrganizationUserCommand.DidNotReceiveWithAnyArgs().RemoveUserAsync(default, default); + } + [Theory] [InlineAutoData(true, false)] [InlineAutoData(false, true)] @@ -157,6 +187,8 @@ public async Task OrganizationsController_UserCanLeaveOrganizationThatDoesntProv _currentContext.OrganizationUser(orgId).Returns(true); _ssoConfigRepository.GetByOrganizationIdAsync(orgId).Returns(ssoConfig); _userService.GetUserByPrincipalAsync(Arg.Any()).Returns(user); + _featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true); + _userService.GetOrganizationsManagingUserAsync(user.Id).Returns(new List()); await _sut.Leave(orgId); From ebd78ff30df67ec13ffc3405044b94f7cc4976de Mon Sep 17 00:00:00 2001 From: Brandon Treston Date: Thu, 7 Nov 2024 14:14:42 -0500 Subject: [PATCH 5/7] [PM-11408] Remove cs delete permission (#4998) * remove user delete permission from CS role --- src/Admin/Utilities/RolePermissionMapping.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Admin/Utilities/RolePermissionMapping.cs b/src/Admin/Utilities/RolePermissionMapping.cs index ec357c7e9b48..e260c264f46f 100644 --- a/src/Admin/Utilities/RolePermissionMapping.cs +++ b/src/Admin/Utilities/RolePermissionMapping.cs @@ -110,7 +110,6 @@ public static class RolePermissionMapping Permission.User_Licensing_View, Permission.User_Billing_View, Permission.User_Billing_LaunchGateway, - Permission.User_Delete, Permission.Org_List_View, Permission.Org_OrgInformation_View, Permission.Org_GeneralDetails_View, From fda7c4912aebdbef84a919827a88fef99fc599ae Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Thu, 7 Nov 2024 14:30:29 -0500 Subject: [PATCH 6/7] [PM-8682] added flags for new device verification notice (#4999) --- src/Core/Constants.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index e152966e52d9..8e759e143326 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -152,6 +152,8 @@ public static class FeatureFlagKeys public const string NewDeviceVerification = "new-device-verification"; public const string RiskInsightsCriticalApplication = "pm-14466-risk-insights-critical-application"; public const string IntegrationPage = "pm-14505-admin-console-integration-page"; + public const string NewDeviceVerificationTemporaryDismiss = "new-device-temporary-dismiss"; + public const string NewDeviceVerificationPermanentDismiss = "new-device-permanent-dismiss"; public static List GetAllKeys() { From d6e624d6394d6fa8fdc71587584bb2d8eb372f44 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 20:39:36 +0100 Subject: [PATCH 7/7] [deps] Tools: Update aws-sdk-net monorepo (#4993) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- src/Core/Core.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 6913a1e894c0..338b908dab73 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -21,8 +21,8 @@ - - + +