From 0385347a3a78fe65dff950f1ec77a9a7f8cda38d Mon Sep 17 00:00:00 2001 From: Stephon Brown Date: Wed, 3 Sep 2025 15:27:01 -0400 Subject: [PATCH 1/8] refactor: remove feature-flag (#6252) --- src/Core/Constants.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 9ddbf5c600..058f4eac69 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -160,7 +160,6 @@ public static class FeatureFlagKeys public const string TrialPayment = "PM-8163-trial-payment"; public const string PM17772_AdminInitiatedSponsorships = "pm-17772-admin-initiated-sponsorships"; public const string UsePricingService = "use-pricing-service"; - public const string PM12276Breadcrumbing = "pm-12276-breadcrumbing-for-business-features"; public const string PM19422_AllowAutomaticTaxUpdates = "pm-19422-allow-automatic-tax-updates"; public const string UseOrganizationWarningsService = "use-organization-warnings-service"; public const string PM21881_ManagePaymentDetailsOutsideCheckout = "pm-21881-manage-payment-details-outside-checkout"; From 4b79b98b316a4af6d292e5c9de05dee3cf4f231a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 10:47:56 +0200 Subject: [PATCH 2/8] [deps]: Update actions/create-github-app-token action to v2 (#6216) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/repository-management.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/repository-management.yml b/.github/workflows/repository-management.yml index 18192ca0ad..ad80d5864c 100644 --- a/.github/workflows/repository-management.yml +++ b/.github/workflows/repository-management.yml @@ -82,7 +82,7 @@ jobs: version: ${{ inputs.version_number_override }} - name: Generate GH App token - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 + uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1 id: app-token with: app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} @@ -200,7 +200,7 @@ jobs: uses: bitwarden/gh-actions/azure-logout@main - name: Generate GH App token - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 + uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1 id: app-token with: app-id: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-ID }} From cdf1d7f074e3c1e4f60b87e2eb75c841aedd28d4 Mon Sep 17 00:00:00 2001 From: MtnBurrit0 <77340197+mimartin12@users.noreply.github.com> Date: Thu, 4 Sep 2025 08:05:11 -0600 Subject: [PATCH 3/8] Add stub for load test work (#6277) * Add stub for load test work * Satisfy linter * Adding required permission for linting --- .github/workflows/load-test.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/load-test.yml diff --git a/.github/workflows/load-test.yml b/.github/workflows/load-test.yml new file mode 100644 index 0000000000..19aab89be3 --- /dev/null +++ b/.github/workflows/load-test.yml @@ -0,0 +1,13 @@ +name: Test Stub +on: + workflow_dispatch: + +jobs: + test: + permissions: + contents: read + name: Test + runs-on: ubuntu-24.04 + steps: + - name: Test + run: exit 0 From 96fe09af893006195e6ecc50e7f6c8b786dea25d Mon Sep 17 00:00:00 2001 From: Ike <137194738+ike-kottlowski@users.noreply.github.com> Date: Thu, 4 Sep 2025 10:08:03 -0400 Subject: [PATCH 4/8] [PM-25415] move files into better place for code ownership (#6275) * chore: move files into better place for code ownership * fix: import correct namespace --- .../SecretsManager/Commands/Projects/CreateProjectCommand.cs | 2 +- .../src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs | 3 ++- .../Authorization/OrganizationClaimsExtensions.cs | 2 +- src/Api/SecretsManager/Controllers/ProjectsController.cs | 2 +- src/Api/SecretsManager/Controllers/SecretsController.cs | 2 +- src/Api/SecretsManager/Controllers/SecretsTrashController.cs | 2 +- src/Api/Startup.cs | 3 ++- src/Api/Utilities/ServiceCollectionExtensions.cs | 2 +- src/Core/AdminConsole/Models/Data/Permissions.cs | 2 +- src/Core/{ => Auth}/Identity/Claims.cs | 2 +- .../Identity/CustomIdentityServiceCollectionExtensions.cs | 0 src/Core/{ => Auth}/Identity/IdentityClientType.cs | 2 +- src/Core/{ => Auth}/IdentityServer/ApiScopes.cs | 2 +- .../ConfigureOpenIdConnectDistributedOptions.cs | 2 +- .../IdentityServer/DistributedCacheCookieManager.cs | 2 +- .../IdentityServer/DistributedCacheTicketDataFormatter.cs | 2 +- .../{ => Auth}/IdentityServer/DistributedCacheTicketStore.cs | 2 +- .../SendAccess/SendAccessClaimsPrincipalExtensions.cs | 2 +- src/Core/Context/CurrentContext.cs | 2 +- src/Core/Context/ICurrentContext.cs | 2 +- src/Core/Enums/AccessClientType.cs | 2 +- .../SelfHosted/SelfHostedSyncSponsorshipsCommand.cs | 2 +- src/Core/Platform/Push/Engines/RelayPushEngine.cs | 4 ++-- .../Platform/PushRegistration/RelayPushRegistrationService.cs | 4 ++-- .../Commands/Projects/Interfaces/ICreateProjectCommand.cs | 2 +- .../Services/Implementations/LaunchDarklyFeatureService.cs | 2 +- src/Core/Utilities/CoreHelpers.cs | 2 +- src/Events/Startup.cs | 2 +- src/Identity/IdentityServer/ApiResources.cs | 4 ++-- .../ClientProviders/InstallationClientProvider.cs | 2 +- .../IdentityServer/ClientProviders/InternalClientProvider.cs | 2 +- .../ClientProviders/OrganizationClientProvider.cs | 4 ++-- .../ClientProviders/SecretsManagerApiKeyProvider.cs | 2 +- .../IdentityServer/ClientProviders/UserClientProvider.cs | 2 +- src/Identity/IdentityServer/ProfileService.cs | 2 +- .../IdentityServer/RequestValidators/BaseRequestValidator.cs | 2 +- .../RequestValidators/CustomTokenRequestValidator.cs | 2 +- .../RequestValidators/SendAccess/SendAccessGrantValidator.cs | 2 +- .../SendAccess/SendEmailOtpRequestValidator.cs | 2 +- .../SendAccess/SendPasswordRequestValidator.cs | 2 +- .../IdentityServer/StaticClients/SendClientBuilder.cs | 4 ++-- src/Identity/Utilities/ServiceCollectionExtensions.cs | 4 ++-- src/Notifications/Startup.cs | 2 +- src/SharedWeb/Utilities/ServiceCollectionExtensions.cs | 2 -- .../SendAccess/SendAccessClaimsPrincipalExtensionsTests.cs | 2 +- .../SendAccessGrantValidatorIntegrationTests.cs | 2 +- .../SendEmailOtpReqestValidatorIntegrationTests.cs | 2 +- .../SendPasswordRequestValidatorIntegrationTests.cs | 4 ++-- .../ClientProviders/InstallationClientProviderTests.cs | 2 +- .../ClientProviders/InternalClientProviderTests.cs | 2 +- .../SendAccess/SendAccessGrantValidatorTests.cs | 4 ++-- .../SendAccess/SendEmailOtpRequestValidatorTests.cs | 4 ++-- .../SendAccess/SendPasswordRequestValidatorTests.cs | 4 ++-- .../IdentityServer/SendPasswordRequestValidatorTests.cs | 4 ++-- 54 files changed, 65 insertions(+), 65 deletions(-) rename src/Core/{ => Auth}/Identity/Claims.cs (98%) rename src/Core/{ => Auth}/Identity/CustomIdentityServiceCollectionExtensions.cs (100%) rename src/Core/{ => Auth}/Identity/IdentityClientType.cs (75%) rename src/Core/{ => Auth}/IdentityServer/ApiScopes.cs (96%) rename src/Core/{ => Auth}/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs (97%) rename src/Core/{ => Auth}/IdentityServer/DistributedCacheCookieManager.cs (98%) rename src/Core/{ => Auth}/IdentityServer/DistributedCacheTicketDataFormatter.cs (98%) rename src/Core/{ => Auth}/IdentityServer/DistributedCacheTicketStore.cs (97%) diff --git a/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs b/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs index 1a5fe07c21..9f37c35f78 100644 --- a/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs +++ b/bitwarden_license/src/Commercial.Core/SecretsManager/Commands/Projects/CreateProjectCommand.cs @@ -1,9 +1,9 @@ // FIXME: Update this file to be null safe and then delete the line below #nullable disable +using Bit.Core.Auth.Identity; using Bit.Core.Context; using Bit.Core.Exceptions; -using Bit.Core.Identity; using Bit.Core.Repositories; using Bit.Core.SecretsManager.Commands.Projects.Interfaces; using Bit.Core.SecretsManager.Entities; diff --git a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs index 546bbfb7c9..db574e71c5 100644 --- a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs +++ b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs @@ -4,6 +4,7 @@ using System.Security.Cryptography.X509Certificates; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Auth.Models.Data; using Bit.Core.Auth.Repositories; using Bit.Core.Settings; @@ -416,7 +417,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider SPOptions = spOptions, SignInScheme = AuthenticationSchemes.BitwardenExternalCookieAuthenticationScheme, SignOutScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme, - CookieManager = new IdentityServer.DistributedCacheCookieManager(), + CookieManager = new DistributedCacheCookieManager(), }; options.IdentityProviders.Add(idp); diff --git a/src/Api/AdminConsole/Authorization/OrganizationClaimsExtensions.cs b/src/Api/AdminConsole/Authorization/OrganizationClaimsExtensions.cs index e21d153bab..a3af3669ac 100644 --- a/src/Api/AdminConsole/Authorization/OrganizationClaimsExtensions.cs +++ b/src/Api/AdminConsole/Authorization/OrganizationClaimsExtensions.cs @@ -1,9 +1,9 @@ #nullable enable using System.Security.Claims; +using Bit.Core.Auth.Identity; using Bit.Core.Context; using Bit.Core.Enums; -using Bit.Core.Identity; using Bit.Core.Models.Data; namespace Bit.Api.AdminConsole.Authorization; diff --git a/src/Api/SecretsManager/Controllers/ProjectsController.cs b/src/Api/SecretsManager/Controllers/ProjectsController.cs index 11b840accf..5dce032ece 100644 --- a/src/Api/SecretsManager/Controllers/ProjectsController.cs +++ b/src/Api/SecretsManager/Controllers/ProjectsController.cs @@ -4,10 +4,10 @@ using Bit.Api.Models.Response; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.SecretsManager.Models.Response; +using Bit.Core.Auth.Identity; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; -using Bit.Core.Identity; using Bit.Core.SecretsManager.AuthorizationRequirements; using Bit.Core.SecretsManager.Commands.Projects.Interfaces; using Bit.Core.SecretsManager.Entities; diff --git a/src/Api/SecretsManager/Controllers/SecretsController.cs b/src/Api/SecretsManager/Controllers/SecretsController.cs index e32d5cd581..e263b9747d 100644 --- a/src/Api/SecretsManager/Controllers/SecretsController.cs +++ b/src/Api/SecretsManager/Controllers/SecretsController.cs @@ -4,10 +4,10 @@ using Bit.Api.Models.Response; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.SecretsManager.Models.Response; +using Bit.Core.Auth.Identity; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; -using Bit.Core.Identity; using Bit.Core.SecretsManager.AuthorizationRequirements; using Bit.Core.SecretsManager.Commands.Secrets.Interfaces; using Bit.Core.SecretsManager.Entities; diff --git a/src/Api/SecretsManager/Controllers/SecretsTrashController.cs b/src/Api/SecretsManager/Controllers/SecretsTrashController.cs index 275e76cc99..d791fa2341 100644 --- a/src/Api/SecretsManager/Controllers/SecretsTrashController.cs +++ b/src/Api/SecretsManager/Controllers/SecretsTrashController.cs @@ -1,8 +1,8 @@ using Bit.Api.SecretsManager.Models.Response; +using Bit.Core.Auth.Identity; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; -using Bit.Core.Identity; using Bit.Core.SecretsManager.Commands.Trash.Interfaces; using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Repositories; diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index 3a08c4fe8a..2d306c4435 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -13,7 +13,6 @@ using Bit.Api.KeyManagement.Validators; using Bit.Api.Tools.Models.Request; using Bit.Api.Vault.Models.Request; using Bit.Core.Auth.Entities; -using Bit.Core.IdentityServer; using Bit.SharedWeb.Health; using Microsoft.IdentityModel.Logging; using Microsoft.OpenApi.Models; @@ -33,6 +32,8 @@ using Bit.Core.Tools.ImportFeatures; using Bit.Core.Auth.Models.Api.Request; using Bit.Core.Dirt.Reports.ReportFeatures; using Bit.Core.Tools.SendFeatures; +using Bit.Core.Auth.IdentityServer; + #if !OSS using Bit.Commercial.Core.SecretsManager; diff --git a/src/Api/Utilities/ServiceCollectionExtensions.cs b/src/Api/Utilities/ServiceCollectionExtensions.cs index 0d8c3dec38..b956fc73bb 100644 --- a/src/Api/Utilities/ServiceCollectionExtensions.cs +++ b/src/Api/Utilities/ServiceCollectionExtensions.cs @@ -2,7 +2,7 @@ using Bit.Api.Tools.Authorization; using Bit.Api.Vault.AuthorizationHandlers.Collections; using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Authorization; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; using Bit.Core.PhishingDomainFeatures; using Bit.Core.PhishingDomainFeatures.Interfaces; using Bit.Core.Repositories; diff --git a/src/Core/AdminConsole/Models/Data/Permissions.cs b/src/Core/AdminConsole/Models/Data/Permissions.cs index def468f18d..75bf2db8c9 100644 --- a/src/Core/AdminConsole/Models/Data/Permissions.cs +++ b/src/Core/AdminConsole/Models/Data/Permissions.cs @@ -1,5 +1,5 @@ using System.Text.Json.Serialization; -using Bit.Core.Identity; +using Bit.Core.Auth.Identity; namespace Bit.Core.Models.Data; diff --git a/src/Core/Identity/Claims.cs b/src/Core/Auth/Identity/Claims.cs similarity index 98% rename from src/Core/Identity/Claims.cs rename to src/Core/Auth/Identity/Claims.cs index 39a036f3f9..ac78e987ae 100644 --- a/src/Core/Identity/Claims.cs +++ b/src/Core/Auth/Identity/Claims.cs @@ -1,4 +1,4 @@ -namespace Bit.Core.Identity; +namespace Bit.Core.Auth.Identity; public static class Claims { diff --git a/src/Core/Identity/CustomIdentityServiceCollectionExtensions.cs b/src/Core/Auth/Identity/CustomIdentityServiceCollectionExtensions.cs similarity index 100% rename from src/Core/Identity/CustomIdentityServiceCollectionExtensions.cs rename to src/Core/Auth/Identity/CustomIdentityServiceCollectionExtensions.cs diff --git a/src/Core/Identity/IdentityClientType.cs b/src/Core/Auth/Identity/IdentityClientType.cs similarity index 75% rename from src/Core/Identity/IdentityClientType.cs rename to src/Core/Auth/Identity/IdentityClientType.cs index 9c43007f25..113877135d 100644 --- a/src/Core/Identity/IdentityClientType.cs +++ b/src/Core/Auth/Identity/IdentityClientType.cs @@ -1,4 +1,4 @@ -namespace Bit.Core.Identity; +namespace Bit.Core.Auth.Identity; public enum IdentityClientType : byte { diff --git a/src/Core/IdentityServer/ApiScopes.cs b/src/Core/Auth/IdentityServer/ApiScopes.cs similarity index 96% rename from src/Core/IdentityServer/ApiScopes.cs rename to src/Core/Auth/IdentityServer/ApiScopes.cs index 77ccb5a58a..8836a168b6 100644 --- a/src/Core/IdentityServer/ApiScopes.cs +++ b/src/Core/Auth/IdentityServer/ApiScopes.cs @@ -1,6 +1,6 @@ using Duende.IdentityServer.Models; -namespace Bit.Core.IdentityServer; +namespace Bit.Core.Auth.IdentityServer; public static class ApiScopes { diff --git a/src/Core/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs b/src/Core/Auth/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs similarity index 97% rename from src/Core/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs rename to src/Core/Auth/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs index 381f81dea5..5319539050 100644 --- a/src/Core/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs +++ b/src/Core/Auth/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs @@ -8,7 +8,7 @@ using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -namespace Bit.Core.IdentityServer; +namespace Bit.Core.Auth.IdentityServer; public class ConfigureOpenIdConnectDistributedOptions : IPostConfigureOptions { diff --git a/src/Core/IdentityServer/DistributedCacheCookieManager.cs b/src/Core/Auth/IdentityServer/DistributedCacheCookieManager.cs similarity index 98% rename from src/Core/IdentityServer/DistributedCacheCookieManager.cs rename to src/Core/Auth/IdentityServer/DistributedCacheCookieManager.cs index a01ff63d8f..138aeaf7e8 100644 --- a/src/Core/IdentityServer/DistributedCacheCookieManager.cs +++ b/src/Core/Auth/IdentityServer/DistributedCacheCookieManager.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; -namespace Bit.Core.IdentityServer; +namespace Bit.Core.Auth.IdentityServer; public class DistributedCacheCookieManager : ICookieManager { diff --git a/src/Core/IdentityServer/DistributedCacheTicketDataFormatter.cs b/src/Core/Auth/IdentityServer/DistributedCacheTicketDataFormatter.cs similarity index 98% rename from src/Core/IdentityServer/DistributedCacheTicketDataFormatter.cs rename to src/Core/Auth/IdentityServer/DistributedCacheTicketDataFormatter.cs index ad3fdee6f0..565d02a838 100644 --- a/src/Core/IdentityServer/DistributedCacheTicketDataFormatter.cs +++ b/src/Core/Auth/IdentityServer/DistributedCacheTicketDataFormatter.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.DataProtection; using Microsoft.Extensions.Caching.Distributed; -namespace Bit.Core.IdentityServer; +namespace Bit.Core.Auth.IdentityServer; public class DistributedCacheTicketDataFormatter : ISecureDataFormat { diff --git a/src/Core/IdentityServer/DistributedCacheTicketStore.cs b/src/Core/Auth/IdentityServer/DistributedCacheTicketStore.cs similarity index 97% rename from src/Core/IdentityServer/DistributedCacheTicketStore.cs rename to src/Core/Auth/IdentityServer/DistributedCacheTicketStore.cs index ddf66f04ec..675b0cd7a5 100644 --- a/src/Core/IdentityServer/DistributedCacheTicketStore.cs +++ b/src/Core/Auth/IdentityServer/DistributedCacheTicketStore.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.Extensions.Caching.Distributed; -namespace Bit.Core.IdentityServer; +namespace Bit.Core.Auth.IdentityServer; public class DistributedCacheTicketStore : ITicketStore { diff --git a/src/Core/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensions.cs b/src/Core/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensions.cs index 7ae7355ba4..f944de381e 100644 --- a/src/Core/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensions.cs +++ b/src/Core/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensions.cs @@ -1,5 +1,5 @@ using System.Security.Claims; -using Bit.Core.Identity; +using Bit.Core.Auth.Identity; namespace Bit.Core.Auth.UserFeatures.SendAccess; diff --git a/src/Core/Context/CurrentContext.cs b/src/Core/Context/CurrentContext.cs index 85c8a81523..e824a30a0e 100644 --- a/src/Core/Context/CurrentContext.cs +++ b/src/Core/Context/CurrentContext.cs @@ -6,10 +6,10 @@ using Bit.Core.AdminConsole.Context; using Bit.Core.AdminConsole.Enums.Provider; using Bit.Core.AdminConsole.Models.Data.Provider; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Auth.Identity; using Bit.Core.Billing.Extensions; using Bit.Core.Entities; using Bit.Core.Enums; -using Bit.Core.Identity; using Bit.Core.Models.Data; using Bit.Core.Repositories; using Bit.Core.Settings; diff --git a/src/Core/Context/ICurrentContext.cs b/src/Core/Context/ICurrentContext.cs index 42843ce6d7..417e220ba2 100644 --- a/src/Core/Context/ICurrentContext.cs +++ b/src/Core/Context/ICurrentContext.cs @@ -3,9 +3,9 @@ using System.Security.Claims; using Bit.Core.AdminConsole.Context; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Auth.Identity; using Bit.Core.Entities; using Bit.Core.Enums; -using Bit.Core.Identity; using Bit.Core.Repositories; using Bit.Core.Settings; using Microsoft.AspNetCore.Http; diff --git a/src/Core/Enums/AccessClientType.cs b/src/Core/Enums/AccessClientType.cs index fb757c6dd6..c7336ee40d 100644 --- a/src/Core/Enums/AccessClientType.cs +++ b/src/Core/Enums/AccessClientType.cs @@ -1,4 +1,4 @@ -using Bit.Core.Identity; +using Bit.Core.Auth.Identity; namespace Bit.Core.Enums; diff --git a/src/Core/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SelfHosted/SelfHostedSyncSponsorshipsCommand.cs b/src/Core/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SelfHosted/SelfHostedSyncSponsorshipsCommand.cs index 76e7b6bb2a..9a995a9cf0 100644 --- a/src/Core/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SelfHosted/SelfHostedSyncSponsorshipsCommand.cs +++ b/src/Core/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SelfHosted/SelfHostedSyncSponsorshipsCommand.cs @@ -1,9 +1,9 @@ // FIXME: Update this file to be null safe and then delete the line below #nullable disable +using Bit.Core.Auth.IdentityServer; using Bit.Core.Entities; using Bit.Core.Exceptions; -using Bit.Core.IdentityServer; using Bit.Core.Models.Api.Request.OrganizationSponsorships; using Bit.Core.Models.Api.Response.OrganizationSponsorships; using Bit.Core.Models.Data.Organizations.OrganizationSponsorships; diff --git a/src/Core/Platform/Push/Engines/RelayPushEngine.cs b/src/Core/Platform/Push/Engines/RelayPushEngine.cs index 66b0229315..cff077c850 100644 --- a/src/Core/Platform/Push/Engines/RelayPushEngine.cs +++ b/src/Core/Platform/Push/Engines/RelayPushEngine.cs @@ -1,6 +1,6 @@ -using Bit.Core.Context; +using Bit.Core.Auth.IdentityServer; +using Bit.Core.Context; using Bit.Core.Enums; -using Bit.Core.IdentityServer; using Bit.Core.Models; using Bit.Core.Models.Api; using Bit.Core.Repositories; diff --git a/src/Core/Platform/PushRegistration/RelayPushRegistrationService.cs b/src/Core/Platform/PushRegistration/RelayPushRegistrationService.cs index 96a259ecf8..0925e92f64 100644 --- a/src/Core/Platform/PushRegistration/RelayPushRegistrationService.cs +++ b/src/Core/Platform/PushRegistration/RelayPushRegistrationService.cs @@ -1,5 +1,5 @@ -using Bit.Core.Enums; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; +using Bit.Core.Enums; using Bit.Core.Models.Api; using Bit.Core.Platform.Push; using Bit.Core.Services; diff --git a/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs b/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs index db377e220e..a1793cc73a 100644 --- a/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs +++ b/src/Core/SecretsManager/Commands/Projects/Interfaces/ICreateProjectCommand.cs @@ -1,4 +1,4 @@ -using Bit.Core.Identity; +using Bit.Core.Auth.Identity; using Bit.Core.SecretsManager.Entities; namespace Bit.Core.SecretsManager.Commands.Projects.Interfaces; diff --git a/src/Core/Services/Implementations/LaunchDarklyFeatureService.cs b/src/Core/Services/Implementations/LaunchDarklyFeatureService.cs index 1fb2348c5a..f118146cb1 100644 --- a/src/Core/Services/Implementations/LaunchDarklyFeatureService.cs +++ b/src/Core/Services/Implementations/LaunchDarklyFeatureService.cs @@ -1,8 +1,8 @@ // FIXME: Update this file to be null safe and then delete the line below #nullable disable +using Bit.Core.Auth.Identity; using Bit.Core.Context; -using Bit.Core.Identity; using Bit.Core.Settings; using Bit.Core.Utilities; using LaunchDarkly.Logging; diff --git a/src/Core/Utilities/CoreHelpers.cs b/src/Core/Utilities/CoreHelpers.cs index 64a038be07..813eb6d1aa 100644 --- a/src/Core/Utilities/CoreHelpers.cs +++ b/src/Core/Utilities/CoreHelpers.cs @@ -16,10 +16,10 @@ using Azure.Storage.Queues.Models; using Bit.Core.AdminConsole.Context; using Bit.Core.AdminConsole.Enums.Provider; using Bit.Core.Auth.Enums; +using Bit.Core.Auth.Identity; using Bit.Core.Billing.Enums; using Bit.Core.Context; using Bit.Core.Entities; -using Bit.Core.Identity; using Bit.Core.Settings; using Duende.IdentityModel; using Microsoft.AspNetCore.DataProtection; diff --git a/src/Events/Startup.cs b/src/Events/Startup.cs index b498bce229..fdeaad04b2 100644 --- a/src/Events/Startup.cs +++ b/src/Events/Startup.cs @@ -1,6 +1,6 @@ using System.Globalization; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Context; -using Bit.Core.IdentityServer; using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Utilities; diff --git a/src/Identity/IdentityServer/ApiResources.cs b/src/Identity/IdentityServer/ApiResources.cs index 61f3dd10ba..d225a7ea33 100644 --- a/src/Identity/IdentityServer/ApiResources.cs +++ b/src/Identity/IdentityServer/ApiResources.cs @@ -1,5 +1,5 @@ -using Bit.Core.Identity; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.Identity; +using Bit.Core.Auth.IdentityServer; using Duende.IdentityModel; using Duende.IdentityServer.Models; diff --git a/src/Identity/IdentityServer/ClientProviders/InstallationClientProvider.cs b/src/Identity/IdentityServer/ClientProviders/InstallationClientProvider.cs index cfa0dee0e6..566b0395b8 100644 --- a/src/Identity/IdentityServer/ClientProviders/InstallationClientProvider.cs +++ b/src/Identity/IdentityServer/ClientProviders/InstallationClientProvider.cs @@ -1,7 +1,7 @@ // FIXME: Update this file to be null safe and then delete the line below #nullable disable -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Platform.Installations; using Duende.IdentityModel; using Duende.IdentityServer.Models; diff --git a/src/Identity/IdentityServer/ClientProviders/InternalClientProvider.cs b/src/Identity/IdentityServer/ClientProviders/InternalClientProvider.cs index 3cab275a8f..70c1e2e06a 100644 --- a/src/Identity/IdentityServer/ClientProviders/InternalClientProvider.cs +++ b/src/Identity/IdentityServer/ClientProviders/InternalClientProvider.cs @@ -1,7 +1,7 @@ #nullable enable using System.Diagnostics; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Settings; using Duende.IdentityModel; using Duende.IdentityServer.Models; diff --git a/src/Identity/IdentityServer/ClientProviders/OrganizationClientProvider.cs b/src/Identity/IdentityServer/ClientProviders/OrganizationClientProvider.cs index 2bcae37ee2..86a1272496 100644 --- a/src/Identity/IdentityServer/ClientProviders/OrganizationClientProvider.cs +++ b/src/Identity/IdentityServer/ClientProviders/OrganizationClientProvider.cs @@ -1,9 +1,9 @@ // FIXME: Update this file to be null safe and then delete the line below #nullable disable +using Bit.Core.Auth.Identity; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Enums; -using Bit.Core.Identity; -using Bit.Core.IdentityServer; using Bit.Core.Repositories; using Duende.IdentityModel; using Duende.IdentityServer.Models; diff --git a/src/Identity/IdentityServer/ClientProviders/SecretsManagerApiKeyProvider.cs b/src/Identity/IdentityServer/ClientProviders/SecretsManagerApiKeyProvider.cs index 11022a40e5..628163ae74 100644 --- a/src/Identity/IdentityServer/ClientProviders/SecretsManagerApiKeyProvider.cs +++ b/src/Identity/IdentityServer/ClientProviders/SecretsManagerApiKeyProvider.cs @@ -1,7 +1,7 @@ // FIXME: Update this file to be null safe and then delete the line below #nullable disable -using Bit.Core.Identity; +using Bit.Core.Auth.Identity; using Bit.Core.Repositories; using Bit.Core.SecretsManager.Models.Data; using Bit.Core.SecretsManager.Repositories; diff --git a/src/Identity/IdentityServer/ClientProviders/UserClientProvider.cs b/src/Identity/IdentityServer/ClientProviders/UserClientProvider.cs index 29d036b893..2d380acdf6 100644 --- a/src/Identity/IdentityServer/ClientProviders/UserClientProvider.cs +++ b/src/Identity/IdentityServer/ClientProviders/UserClientProvider.cs @@ -3,9 +3,9 @@ using System.Collections.ObjectModel; using System.Security.Claims; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Auth.Identity; using Bit.Core.Billing.Services; using Bit.Core.Context; -using Bit.Core.Identity; using Bit.Core.Repositories; using Bit.Core.Utilities; using Duende.IdentityModel; diff --git a/src/Identity/IdentityServer/ProfileService.cs b/src/Identity/IdentityServer/ProfileService.cs index 74173a7e9d..9ea8fcf471 100644 --- a/src/Identity/IdentityServer/ProfileService.cs +++ b/src/Identity/IdentityServer/ProfileService.cs @@ -1,9 +1,9 @@ using System.Security.Claims; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Auth.Identity; using Bit.Core.Billing.Services; using Bit.Core.Context; using Bit.Core.Enums; -using Bit.Core.Identity; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Utilities; diff --git a/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs b/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs index 5a8cb8645e..e57ed1c85f 100644 --- a/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/BaseRequestValidator.cs @@ -8,12 +8,12 @@ using Bit.Core.AdminConsole.OrganizationFeatures.Policies; using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; +using Bit.Core.Auth.Identity; using Bit.Core.Auth.Models.Api.Response; using Bit.Core.Auth.Repositories; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Enums; -using Bit.Core.Identity; using Bit.Core.Models.Api; using Bit.Core.Models.Api.Response; using Bit.Core.Repositories; diff --git a/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs b/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs index c7bf1a77db..1495973b80 100644 --- a/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/CustomTokenRequestValidator.cs @@ -3,11 +3,11 @@ using System.Security.Claims; using Bit.Core; using Bit.Core.AdminConsole.OrganizationFeatures.Policies; using Bit.Core.AdminConsole.Services; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Auth.Models.Api.Response; using Bit.Core.Auth.Repositories; using Bit.Core.Context; using Bit.Core.Entities; -using Bit.Core.IdentityServer; using Bit.Core.Platform.Installations; using Bit.Core.Repositories; using Bit.Core.Services; diff --git a/src/Identity/IdentityServer/RequestValidators/SendAccess/SendAccessGrantValidator.cs b/src/Identity/IdentityServer/RequestValidators/SendAccess/SendAccessGrantValidator.cs index 5fe0b7b724..2ecc5a9704 100644 --- a/src/Identity/IdentityServer/RequestValidators/SendAccess/SendAccessGrantValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/SendAccess/SendAccessGrantValidator.cs @@ -1,6 +1,6 @@ using System.Security.Claims; using Bit.Core; -using Bit.Core.Identity; +using Bit.Core.Auth.Identity; using Bit.Core.Services; using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.SendFeatures.Queries.Interfaces; diff --git a/src/Identity/IdentityServer/RequestValidators/SendAccess/SendEmailOtpRequestValidator.cs b/src/Identity/IdentityServer/RequestValidators/SendAccess/SendEmailOtpRequestValidator.cs index e26556eb80..ca48c4fbec 100644 --- a/src/Identity/IdentityServer/RequestValidators/SendAccess/SendEmailOtpRequestValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/SendAccess/SendEmailOtpRequestValidator.cs @@ -1,6 +1,6 @@ using System.Security.Claims; +using Bit.Core.Auth.Identity; using Bit.Core.Auth.Identity.TokenProviders; -using Bit.Core.Identity; using Bit.Core.Services; using Bit.Core.Tools.Models.Data; using Bit.Identity.IdentityServer.Enums; diff --git a/src/Identity/IdentityServer/RequestValidators/SendAccess/SendPasswordRequestValidator.cs b/src/Identity/IdentityServer/RequestValidators/SendAccess/SendPasswordRequestValidator.cs index 4eade01a49..a514e3bc8b 100644 --- a/src/Identity/IdentityServer/RequestValidators/SendAccess/SendPasswordRequestValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/SendAccess/SendPasswordRequestValidator.cs @@ -1,5 +1,5 @@ using System.Security.Claims; -using Bit.Core.Identity; +using Bit.Core.Auth.Identity; using Bit.Core.KeyManagement.Sends; using Bit.Core.Tools.Models.Data; using Bit.Identity.IdentityServer.Enums; diff --git a/src/Identity/IdentityServer/StaticClients/SendClientBuilder.cs b/src/Identity/IdentityServer/StaticClients/SendClientBuilder.cs index 7197d435ed..6424316505 100644 --- a/src/Identity/IdentityServer/StaticClients/SendClientBuilder.cs +++ b/src/Identity/IdentityServer/StaticClients/SendClientBuilder.cs @@ -1,5 +1,5 @@ -using Bit.Core.Enums; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; +using Bit.Core.Enums; using Bit.Core.Settings; using Bit.Identity.IdentityServer.Enums; using Duende.IdentityServer.Models; diff --git a/src/Identity/Utilities/ServiceCollectionExtensions.cs b/src/Identity/Utilities/ServiceCollectionExtensions.cs index 95c067d884..9d062e5c06 100644 --- a/src/Identity/Utilities/ServiceCollectionExtensions.cs +++ b/src/Identity/Utilities/ServiceCollectionExtensions.cs @@ -1,5 +1,5 @@ -using Bit.Core.Auth.Repositories; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; +using Bit.Core.Auth.Repositories; using Bit.Core.Settings; using Bit.Core.Tools.Models.Data; using Bit.Core.Utilities; diff --git a/src/Notifications/Startup.cs b/src/Notifications/Startup.cs index c939d0d2fd..eb3c3f8682 100644 --- a/src/Notifications/Startup.cs +++ b/src/Notifications/Startup.cs @@ -1,5 +1,5 @@ using System.Globalization; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.SharedWeb.Utilities; diff --git a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs index 0dd5431dd7..4f0d0d4397 100644 --- a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs +++ b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs @@ -30,8 +30,6 @@ using Bit.Core.Dirt.Reports.ReportFeatures; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.HostedServices; -using Bit.Core.Identity; -using Bit.Core.IdentityServer; using Bit.Core.KeyManagement; using Bit.Core.NotificationCenter; using Bit.Core.OrganizationFeatures; diff --git a/test/Core.Test/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensionsTests.cs b/test/Core.Test/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensionsTests.cs index bf5322d916..ac625dad9e 100644 --- a/test/Core.Test/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensionsTests.cs +++ b/test/Core.Test/Auth/UserFeatures/SendAccess/SendAccessClaimsPrincipalExtensionsTests.cs @@ -1,6 +1,6 @@ using System.Security.Claims; +using Bit.Core.Auth.Identity; using Bit.Core.Auth.UserFeatures.SendAccess; -using Bit.Core.Identity; using Xunit; namespace Bit.Core.Test.Auth.UserFeatures.SendAccess; diff --git a/test/Identity.IntegrationTest/RequestValidation/SendAccessGrantValidatorIntegrationTests.cs b/test/Identity.IntegrationTest/RequestValidation/SendAccessGrantValidatorIntegrationTests.cs index 3b0cf2c282..ca6417d49c 100644 --- a/test/Identity.IntegrationTest/RequestValidation/SendAccessGrantValidatorIntegrationTests.cs +++ b/test/Identity.IntegrationTest/RequestValidation/SendAccessGrantValidatorIntegrationTests.cs @@ -1,6 +1,6 @@ using Bit.Core; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Enums; -using Bit.Core.IdentityServer; using Bit.Core.Services; using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.SendFeatures.Queries.Interfaces; diff --git a/test/Identity.IntegrationTest/RequestValidation/SendEmailOtpReqestValidatorIntegrationTests.cs b/test/Identity.IntegrationTest/RequestValidation/SendEmailOtpReqestValidatorIntegrationTests.cs index 9d9bc03ef5..9a097cc061 100644 --- a/test/Identity.IntegrationTest/RequestValidation/SendEmailOtpReqestValidatorIntegrationTests.cs +++ b/test/Identity.IntegrationTest/RequestValidation/SendEmailOtpReqestValidatorIntegrationTests.cs @@ -1,6 +1,6 @@ using Bit.Core.Auth.Identity.TokenProviders; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Enums; -using Bit.Core.IdentityServer; using Bit.Core.Services; using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.SendFeatures.Queries.Interfaces; diff --git a/test/Identity.IntegrationTest/RequestValidation/SendPasswordRequestValidatorIntegrationTests.cs b/test/Identity.IntegrationTest/RequestValidation/SendPasswordRequestValidatorIntegrationTests.cs index 232adb6884..856ffe1f6e 100644 --- a/test/Identity.IntegrationTest/RequestValidation/SendPasswordRequestValidatorIntegrationTests.cs +++ b/test/Identity.IntegrationTest/RequestValidation/SendPasswordRequestValidatorIntegrationTests.cs @@ -1,5 +1,5 @@ -using Bit.Core.Enums; -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; +using Bit.Core.Enums; using Bit.Core.KeyManagement.Sends; using Bit.Core.Services; using Bit.Core.Tools.Models.Data; diff --git a/test/Identity.Test/IdentityServer/ClientProviders/InstallationClientProviderTests.cs b/test/Identity.Test/IdentityServer/ClientProviders/InstallationClientProviderTests.cs index b53e6ea15f..f9949c0c3a 100644 --- a/test/Identity.Test/IdentityServer/ClientProviders/InstallationClientProviderTests.cs +++ b/test/Identity.Test/IdentityServer/ClientProviders/InstallationClientProviderTests.cs @@ -1,4 +1,4 @@ -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Platform.Installations; using Bit.Identity.IdentityServer.ClientProviders; using Duende.IdentityModel; diff --git a/test/Identity.Test/IdentityServer/ClientProviders/InternalClientProviderTests.cs b/test/Identity.Test/IdentityServer/ClientProviders/InternalClientProviderTests.cs index 4e5e659218..dda48f2af3 100644 --- a/test/Identity.Test/IdentityServer/ClientProviders/InternalClientProviderTests.cs +++ b/test/Identity.Test/IdentityServer/ClientProviders/InternalClientProviderTests.cs @@ -1,4 +1,4 @@ -using Bit.Core.IdentityServer; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Settings; using Bit.Identity.IdentityServer.ClientProviders; using Duende.IdentityModel; diff --git a/test/Identity.Test/IdentityServer/SendAccess/SendAccessGrantValidatorTests.cs b/test/Identity.Test/IdentityServer/SendAccess/SendAccessGrantValidatorTests.cs index e651709c47..017ad70354 100644 --- a/test/Identity.Test/IdentityServer/SendAccess/SendAccessGrantValidatorTests.cs +++ b/test/Identity.Test/IdentityServer/SendAccess/SendAccessGrantValidatorTests.cs @@ -1,8 +1,8 @@ using System.Collections.Specialized; using Bit.Core; +using Bit.Core.Auth.Identity; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Enums; -using Bit.Core.Identity; -using Bit.Core.IdentityServer; using Bit.Core.Services; using Bit.Core.Tools.Models.Data; using Bit.Core.Tools.SendFeatures.Queries.Interfaces; diff --git a/test/Identity.Test/IdentityServer/SendAccess/SendEmailOtpRequestValidatorTests.cs b/test/Identity.Test/IdentityServer/SendAccess/SendEmailOtpRequestValidatorTests.cs index 2fd21fd4cf..70a1585d8b 100644 --- a/test/Identity.Test/IdentityServer/SendAccess/SendEmailOtpRequestValidatorTests.cs +++ b/test/Identity.Test/IdentityServer/SendAccess/SendEmailOtpRequestValidatorTests.cs @@ -1,8 +1,8 @@ using System.Collections.Specialized; +using Bit.Core.Auth.Identity; using Bit.Core.Auth.Identity.TokenProviders; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Enums; -using Bit.Core.Identity; -using Bit.Core.IdentityServer; using Bit.Core.Services; using Bit.Core.Tools.Models.Data; using Bit.Core.Utilities; diff --git a/test/Identity.Test/IdentityServer/SendAccess/SendPasswordRequestValidatorTests.cs b/test/Identity.Test/IdentityServer/SendAccess/SendPasswordRequestValidatorTests.cs index e2b8b49830..e77626d37b 100644 --- a/test/Identity.Test/IdentityServer/SendAccess/SendPasswordRequestValidatorTests.cs +++ b/test/Identity.Test/IdentityServer/SendAccess/SendPasswordRequestValidatorTests.cs @@ -1,8 +1,8 @@ using System.Collections.Specialized; +using Bit.Core.Auth.Identity; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Auth.UserFeatures.SendAccess; using Bit.Core.Enums; -using Bit.Core.Identity; -using Bit.Core.IdentityServer; using Bit.Core.KeyManagement.Sends; using Bit.Core.Tools.Models.Data; using Bit.Core.Utilities; diff --git a/test/Identity.Test/IdentityServer/SendPasswordRequestValidatorTests.cs b/test/Identity.Test/IdentityServer/SendPasswordRequestValidatorTests.cs index ccee33d8c7..2ad1039a98 100644 --- a/test/Identity.Test/IdentityServer/SendPasswordRequestValidatorTests.cs +++ b/test/Identity.Test/IdentityServer/SendPasswordRequestValidatorTests.cs @@ -1,8 +1,8 @@ using System.Collections.Specialized; +using Bit.Core.Auth.Identity; +using Bit.Core.Auth.IdentityServer; using Bit.Core.Auth.UserFeatures.SendAccess; using Bit.Core.Enums; -using Bit.Core.Identity; -using Bit.Core.IdentityServer; using Bit.Core.KeyManagement.Sends; using Bit.Core.Tools.Models.Data; using Bit.Core.Utilities; From e456b4ce219dd4ee166e98c415027ee4a445b537 Mon Sep 17 00:00:00 2001 From: Brandon Treston Date: Thu, 4 Sep 2025 12:23:14 -0400 Subject: [PATCH 5/8] add feature flag (#6284) --- src/Core/Constants.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 058f4eac69..57798204ea 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -128,6 +128,7 @@ public static class FeatureFlagKeys public const string CreateDefaultLocation = "pm-19467-create-default-location"; public const string DirectoryConnectorPreventUserRemoval = "pm-24592-directory-connector-prevent-user-removal"; public const string CipherRepositoryBulkResourceCreation = "pm-24951-cipher-repository-bulk-resource-creation-service"; + public const string CollectionVaultRefactor = "pm-25030-resolve-ts-upgrade-errors"; /* Auth Team */ public const string TwoFactorExtensionDataPersistence = "pm-9115-two-factor-extension-data-persistence"; From 8b30c33eaebf244661fb876006d63093bbdae2e1 Mon Sep 17 00:00:00 2001 From: Vijay Oommen Date: Thu, 4 Sep 2025 12:54:24 -0500 Subject: [PATCH 6/8] PM-25413 no badRequest result because of error from Onyx (#6285) --- .../Controllers/FreshdeskController.cs | 15 ++++-- .../Controllers/FreshdeskControllerTests.cs | 51 +++++++++++++++++-- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/Billing/Controllers/FreshdeskController.cs b/src/Billing/Controllers/FreshdeskController.cs index 3f26e28786..a854d2d49f 100644 --- a/src/Billing/Controllers/FreshdeskController.cs +++ b/src/Billing/Controllers/FreshdeskController.cs @@ -152,6 +152,12 @@ public class FreshdeskController : Controller return new BadRequestResult(); } + // if there is no description, then we don't send anything to onyx + if (string.IsNullOrEmpty(model.TicketDescriptionText.Trim())) + { + return Ok(); + } + // create the onyx `answer-with-citation` request var onyxRequestModel = new OnyxAnswerWithCitationRequestModel(model.TicketDescriptionText, _billingSettings.Onyx.PersonaId); var onyxRequest = new HttpRequestMessage(HttpMethod.Post, @@ -164,9 +170,12 @@ public class FreshdeskController : Controller // the CallOnyxApi will return a null if we have an error response if (onyxJsonResponse?.Answer == null || !string.IsNullOrEmpty(onyxJsonResponse?.ErrorMsg)) { - return BadRequest( - string.Format("Failed to get a valid response from Onyx API. Response: {0}", - JsonSerializer.Serialize(onyxJsonResponse ?? new OnyxAnswerWithCitationResponseModel()))); + _logger.LogWarning("Error getting answer from Onyx AI. Freshdesk model: {model}\r\n Onyx query {query}\r\nresponse: {response}. ", + JsonSerializer.Serialize(model), + JsonSerializer.Serialize(onyxRequestModel), + JsonSerializer.Serialize(onyxJsonResponse)); + + return Ok(); // return ok so we don't retry } // add the answer as a note to the ticket diff --git a/test/Billing.Test/Controllers/FreshdeskControllerTests.cs b/test/Billing.Test/Controllers/FreshdeskControllerTests.cs index f0a34ff232..8fd0769a02 100644 --- a/test/Billing.Test/Controllers/FreshdeskControllerTests.cs +++ b/test/Billing.Test/Controllers/FreshdeskControllerTests.cs @@ -8,6 +8,7 @@ using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NSubstitute; using NSubstitute.ReceivedExtensions; @@ -126,7 +127,7 @@ public class FreshdeskControllerTests [Theory] [BitAutoData(WebhookKey)] - public async Task PostWebhookOnyxAi_invalid_onyx_response_results_in_BadRequest( + public async Task PostWebhookOnyxAi_invalid_onyx_response_results_is_logged( string freshdeskWebhookKey, FreshdeskOnyxAiWebhookModel model, SutProvider sutProvider) { @@ -150,8 +151,18 @@ public class FreshdeskControllerTests var response = await sutProvider.Sut.PostWebhookOnyxAi(freshdeskWebhookKey, model); - var result = Assert.IsAssignableFrom(response); - Assert.Equal(StatusCodes.Status400BadRequest, result.StatusCode); + var statusCodeResult = Assert.IsAssignableFrom(response); + Assert.Equal(StatusCodes.Status200OK, statusCodeResult.StatusCode); + + var _logger = sutProvider.GetDependency>(); + + // workaround because _logger.Received(1).LogWarning(...) does not work + _logger.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "Log" && c.GetArguments()[1].ToString().Contains("Error getting answer from Onyx AI")); + + // sent call to Onyx API - but we got an error response + _ = mockOnyxHttpMessageHandler.Received(1).Send(Arg.Any(), Arg.Any()); + // did not call freshdesk to add a note since onyx failed + _ = mockFreshdeskHttpMessageHandler.DidNotReceive().Send(Arg.Any(), Arg.Any()); } [Theory] @@ -174,10 +185,9 @@ public class FreshdeskControllerTests .Returns(mockFreshdeskAddNoteResponse); var freshdeskHttpClient = new HttpClient(mockFreshdeskHttpMessageHandler); - // mocking Onyx api response given a ticket description var mockOnyxHttpMessageHandler = Substitute.ForPartsOf(); - onyxResponse.ErrorMsg = string.Empty; + onyxResponse.ErrorMsg = "string.Empty"; var mockOnyxResponse = new HttpResponseMessage(System.Net.HttpStatusCode.OK) { Content = new StringContent(JsonSerializer.Serialize(onyxResponse)) @@ -195,6 +205,37 @@ public class FreshdeskControllerTests Assert.Equal(StatusCodes.Status200OK, result.StatusCode); } + [Theory] + [BitAutoData(WebhookKey)] + public async Task PostWebhookOnyxAi_ticket_description_is_empty_return_success( + string freshdeskWebhookKey, FreshdeskOnyxAiWebhookModel model, + SutProvider sutProvider) + { + var billingSettings = sutProvider.GetDependency>().Value; + billingSettings.FreshDesk.WebhookKey.Returns(freshdeskWebhookKey); + billingSettings.Onyx.BaseUrl.Returns("http://simulate-onyx-api.com/api"); + + model.TicketDescriptionText = " "; // empty description + + // mocking freshdesk api add note request (POST) + var mockFreshdeskHttpMessageHandler = Substitute.ForPartsOf(); + var freshdeskHttpClient = new HttpClient(mockFreshdeskHttpMessageHandler); + + // mocking Onyx api response given a ticket description + var mockOnyxHttpMessageHandler = Substitute.ForPartsOf(); + var onyxHttpClient = new HttpClient(mockOnyxHttpMessageHandler); + + sutProvider.GetDependency().CreateClient("FreshdeskApi").Returns(freshdeskHttpClient); + sutProvider.GetDependency().CreateClient("OnyxApi").Returns(onyxHttpClient); + + var response = await sutProvider.Sut.PostWebhookOnyxAi(freshdeskWebhookKey, model); + + var result = Assert.IsAssignableFrom(response); + Assert.Equal(StatusCodes.Status200OK, result.StatusCode); + _ = mockFreshdeskHttpMessageHandler.DidNotReceive().Send(Arg.Any(), Arg.Any()); + _ = mockOnyxHttpMessageHandler.DidNotReceive().Send(Arg.Any(), Arg.Any()); + } + public class MockHttpMessageHandler : HttpMessageHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) From 1b0be3e87f22644ee67dcfe9b0e199e264045738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Tom=C3=A9?= <108268980+r-tome@users.noreply.github.com> Date: Fri, 5 Sep 2025 11:22:50 +0100 Subject: [PATCH 7/8] [PM-22839] Add SSO configuration fields to organization user details for hiding device approvals page (#6245) * Add SsoEnabled field to OrganizationUserOrganizationDetailsView - Updated OrganizationUserOrganizationDetailsViewQuery to include SsoEnabled property. - Modified SQL view to select SsoEnabled from SsoConfig. - Created migration script to alter the view and refresh dependent views. * Enhance OrganizationUserRepositoryTests to include SSO configuration - Added ISsoConfigRepository dependency to GetManyDetailsByUserAsync test. - Created SsoConfigurationData instance and integrated SSO configuration checks in assertions. - Updated tests to validate SSO-related properties in the response model. * Add SSO properties to ProfileOrganizationResponseModel and OrganizationUserOrganizationDetails - Introduced SsoEnabled and SsoMemberDecryptionType fields in ProfileOrganizationResponseModel. - Added SsoEnabled property to OrganizationUserOrganizationDetails for enhanced SSO configuration support. --- .../ProfileOrganizationResponseModel.cs | 4 + .../OrganizationUserOrganizationDetails.cs | 1 + ...izationUserOrganizationDetailsViewQuery.cs | 1 + ...rganizationUserOrganizationDetailsView.sql | 1 + .../OrganizationUserRepositoryTests.cs | 21 ++++- ...8-25_00_OrgUserOrgDetailsAddSsoEnabled.sql | 86 +++++++++++++++++++ 6 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 util/Migrator/DbScripts/2025-08-25_00_OrgUserOrgDetailsAddSsoEnabled.sql diff --git a/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs b/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs index e421c3247e..fd2bfe06dc 100644 --- a/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs +++ b/src/Api/AdminConsole/Models/Response/ProfileOrganizationResponseModel.cs @@ -78,12 +78,14 @@ public class ProfileOrganizationResponseModel : ResponseModel UseRiskInsights = organization.UseRiskInsights; UseOrganizationDomains = organization.UseOrganizationDomains; UseAdminSponsoredFamilies = organization.UseAdminSponsoredFamilies; + SsoEnabled = organization.SsoEnabled ?? false; if (organization.SsoConfig != null) { var ssoConfigData = SsoConfigurationData.Deserialize(organization.SsoConfig); KeyConnectorEnabled = ssoConfigData.MemberDecryptionType == MemberDecryptionType.KeyConnector && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl); KeyConnectorUrl = ssoConfigData.KeyConnectorUrl; + SsoMemberDecryptionType = ssoConfigData.MemberDecryptionType; } } @@ -160,4 +162,6 @@ public class ProfileOrganizationResponseModel : ResponseModel public bool UseOrganizationDomains { get; set; } public bool UseAdminSponsoredFamilies { get; set; } public bool IsAdminInitiated { get; set; } + public bool SsoEnabled { get; set; } + public MemberDecryptionType? SsoMemberDecryptionType { 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 bad06ccf64..b7e573c4e6 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserOrganizationDetails.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/OrganizationUsers/OrganizationUserOrganizationDetails.cs @@ -49,6 +49,7 @@ public class OrganizationUserOrganizationDetails public string ProviderName { get; set; } public ProviderType? ProviderType { get; set; } public string FamilySponsorshipFriendlyName { get; set; } + public bool? SsoEnabled { get; set; } public string SsoConfig { get; set; } public DateTime? FamilySponsorshipLastSyncDate { get; set; } public DateTime? FamilySponsorshipValidUntil { get; set; } diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs index 71bf113416..26d3a128fc 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/OrganizationUserOrganizationDetailsViewQuery.cs @@ -56,6 +56,7 @@ public class OrganizationUserOrganizationDetailsViewQuery : IQuery Date: Fri, 5 Sep 2025 12:01:14 +0100 Subject: [PATCH 8/8] [PM-21752] Add granular events for collection management settings (#6269) * Add new event types for collection management settings in EventType enum * Refactor collection management settings update process in OrganizationsController and IOrganizationService. Introduced UpdateCollectionManagementSettingsAsync method to streamline updates and logging for collection management settings. * Add unit tests for collection management settings updates in OrganizationsController and OrganizationService. Implemented tests to verify the successful update of collection management settings and the logging of specific events when settings are changed. Added error handling for cases where the organization is not found. * Refactor collection management settings handling in OrganizationsController and IOrganizationService. Updated the UpdateCollectionManagementSettingsAsync method to accept a single settings object, simplifying the parameter list and improving code readability. Introduced a new OrganizationCollectionManagementSettings model to encapsulate collection management settings. Adjusted related tests to reflect these changes. * Add Obsolete attribute to Organization_CollectionManagement_Updated event in EventType enum --- .../Controllers/OrganizationsController.cs | 8 +- ...nCollectionManagementUpdateRequestModel.cs | 16 ++- src/Core/AdminConsole/Enums/EventType.cs | 11 +- ...rganizationCollectionManagementSettings.cs | 9 ++ .../Services/IOrganizationService.cs | 4 +- .../Implementations/OrganizationService.cs | 74 +++++++++++- .../OrganizationsControllerTests.cs | 39 +++++++ .../Services/OrganizationServiceTests.cs | 107 +++++++++++++++++- 8 files changed, 242 insertions(+), 26 deletions(-) create mode 100644 src/Core/AdminConsole/Models/Business/OrganizationCollectionManagementSettings.cs diff --git a/src/Api/AdminConsole/Controllers/OrganizationsController.cs b/src/Api/AdminConsole/Controllers/OrganizationsController.cs index 8b1a6243c3..17e6a60cd9 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationsController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationsController.cs @@ -554,18 +554,12 @@ public class OrganizationsController : Controller [HttpPut("{id}/collection-management")] public async Task PutCollectionManagement(Guid id, [FromBody] OrganizationCollectionManagementUpdateRequestModel model) { - var organization = await _organizationRepository.GetByIdAsync(id); - if (organization == null) - { - throw new NotFoundException(); - } - if (!await _currentContext.OrganizationOwner(id)) { throw new NotFoundException(); } - await _organizationService.UpdateAsync(model.ToOrganization(organization, _featureService), eventType: EventType.Organization_CollectionManagement_Updated); + var organization = await _organizationService.UpdateCollectionManagementSettingsAsync(id, model.ToSettings()); var plan = await _pricingClient.GetPlan(organization.PlanType); return new OrganizationResponseModel(organization, plan); } diff --git a/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs b/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs index 829840c896..93866161c0 100644 --- a/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs +++ b/src/Api/Models/Request/Organizations/OrganizationCollectionManagementUpdateRequestModel.cs @@ -1,5 +1,4 @@ -using Bit.Core.AdminConsole.Entities; -using Bit.Core.Services; +using Bit.Core.AdminConsole.Models.Business; namespace Bit.Api.Models.Request.Organizations; @@ -10,12 +9,11 @@ public class OrganizationCollectionManagementUpdateRequestModel public bool LimitItemDeletion { get; set; } public bool AllowAdminAccessToAllCollectionItems { get; set; } - public virtual Organization ToOrganization(Organization existingOrganization, IFeatureService featureService) + public OrganizationCollectionManagementSettings ToSettings() => new() { - existingOrganization.LimitCollectionCreation = LimitCollectionCreation; - existingOrganization.LimitCollectionDeletion = LimitCollectionDeletion; - existingOrganization.LimitItemDeletion = LimitItemDeletion; - existingOrganization.AllowAdminAccessToAllCollectionItems = AllowAdminAccessToAllCollectionItems; - return existingOrganization; - } + LimitCollectionCreation = LimitCollectionCreation, + LimitCollectionDeletion = LimitCollectionDeletion, + LimitItemDeletion = LimitItemDeletion, + AllowAdminAccessToAllCollectionItems = AllowAdminAccessToAllCollectionItems + }; } diff --git a/src/Core/AdminConsole/Enums/EventType.cs b/src/Core/AdminConsole/Enums/EventType.cs index 32ea4a64e9..81501fd6ec 100644 --- a/src/Core/AdminConsole/Enums/EventType.cs +++ b/src/Core/AdminConsole/Enums/EventType.cs @@ -70,7 +70,16 @@ public enum EventType : int Organization_EnabledKeyConnector = 1606, Organization_DisabledKeyConnector = 1607, Organization_SponsorshipsSynced = 1608, - Organization_CollectionManagement_Updated = 1609, + [Obsolete("Use other specific Organization_CollectionManagement events instead")] + Organization_CollectionManagement_Updated = 1609, // TODO: Will be removed in PM-25315 + Organization_CollectionManagement_LimitCollectionCreationEnabled = 1610, + Organization_CollectionManagement_LimitCollectionCreationDisabled = 1611, + Organization_CollectionManagement_LimitCollectionDeletionEnabled = 1612, + Organization_CollectionManagement_LimitCollectionDeletionDisabled = 1613, + Organization_CollectionManagement_LimitItemDeletionEnabled = 1614, + Organization_CollectionManagement_LimitItemDeletionDisabled = 1615, + Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsEnabled = 1616, + Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsDisabled = 1617, Policy_Updated = 1700, diff --git a/src/Core/AdminConsole/Models/Business/OrganizationCollectionManagementSettings.cs b/src/Core/AdminConsole/Models/Business/OrganizationCollectionManagementSettings.cs new file mode 100644 index 0000000000..aff2244598 --- /dev/null +++ b/src/Core/AdminConsole/Models/Business/OrganizationCollectionManagementSettings.cs @@ -0,0 +1,9 @@ +namespace Bit.Core.AdminConsole.Models.Business; + +public record OrganizationCollectionManagementSettings +{ + public bool LimitCollectionCreation { get; set; } + public bool LimitCollectionDeletion { get; set; } + public bool LimitItemDeletion { get; set; } + public bool AllowAdminAccessToAllCollectionItems { get; set; } +} diff --git a/src/Core/AdminConsole/Services/IOrganizationService.cs b/src/Core/AdminConsole/Services/IOrganizationService.cs index 8c47ae049c..94df74afdf 100644 --- a/src/Core/AdminConsole/Services/IOrganizationService.cs +++ b/src/Core/AdminConsole/Services/IOrganizationService.cs @@ -2,6 +2,7 @@ #nullable disable using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Models.Business; using Bit.Core.Auth.Enums; using Bit.Core.Entities; using Bit.Core.Enums; @@ -19,7 +20,8 @@ public interface IOrganizationService Task AdjustSeatsAsync(Guid organizationId, int seatAdjustment); Task VerifyBankAsync(Guid organizationId, int amount1, int amount2); Task UpdateExpirationDateAsync(Guid organizationId, DateTime? expirationDate); - Task UpdateAsync(Organization organization, bool updateBilling = false, EventType eventType = EventType.Organization_Updated); + Task UpdateAsync(Organization organization, bool updateBilling = false); + Task UpdateCollectionManagementSettingsAsync(Guid organizationId, OrganizationCollectionManagementSettings settings); Task UpdateTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type); Task DisableTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type); Task InviteUserAsync(Guid organizationId, Guid? invitingUserId, EventSystemUser? systemUser, diff --git a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs index f418737508..57eb4f51de 100644 --- a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs +++ b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs @@ -5,6 +5,7 @@ using System.Text.Json; using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Enums.Provider; +using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers; @@ -378,8 +379,7 @@ public class OrganizationService : IOrganizationService } } - public async Task UpdateAsync(Organization organization, bool updateBilling = false, - EventType eventType = EventType.Organization_Updated) + public async Task UpdateAsync(Organization organization, bool updateBilling = false) { if (organization.Id == default(Guid)) { @@ -395,7 +395,7 @@ public class OrganizationService : IOrganizationService } } - await ReplaceAndUpdateCacheAsync(organization, eventType); + await ReplaceAndUpdateCacheAsync(organization, EventType.Organization_Updated); if (updateBilling && !string.IsNullOrWhiteSpace(organization.GatewayCustomerId)) { @@ -420,11 +420,35 @@ public class OrganizationService : IOrganizationService }, }); } + } - if (eventType == EventType.Organization_CollectionManagement_Updated) + public async Task UpdateCollectionManagementSettingsAsync(Guid organizationId, OrganizationCollectionManagementSettings settings) + { + var existingOrganization = await _organizationRepository.GetByIdAsync(organizationId); + if (existingOrganization == null) { - await _pushNotificationService.PushSyncOrganizationCollectionManagementSettingsAsync(organization); + throw new NotFoundException(); } + + // Create logging actions based on what will change + var loggingActions = CreateCollectionManagementLoggingActions(existingOrganization, settings); + + existingOrganization.LimitCollectionCreation = settings.LimitCollectionCreation; + existingOrganization.LimitCollectionDeletion = settings.LimitCollectionDeletion; + existingOrganization.LimitItemDeletion = settings.LimitItemDeletion; + existingOrganization.AllowAdminAccessToAllCollectionItems = settings.AllowAdminAccessToAllCollectionItems; + existingOrganization.RevisionDate = DateTime.UtcNow; + + await ReplaceAndUpdateCacheAsync(existingOrganization); + + if (loggingActions.Any()) + { + await Task.WhenAll(loggingActions.Select(action => action())); + } + + await _pushNotificationService.PushSyncOrganizationCollectionManagementSettingsAsync(existingOrganization); + + return existingOrganization; } public async Task UpdateTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type) @@ -1214,4 +1238,44 @@ public class OrganizationService : IOrganizationService return status; } + + private List> CreateCollectionManagementLoggingActions( + Organization existingOrganization, OrganizationCollectionManagementSettings settings) + { + var loggingActions = new List>(); + + if (existingOrganization.LimitCollectionCreation != settings.LimitCollectionCreation) + { + var eventType = settings.LimitCollectionCreation + ? EventType.Organization_CollectionManagement_LimitCollectionCreationEnabled + : EventType.Organization_CollectionManagement_LimitCollectionCreationDisabled; + loggingActions.Add(() => _eventService.LogOrganizationEventAsync(existingOrganization, eventType)); + } + + if (existingOrganization.LimitCollectionDeletion != settings.LimitCollectionDeletion) + { + var eventType = settings.LimitCollectionDeletion + ? EventType.Organization_CollectionManagement_LimitCollectionDeletionEnabled + : EventType.Organization_CollectionManagement_LimitCollectionDeletionDisabled; + loggingActions.Add(() => _eventService.LogOrganizationEventAsync(existingOrganization, eventType)); + } + + if (existingOrganization.LimitItemDeletion != settings.LimitItemDeletion) + { + var eventType = settings.LimitItemDeletion + ? EventType.Organization_CollectionManagement_LimitItemDeletionEnabled + : EventType.Organization_CollectionManagement_LimitItemDeletionDisabled; + loggingActions.Add(() => _eventService.LogOrganizationEventAsync(existingOrganization, eventType)); + } + + if (existingOrganization.AllowAdminAccessToAllCollectionItems != settings.AllowAdminAccessToAllCollectionItems) + { + var eventType = settings.AllowAdminAccessToAllCollectionItems + ? EventType.Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsEnabled + : EventType.Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsDisabled; + loggingActions.Add(() => _eventService.LogOrganizationEventAsync(existingOrganization, eventType)); + } + + return loggingActions; + } } diff --git a/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs b/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs index 3484c9a995..00fd3c3b4e 100644 --- a/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs +++ b/test/Api.Test/AdminConsole/Controllers/OrganizationsControllerTests.cs @@ -2,10 +2,12 @@ using AutoFixture.Xunit2; using Bit.Api.AdminConsole.Controllers; using Bit.Api.Auth.Models.Request.Accounts; +using Bit.Api.Models.Request.Organizations; using Bit.Core; using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Enums.Provider; +using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.Models.Business.Tokenables; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationApiKeys.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.Organizations; @@ -29,6 +31,7 @@ using Bit.Core.Exceptions; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Tokens; +using Bit.Core.Utilities; using Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider; using NSubstitute; using Xunit; @@ -293,4 +296,40 @@ public class OrganizationsControllerTests : IDisposable Assert.True(result.ResetPasswordEnabled); } + + [Theory, AutoData] + public async Task PutCollectionManagement_ValidRequest_Success( + Organization organization, + OrganizationCollectionManagementUpdateRequestModel model) + { + // Arrange + _currentContext.OrganizationOwner(organization.Id).Returns(true); + + var plan = StaticStore.GetPlan(PlanType.EnterpriseAnnually); + _pricingClient.GetPlan(Arg.Any()).Returns(plan); + + _organizationService + .UpdateCollectionManagementSettingsAsync( + organization.Id, + Arg.Is(s => + s.LimitCollectionCreation == model.LimitCollectionCreation && + s.LimitCollectionDeletion == model.LimitCollectionDeletion && + s.LimitItemDeletion == model.LimitItemDeletion && + s.AllowAdminAccessToAllCollectionItems == model.AllowAdminAccessToAllCollectionItems)) + .Returns(organization); + + // Act + await _sut.PutCollectionManagement(organization.Id, model); + + // Assert + await _organizationService + .Received(1) + .UpdateCollectionManagementSettingsAsync( + organization.Id, + Arg.Is(s => + s.LimitCollectionCreation == model.LimitCollectionCreation && + s.LimitCollectionDeletion == model.LimitCollectionDeletion && + s.LimitItemDeletion == model.LimitItemDeletion && + s.AllowAdminAccessToAllCollectionItems == model.AllowAdminAccessToAllCollectionItems)); + } } diff --git a/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs b/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs index e3f26a898d..33f2e78799 100644 --- a/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs +++ b/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs @@ -1,6 +1,7 @@ using System.Text.Json; using Bit.Core.AdminConsole.Entities.Provider; using Bit.Core.AdminConsole.Enums.Provider; +using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; @@ -27,7 +28,6 @@ using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Fakes; using NSubstitute; using NSubstitute.ExceptionExtensions; -using NSubstitute.ReceivedExtensions; using NSubstitute.ReturnsExtensions; using Stripe; using Xunit; @@ -42,8 +42,6 @@ public class OrganizationServiceTests { private readonly IDataProtectorTokenFactory _orgUserInviteTokenDataFactory = new FakeDataProtectorTokenFactory(); - - [Theory] [OrganizationInviteCustomize(InviteeUserType = OrganizationUserType.User, InvitorUserType = OrganizationUserType.Owner), OrganizationCustomize, BitAutoData] @@ -1229,6 +1227,109 @@ public class OrganizationServiceTests .GetByIdentifierAsync(Arg.Is(id => id == organization.Identifier)); } + [Theory] + [BitAutoData(false, true, false, true)] + [BitAutoData(true, false, true, false)] + public async Task UpdateCollectionManagementSettingsAsync_WhenSettingsChanged_LogsSpecificEvents( + bool newLimitCollectionCreation, + bool newLimitCollectionDeletion, + bool newLimitItemDeletion, + bool newAllowAdminAccessToAllCollectionItems, + Organization existingOrganization, SutProvider sutProvider) + { + // Arrange + existingOrganization.LimitCollectionCreation = false; + existingOrganization.LimitCollectionDeletion = false; + existingOrganization.LimitItemDeletion = false; + existingOrganization.AllowAdminAccessToAllCollectionItems = false; + + sutProvider.GetDependency() + .GetByIdAsync(existingOrganization.Id) + .Returns(existingOrganization); + + var settings = new OrganizationCollectionManagementSettings + { + LimitCollectionCreation = newLimitCollectionCreation, + LimitCollectionDeletion = newLimitCollectionDeletion, + LimitItemDeletion = newLimitItemDeletion, + AllowAdminAccessToAllCollectionItems = newAllowAdminAccessToAllCollectionItems + }; + + // Act + await sutProvider.Sut.UpdateCollectionManagementSettingsAsync(existingOrganization.Id, settings); + + // Assert + var eventService = sutProvider.GetDependency(); + if (newLimitCollectionCreation) + { + await eventService.Received(1).LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_LimitCollectionCreationEnabled)); + } + else + { + await eventService.DidNotReceive().LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_LimitCollectionCreationEnabled)); + } + + if (newLimitCollectionDeletion) + { + await eventService.Received(1).LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_LimitCollectionDeletionEnabled)); + } + else + { + await eventService.DidNotReceive().LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_LimitCollectionDeletionEnabled)); + } + + if (newLimitItemDeletion) + { + await eventService.Received(1).LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_LimitItemDeletionEnabled)); + } + else + { + await eventService.DidNotReceive().LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_LimitItemDeletionEnabled)); + } + + if (newAllowAdminAccessToAllCollectionItems) + { + await eventService.Received(1).LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsEnabled)); + } + else + { + await eventService.DidNotReceive().LogOrganizationEventAsync( + Arg.Is(org => org.Id == existingOrganization.Id), + Arg.Is(e => e == EventType.Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsEnabled)); + } + } + + [Theory, BitAutoData] + public async Task UpdateCollectionManagementSettingsAsync_WhenOrganizationNotFound_ThrowsNotFoundException( + Guid organizationId, OrganizationCollectionManagementSettings settings, SutProvider sutProvider) + { + // Arrange + sutProvider.GetDependency() + .GetByIdAsync(organizationId) + .Returns((Organization)null); + + // Act/Assert + await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateCollectionManagementSettingsAsync(organizationId, settings)); + + await sutProvider.GetDependency() + .Received(1) + .GetByIdAsync(organizationId); + } + // Must set real guids in order for dictionary of guids to not throw aggregate exceptions private void SetupOrgUserRepositoryCreateManyAsyncMock(IOrganizationUserRepository organizationUserRepository) {