From b2a3ac46333aa63890f623d033bc9eb6240f5ab8 Mon Sep 17 00:00:00 2001 From: tangowithfoxtrot <5676771+tangowithfoxtrot@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:38:18 -0800 Subject: [PATCH 01/20] update secret import char limit (#3405) --- src/Api/SecretsManager/Models/Request/SMImportRequestModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Api/SecretsManager/Models/Request/SMImportRequestModel.cs b/src/Api/SecretsManager/Models/Request/SMImportRequestModel.cs index 13cc3b6f73..a63e2c180d 100644 --- a/src/Api/SecretsManager/Models/Request/SMImportRequestModel.cs +++ b/src/Api/SecretsManager/Models/Request/SMImportRequestModel.cs @@ -36,12 +36,12 @@ public class SMImportRequestModel [Required] [EncryptedString] - [EncryptedStringLength(1000)] + [EncryptedStringLength(35000)] public string Value { get; set; } [Required] [EncryptedString] - [EncryptedStringLength(1000)] + [EncryptedStringLength(10000)] public string Note { get; set; } [Required] From cf38ff3c1920f69ca5285d989b57379419ed710e Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Fri, 17 Nov 2023 15:12:49 -0500 Subject: [PATCH 02/20] [AC-1828] [AC-1807] Aggregated admin panel pricing fixes (#3448) * AC-1828: Allow reseller to add all teams and enterprise orgs * AC-1807: Only show provider-eligible plans on Organization edit * Thomas' feedback * Matt's feedback --- .../Views/Shared/_OrganizationForm.cshtml | 6 +- .../Repositories/OrganizationRepository.cs | 15 +++-- ...rganization_UnassignedToProviderSearch.sql | 4 +- ...OrganizationUnassignedToProviderSearch.sql | 64 +++++++++++++++++++ 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 util/Migrator/DbScripts/2023-11-14_00_UpdateOrganizationUnassignedToProviderSearch.sql diff --git a/src/Admin/Views/Shared/_OrganizationForm.cshtml b/src/Admin/Views/Shared/_OrganizationForm.cshtml index 76502ff75b..72076cbd37 100644 --- a/src/Admin/Views/Shared/_OrganizationForm.cshtml +++ b/src/Admin/Views/Shared/_OrganizationForm.cshtml @@ -82,7 +82,11 @@ @{ var planTypes = Enum.GetValues() - .Where(p => Model.Provider == null || p is >= PlanType.TeamsMonthly and <= PlanType.TeamsStarter) + .Where(p => + Model.Provider == null || + (Model.Provider != null + && p is >= PlanType.TeamsMonthly2019 and <= PlanType.EnterpriseAnnually2019 or >= PlanType.TeamsMonthly2020 and <= PlanType.EnterpriseAnnually) + ) .Select(e => new SelectListItem { Value = ((int)e).ToString(), diff --git a/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs b/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs index b20026a6b7..b7ee85543f 100644 --- a/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs @@ -96,12 +96,17 @@ public class OrganizationRepository : Repository> SearchUnassignedToProviderAsync(string name, string ownerEmail, int skip, int take) { using var scope = ServiceScopeFactory.CreateScope(); + var dbContext = GetDatabaseContext(scope); - var query = from o in dbContext.Organizations - where o.PlanType >= PlanType.TeamsMonthly2020 && o.PlanType <= PlanType.EnterpriseAnnually && - !dbContext.ProviderOrganizations.Any(po => po.OrganizationId == o.Id) && - (string.IsNullOrWhiteSpace(name) || EF.Functions.Like(o.Name, $"%{name}%")) - select o; + + var query = + from o in dbContext.Organizations + where + ((o.PlanType >= PlanType.TeamsMonthly2019 && o.PlanType <= PlanType.EnterpriseAnnually2019) || + (o.PlanType >= PlanType.TeamsMonthly2020 && o.PlanType <= PlanType.EnterpriseAnnually)) && + !dbContext.ProviderOrganizations.Any(po => po.OrganizationId == o.Id) && + (string.IsNullOrWhiteSpace(name) || EF.Functions.Like(o.Name, $"%{name}%")) + select o; if (string.IsNullOrWhiteSpace(ownerEmail)) { diff --git a/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql b/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql index 45fcbaeb9b..dc71c809eb 100644 --- a/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql +++ b/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql @@ -21,7 +21,7 @@ BEGIN INNER JOIN [dbo].[User] U ON U.[Id] = OU.[UserId] WHERE - O.[PlanType] >= 8 AND O.[PlanType] <= 11 -- Get 'Team' and 'Enterprise' Organizations + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) AND (U.[Email] LIKE @OwnerLikeSearch) @@ -36,7 +36,7 @@ BEGIN FROM [dbo].[OrganizationView] O WHERE - O.[PlanType] >= 8 AND O.[PlanType] <= 11 -- Get 'Team' and 'Enterprise' Organizations + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) ORDER BY O.[CreationDate] DESC diff --git a/util/Migrator/DbScripts/2023-11-14_00_UpdateOrganizationUnassignedToProviderSearch.sql b/util/Migrator/DbScripts/2023-11-14_00_UpdateOrganizationUnassignedToProviderSearch.sql new file mode 100644 index 0000000000..5d85eb4869 --- /dev/null +++ b/util/Migrator/DbScripts/2023-11-14_00_UpdateOrganizationUnassignedToProviderSearch.sql @@ -0,0 +1,64 @@ +/* + This procedure is used by the Bitwarden Admin Panel to retrieve the + Organizations a Reseller Provider is capable of adding as a client. + + Currently, the procedure is only surfacing Organizations with the most + current Enterprise or Teams plans, but we actually need to surface any + Enterprise or Teams plan regardless of the version as all of them are + applicable to Resellers. +*/ + +-- Drop existing SPROC +IF OBJECT_ID('[dbo].[Organization_UnassignedToProviderSearch]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[Organization_UnassignedToProviderSearch] +END +GO + +CREATE PROCEDURE [dbo].[Organization_UnassignedToProviderSearch] + @Name NVARCHAR(50), + @OwnerEmail NVARCHAR(256), + @Skip INT = 0, + @Take INT = 25 +WITH RECOMPILE +AS +BEGIN + SET NOCOUNT ON + DECLARE @NameLikeSearch NVARCHAR(55) = '%' + @Name + '%' + DECLARE @OwnerLikeSearch NVARCHAR(55) = @OwnerEmail + '%' + + IF @OwnerEmail IS NOT NULL + BEGIN + SELECT + O.* + FROM + [dbo].[OrganizationView] O + INNER JOIN + [dbo].[OrganizationUser] OU ON O.[Id] = OU.[OrganizationId] + INNER JOIN + [dbo].[User] U ON U.[Id] = OU.[UserId] + WHERE + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations + AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) + AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) + AND (U.[Email] LIKE @OwnerLikeSearch) + ORDER BY O.[CreationDate] DESC + OFFSET @Skip ROWS + FETCH NEXT @Take ROWS ONLY + END + ELSE + BEGIN + SELECT + O.* + FROM + [dbo].[OrganizationView] O + WHERE + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations + AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) + AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) + ORDER BY O.[CreationDate] DESC + OFFSET @Skip ROWS + FETCH NEXT @Take ROWS ONLY + END +END +GO From 07c202ecafb351f33e4c19bcf44dbf64d146077c Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:05:35 -0500 Subject: [PATCH 03/20] Block org seat scaling when has Reseller provider (#3385) --- .../Implementations/OrganizationService.cs | 17 +++++++++-- .../Services/OrganizationServiceTests.cs | 29 ++++++++++++++++--- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index e7275a6d26..be5eabb6e7 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -57,6 +57,7 @@ public class OrganizationService : IOrganizationService private readonly IProviderUserRepository _providerUserRepository; private readonly ICountNewSmSeatsRequiredQuery _countNewSmSeatsRequiredQuery; private readonly IUpdateSecretsManagerSubscriptionCommand _updateSecretsManagerSubscriptionCommand; + private readonly IProviderRepository _providerRepository; private readonly IOrgUserInviteTokenableFactory _orgUserInviteTokenableFactory; private readonly IDataProtectorTokenFactory _orgUserInviteTokenDataFactory; private readonly IFeatureService _featureService; @@ -90,6 +91,7 @@ public class OrganizationService : IOrganizationService IOrgUserInviteTokenableFactory orgUserInviteTokenableFactory, IDataProtectorTokenFactory orgUserInviteTokenDataFactory, IUpdateSecretsManagerSubscriptionCommand updateSecretsManagerSubscriptionCommand, + IProviderRepository providerRepository, IFeatureService featureService) { _organizationRepository = organizationRepository; @@ -118,6 +120,7 @@ public class OrganizationService : IOrganizationService _providerUserRepository = providerUserRepository; _countNewSmSeatsRequiredQuery = countNewSmSeatsRequiredQuery; _updateSecretsManagerSubscriptionCommand = updateSecretsManagerSubscriptionCommand; + _providerRepository = providerRepository; _orgUserInviteTokenableFactory = orgUserInviteTokenableFactory; _orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory; _featureService = featureService; @@ -862,7 +865,7 @@ public class OrganizationService : IOrganizationService if (newSeatsRequired > 0) { - var (canScale, failureReason) = CanScale(organization, newSeatsRequired); + var (canScale, failureReason) = await CanScaleAsync(organization, newSeatsRequired); if (!canScale) { throw new BadRequestException(failureReason); @@ -1182,7 +1185,8 @@ public class OrganizationService : IOrganizationService return result; } - internal (bool canScale, string failureReason) CanScale(Organization organization, + internal async Task<(bool canScale, string failureReason)> CanScaleAsync( + Organization organization, int seatsToAdd) { var failureReason = ""; @@ -1197,6 +1201,13 @@ public class OrganizationService : IOrganizationService return (true, failureReason); } + var provider = await _providerRepository.GetByOrganizationIdAsync(organization.Id); + + if (provider is { Enabled: true, Type: ProviderType.Reseller }) + { + return (false, "Seat limit has been reached. Contact your provider to purchase additional seats."); + } + if (organization.Seats.HasValue && organization.MaxAutoscaleSeats.HasValue && organization.MaxAutoscaleSeats.Value < organization.Seats.Value + seatsToAdd) @@ -1214,7 +1225,7 @@ public class OrganizationService : IOrganizationService return; } - var (canScale, failureMessage) = CanScale(organization, seatsToAdd); + var (canScale, failureMessage) = await CanScaleAsync(organization, seatsToAdd); if (!canScale) { throw new BadRequestException(failureMessage); diff --git a/test/Core.Test/Services/OrganizationServiceTests.cs b/test/Core.Test/Services/OrganizationServiceTests.cs index 210e59681b..a169a0093e 100644 --- a/test/Core.Test/Services/OrganizationServiceTests.cs +++ b/test/Core.Test/Services/OrganizationServiceTests.cs @@ -34,6 +34,7 @@ using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Fakes; using NSubstitute; using NSubstitute.ExceptionExtensions; +using NSubstitute.ReturnsExtensions; using Xunit; using Organization = Bit.Core.Entities.Organization; using OrganizationUser = Bit.Core.Entities.OrganizationUser; @@ -1606,15 +1607,16 @@ public class OrganizationServiceTests [BitAutoData(0, null, 100, true, "")] [BitAutoData(1, 100, null, true, "")] [BitAutoData(1, 100, 100, false, "Seat limit has been reached")] - public void CanScale(int seatsToAdd, int? currentSeats, int? maxAutoscaleSeats, + public async Task CanScaleAsync(int seatsToAdd, int? currentSeats, int? maxAutoscaleSeats, bool expectedResult, string expectedFailureMessage, Organization organization, SutProvider sutProvider) { organization.Seats = currentSeats; organization.MaxAutoscaleSeats = maxAutoscaleSeats; sutProvider.GetDependency().ManageUsers(organization.Id).Returns(true); + sutProvider.GetDependency().GetByOrganizationIdAsync(organization.Id).ReturnsNull(); - var (result, failureMessage) = sutProvider.Sut.CanScale(organization, seatsToAdd); + var (result, failureMessage) = await sutProvider.Sut.CanScaleAsync(organization, seatsToAdd); if (expectedFailureMessage == string.Empty) { @@ -1628,16 +1630,35 @@ public class OrganizationServiceTests } [Theory, PaidOrganizationCustomize, BitAutoData] - public void CanScale_FailsOnSelfHosted(Organization organization, + public async Task CanScaleAsync_FailsOnSelfHosted(Organization organization, SutProvider sutProvider) { sutProvider.GetDependency().SelfHosted.Returns(true); - var (result, failureMessage) = sutProvider.Sut.CanScale(organization, 10); + var (result, failureMessage) = await sutProvider.Sut.CanScaleAsync(organization, 10); Assert.False(result); Assert.Contains("Cannot autoscale on self-hosted instance", failureMessage); } + [Theory, PaidOrganizationCustomize, BitAutoData] + public async Task CanScaleAsync_FailsOnResellerManagedOrganization( + Organization organization, + SutProvider sutProvider) + { + var provider = new Provider + { + Enabled = true, + Type = ProviderType.Reseller + }; + + sutProvider.GetDependency().GetByOrganizationIdAsync(organization.Id).Returns(provider); + + var (result, failureMessage) = await sutProvider.Sut.CanScaleAsync(organization, 10); + + Assert.False(result); + Assert.Contains("Seat limit has been reached. Contact your provider to purchase additional seats.", failureMessage); + } + [Theory, PaidOrganizationCustomize, BitAutoData] public async Task Delete_Success(Organization organization, SutProvider sutProvider) { From 80740aa4ba994d968f9c52a2e63b0e3e062a56b9 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Mon, 20 Nov 2023 15:55:31 +0100 Subject: [PATCH 04/20] [PM-2032] Server endpoints to support authentication with a passkey (#3361) * [PM-2032] feat: add assertion options tokenable * [PM-2032] feat: add request and response models * [PM-2032] feat: implement `assertion-options` identity endpoint * [PM-2032] feat: implement authentication with passkey * [PM-2032] chore: rename to `WebAuthnGrantValidator` * [PM-2032] fix: add missing subsitute * [PM-2032] feat: start adding builder * [PM-2032] feat: add support for KeyConnector * [PM-2032] feat: add first version of TDE * [PM-2032] chore: refactor WithSso * [PM-2023] feat: add support for TDE feature flag * [PM-2023] feat: add support for approving devices * [PM-2023] feat: add support for hasManageResetPasswordPermission * [PM-2032] feat: add support for hasAdminApproval * [PM-2032] chore: don't supply device if not necessary * [PM-2032] chore: clean up imports * [PM-2023] feat: extract interface * [PM-2023] chore: add clarifying comment * [PM-2023] feat: use new builder in production code * [PM-2032] feat: add support for PRF * [PM-2032] chore: clean-up todos * [PM-2023] chore: remove token which is no longer used * [PM-2032] chore: remove todo * [PM-2032] feat: improve assertion error handling * [PM-2032] fix: linting issues * [PM-2032] fix: revert changes to `launchSettings.json` * [PM-2023] chore: clean up assertion endpoint * [PM-2032] feat: bypass 2FA * [PM-2032] fix: rename prf option to singular * [PM-2032] fix: lint * [PM-2032] fix: typo * [PM-2032] chore: improve builder tests Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> * [PM-2032] chore: clarify why we don't require 2FA * [PM-2023] feat: move `identityProvider` constant to common class * [PM-2032] fix: lint * [PM-2023] fix: move `IdentityProvider` to core.Constants * [PM-2032] fix: missing import * [PM-2032] chore: refactor token timespan to use `TimeSpan` * [PM-2032] chore: make `StartWebAuthnLoginAssertion` sync * [PM-2032] chore: use `FromMinutes` * [PM-2032] fix: change to 17 minutes to cover webauthn assertion * [PM-2032] chore: do not use `async void` * [PM-2032] fix: comment saying wrong amount of minutes * [PM-2032] feat: put validator behind feature flag * [PM-2032] fix: lint --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> --- .../WebAuthnLoginAssertionOptionsScope.cs | 7 + ...AuthnLoginAssertionOptionsResponseModel.cs | 18 ++ .../Api/Response/UserDecryptionOptions.cs | 20 ++ .../WebAuthnLoginAssertionOptionsTokenable.cs | 47 +++++ .../Tokenables/WebAuthnLoginTokenable.cs | 43 ----- src/Core/Auth/Utilities/GuidUtilities.cs | 19 ++ src/Core/Constants.cs | 5 + src/Core/Services/IUserService.cs | 5 +- .../Services/Implementations/UserService.cs | 71 +++----- .../Controllers/AccountsController.cs | 49 ++--- src/Identity/IdentityServer/ApiClient.cs | 2 +- .../IdentityServer/BaseRequestValidator.cs | 84 ++------- .../CustomTokenRequestValidator.cs | 5 +- .../IUserDecryptionOptionsBuilder.cs | 13 ++ .../ResourceOwnerPasswordValidator.cs | 8 +- .../UserDecryptionOptionsBuilder.cs | 155 ++++++++++++++++ .../IdentityServer/WebAuthnGrantValidator.cs | 150 +++++++++++++++ .../Utilities/ServiceCollectionExtensions.cs | 4 +- .../Utilities/ServiceCollectionExtensions.cs | 12 +- ...uthnLoginAssertionOptionsTokenableTests.cs | 61 +++++++ test/Core.Test/Services/UserServiceTests.cs | 99 +++++++++- .../openid-configuration.json | 22 +-- .../Controllers/AccountsControllerTests.cs | 7 +- .../UserDecryptionOptionsBuilderTests.cs | 172 ++++++++++++++++++ 24 files changed, 855 insertions(+), 223 deletions(-) create mode 100644 src/Core/Auth/Enums/WebAuthnLoginAssertionOptionsScope.cs create mode 100644 src/Core/Auth/Models/Api/Response/Accounts/WebAuthnLoginAssertionOptionsResponseModel.cs create mode 100644 src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenable.cs delete mode 100644 src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginTokenable.cs create mode 100644 src/Core/Auth/Utilities/GuidUtilities.cs create mode 100644 src/Identity/IdentityServer/IUserDecryptionOptionsBuilder.cs create mode 100644 src/Identity/IdentityServer/UserDecryptionOptionsBuilder.cs create mode 100644 src/Identity/IdentityServer/WebAuthnGrantValidator.cs create mode 100644 test/Core.Test/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenableTests.cs create mode 100644 test/Identity.Test/IdentityServer/UserDecryptionOptionsBuilderTests.cs diff --git a/src/Core/Auth/Enums/WebAuthnLoginAssertionOptionsScope.cs b/src/Core/Auth/Enums/WebAuthnLoginAssertionOptionsScope.cs new file mode 100644 index 0000000000..bcafc0e89f --- /dev/null +++ b/src/Core/Auth/Enums/WebAuthnLoginAssertionOptionsScope.cs @@ -0,0 +1,7 @@ +namespace Bit.Core.Auth.Enums; + +public enum WebAuthnLoginAssertionOptionsScope +{ + Authentication = 0, + PrfRegistration = 1 +} diff --git a/src/Core/Auth/Models/Api/Response/Accounts/WebAuthnLoginAssertionOptionsResponseModel.cs b/src/Core/Auth/Models/Api/Response/Accounts/WebAuthnLoginAssertionOptionsResponseModel.cs new file mode 100644 index 0000000000..6a0641246b --- /dev/null +++ b/src/Core/Auth/Models/Api/Response/Accounts/WebAuthnLoginAssertionOptionsResponseModel.cs @@ -0,0 +1,18 @@ + +using Bit.Core.Models.Api; +using Fido2NetLib; + +namespace Bit.Core.Auth.Models.Api.Response.Accounts; + +public class WebAuthnLoginAssertionOptionsResponseModel : ResponseModel +{ + private const string ResponseObj = "webAuthnLoginAssertionOptions"; + + public WebAuthnLoginAssertionOptionsResponseModel() : base(ResponseObj) + { + } + + public AssertionOptions Options { get; set; } + public string Token { get; set; } +} + diff --git a/src/Core/Auth/Models/Api/Response/UserDecryptionOptions.cs b/src/Core/Auth/Models/Api/Response/UserDecryptionOptions.cs index edfcce5a51..06990afea9 100644 --- a/src/Core/Auth/Models/Api/Response/UserDecryptionOptions.cs +++ b/src/Core/Auth/Models/Api/Response/UserDecryptionOptions.cs @@ -16,6 +16,12 @@ public class UserDecryptionOptions : ResponseModel /// public bool HasMasterPassword { get; set; } + /// + /// Gets or sets the WebAuthn PRF decryption keys. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public WebAuthnPrfDecryptionOption? WebAuthnPrfOption { get; set; } + /// /// Gets or sets information regarding this users trusted device decryption setup. /// @@ -29,6 +35,20 @@ public class UserDecryptionOptions : ResponseModel public KeyConnectorUserDecryptionOption? KeyConnectorOption { get; set; } } +public class WebAuthnPrfDecryptionOption +{ + public string EncryptedPrivateKey { get; } + public string EncryptedUserKey { get; } + + public WebAuthnPrfDecryptionOption( + string encryptedPrivateKey, + string encryptedUserKey) + { + EncryptedPrivateKey = encryptedPrivateKey; + EncryptedUserKey = encryptedUserKey; + } +} + public class TrustedDeviceUserDecryptionOption { public bool HasAdminApproval { get; } diff --git a/src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenable.cs b/src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenable.cs new file mode 100644 index 0000000000..017033b00a --- /dev/null +++ b/src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenable.cs @@ -0,0 +1,47 @@ +using System.Text.Json.Serialization; +using Bit.Core.Auth.Enums; +using Bit.Core.Tokens; +using Fido2NetLib; + +namespace Bit.Core.Auth.Models.Business.Tokenables; + +public class WebAuthnLoginAssertionOptionsTokenable : ExpiringTokenable +{ + // Lifetime 17 minutes = + // - 6 Minutes for Attestation (max webauthn timeout) + // - 6 Minutes for PRF Assertion (max webauthn timeout) + // - 5 minutes for user to complete the process (name their passkey, etc) + private static readonly TimeSpan _tokenLifetime = TimeSpan.FromMinutes(17); + public const string ClearTextPrefix = "BWWebAuthnLoginAssertionOptions_"; + public const string DataProtectorPurpose = "WebAuthnLoginAssertionOptionsDataProtector"; + public const string TokenIdentifier = "WebAuthnLoginAssertionOptionsToken"; + + public string Identifier { get; set; } = TokenIdentifier; + public AssertionOptions Options { get; set; } + public WebAuthnLoginAssertionOptionsScope Scope { get; set; } + + [JsonConstructor] + public WebAuthnLoginAssertionOptionsTokenable() + { + ExpirationDate = DateTime.UtcNow.Add(_tokenLifetime); + } + + public WebAuthnLoginAssertionOptionsTokenable(WebAuthnLoginAssertionOptionsScope scope, AssertionOptions options) : this() + { + Scope = scope; + Options = options; + } + + public bool TokenIsValid(WebAuthnLoginAssertionOptionsScope scope) + { + if (!Valid) + { + return false; + } + + return Scope == scope; + } + + protected override bool TokenIsValid() => Identifier == TokenIdentifier && Options != null; +} + diff --git a/src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginTokenable.cs b/src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginTokenable.cs deleted file mode 100644 index b27b1fb355..0000000000 --- a/src/Core/Auth/Models/Business/Tokenables/WebAuthnLoginTokenable.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Text.Json.Serialization; -using Bit.Core.Entities; -using Bit.Core.Tokens; - -namespace Bit.Core.Auth.Models.Business.Tokenables; - -public class WebAuthnLoginTokenable : ExpiringTokenable -{ - private const double _tokenLifetimeInHours = (double)1 / 60; // 1 minute - public const string ClearTextPrefix = "BWWebAuthnLogin_"; - public const string DataProtectorPurpose = "WebAuthnLoginDataProtector"; - public const string TokenIdentifier = "WebAuthnLoginToken"; - - public string Identifier { get; set; } = TokenIdentifier; - public Guid Id { get; set; } - public string Email { get; set; } - - [JsonConstructor] - public WebAuthnLoginTokenable() - { - ExpirationDate = DateTime.UtcNow.AddHours(_tokenLifetimeInHours); - } - - public WebAuthnLoginTokenable(User user) : this() - { - Id = user?.Id ?? default; - Email = user?.Email; - } - - public bool TokenIsValid(User user) - { - if (Id == default || Email == default || user == null) - { - return false; - } - - return Id == user.Id && - Email.Equals(user.Email, StringComparison.InvariantCultureIgnoreCase); - } - - // Validates deserialized - protected override bool TokenIsValid() => Identifier == TokenIdentifier && Id != default && !string.IsNullOrWhiteSpace(Email); -} diff --git a/src/Core/Auth/Utilities/GuidUtilities.cs b/src/Core/Auth/Utilities/GuidUtilities.cs new file mode 100644 index 0000000000..043e326b12 --- /dev/null +++ b/src/Core/Auth/Utilities/GuidUtilities.cs @@ -0,0 +1,19 @@ +namespace Bit.Core.Auth.Utilities; + +public static class GuidUtilities +{ + public static bool TryParseBytes(ReadOnlySpan bytes, out Guid guid) + { + try + { + guid = new Guid(bytes); + return true; + } + catch + { + guid = Guid.Empty; + return false; + } + } +} + diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 208b431162..aea0b56fe2 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -38,6 +38,11 @@ public static class Constants /// regardless of whether there is a proration or not. /// public const string AlwaysInvoice = "always_invoice"; + + /// + /// Used by IdentityServer to identify our own provider. + /// + public const string IdentityProvider = "bitwarden"; } public static class TokenPurposes diff --git a/src/Core/Services/IUserService.cs b/src/Core/Services/IUserService.cs index 14401548b2..c9ccef661f 100644 --- a/src/Core/Services/IUserService.cs +++ b/src/Core/Services/IUserService.cs @@ -1,4 +1,5 @@ using System.Security.Claims; +using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models; using Bit.Core.Entities; @@ -29,8 +30,8 @@ public interface IUserService Task CompleteWebAuthRegistrationAsync(User user, int value, string name, AuthenticatorAttestationRawResponse attestationResponse); Task StartWebAuthnLoginRegistrationAsync(User user); Task CompleteWebAuthLoginRegistrationAsync(User user, string name, CredentialCreateOptions options, AuthenticatorAttestationRawResponse attestationResponse, bool supportsPrf, string encryptedUserKey = null, string encryptedPublicKey = null, string encryptedPrivateKey = null); - Task StartWebAuthnLoginAssertionAsync(User user); - Task CompleteWebAuthLoginAssertionAsync(AuthenticatorAssertionRawResponse assertionResponse, User user); + AssertionOptions StartWebAuthnLoginAssertion(); + Task<(User, WebAuthnCredential)> CompleteWebAuthLoginAssertionAsync(AssertionOptions options, AuthenticatorAssertionRawResponse assertionResponse); Task SendEmailVerificationAsync(User user); Task ConfirmEmailAsync(User user, string token); Task InitiateEmailChangeAsync(User user, string newEmail); diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs index 95ad5ac4c6..1d7f95f1f9 100644 --- a/src/Core/Services/Implementations/UserService.cs +++ b/src/Core/Services/Implementations/UserService.cs @@ -6,6 +6,7 @@ using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Repositories; +using Bit.Core.Auth.Utilities; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Enums; @@ -61,9 +62,8 @@ public class UserService : UserManager, IUserService, IDisposable private readonly IAcceptOrgUserCommand _acceptOrgUserCommand; private readonly IProviderUserRepository _providerUserRepository; private readonly IStripeSyncService _stripeSyncService; - private readonly IWebAuthnCredentialRepository _webAuthnCredentialRepository; - private readonly IDataProtectorTokenFactory _webAuthnLoginTokenizer; private readonly IDataProtectorTokenFactory _orgUserInviteTokenDataFactory; + private readonly IWebAuthnCredentialRepository _webAuthnCredentialRepository; public UserService( IUserRepository userRepository, @@ -96,8 +96,7 @@ public class UserService : UserManager, IUserService, IDisposable IProviderUserRepository providerUserRepository, IStripeSyncService stripeSyncService, IDataProtectorTokenFactory orgUserInviteTokenDataFactory, - IWebAuthnCredentialRepository webAuthnRepository, - IDataProtectorTokenFactory webAuthnLoginTokenizer) + IWebAuthnCredentialRepository webAuthnRepository) : base( store, optionsAccessor, @@ -136,7 +135,6 @@ public class UserService : UserManager, IUserService, IDisposable _stripeSyncService = stripeSyncService; _orgUserInviteTokenDataFactory = orgUserInviteTokenDataFactory; _webAuthnCredentialRepository = webAuthnRepository; - _webAuthnLoginTokenizer = webAuthnLoginTokenizer; } public Guid? GetProperUserId(ClaimsPrincipal principal) @@ -586,45 +584,33 @@ public class UserService : UserManager, IUserService, IDisposable return true; } - public async Task StartWebAuthnLoginAssertionAsync(User user) + public AssertionOptions StartWebAuthnLoginAssertion() { - var provider = user.GetTwoFactorProvider(TwoFactorProviderType.WebAuthn); - var existingKeys = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id); - var existingCredentials = existingKeys - .Select(k => new PublicKeyCredentialDescriptor(CoreHelpers.Base64UrlDecode(k.CredentialId))) - .ToList(); - - if (existingCredentials.Count == 0) - { - return null; - } - - // TODO: PRF? - var exts = new AuthenticationExtensionsClientInputs - { - UserVerificationMethod = true - }; - var options = _fido2.GetAssertionOptions(existingCredentials, UserVerificationRequirement.Required, exts); - - // TODO: temp save options to user record somehow - - return options; + return _fido2.GetAssertionOptions(Enumerable.Empty(), UserVerificationRequirement.Required); } - public async Task CompleteWebAuthLoginAssertionAsync(AuthenticatorAssertionRawResponse assertionResponse, User user) + public async Task<(User, WebAuthnCredential)> CompleteWebAuthLoginAssertionAsync(AssertionOptions options, AuthenticatorAssertionRawResponse assertionResponse) { - // TODO: Get options from user record somehow, then clear them - var options = AssertionOptions.FromJson(""); - - var userCredentials = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id); - var assertionId = CoreHelpers.Base64UrlEncode(assertionResponse.Id); - var credential = userCredentials.FirstOrDefault(c => c.CredentialId == assertionId); - if (credential == null) + if (!GuidUtilities.TryParseBytes(assertionResponse.Response.UserHandle, out var userId)) { - return null; + throw new BadRequestException("Invalid credential."); } - // TODO: Callback to ensure credential ID is unique. Do we care? I don't think so. + var user = await _userRepository.GetByIdAsync(userId); + if (user == null) + { + throw new BadRequestException("Invalid credential."); + } + + var userCredentials = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id); + var assertedCredentialId = CoreHelpers.Base64UrlEncode(assertionResponse.Id); + var credential = userCredentials.FirstOrDefault(c => c.CredentialId == assertedCredentialId); + if (credential == null) + { + throw new BadRequestException("Invalid credential."); + } + + // Always return true, since we've already filtered the credentials after user id IsUserHandleOwnerOfCredentialIdAsync callback = (args, cancellationToken) => Task.FromResult(true); var credentialPublicKey = CoreHelpers.Base64UrlDecode(credential.PublicKey); var assertionVerificationResult = await _fido2.MakeAssertionAsync( @@ -634,15 +620,12 @@ public class UserService : UserManager, IUserService, IDisposable credential.Counter = (int)assertionVerificationResult.Counter; await _webAuthnCredentialRepository.ReplaceAsync(credential); - if (assertionVerificationResult.Status == "ok") + if (assertionVerificationResult.Status != "ok") { - var token = _webAuthnLoginTokenizer.Protect(new WebAuthnLoginTokenable(user)); - return token; - } - else - { - return null; + throw new BadRequestException("Invalid credential."); } + + return (user, credential); } public async Task SendEmailVerificationAsync(User user) diff --git a/src/Identity/Controllers/AccountsController.cs b/src/Identity/Controllers/AccountsController.cs index 9073884d8c..a686afa533 100644 --- a/src/Identity/Controllers/AccountsController.cs +++ b/src/Identity/Controllers/AccountsController.cs @@ -1,6 +1,8 @@ using Bit.Core; +using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Api.Request.Accounts; using Bit.Core.Auth.Models.Api.Response.Accounts; +using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Services; using Bit.Core.Auth.Utilities; using Bit.Core.Enums; @@ -8,9 +10,9 @@ using Bit.Core.Exceptions; using Bit.Core.Models.Data; using Bit.Core.Repositories; using Bit.Core.Services; +using Bit.Core.Tokens; using Bit.Core.Utilities; using Bit.SharedWeb.Utilities; -using Fido2NetLib; using Microsoft.AspNetCore.Mvc; namespace Bit.Identity.Controllers; @@ -23,17 +25,21 @@ public class AccountsController : Controller private readonly IUserRepository _userRepository; private readonly IUserService _userService; private readonly ICaptchaValidationService _captchaValidationService; + private readonly IDataProtectorTokenFactory _assertionOptionsDataProtector; + public AccountsController( ILogger logger, IUserRepository userRepository, IUserService userService, - ICaptchaValidationService captchaValidationService) + ICaptchaValidationService captchaValidationService, + IDataProtectorTokenFactory assertionOptionsDataProtector) { _logger = logger; _userRepository = userRepository; _userService = userService; _captchaValidationService = captchaValidationService; + _assertionOptionsDataProtector = assertionOptionsDataProtector; } // Moved from API, If you modify this endpoint, please update API as well. Self hosted installs still use the API endpoints. @@ -75,36 +81,19 @@ public class AccountsController : Controller return new PreloginResponseModel(kdfInformation); } - [HttpPost("webauthn-assertion-options")] - [ApiExplorerSettings(IgnoreApi = true)] // Disable Swagger due to CredentialCreateOptions not converting properly + [HttpPost("webauthn/assertion-options")] [RequireFeature(FeatureFlagKeys.PasswordlessLogin)] - // TODO: Create proper models for this call - public async Task PostWebAuthnAssertionOptions([FromBody] PreloginRequestModel model) + public WebAuthnLoginAssertionOptionsResponseModel PostWebAuthnLoginAssertionOptions() { - var user = await _userRepository.GetByEmailAsync(model.Email); - if (user == null) + var options = _userService.StartWebAuthnLoginAssertion(); + + var tokenable = new WebAuthnLoginAssertionOptionsTokenable(WebAuthnLoginAssertionOptionsScope.Authentication, options); + var token = _assertionOptionsDataProtector.Protect(tokenable); + + return new WebAuthnLoginAssertionOptionsResponseModel { - // TODO: return something? possible enumeration attacks with this response - return new AssertionOptions(); - } - - var options = await _userService.StartWebAuthnLoginAssertionAsync(user); - return options; - } - - [HttpPost("webauthn-assertion")] - [RequireFeature(FeatureFlagKeys.PasswordlessLogin)] - // TODO: Create proper models for this call - public async Task PostWebAuthnAssertion([FromBody] PreloginRequestModel model) - { - var user = await _userRepository.GetByEmailAsync(model.Email); - if (user == null) - { - // TODO: proper response here? - throw new BadRequestException(); - } - - var token = await _userService.CompleteWebAuthLoginAssertionAsync(null, user); - return token; + Options = options, + Token = token + }; } } diff --git a/src/Identity/IdentityServer/ApiClient.cs b/src/Identity/IdentityServer/ApiClient.cs index 8d2a294bec..7457a8d0e9 100644 --- a/src/Identity/IdentityServer/ApiClient.cs +++ b/src/Identity/IdentityServer/ApiClient.cs @@ -13,7 +13,7 @@ public class ApiClient : Client string[] scopes = null) { ClientId = id; - AllowedGrantTypes = new[] { GrantType.ResourceOwnerPassword, GrantType.AuthorizationCode }; + AllowedGrantTypes = new[] { GrantType.ResourceOwnerPassword, GrantType.AuthorizationCode, WebAuthnGrantValidator.GrantType }; RefreshTokenExpiration = TokenExpiration.Sliding; RefreshTokenUsage = TokenUsage.ReUse; SlidingRefreshTokenLifetime = 86400 * refreshTokenSlidingDays; diff --git a/src/Identity/IdentityServer/BaseRequestValidator.cs b/src/Identity/IdentityServer/BaseRequestValidator.cs index d52d3064a6..c01dc22303 100644 --- a/src/Identity/IdentityServer/BaseRequestValidator.cs +++ b/src/Identity/IdentityServer/BaseRequestValidator.cs @@ -10,7 +10,6 @@ using Bit.Core.Auth.Models; using Bit.Core.Auth.Models.Api.Response; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Repositories; -using Bit.Core.Auth.Utilities; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Enums; @@ -23,7 +22,6 @@ using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Tokens; using Bit.Core.Utilities; -using Bit.Identity.Utilities; using IdentityServer4.Validation; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Caching.Distributed; @@ -35,7 +33,6 @@ public abstract class BaseRequestValidator where T : class private UserManager _userManager; private readonly IDeviceRepository _deviceRepository; private readonly IDeviceService _deviceService; - private readonly IUserService _userService; private readonly IEventService _eventService; private readonly IOrganizationDuoWebTokenProvider _organizationDuoWebTokenProvider; private readonly IOrganizationRepository _organizationRepository; @@ -53,6 +50,8 @@ public abstract class BaseRequestValidator where T : class protected IPolicyService PolicyService { get; } protected IFeatureService FeatureService { get; } protected ISsoConfigRepository SsoConfigRepository { get; } + protected IUserService _userService { get; } + protected IUserDecryptionOptionsBuilder UserDecryptionOptionsBuilder { get; } public BaseRequestValidator( UserManager userManager, @@ -73,7 +72,8 @@ public abstract class BaseRequestValidator where T : class IDataProtectorTokenFactory tokenDataFactory, IFeatureService featureService, ISsoConfigRepository ssoConfigRepository, - IDistributedCache distributedCache) + IDistributedCache distributedCache, + IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder) { _userManager = userManager; _deviceRepository = deviceRepository; @@ -96,11 +96,12 @@ public abstract class BaseRequestValidator where T : class _distributedCache = distributedCache; _cacheEntryOptions = new DistributedCacheEntryOptions { - // This sets the time an item is cached to 15 minutes. This value is hard coded - // to 15 because to it covers all time-out windows for both Authenticators and + // This sets the time an item is cached to 17 minutes. This value is hard coded + // to 17 because to it covers all time-out windows for both Authenticators and // Email TOTP. - AbsoluteExpirationRelativeToNow = new TimeSpan(0, 15, 0) + AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(17) }; + UserDecryptionOptionsBuilder = userDecryptionOptionsBuilder; } protected async Task ValidateAsync(T context, ValidatedTokenRequest request, @@ -333,7 +334,7 @@ public abstract class BaseRequestValidator where T : class protected abstract void SetErrorResult(T context, Dictionary customResponse); protected abstract ClaimsPrincipal GetSubject(T context); - private async Task> RequiresTwoFactorAsync(User user, ValidatedTokenRequest request) + protected virtual async Task> RequiresTwoFactorAsync(User user, ValidatedTokenRequest request) { if (request.GrantType == "client_credentials") { @@ -612,67 +613,12 @@ public abstract class BaseRequestValidator where T : class /// private async Task CreateUserDecryptionOptionsAsync(User user, Device device, ClaimsPrincipal subject) { - var ssoConfiguration = await GetSsoConfigurationDataAsync(subject); - - var userDecryptionOption = new UserDecryptionOptions - { - HasMasterPassword = !string.IsNullOrEmpty(user.MasterPassword) - }; - - var ssoConfigurationData = ssoConfiguration?.GetData(); - - if (ssoConfigurationData is { MemberDecryptionType: MemberDecryptionType.KeyConnector } && !string.IsNullOrEmpty(ssoConfigurationData.KeyConnectorUrl)) - { - // KeyConnector makes it mutually exclusive - userDecryptionOption.KeyConnectorOption = new KeyConnectorUserDecryptionOption(ssoConfigurationData.KeyConnectorUrl); - return userDecryptionOption; - } - - // Only add the trusted device specific option when the flag is turned on - if (FeatureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, CurrentContext) && ssoConfigurationData is { MemberDecryptionType: MemberDecryptionType.TrustedDeviceEncryption }) - { - string? encryptedPrivateKey = null; - string? encryptedUserKey = null; - if (device.IsTrusted()) - { - encryptedPrivateKey = device.EncryptedPrivateKey; - encryptedUserKey = device.EncryptedUserKey; - } - - var allDevices = await _deviceRepository.GetManyByUserIdAsync(user.Id); - // Checks if the current user has any devices that are capable of approving login with device requests except for - // their current device. - // NOTE: this doesn't check for if the users have configured the devices to be capable of approving requests as that is a client side setting. - var hasLoginApprovingDevice = allDevices - .Where(d => d.Identifier != device.Identifier && LoginApprovingDeviceTypes.Types.Contains(d.Type)) - .Any(); - - // Determine if user has manage reset password permission as post sso logic requires it for forcing users with this permission to set a MP - var hasManageResetPasswordPermission = false; - - // when a user is being created via JIT provisioning, they will not have any orgs so we can't assume we will have orgs here - if (CurrentContext.Organizations.Any(o => o.Id == ssoConfiguration!.OrganizationId)) - { - // TDE requires single org so grabbing first org & id is fine. - hasManageResetPasswordPermission = await CurrentContext.ManageResetPassword(ssoConfiguration!.OrganizationId); - } - - // If sso configuration data is not null then I know for sure that ssoConfiguration isn't null - var organizationUser = await _organizationUserRepository.GetByOrganizationAsync(ssoConfiguration!.OrganizationId, user.Id); - - // They are only able to be approved by an admin if they have enrolled is reset password - var hasAdminApproval = !string.IsNullOrEmpty(organizationUser.ResetPasswordKey); - - // TrustedDeviceEncryption only exists for SSO, but if that ever changes this value won't always be true - userDecryptionOption.TrustedDeviceOption = new TrustedDeviceUserDecryptionOption( - hasAdminApproval, - hasLoginApprovingDevice, - hasManageResetPasswordPermission, - encryptedPrivateKey, - encryptedUserKey); - } - - return userDecryptionOption; + var ssoConfig = await GetSsoConfigurationDataAsync(subject); + return await UserDecryptionOptionsBuilder + .ForUser(user) + .WithDevice(device) + .WithSso(ssoConfig) + .BuildAsync(); } private async Task GetSsoConfigurationDataAsync(ClaimsPrincipal subject) diff --git a/src/Identity/IdentityServer/CustomTokenRequestValidator.cs b/src/Identity/IdentityServer/CustomTokenRequestValidator.cs index a15a738372..00f563154f 100644 --- a/src/Identity/IdentityServer/CustomTokenRequestValidator.cs +++ b/src/Identity/IdentityServer/CustomTokenRequestValidator.cs @@ -44,12 +44,13 @@ public class CustomTokenRequestValidator : BaseRequestValidator tokenDataFactory, IFeatureService featureService, - IDistributedCache distributedCache) + IDistributedCache distributedCache, + IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder) : base(userManager, deviceRepository, deviceService, userService, eventService, organizationDuoWebTokenProvider, organizationRepository, organizationUserRepository, applicationCacheService, mailService, logger, currentContext, globalSettings, userRepository, policyService, tokenDataFactory, featureService, ssoConfigRepository, - distributedCache) + distributedCache, userDecryptionOptionsBuilder) { _userManager = userManager; } diff --git a/src/Identity/IdentityServer/IUserDecryptionOptionsBuilder.cs b/src/Identity/IdentityServer/IUserDecryptionOptionsBuilder.cs new file mode 100644 index 0000000000..dad9d8e27d --- /dev/null +++ b/src/Identity/IdentityServer/IUserDecryptionOptionsBuilder.cs @@ -0,0 +1,13 @@ +using Bit.Core.Auth.Entities; +using Bit.Core.Auth.Models.Api.Response; +using Bit.Core.Entities; + +namespace Bit.Identity.IdentityServer; +public interface IUserDecryptionOptionsBuilder +{ + IUserDecryptionOptionsBuilder ForUser(User user); + IUserDecryptionOptionsBuilder WithDevice(Device device); + IUserDecryptionOptionsBuilder WithSso(SsoConfig ssoConfig); + IUserDecryptionOptionsBuilder WithWebAuthnLoginCredential(WebAuthnCredential credential); + Task BuildAsync(); +} diff --git a/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs index 8b8b0be52d..52e39e64a6 100644 --- a/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs +++ b/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs @@ -1,4 +1,5 @@ using System.Security.Claims; +using Bit.Core; using Bit.Core.Auth.Identity; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Repositories; @@ -46,11 +47,12 @@ public class ResourceOwnerPasswordValidator : BaseRequestValidator tokenDataFactory, IFeatureService featureService, ISsoConfigRepository ssoConfigRepository, - IDistributedCache distributedCache) + IDistributedCache distributedCache, + IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder) : base(userManager, deviceRepository, deviceService, userService, eventService, organizationDuoWebTokenProvider, organizationRepository, organizationUserRepository, applicationCacheService, mailService, logger, currentContext, globalSettings, userRepository, policyService, - tokenDataFactory, featureService, ssoConfigRepository, distributedCache) + tokenDataFactory, featureService, ssoConfigRepository, distributedCache, userDecryptionOptionsBuilder) { _userManager = userManager; _userService = userService; @@ -144,7 +146,7 @@ public class ResourceOwnerPasswordValidator : BaseRequestValidator claims, Dictionary customResponse) { context.Result = new GrantValidationResult(user.Id.ToString(), "Application", - identityProvider: "bitwarden", + identityProvider: Constants.IdentityProvider, claims: claims.Count > 0 ? claims : null, customResponse: customResponse); return Task.CompletedTask; diff --git a/src/Identity/IdentityServer/UserDecryptionOptionsBuilder.cs b/src/Identity/IdentityServer/UserDecryptionOptionsBuilder.cs new file mode 100644 index 0000000000..4366ddbda3 --- /dev/null +++ b/src/Identity/IdentityServer/UserDecryptionOptionsBuilder.cs @@ -0,0 +1,155 @@ +using Bit.Core; +using Bit.Core.Auth.Entities; +using Bit.Core.Auth.Enums; +using Bit.Core.Auth.Models.Api.Response; +using Bit.Core.Auth.Utilities; +using Bit.Core.Context; +using Bit.Core.Entities; +using Bit.Core.Repositories; +using Bit.Core.Services; +using Bit.Identity.Utilities; + +namespace Bit.Identity.IdentityServer; + +#nullable enable +/// +/// Used to create a list of all possible ways the newly authenticated user can decrypt their vault contents +/// +/// Note: Do not use this as an injected service if you intend to build multiple independent UserDecryptionOptions +/// +public class UserDecryptionOptionsBuilder : IUserDecryptionOptionsBuilder +{ + private readonly ICurrentContext _currentContext; + private readonly IFeatureService _featureService; + private readonly IDeviceRepository _deviceRepository; + private readonly IOrganizationUserRepository _organizationUserRepository; + + private UserDecryptionOptions _options = new UserDecryptionOptions(); + private User? _user; + private Core.Auth.Entities.SsoConfig? _ssoConfig; + private Device? _device; + + public UserDecryptionOptionsBuilder( + ICurrentContext currentContext, + IFeatureService featureService, + IDeviceRepository deviceRepository, + IOrganizationUserRepository organizationUserRepository + ) + { + _currentContext = currentContext; + _featureService = featureService; + _deviceRepository = deviceRepository; + _organizationUserRepository = organizationUserRepository; + } + + public IUserDecryptionOptionsBuilder ForUser(User user) + { + _options.HasMasterPassword = user.HasMasterPassword(); + _user = user; + return this; + } + + public IUserDecryptionOptionsBuilder WithSso(Core.Auth.Entities.SsoConfig ssoConfig) + { + _ssoConfig = ssoConfig; + return this; + } + + public IUserDecryptionOptionsBuilder WithDevice(Device device) + { + _device = device; + return this; + } + + public IUserDecryptionOptionsBuilder WithWebAuthnLoginCredential(WebAuthnCredential credential) + { + if (credential.GetPrfStatus() == WebAuthnPrfStatus.Enabled) + { + _options.WebAuthnPrfOption = new WebAuthnPrfDecryptionOption(credential.EncryptedPrivateKey, credential.EncryptedUserKey); + } + return this; + } + + public async Task BuildAsync() + { + BuildKeyConnectorOptions(); + await BuildTrustedDeviceOptions(); + + return _options; + } + + private void BuildKeyConnectorOptions() + { + if (_ssoConfig == null) + { + return; + } + + var ssoConfigurationData = _ssoConfig.GetData(); + if (ssoConfigurationData is { MemberDecryptionType: MemberDecryptionType.KeyConnector } && !string.IsNullOrEmpty(ssoConfigurationData.KeyConnectorUrl)) + { + _options.KeyConnectorOption = new KeyConnectorUserDecryptionOption(ssoConfigurationData.KeyConnectorUrl); + } + } + + private async Task BuildTrustedDeviceOptions() + { + // TrustedDeviceEncryption only exists for SSO, if that changes then these guards should change + if (_ssoConfig == null || !_featureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, _currentContext)) + { + return; + } + + var ssoConfigurationData = _ssoConfig.GetData(); + if (ssoConfigurationData is not { MemberDecryptionType: MemberDecryptionType.TrustedDeviceEncryption }) + { + return; + } + + string? encryptedPrivateKey = null; + string? encryptedUserKey = null; + if (_device != null && _device.IsTrusted()) + { + encryptedPrivateKey = _device.EncryptedPrivateKey; + encryptedUserKey = _device.EncryptedUserKey; + } + + var hasLoginApprovingDevice = false; + if (_device != null && _user != null) + { + var allDevices = await _deviceRepository.GetManyByUserIdAsync(_user.Id); + // Checks if the current user has any devices that are capable of approving login with device requests except for + // their current device. + // NOTE: this doesn't check for if the users have configured the devices to be capable of approving requests as that is a client side setting. + hasLoginApprovingDevice = allDevices + .Where(d => d.Identifier != _device.Identifier && LoginApprovingDeviceTypes.Types.Contains(d.Type)) + .Any(); + } + + // Determine if user has manage reset password permission as post sso logic requires it for forcing users with this permission to set a MP + var hasManageResetPasswordPermission = false; + // when a user is being created via JIT provisioning, they will not have any orgs so we can't assume we will have orgs here + if (_currentContext.Organizations != null && _currentContext.Organizations.Any(o => o.Id == _ssoConfig.OrganizationId)) + { + // TDE requires single org so grabbing first org & id is fine. + hasManageResetPasswordPermission = await _currentContext.ManageResetPassword(_ssoConfig!.OrganizationId); + } + + var hasAdminApproval = false; + if (_user != null) + { + // If sso configuration data is not null then I know for sure that ssoConfiguration isn't null + var organizationUser = await _organizationUserRepository.GetByOrganizationAsync(_ssoConfig.OrganizationId, _user.Id); + + // They are only able to be approved by an admin if they have enrolled is reset password + hasAdminApproval = organizationUser != null && !string.IsNullOrEmpty(organizationUser.ResetPasswordKey); + } + + _options.TrustedDeviceOption = new TrustedDeviceUserDecryptionOption( + hasAdminApproval, + hasLoginApprovingDevice, + hasManageResetPasswordPermission, + encryptedPrivateKey, + encryptedUserKey); + } +} diff --git a/src/Identity/IdentityServer/WebAuthnGrantValidator.cs b/src/Identity/IdentityServer/WebAuthnGrantValidator.cs new file mode 100644 index 0000000000..8d3761d6c0 --- /dev/null +++ b/src/Identity/IdentityServer/WebAuthnGrantValidator.cs @@ -0,0 +1,150 @@ +using System.Security.Claims; +using System.Text.Json; +using Bit.Core; +using Bit.Core.Auth.Enums; +using Bit.Core.Auth.Identity; +using Bit.Core.Auth.Models.Business.Tokenables; +using Bit.Core.Auth.Repositories; +using Bit.Core.Context; +using Bit.Core.Entities; +using Bit.Core.Repositories; +using Bit.Core.Services; +using Bit.Core.Settings; +using Bit.Core.Tokens; +using Fido2NetLib; +using IdentityServer4.Models; +using IdentityServer4.Validation; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Caching.Distributed; + +namespace Bit.Identity.IdentityServer; + +public class WebAuthnGrantValidator : BaseRequestValidator, IExtensionGrantValidator +{ + public const string GrantType = "webauthn"; + + private readonly IDataProtectorTokenFactory _assertionOptionsDataProtector; + + public WebAuthnGrantValidator( + UserManager userManager, + IDeviceRepository deviceRepository, + IDeviceService deviceService, + IUserService userService, + IEventService eventService, + IOrganizationDuoWebTokenProvider organizationDuoWebTokenProvider, + IOrganizationRepository organizationRepository, + IOrganizationUserRepository organizationUserRepository, + IApplicationCacheService applicationCacheService, + IMailService mailService, + ILogger logger, + ICurrentContext currentContext, + GlobalSettings globalSettings, + ISsoConfigRepository ssoConfigRepository, + IUserRepository userRepository, + IPolicyService policyService, + IDataProtectorTokenFactory tokenDataFactory, + IDataProtectorTokenFactory assertionOptionsDataProtector, + IFeatureService featureService, + IDistributedCache distributedCache, + IUserDecryptionOptionsBuilder userDecryptionOptionsBuilder + ) + : base(userManager, deviceRepository, deviceService, userService, eventService, + organizationDuoWebTokenProvider, organizationRepository, organizationUserRepository, + applicationCacheService, mailService, logger, currentContext, globalSettings, + userRepository, policyService, tokenDataFactory, featureService, ssoConfigRepository, distributedCache, userDecryptionOptionsBuilder) + { + _assertionOptionsDataProtector = assertionOptionsDataProtector; + } + + string IExtensionGrantValidator.GrantType => "webauthn"; + + public async Task ValidateAsync(ExtensionGrantValidationContext context) + { + if (!FeatureService.IsEnabled(FeatureFlagKeys.PasswordlessLogin, CurrentContext)) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); + return; + } + + var rawToken = context.Request.Raw.Get("token"); + var rawDeviceResponse = context.Request.Raw.Get("deviceResponse"); + if (string.IsNullOrWhiteSpace(rawToken) || string.IsNullOrWhiteSpace(rawDeviceResponse)) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); + return; + } + + var verified = _assertionOptionsDataProtector.TryUnprotect(rawToken, out var token) && + token.TokenIsValid(WebAuthnLoginAssertionOptionsScope.Authentication); + var deviceResponse = JsonSerializer.Deserialize(rawDeviceResponse); + + if (!verified) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest); + return; + } + + var (user, credential) = await _userService.CompleteWebAuthLoginAssertionAsync(token.Options, deviceResponse); + var validatorContext = new CustomValidatorRequestContext + { + User = user, + KnownDevice = await KnownDeviceAsync(user, context.Request) + }; + + UserDecryptionOptionsBuilder.WithWebAuthnLoginCredential(credential); + + await ValidateAsync(context, context.Request, validatorContext); + } + + protected override Task ValidateContextAsync(ExtensionGrantValidationContext context, + CustomValidatorRequestContext validatorContext) + { + if (validatorContext.User == null) + { + return Task.FromResult(false); + } + + return Task.FromResult(true); + } + + protected override Task SetSuccessResult(ExtensionGrantValidationContext context, User user, + List claims, Dictionary customResponse) + { + context.Result = new GrantValidationResult(user.Id.ToString(), "Application", + identityProvider: Constants.IdentityProvider, + claims: claims.Count > 0 ? claims : null, + customResponse: customResponse); + return Task.CompletedTask; + } + + protected override ClaimsPrincipal GetSubject(ExtensionGrantValidationContext context) + { + return context.Result.Subject; + } + + protected override Task> RequiresTwoFactorAsync(User user, ValidatedTokenRequest request) + { + // We consider Fido2 userVerification a second factor, so we don't require a second factor here. + return Task.FromResult(new Tuple(false, null)); + } + + protected override void SetTwoFactorResult(ExtensionGrantValidationContext context, + Dictionary customResponse) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Two factor required.", + customResponse); + } + + protected override void SetSsoResult(ExtensionGrantValidationContext context, + Dictionary customResponse) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Sso authentication required.", + customResponse); + } + + protected override void SetErrorResult(ExtensionGrantValidationContext context, + Dictionary customResponse) + { + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, customResponse: customResponse); + } +} diff --git a/src/Identity/Utilities/ServiceCollectionExtensions.cs b/src/Identity/Utilities/ServiceCollectionExtensions.cs index 068e12bd40..53b9c49e90 100644 --- a/src/Identity/Utilities/ServiceCollectionExtensions.cs +++ b/src/Identity/Utilities/ServiceCollectionExtensions.cs @@ -17,6 +17,7 @@ public static class ServiceCollectionExtensions services.AddSingleton(); services.AddTransient(); + services.AddTransient(); var issuerUri = new Uri(globalSettings.BaseServiceUri.InternalIdentity); var identityServerBuilder = services @@ -44,7 +45,8 @@ public static class ServiceCollectionExtensions .AddResourceOwnerValidator() .AddPersistedGrantStore() .AddClientStore() - .AddIdentityServerCertificate(env, globalSettings); + .AddIdentityServerCertificate(env, globalSettings) + .AddExtensionGrantValidator(); services.AddTransient(); return identityServerBuilder; diff --git a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs index c12c849e37..2a2a06efe0 100644 --- a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs +++ b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs @@ -168,18 +168,18 @@ public static class ServiceCollectionExtensions SsoTokenable.DataProtectorPurpose, serviceProvider.GetDataProtectionProvider(), serviceProvider.GetRequiredService>>())); - services.AddSingleton>(serviceProvider => - new DataProtectorTokenFactory( - WebAuthnLoginTokenable.ClearTextPrefix, - WebAuthnLoginTokenable.DataProtectorPurpose, - serviceProvider.GetDataProtectionProvider(), - serviceProvider.GetRequiredService>>())); services.AddSingleton>(serviceProvider => new DataProtectorTokenFactory( WebAuthnCredentialCreateOptionsTokenable.ClearTextPrefix, WebAuthnCredentialCreateOptionsTokenable.DataProtectorPurpose, serviceProvider.GetDataProtectionProvider(), serviceProvider.GetRequiredService>>())); + services.AddSingleton>(serviceProvider => + new DataProtectorTokenFactory( + WebAuthnLoginAssertionOptionsTokenable.ClearTextPrefix, + WebAuthnLoginAssertionOptionsTokenable.DataProtectorPurpose, + serviceProvider.GetDataProtectionProvider(), + serviceProvider.GetRequiredService>>())); services.AddSingleton>(serviceProvider => new DataProtectorTokenFactory( SsoEmail2faSessionTokenable.ClearTextPrefix, diff --git a/test/Core.Test/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenableTests.cs b/test/Core.Test/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenableTests.cs new file mode 100644 index 0000000000..3978fef0f4 --- /dev/null +++ b/test/Core.Test/Auth/Models/Business/Tokenables/WebAuthnLoginAssertionOptionsTokenableTests.cs @@ -0,0 +1,61 @@ +using Bit.Core.Auth.Enums; +using Bit.Core.Auth.Models.Business.Tokenables; +using Bit.Test.Common.AutoFixture.Attributes; +using Fido2NetLib; +using Xunit; + +namespace Bit.Core.Test.Auth.Models.Business.Tokenables; + +public class WebAuthnLoginAssertionOptionsTokenableTests +{ + [Theory, BitAutoData] + public void Valid_TokenWithoutOptions_ReturnsFalse(WebAuthnLoginAssertionOptionsScope scope) + { + var token = new WebAuthnLoginAssertionOptionsTokenable(scope, null); + + var isValid = token.Valid; + + Assert.False(isValid); + } + + [Theory, BitAutoData] + public void Valid_NewlyCreatedToken_ReturnsTrue(WebAuthnLoginAssertionOptionsScope scope, AssertionOptions createOptions) + { + var token = new WebAuthnLoginAssertionOptionsTokenable(scope, createOptions); + + + var isValid = token.Valid; + + Assert.True(isValid); + } + + [Theory, BitAutoData] + public void ValidIsValid_TokenWithoutOptions_ReturnsFalse(WebAuthnLoginAssertionOptionsScope scope) + { + var token = new WebAuthnLoginAssertionOptionsTokenable(scope, null); + + var isValid = token.TokenIsValid(scope); + + Assert.False(isValid); + } + + [Theory, BitAutoData] + public void ValidIsValid_NonMatchingScope_ReturnsFalse(WebAuthnLoginAssertionOptionsScope scope1, WebAuthnLoginAssertionOptionsScope scope2, AssertionOptions createOptions) + { + var token = new WebAuthnLoginAssertionOptionsTokenable(scope1, createOptions); + + var isValid = token.TokenIsValid(scope2); + + Assert.False(isValid); + } + + [Theory, BitAutoData] + public void ValidIsValid_SameScope_ReturnsTrue(WebAuthnLoginAssertionOptionsScope scope, AssertionOptions createOptions) + { + var token = new WebAuthnLoginAssertionOptionsTokenable(scope, createOptions); + + var isValid = token.TokenIsValid(scope); + + Assert.True(isValid); + } +} diff --git a/test/Core.Test/Services/UserServiceTests.cs b/test/Core.Test/Services/UserServiceTests.cs index 724532f3c5..c3bd1b2830 100644 --- a/test/Core.Test/Services/UserServiceTests.cs +++ b/test/Core.Test/Services/UserServiceTests.cs @@ -1,4 +1,5 @@ -using System.Text.Json; +using System.Text; +using System.Text.Json; using AutoFixture; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Auth.Entities; @@ -8,26 +9,29 @@ using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Repositories; using Bit.Core.Context; using Bit.Core.Entities; +using Bit.Core.Exceptions; using Bit.Core.Models.Business; using Bit.Core.Models.Data.Organizations; using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; -using Bit.Core.Tokens; using Bit.Core.Tools.Services; +using Bit.Core.Utilities; using Bit.Core.Vault.Repositories; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Fakes; using Bit.Test.Common.Helpers; using Fido2NetLib; +using Fido2NetLib.Objects; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NSubstitute; using NSubstitute.ReceivedExtensions; +using NSubstitute.ReturnsExtensions; using Xunit; namespace Bit.Core.Test.Services; @@ -188,7 +192,7 @@ public class UserServiceTests } [Theory, BitAutoData] - public async void CompleteWebAuthLoginRegistrationAsync_ExceedsExistingCredentialsLimit_ReturnsFalse(SutProvider sutProvider, User user, CredentialCreateOptions options, AuthenticatorAttestationRawResponse response, Generator credentialGenerator) + public async Task CompleteWebAuthLoginRegistrationAsync_ExceedsExistingCredentialsLimit_ReturnsFalse(SutProvider sutProvider, User user, CredentialCreateOptions options, AuthenticatorAttestationRawResponse response, Generator credentialGenerator) { // Arrange var existingCredentials = credentialGenerator.Take(5).ToList(); @@ -202,6 +206,92 @@ public class UserServiceTests sutProvider.GetDependency().DidNotReceive(); } + [Theory, BitAutoData] + public async Task CompleteWebAuthLoginAssertionAsync_InvalidUserHandle_ThrowsBadRequestException(SutProvider sutProvider, AssertionOptions options, AuthenticatorAssertionRawResponse response) + { + // Arrange + response.Response.UserHandle = Encoding.UTF8.GetBytes("invalid-user-handle"); + + // Act + var result = async () => await sutProvider.Sut.CompleteWebAuthLoginAssertionAsync(options, response); + + // Assert + await Assert.ThrowsAsync(result); + } + + [Theory, BitAutoData] + public async Task CompleteWebAuthLoginAssertionAsync_UserNotFound_ThrowsBadRequestException(SutProvider sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response) + { + // Arrange + response.Response.UserHandle = user.Id.ToByteArray(); + sutProvider.GetDependency().GetByIdAsync(user.Id).ReturnsNull(); + + // Act + var result = async () => await sutProvider.Sut.CompleteWebAuthLoginAssertionAsync(options, response); + + // Assert + await Assert.ThrowsAsync(result); + } + + [Theory, BitAutoData] + public async Task CompleteWebAuthLoginAssertionAsync_NoMatchingCredentialExists_ThrowsBadRequestException(SutProvider sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response) + { + // Arrange + response.Response.UserHandle = user.Id.ToByteArray(); + sutProvider.GetDependency().GetByIdAsync(user.Id).Returns(user); + sutProvider.GetDependency().GetManyByUserIdAsync(user.Id).Returns(new WebAuthnCredential[] { }); + + // Act + var result = async () => await sutProvider.Sut.CompleteWebAuthLoginAssertionAsync(options, response); + + // Assert + await Assert.ThrowsAsync(result); + } + + [Theory, BitAutoData] + public async Task CompleteWebAuthLoginAssertionAsync_AssertionFails_ThrowsBadRequestException(SutProvider sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response, WebAuthnCredential credential, AssertionVerificationResult assertionResult) + { + // Arrange + var credentialId = Guid.NewGuid().ToByteArray(); + credential.CredentialId = CoreHelpers.Base64UrlEncode(credentialId); + response.Id = credentialId; + response.Response.UserHandle = user.Id.ToByteArray(); + assertionResult.Status = "Not ok"; + sutProvider.GetDependency().GetByIdAsync(user.Id).Returns(user); + sutProvider.GetDependency().GetManyByUserIdAsync(user.Id).Returns(new WebAuthnCredential[] { credential }); + sutProvider.GetDependency().MakeAssertionAsync(response, options, Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(assertionResult); + + // Act + var result = async () => await sutProvider.Sut.CompleteWebAuthLoginAssertionAsync(options, response); + + // Assert + await Assert.ThrowsAsync(result); + } + + [Theory, BitAutoData] + public async Task CompleteWebAuthLoginAssertionAsync_AssertionSucceeds_ReturnsUserAndCredential(SutProvider sutProvider, User user, AssertionOptions options, AuthenticatorAssertionRawResponse response, WebAuthnCredential credential, AssertionVerificationResult assertionResult) + { + // Arrange + var credentialId = Guid.NewGuid().ToByteArray(); + credential.CredentialId = CoreHelpers.Base64UrlEncode(credentialId); + response.Id = credentialId; + response.Response.UserHandle = user.Id.ToByteArray(); + assertionResult.Status = "ok"; + sutProvider.GetDependency().GetByIdAsync(user.Id).Returns(user); + sutProvider.GetDependency().GetManyByUserIdAsync(user.Id).Returns(new WebAuthnCredential[] { credential }); + sutProvider.GetDependency().MakeAssertionAsync(response, options, Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(assertionResult); + + // Act + var result = await sutProvider.Sut.CompleteWebAuthLoginAssertionAsync(options, response); + + // Assert + var (userResult, credentialResult) = result; + Assert.Equal(user, userResult); + Assert.Equal(credential, credentialResult); + } + [Flags] public enum ShouldCheck { @@ -278,8 +368,7 @@ public class UserServiceTests sutProvider.GetDependency(), sutProvider.GetDependency(), new FakeDataProtectorTokenFactory(), - sutProvider.GetDependency(), - sutProvider.GetDependency>() + sutProvider.GetDependency() ); var actualIsVerified = await sut.VerifySecretAsync(user, secret); diff --git a/test/Identity.IntegrationTest/openid-configuration.json b/test/Identity.IntegrationTest/openid-configuration.json index 9442330da7..97e8105f48 100644 --- a/test/Identity.IntegrationTest/openid-configuration.json +++ b/test/Identity.IntegrationTest/openid-configuration.json @@ -38,7 +38,8 @@ "refresh_token", "implicit", "password", - "urn:ietf:params:oauth:grant-type:device_code" + "urn:ietf:params:oauth:grant-type:device_code", + "webauthn" ], "response_types_supported": [ "code", @@ -49,24 +50,13 @@ "code token", "code id_token token" ], - "response_modes_supported": [ - "form_post", - "query", - "fragment" - ], + "response_modes_supported": ["form_post", "query", "fragment"], "token_endpoint_auth_methods_supported": [ "client_secret_basic", "client_secret_post" ], - "id_token_signing_alg_values_supported": [ - "RS256" - ], - "subject_types_supported": [ - "public" - ], - "code_challenge_methods_supported": [ - "plain", - "S256" - ], + "id_token_signing_alg_values_supported": ["RS256"], + "subject_types_supported": ["public"], + "code_challenge_methods_supported": ["plain", "S256"], "request_parameter_supported": true } diff --git a/test/Identity.Test/Controllers/AccountsControllerTests.cs b/test/Identity.Test/Controllers/AccountsControllerTests.cs index 32473593dc..3d94fd54ba 100644 --- a/test/Identity.Test/Controllers/AccountsControllerTests.cs +++ b/test/Identity.Test/Controllers/AccountsControllerTests.cs @@ -1,4 +1,5 @@ using Bit.Core.Auth.Models.Api.Request.Accounts; +using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Services; using Bit.Core.Entities; using Bit.Core.Enums; @@ -6,6 +7,7 @@ using Bit.Core.Exceptions; using Bit.Core.Models.Data; using Bit.Core.Repositories; using Bit.Core.Services; +using Bit.Core.Tokens; using Bit.Identity.Controllers; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; @@ -22,6 +24,7 @@ public class AccountsControllerTests : IDisposable private readonly IUserRepository _userRepository; private readonly IUserService _userService; private readonly ICaptchaValidationService _captchaValidationService; + private readonly IDataProtectorTokenFactory _assertionOptionsDataProtector; public AccountsControllerTests() { @@ -29,11 +32,13 @@ public class AccountsControllerTests : IDisposable _userRepository = Substitute.For(); _userService = Substitute.For(); _captchaValidationService = Substitute.For(); + _assertionOptionsDataProtector = Substitute.For>(); _sut = new AccountsController( _logger, _userRepository, _userService, - _captchaValidationService + _captchaValidationService, + _assertionOptionsDataProtector ); } diff --git a/test/Identity.Test/IdentityServer/UserDecryptionOptionsBuilderTests.cs b/test/Identity.Test/IdentityServer/UserDecryptionOptionsBuilderTests.cs new file mode 100644 index 0000000000..604c7709b7 --- /dev/null +++ b/test/Identity.Test/IdentityServer/UserDecryptionOptionsBuilderTests.cs @@ -0,0 +1,172 @@ +using Bit.Core; +using Bit.Core.Auth.Entities; +using Bit.Core.Auth.Enums; +using Bit.Core.Auth.Models.Data; +using Bit.Core.Context; +using Bit.Core.Entities; +using Bit.Core.Repositories; +using Bit.Core.Services; +using Bit.Identity.IdentityServer; +using Bit.Identity.Utilities; +using Bit.Test.Common.AutoFixture.Attributes; +using NSubstitute; +using Xunit; + +namespace Bit.Identity.Test.IdentityServer; + +public class UserDecryptionOptionsBuilderTests +{ + private readonly ICurrentContext _currentContext; + private readonly IFeatureService _featureService; + private readonly IDeviceRepository _deviceRepository; + private readonly IOrganizationUserRepository _organizationUserRepository; + private readonly UserDecryptionOptionsBuilder _builder; + + public UserDecryptionOptionsBuilderTests() + { + _currentContext = Substitute.For(); + _featureService = Substitute.For(); + _deviceRepository = Substitute.For(); + _organizationUserRepository = Substitute.For(); + _builder = new UserDecryptionOptionsBuilder(_currentContext, _featureService, _deviceRepository, _organizationUserRepository); + } + + [Theory] + [BitAutoData(true, true, true)] // All keys are non-null + [BitAutoData(false, false, false)] // All keys are null + [BitAutoData(false, false, true)] // EncryptedUserKey is non-null, others are null + [BitAutoData(false, true, false)] // EncryptedPublicKey is non-null, others are null + [BitAutoData(true, false, false)] // EncryptedPrivateKey is non-null, others are null + [BitAutoData(true, false, true)] // EncryptedPrivateKey and EncryptedUserKey are non-null, EncryptedPublicKey is null + [BitAutoData(true, true, false)] // EncryptedPrivateKey and EncryptedPublicKey are non-null, EncryptedUserKey is null + [BitAutoData(false, true, true)] // EncryptedPublicKey and EncryptedUserKey are non-null, EncryptedPrivateKey is null + public async Task WithWebAuthnLoginCredential_VariousKeyCombinations_ShouldReturnCorrectPrfOption( + bool hasEncryptedPrivateKey, + bool hasEncryptedPublicKey, + bool hasEncryptedUserKey, + WebAuthnCredential credential) + { + credential.EncryptedPrivateKey = hasEncryptedPrivateKey ? "encryptedPrivateKey" : null; + credential.EncryptedPublicKey = hasEncryptedPublicKey ? "encryptedPublicKey" : null; + credential.EncryptedUserKey = hasEncryptedUserKey ? "encryptedUserKey" : null; + + var result = await _builder.WithWebAuthnLoginCredential(credential).BuildAsync(); + + if (credential.GetPrfStatus() == WebAuthnPrfStatus.Enabled) + { + Assert.NotNull(result.WebAuthnPrfOption); + Assert.Equal(credential.EncryptedPrivateKey, result.WebAuthnPrfOption!.EncryptedPrivateKey); + Assert.Equal(credential.EncryptedUserKey, result.WebAuthnPrfOption!.EncryptedUserKey); + } + else + { + Assert.Null(result.WebAuthnPrfOption); + } + } + + [Theory, BitAutoData] + public async Task Build_WhenKeyConnectorIsEnabled_ShouldReturnKeyConnectorOptions(SsoConfig ssoConfig, SsoConfigurationData configurationData) + { + configurationData.MemberDecryptionType = MemberDecryptionType.KeyConnector; + ssoConfig.Data = configurationData.Serialize(); + + var result = await _builder.WithSso(ssoConfig).BuildAsync(); + + Assert.NotNull(result.KeyConnectorOption); + Assert.Equal(configurationData.KeyConnectorUrl, result.KeyConnectorOption!.KeyConnectorUrl); + } + + [Theory, BitAutoData] + public async Task Build_WhenTrustedDeviceIsEnabled_ShouldReturnTrustedDeviceOptions(SsoConfig ssoConfig, SsoConfigurationData configurationData, Device device) + { + _featureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, _currentContext).Returns(true); + configurationData.MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption; + ssoConfig.Data = configurationData.Serialize(); + + var result = await _builder.WithSso(ssoConfig).WithDevice(device).BuildAsync(); + + Assert.NotNull(result.TrustedDeviceOption); + Assert.False(result.TrustedDeviceOption!.HasAdminApproval); + Assert.False(result.TrustedDeviceOption!.HasLoginApprovingDevice); + Assert.False(result.TrustedDeviceOption!.HasManageResetPasswordPermission); + } + + // TODO: Remove when FeatureFlagKeys.TrustedDeviceEncryption is removed + [Theory, BitAutoData] + public async Task Build_WhenTrustedDeviceIsEnabledButFeatureFlagIsDisabled_ShouldNotReturnTrustedDeviceOptions(SsoConfig ssoConfig, SsoConfigurationData configurationData, Device device) + { + _featureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, _currentContext).Returns(false); + configurationData.MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption; + ssoConfig.Data = configurationData.Serialize(); + + var result = await _builder.WithSso(ssoConfig).WithDevice(device).BuildAsync(); + + Assert.Null(result.TrustedDeviceOption); + } + + [Theory, BitAutoData] + public async Task Build_WhenDeviceIsTrusted_ShouldReturnKeys(SsoConfig ssoConfig, SsoConfigurationData configurationData, Device device) + { + _featureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, _currentContext).Returns(true); + configurationData.MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption; + ssoConfig.Data = configurationData.Serialize(); + device.EncryptedPrivateKey = "encryptedPrivateKey"; + device.EncryptedPublicKey = "encryptedPublicKey"; + device.EncryptedUserKey = "encryptedUserKey"; + + var result = await _builder.WithSso(ssoConfig).WithDevice(device).BuildAsync(); + + Assert.Equal(device.EncryptedPrivateKey, result.TrustedDeviceOption?.EncryptedPrivateKey); + Assert.Equal(device.EncryptedUserKey, result.TrustedDeviceOption?.EncryptedUserKey); + } + + [Theory, BitAutoData] + public async Task Build_WhenHasLoginApprovingDevice_ShouldApprovingDeviceTrue(SsoConfig ssoConfig, SsoConfigurationData configurationData, User user, Device device, Device approvingDevice) + { + _featureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, _currentContext).Returns(true); + configurationData.MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption; + ssoConfig.Data = configurationData.Serialize(); + approvingDevice.Type = LoginApprovingDeviceTypes.Types.First(); + _deviceRepository.GetManyByUserIdAsync(user.Id).Returns(new Device[] { approvingDevice }); + + var result = await _builder.ForUser(user).WithSso(ssoConfig).WithDevice(device).BuildAsync(); + + Assert.True(result.TrustedDeviceOption?.HasLoginApprovingDevice); + } + + [Theory, BitAutoData] + public async Task Build_WhenManageResetPasswordPermissions_ShouldReturnHasManageResetPasswordPermissionTrue( + SsoConfig ssoConfig, + SsoConfigurationData configurationData, + CurrentContextOrganization organization) + { + _featureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, _currentContext).Returns(true); + configurationData.MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption; + ssoConfig.Data = configurationData.Serialize(); + ssoConfig.OrganizationId = organization.Id; + _currentContext.Organizations.Returns(new List(new CurrentContextOrganization[] { organization })); + _currentContext.ManageResetPassword(organization.Id).Returns(true); + + var result = await _builder.WithSso(ssoConfig).BuildAsync(); + + Assert.True(result.TrustedDeviceOption?.HasManageResetPasswordPermission); + } + + [Theory, BitAutoData] + public async Task Build_WhenUserHasEnrolledIntoPasswordReset_ShouldReturnHasAdminApprovalTrue( + SsoConfig ssoConfig, + SsoConfigurationData configurationData, + OrganizationUser organizationUser, + User user) + { + _featureService.IsEnabled(FeatureFlagKeys.TrustedDeviceEncryption, _currentContext).Returns(true); + configurationData.MemberDecryptionType = MemberDecryptionType.TrustedDeviceEncryption; + ssoConfig.Data = configurationData.Serialize(); + organizationUser.ResetPasswordKey = "resetPasswordKey"; + _organizationUserRepository.GetByOrganizationAsync(ssoConfig.OrganizationId, user.Id).Returns(organizationUser); + + var result = await _builder.ForUser(user).WithSso(ssoConfig).BuildAsync(); + + Assert.True(result.TrustedDeviceOption?.HasAdminApproval); + } +} From 04253d9bca651b9cf4023ac51a621aaa720bda2f Mon Sep 17 00:00:00 2001 From: Colton Hurst Date: Mon, 20 Nov 2023 12:36:02 -0500 Subject: [PATCH 05/20] SM-1010: Turn off secrets manager beta with a new migration (#3451) --- .../2023-11-15_00_TurnOffSecretsManagerBeta.sql | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 util/Migrator/DbScripts/2023-11-15_00_TurnOffSecretsManagerBeta.sql diff --git a/util/Migrator/DbScripts/2023-11-15_00_TurnOffSecretsManagerBeta.sql b/util/Migrator/DbScripts/2023-11-15_00_TurnOffSecretsManagerBeta.sql new file mode 100644 index 0000000000..b242d977b6 --- /dev/null +++ b/util/Migrator/DbScripts/2023-11-15_00_TurnOffSecretsManagerBeta.sql @@ -0,0 +1,16 @@ +IF COL_LENGTH('[dbo].[Organization]', 'SecretsManagerBeta') IS NOT NULL +BEGIN + -- Set AccessSecretsManager to 0 for Organization Users in SM Beta orgs + UPDATE [dbo].[OrganizationUser] + SET AccessSecretsManager = 0 + FROM [dbo].[OrganizationUser] AS ou + INNER JOIN [dbo].[Organization] AS o ON ou.OrganizationId = o.Id + WHERE o.SecretsManagerBeta = 1 AND ou.AccessSecretsManager = 1 + + -- Set UseSecretsManager and SecretsManagerBeta to 0 for Organizations in SM Beta + UPDATE [dbo].[Organization] + SET UseSecretsManager = 0, SecretsManagerBeta = 0 + FROM [dbo].[Organization] AS o + WHERE o.SecretsManagerBeta = 1 +END +GO From c8fd81a10e10148727d76386700bf5cd67e9dcc2 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Mon, 20 Nov 2023 13:26:36 -0500 Subject: [PATCH 06/20] Prefer compounds for preLaunchTasks (#3446) --- .vscode/launch.json | 292 +++++++++++++++++++++++++++++++------------- .vscode/tasks.json | 59 +++++++++ 2 files changed, 264 insertions(+), 87 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 564c94e6f3..e260116a24 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,94 +7,251 @@ { "name": "Min Server", "configurations": [ - "Identity", - "API" + "run-Identity", + "run-API" ], "presentation": { "hidden": false, "group": "AA_compounds", "order": 1 }, + "preLaunchTask": "buildIdentityApi", "stopAll": true }, { "name": "Admin, API, Identity", "configurations": [ - "Admin", - "API", - "Identity" + "run-Admin", + "run-API", + "run-Identity" ], "presentation": { "hidden": false, "group": "AA_compounds", "order": 3 }, + "preLaunchTask": "buildIdentityApiAdmin", "stopAll": true }, { "name": "Full Server", "configurations": [ - "Admin", - "API", - "EventsProcessor", - "Identity", - "Sso", - "Icons", - "Billing", - "Notifications" + "run-Admin", + "run-API", + "run-EventsProcessor", + "run-Identity", + "run-Sso", + "run-Icons", + "run-Billing", + "run-Notifications" ], "presentation": { "hidden": false, "group": "AA_compounds", "order": 4 }, + "preLaunchTask": "buildFullServer", "stopAll": true }, { "name": "Self Host: Bit", "configurations": [ - "Admin-SelfHost", - "API-SelfHost", - "EventsProcessor-SelfHost", - "Identity-SelfHost", - "Sso-SelfHost", - "Notifications-SelfHost" + "run-Admin-SelfHost", + "run-API-SelfHost", + "run-EventsProcessor-SelfHost", + "run-Identity-SelfHost", + "run-Sso-SelfHost", + "run-Notifications-SelfHost" ], "presentation": { "hidden": false, "group": "AA_compounds", "order": 2 }, + "preLaunchTask": "buildSelfHostBit", "stopAll": true }, { "name": "Self Host: OSS", "configurations": [ - "Admin-SelfHost", - "API-SelfHost", - "EventsProcessor-SelfHost", - "Identity-SelfHost", + "run-Admin-SelfHost", + "run-API-SelfHost", + "run-EventsProcessor-SelfHost", + "run-Identity-SelfHost", ], "presentation": { "hidden": false, "group": "AA_compounds", "order": 99 }, + "preLaunchTask": "buildSelfHostOss", "stopAll": true - } - ], - "configurations": [ + }, { - "name": "Identity", + "name": "Admin", + "configurations": [ + "run-Admin" + ], "presentation": { "hidden": false, "group": "cloud", - "order": 10 + }, + "preLaunchTask": "buildAdmin", + }, + { + "name": "API", + "configurations": [ + "run-API" + ], + "presentation": { + "hidden": false, + "group": "cloud", + }, + "preLaunchTask": "buildAPI", + }, + { + "name": "Billing", + "configurations": [ + "run-Billing" + ], + "presentation": { + "hidden": false, + "group": "cloud", + }, + "preLaunchTask": "buildBilling", + }, + { + "name": "Events Processor", + "configurations": [ + "run-EventsProcessor" + ], + "presentation": { + "hidden": false, + "group": "cloud", + }, + "preLaunchTask": "buildEventsProcessor", + }, + { + "name": "Icons", + "configurations": [ + "run-Icons" + ], + "presentation": { + "hidden": false, + "group": "cloud", + }, + "preLaunchTask": "buildIcons", + }, + { + "name": "Identity", + "configurations": [ + "run-Identity" + ], + "presentation": { + "hidden": false, + "group": "cloud", + }, + "preLaunchTask": "buildIdentity", + }, + { + "name": "Notifications", + "configurations": [ + "run-Notifications" + ], + "presentation": { + "hidden": false, + "group": "cloud", + }, + "preLaunchTask": "buildNotifications", + }, + { + "name": "SSO", + "configurations": [ + "run-Sso" + ], + "presentation": { + "hidden": false, + "group": "cloud", + }, + "preLaunchTask": "buildSso", + }, + { + "name": "Admin Self Host", + "configurations": [ + "run-Admin-SelfHost" + ], + "presentation": { + "hidden": false, + "group": "self-host", + }, + "preLaunchTask": "buildAdmin", + }, + { + "name": "API Self Host", + "configurations": [ + "run-API-SelfHost" + ], + "presentation": { + "hidden": false, + "group": "self-host", + }, + "preLaunchTask": "buildAPI", + }, + { + "name": "Events Processor Self Host", + "configurations": [ + "run-EventsProcessor-SelfHost" + ], + "presentation": { + "hidden": false, + "group": "self-host", + }, + "preLaunchTask": "buildEventsProcessor", + }, + { + "name": "Identity Self Host", + "configurations": [ + "run-Identity-SelfHost" + ], + "presentation": { + "hidden": false, + "group": "self-host", + }, + "preLaunchTask": "buildIdentity", + }, + { + "name": "Notifications Self Host", + "configurations": [ + "run-Notifications-SelfHost" + ], + "presentation": { + "hidden": false, + "group": "self-host", + }, + "preLaunchTask": "buildNotifications", + }, + { + "name": "SSO Self Host", + "configurations": [ + "run-Sso-SelfHost" + ], + "presentation": { + "hidden": false, + "group": "self-host", + }, + "preLaunchTask": "buildSso", + }, + ], + "configurations": [ + // Configurations represent run-only scenarios so that they can be used in multiple compounds + { + "name": "run-Identity", + "presentation": { + "hidden": true, }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildIdentity", "program": "${workspaceFolder}/src/Identity/bin/Debug/net6.0/Identity.dll", "args": [], "cwd": "${workspaceFolder}/src/Identity", @@ -107,16 +264,13 @@ } }, { - "name": "API", + "name": "run-API", "presentation": { - "hidden": false, - "group": "cloud", - "order": 10 + "hidden": true, }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildAPI", "program": "${workspaceFolder}/src/Api/bin/Debug/net6.0/Api.dll", "args": [], "cwd": "${workspaceFolder}/src/Api", @@ -129,16 +283,13 @@ } }, { - "name": "Billing", + "name": "run-Billing", "presentation": { - "hidden": false, - "group": "cloud", - "order": 10 + "hidden": true, }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildBilling", "program": "${workspaceFolder}/src/Billing/bin/Debug/net6.0/Billing.dll", "args": [], "cwd": "${workspaceFolder}/src/Billing", @@ -151,16 +302,13 @@ } }, { - "name": "Admin", + "name": "run-Admin", "presentation": { - "hidden": false, - "group": "cloud", - "order": 20 + "hidden": true, }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildAdmin", "OS-COMMENT4": "If you have changed target frameworks, make sure to update the program path.", "program": "${workspaceFolder}/src/Admin/bin/Debug/net6.0/Admin.dll", "args": [], @@ -175,16 +323,13 @@ } }, { - "name": "Sso", + "name": "run-Sso", "presentation": { - "hidden": false, - "group": "cloud", - "order": 50 + "hidden": true, }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildSso", "program": "${workspaceFolder}/bitwarden_license/src/Sso/bin/Debug/net6.0/Sso.dll", "args": [], "cwd": "${workspaceFolder}/bitwarden_license/src/Sso", @@ -197,16 +342,13 @@ } }, { - "name": "EventsProcessor", + "name": "run-EventsProcessor", "presentation": { - "hidden": false, - "group": "cloud", - "order": 90 + "hidden": true, }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildEventsProcessor", "program": "${workspaceFolder}/src/EventsProcessor/bin/Debug/net6.0/EventsProcessor.dll", "args": [], "cwd": "${workspaceFolder}/src/EventsProcessor", @@ -219,16 +361,13 @@ } }, { - "name": "Icons", + "name": "run-Icons", "presentation": { - "hidden": false, - "group": "cloud", - "order": 90 + "hidden": true, }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildIcons", "program": "${workspaceFolder}/src/Icons/bin/Debug/net6.0/Icons.dll", "args": [], "cwd": "${workspaceFolder}/src/Icons", @@ -241,16 +380,13 @@ } }, { - "name": "Notifications", + "name": "run-Notifications", "presentation": { "hidden": true, - "group": "cloud", - "order": 100 }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildNotifications", "program": "${workspaceFolder}/src/Notifications/bin/Debug/net6.0/Notifications.dll", "args": [], "cwd": "${workspaceFolder}/src/Notifications", @@ -263,16 +399,13 @@ } }, { - "name": "Identity-SelfHost", + "name": "run-Identity-SelfHost", "presentation": { "hidden": true, - "group": "self-host", - "order": 999 }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildIdentity", "program": "${workspaceFolder}/src/Identity/bin/Debug/net6.0/Identity.dll", "args": [], "cwd": "${workspaceFolder}/src/Identity", @@ -287,16 +420,13 @@ } }, { - "name": "API-SelfHost", + "name": "run-API-SelfHost", "presentation": { "hidden": true, - "group": "self-host", - "order": 999 }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildAPI", "program": "${workspaceFolder}/src/Api/bin/Debug/net6.0/Api.dll", "args": [], "cwd": "${workspaceFolder}/src/Api", @@ -311,16 +441,13 @@ } }, { - "name": "Admin-SelfHost", + "name": "run-Admin-SelfHost", "presentation": { "hidden": true, - "group": "self-host", - "order": 999 }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildAdmin", "OS-COMMENT4": "If you have changed target frameworks, make sure to update the program path.", "program": "${workspaceFolder}/src/Admin/bin/Debug/net6.0/Admin.dll", "args": [], @@ -337,16 +464,13 @@ } }, { - "name": "Sso-SelfHost", + "name": "run-Sso-SelfHost", "presentation": { "hidden": true, - "group": "self-host", - "order": 999 }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildSso", "program": "${workspaceFolder}/bitwarden_license/src/Sso/bin/Debug/net6.0/Sso.dll", "args": [], "cwd": "${workspaceFolder}/bitwarden_license/src/Sso", @@ -361,16 +485,13 @@ } }, { - "name": "Notifications-SelfHost", + "name": "run-Notifications-SelfHost", "presentation": { "hidden": true, - "group": "self-host", - "order": 999 }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildNotifications", "program": "${workspaceFolder}/src/Notifications/bin/Debug/net6.0/Notifications.dll", "args": [], "cwd": "${workspaceFolder}/src/Notifications", @@ -385,16 +506,13 @@ } }, { - "name": "EventsProcessor-SelfHost", + "name": "run-EventsProcessor-SelfHost", "presentation": { "hidden": true, - "group": "self-host", - "order": 999 }, "requireExactSource": true, "type": "coreclr", "request": "launch", - "preLaunchTask": "buildEventsProcessor", "program": "${workspaceFolder}/src/EventsProcessor/bin/Debug/net6.0/EventsProcessor.dll", "args": [], "cwd": "${workspaceFolder}/src/EventsProcessor", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 61d1f92404..69077ec5d1 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,6 +1,65 @@ { "version": "2.0.0", "tasks": [ + { + "label": "buildIdentityApi", + "dependsOrder": "sequence", + "dependsOn": [ + "buildIdentity", + "buildAPI" + ], + "problemMatcher": [ + "$msCompile" + ] + }, + { + "label": "buildIdentityApiAdmin", + "dependsOrder": "sequence", + "dependsOn": [ + "buildIdentity", + "buildAPI", + "buildAdmin" + ], + "problemMatcher": [ + "$msCompile" + ] + }, + { + "label": "buildFullServer", + "dependsOrder": "sequence", + "dependsOn": [ + "buildAdmin", + "buildAPI", + "buildEventsProcessor", + "buildIdentity", + "buildSso", + "buildIcons", + "buildBilling", + "buildNotifications", + ], + }, + { + "label": "buildSelfHostBit", + "dependsOrder": "sequence", + "dependsOn": [ + "buildAdmin", + "buildAPI", + "buildEventsProcessor", + "buildIdentity", + "buildSso", + "buildNotifications", + ], + }, + { + "label": "buildSelfHostOss", + "dependsOrder": "sequence", + "dependsOn": [ + "buildAdmin", + "buildAPI", + "buildEventsProcessor", + "buildIdentity", + ], + }, { "label": "buildIcons", "command": "dotnet", From 544dadec9f6eb78fb0d45431217a53e01e2e531c Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Mon, 20 Nov 2023 13:36:37 -0500 Subject: [PATCH 07/20] PM-3231 add feature flag for vault onboarding work (#3449) --- src/Core/Constants.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index aea0b56fe2..c72680cd21 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -62,6 +62,7 @@ public static class FeatureFlagKeys public const string PasswordlessLogin = "passwordless-login"; public const string TrustedDeviceEncryption = "trusted-device-encryption"; public const string Fido2VaultCredentials = "fido2-vault-credentials"; + public const string VaultOnboarding = "vault-onboarding"; public const string AutofillV2 = "autofill-v2"; public const string BrowserFilelessImport = "browser-fileless-import"; public const string FlexibleCollections = "flexible-collections"; From de3252489111819f2927ff36de742617cc5b3102 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Mon, 20 Nov 2023 15:33:10 -0500 Subject: [PATCH 08/20] Disable renewal email for org owners on invoice.upcoming (#3454) --- src/Billing/Controllers/StripeController.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Billing/Controllers/StripeController.cs b/src/Billing/Controllers/StripeController.cs index 64053b31f2..de8b9a6239 100644 --- a/src/Billing/Controllers/StripeController.cs +++ b/src/Billing/Controllers/StripeController.cs @@ -264,9 +264,16 @@ public class StripeController : Controller await SendEmails(new List { organization.BillingEmail }); - var ownerEmails = await _organizationRepository.GetOwnerEmailAddressesById(organization.Id); + /* + * TODO: https://bitwarden.atlassian.net/browse/PM-4862 + * Disabling this as part of a hot fix. It needs to check whether the organization + * belongs to a Reseller provider and only send an email to the organization owners if it does. + * It also requires a new email template as the current one contains too much billing information. + */ - await SendEmails(ownerEmails); + // var ownerEmails = await _organizationRepository.GetOwnerEmailAddressesById(organization.Id); + + // await SendEmails(ownerEmails); } else if (userId.HasValue) { From 03b91366231348772da79fd2d728343537493468 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:30:48 -0500 Subject: [PATCH 09/20] Revert "[PM-3892] Implement dollar threshold for all subscriptions (#3283)" (#3455) This reverts commit d9faa9a6dfd7d68b6f19c1d1ba9bb40b6d54496f. --- src/Core/Constants.cs | 14 - .../Models/Business/InvoicePreviewResult.cs | 7 - .../Models/Business/PendingInoviceItems.cs | 9 - .../Business/SecretsManagerSubscribeUpdate.cs | 8 +- src/Core/Services/IStripeAdapter.cs | 4 - .../Services/Implementations/StripeAdapter.cs | 18 - .../Implementations/StripePaymentService.cs | 392 +++--------------- .../Services/StripePaymentServiceTests.cs | 296 ------------- 8 files changed, 56 insertions(+), 692 deletions(-) delete mode 100644 src/Core/Models/Business/InvoicePreviewResult.cs delete mode 100644 src/Core/Models/Business/PendingInoviceItems.cs diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index c72680cd21..258c67b7f2 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -25,20 +25,6 @@ public static class Constants public const string CipherKeyEncryptionMinimumVersion = "2023.9.2"; - /// - /// When you set the ProrationBehavior to create_prorations, - /// Stripe will automatically create prorations for any changes made to the subscription, - /// such as changing the plan, adding or removing quantities, or applying discounts. - /// - public const string CreateProrations = "create_prorations"; - - /// - /// When you set the ProrationBehavior to always_invoice, - /// Stripe will always generate an invoice when a subscription update occurs, - /// regardless of whether there is a proration or not. - /// - public const string AlwaysInvoice = "always_invoice"; - /// /// Used by IdentityServer to identify our own provider. /// diff --git a/src/Core/Models/Business/InvoicePreviewResult.cs b/src/Core/Models/Business/InvoicePreviewResult.cs deleted file mode 100644 index d9e211cfb2..0000000000 --- a/src/Core/Models/Business/InvoicePreviewResult.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Bit.Core.Models.Business; - -public class InvoicePreviewResult -{ - public bool IsInvoicedNow { get; set; } - public string PaymentIntentClientSecret { get; set; } -} diff --git a/src/Core/Models/Business/PendingInoviceItems.cs b/src/Core/Models/Business/PendingInoviceItems.cs deleted file mode 100644 index 1aee15a3aa..0000000000 --- a/src/Core/Models/Business/PendingInoviceItems.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Stripe; - -namespace Bit.Core.Models.Business; - -public class PendingInoviceItems -{ - public IEnumerable PendingInvoiceItems { get; set; } - public IDictionary PendingInvoiceItemsDict { get; set; } -} diff --git a/src/Core/Models/Business/SecretsManagerSubscribeUpdate.cs b/src/Core/Models/Business/SecretsManagerSubscribeUpdate.cs index 54bc8cb95e..8f3fb89349 100644 --- a/src/Core/Models/Business/SecretsManagerSubscribeUpdate.cs +++ b/src/Core/Models/Business/SecretsManagerSubscribeUpdate.cs @@ -44,7 +44,7 @@ public class SecretsManagerSubscribeUpdate : SubscriptionUpdate { updatedItems.Add(new SubscriptionItemOptions { - Plan = _plan.SecretsManager.StripeSeatPlanId, + Price = _plan.SecretsManager.StripeSeatPlanId, Quantity = _additionalSeats }); } @@ -53,7 +53,7 @@ public class SecretsManagerSubscribeUpdate : SubscriptionUpdate { updatedItems.Add(new SubscriptionItemOptions { - Plan = _plan.SecretsManager.StripeServiceAccountPlanId, + Price = _plan.SecretsManager.StripeServiceAccountPlanId, Quantity = _additionalServiceAccounts }); } @@ -63,14 +63,14 @@ public class SecretsManagerSubscribeUpdate : SubscriptionUpdate { updatedItems.Add(new SubscriptionItemOptions { - Plan = _plan.SecretsManager.StripeSeatPlanId, + Price = _plan.SecretsManager.StripeSeatPlanId, Quantity = _previousSeats, Deleted = _previousSeats == 0 ? true : (bool?)null, }); updatedItems.Add(new SubscriptionItemOptions { - Plan = _plan.SecretsManager.StripeServiceAccountPlanId, + Price = _plan.SecretsManager.StripeServiceAccountPlanId, Quantity = _previousServiceAccounts, Deleted = _previousServiceAccounts == 0 ? true : (bool?)null, }); diff --git a/src/Core/Services/IStripeAdapter.cs b/src/Core/Services/IStripeAdapter.cs index f79cc1200e..60d14ffad8 100644 --- a/src/Core/Services/IStripeAdapter.cs +++ b/src/Core/Services/IStripeAdapter.cs @@ -1,5 +1,4 @@ using Bit.Core.Models.BitStripe; -using Stripe; namespace Bit.Core.Services; @@ -15,11 +14,8 @@ public interface IStripeAdapter Task SubscriptionUpdateAsync(string id, Stripe.SubscriptionUpdateOptions options = null); Task SubscriptionCancelAsync(string Id, Stripe.SubscriptionCancelOptions options = null); Task InvoiceUpcomingAsync(Stripe.UpcomingInvoiceOptions options); - Task InvoiceCreateAsync(Stripe.InvoiceCreateOptions options); - Task InvoiceItemCreateAsync(Stripe.InvoiceItemCreateOptions options); Task InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options); Task> InvoiceListAsync(StripeInvoiceListOptions options); - IEnumerable InvoiceItemListAsync(InvoiceItemListOptions options); Task InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options); Task InvoiceFinalizeInvoiceAsync(string id, Stripe.InvoiceFinalizeOptions options); Task InvoiceSendInvoiceAsync(string id, Stripe.InvoiceSendOptions options); diff --git a/src/Core/Services/Implementations/StripeAdapter.cs b/src/Core/Services/Implementations/StripeAdapter.cs index 28dd35034c..747510d052 100644 --- a/src/Core/Services/Implementations/StripeAdapter.cs +++ b/src/Core/Services/Implementations/StripeAdapter.cs @@ -1,5 +1,4 @@ using Bit.Core.Models.BitStripe; -using Stripe; namespace Bit.Core.Services; @@ -17,7 +16,6 @@ public class StripeAdapter : IStripeAdapter private readonly Stripe.BankAccountService _bankAccountService; private readonly Stripe.PriceService _priceService; private readonly Stripe.TestHelpers.TestClockService _testClockService; - private readonly Stripe.InvoiceItemService _invoiceItemService; public StripeAdapter() { @@ -33,7 +31,6 @@ public class StripeAdapter : IStripeAdapter _bankAccountService = new Stripe.BankAccountService(); _priceService = new Stripe.PriceService(); _testClockService = new Stripe.TestHelpers.TestClockService(); - _invoiceItemService = new Stripe.InvoiceItemService(); } public Task CustomerCreateAsync(Stripe.CustomerCreateOptions options) @@ -82,16 +79,6 @@ public class StripeAdapter : IStripeAdapter return _invoiceService.UpcomingAsync(options); } - public Task InvoiceCreateAsync(Stripe.InvoiceCreateOptions options) - { - return _invoiceService.CreateAsync(options); - } - - public Task InvoiceItemCreateAsync(Stripe.InvoiceItemCreateOptions options) - { - return _invoiceItemService.CreateAsync(options); - } - public Task InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options) { return _invoiceService.GetAsync(id, options); @@ -116,11 +103,6 @@ public class StripeAdapter : IStripeAdapter return invoices; } - public IEnumerable InvoiceItemListAsync(InvoiceItemListOptions options) - { - return _invoiceItemService.ListAutoPaging(options); - } - public Task InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options) { return _invoiceService.UpdateAsync(id, options); diff --git a/src/Core/Services/Implementations/StripePaymentService.cs b/src/Core/Services/Implementations/StripePaymentService.cs index 67de73a188..320145ecd4 100644 --- a/src/Core/Services/Implementations/StripePaymentService.cs +++ b/src/Core/Services/Implementations/StripePaymentService.cs @@ -7,7 +7,6 @@ using Bit.Core.Models.Business; using Bit.Core.Repositories; using Bit.Core.Settings; using Microsoft.Extensions.Logging; -using Stripe; using StaticStore = Bit.Core.Models.StaticStore; using TaxRate = Bit.Core.Entities.TaxRate; @@ -751,14 +750,16 @@ public class StripePaymentService : IPaymentService prorationDate ??= DateTime.UtcNow; var collectionMethod = sub.CollectionMethod; var daysUntilDue = sub.DaysUntilDue; + var chargeNow = collectionMethod == "charge_automatically"; var updatedItemOptions = subscriptionUpdate.UpgradeItemsOptions(sub); var subUpdateOptions = new Stripe.SubscriptionUpdateOptions { Items = updatedItemOptions, - ProrationBehavior = Constants.CreateProrations, + ProrationBehavior = "always_invoice", DaysUntilDue = daysUntilDue ?? 1, - CollectionMethod = "send_invoice" + CollectionMethod = "send_invoice", + ProrationDate = prorationDate, }; if (!subscriptionUpdate.UpdateNeeded(sub)) @@ -792,50 +793,66 @@ public class StripePaymentService : IPaymentService string paymentIntentClientSecret = null; try { - var subItemOptions = updatedItemOptions.Select(itemOption => - new Stripe.InvoiceSubscriptionItemOptions - { - Id = itemOption.Id, - Plan = itemOption.Plan, - Quantity = itemOption.Quantity, - }).ToList(); - - var reviewInvoiceResponse = await PreviewUpcomingInvoiceAndPayAsync(storableSubscriber, subItemOptions); - paymentIntentClientSecret = reviewInvoiceResponse.PaymentIntentClientSecret; - var subResponse = await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, subUpdateOptions); - var invoice = - await _stripeAdapter.InvoiceGetAsync(subResponse?.LatestInvoiceId, new Stripe.InvoiceGetOptions()); + + var invoice = await _stripeAdapter.InvoiceGetAsync(subResponse?.LatestInvoiceId, new Stripe.InvoiceGetOptions()); if (invoice == null) { throw new BadRequestException("Unable to locate draft invoice for subscription update."); } - } - catch (Exception e) - { - // Need to revert the subscription - await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new Stripe.SubscriptionUpdateOptions + + if (invoice.AmountDue > 0 && updatedItemOptions.Any(i => i.Quantity > 0)) { - Items = subscriptionUpdate.RevertItemsOptions(sub), - // This proration behavior prevents a false "credit" from - // being applied forward to the next month's invoice - ProrationBehavior = "none", - CollectionMethod = collectionMethod, - DaysUntilDue = daysUntilDue, - }); - throw; + try + { + if (chargeNow) + { + paymentIntentClientSecret = await PayInvoiceAfterSubscriptionChangeAsync( + storableSubscriber, invoice); + } + else + { + invoice = await _stripeAdapter.InvoiceFinalizeInvoiceAsync(subResponse.LatestInvoiceId, new Stripe.InvoiceFinalizeOptions + { + AutoAdvance = false, + }); + await _stripeAdapter.InvoiceSendInvoiceAsync(invoice.Id, new Stripe.InvoiceSendOptions()); + paymentIntentClientSecret = null; + } + } + catch + { + // Need to revert the subscription + await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new Stripe.SubscriptionUpdateOptions + { + Items = subscriptionUpdate.RevertItemsOptions(sub), + // This proration behavior prevents a false "credit" from + // being applied forward to the next month's invoice + ProrationBehavior = "none", + CollectionMethod = collectionMethod, + DaysUntilDue = daysUntilDue, + }); + throw; + } + } + else if (!invoice.Paid) + { + // Pay invoice with no charge to customer this completes the invoice immediately without waiting the scheduled 1h + invoice = await _stripeAdapter.InvoicePayAsync(subResponse.LatestInvoiceId); + paymentIntentClientSecret = null; + } + } finally { // Change back the subscription collection method and/or days until due if (collectionMethod != "send_invoice" || daysUntilDue == null) { - await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, - new Stripe.SubscriptionUpdateOptions - { - CollectionMethod = collectionMethod, - DaysUntilDue = daysUntilDue, - }); + await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new Stripe.SubscriptionUpdateOptions + { + CollectionMethod = collectionMethod, + DaysUntilDue = daysUntilDue, + }); } } @@ -918,7 +935,6 @@ public class StripePaymentService : IPaymentService await _stripeAdapter.CustomerDeleteAsync(subscriber.GatewayCustomerId); } - //This method is no-longer is use because we return the dollar threshold feature on invoice will be generated. but we dont want to lose this implementation. public async Task PayInvoiceAfterSubscriptionChangeAsync(ISubscriber subscriber, Stripe.Invoice invoice) { var customerOptions = new Stripe.CustomerGetOptions(); @@ -1088,310 +1104,6 @@ public class StripePaymentService : IPaymentService return paymentIntentClientSecret; } - internal async Task PreviewUpcomingInvoiceAndPayAsync(ISubscriber subscriber, - List subItemOptions, int prorateThreshold = 50000) - { - var customer = await CheckInAppPurchaseMethod(subscriber); - - string paymentIntentClientSecret = null; - - var pendingInvoiceItems = GetPendingInvoiceItems(subscriber); - - var upcomingPreview = await GetUpcomingInvoiceAsync(subscriber, subItemOptions); - - var itemsForInvoice = GetItemsForInvoice(subItemOptions, upcomingPreview, pendingInvoiceItems); - var invoiceAmount = itemsForInvoice?.Sum(i => i.Amount) ?? 0; - var invoiceNow = invoiceAmount >= prorateThreshold; - if (invoiceNow) - { - await ProcessImmediateInvoiceAsync(subscriber, upcomingPreview, invoiceAmount, customer, itemsForInvoice, pendingInvoiceItems, paymentIntentClientSecret); - } - - return new InvoicePreviewResult { IsInvoicedNow = invoiceNow, PaymentIntentClientSecret = paymentIntentClientSecret }; - } - - private async Task ProcessImmediateInvoiceAsync(ISubscriber subscriber, Invoice upcomingPreview, long invoiceAmount, - Customer customer, IEnumerable itemsForInvoice, PendingInoviceItems pendingInvoiceItems, - string paymentIntentClientSecret) - { - // Owes more than prorateThreshold on the next invoice. - // Invoice them and pay now instead of waiting until the next billing cycle. - - string cardPaymentMethodId = null; - var invoiceAmountDue = upcomingPreview.StartingBalance + invoiceAmount; - cardPaymentMethodId = GetCardPaymentMethodId(invoiceAmountDue, customer, cardPaymentMethodId); - - Stripe.Invoice invoice = null; - var createdInvoiceItems = new List(); - Braintree.Transaction braintreeTransaction = null; - - try - { - await CreateInvoiceItemsAsync(subscriber, itemsForInvoice, pendingInvoiceItems, createdInvoiceItems); - - invoice = await CreateInvoiceAsync(subscriber, cardPaymentMethodId); - - var invoicePayOptions = new Stripe.InvoicePayOptions(); - await CreateBrainTreeTransactionRequestAsync(subscriber, invoice, customer, invoicePayOptions, - cardPaymentMethodId, braintreeTransaction); - - await InvoicePayAsync(invoicePayOptions, invoice, paymentIntentClientSecret); - } - catch (Exception e) - { - if (braintreeTransaction != null) - { - await _btGateway.Transaction.RefundAsync(braintreeTransaction.Id); - } - - if (invoice != null) - { - if (invoice.Status == "paid") - { - // It's apparently paid, so we return without throwing an exception - return new InvoicePreviewResult - { - IsInvoicedNow = false, - PaymentIntentClientSecret = paymentIntentClientSecret - }; - } - - await RestoreInvoiceItemsAsync(invoice, customer, pendingInvoiceItems.PendingInvoiceItems); - } - else - { - foreach (var ii in createdInvoiceItems) - { - await _stripeAdapter.InvoiceDeleteAsync(ii.Id); - } - } - - if (e is Stripe.StripeException strEx && - (strEx.StripeError?.Message?.Contains("cannot be used because it is not verified") ?? false)) - { - throw new GatewayException("Bank account is not yet verified."); - } - - throw; - } - - return new InvoicePreviewResult - { - IsInvoicedNow = false, - PaymentIntentClientSecret = paymentIntentClientSecret - }; - } - - private static IEnumerable GetItemsForInvoice(List subItemOptions, Invoice upcomingPreview, - PendingInoviceItems pendingInvoiceItems) - { - var itemsForInvoice = upcomingPreview.Lines?.Data? - .Where(i => pendingInvoiceItems.PendingInvoiceItemsDict.ContainsKey(i.Id) || - (i.Plan.Id == subItemOptions[0]?.Plan && i.Proration)); - return itemsForInvoice; - } - - private PendingInoviceItems GetPendingInvoiceItems(ISubscriber subscriber) - { - var pendingInvoiceItems = new PendingInoviceItems(); - var invoiceItems = _stripeAdapter.InvoiceItemListAsync(new Stripe.InvoiceItemListOptions - { - Customer = subscriber.GatewayCustomerId - }).ToList().Where(i => i.InvoiceId == null); - pendingInvoiceItems.PendingInvoiceItemsDict = invoiceItems.ToDictionary(pii => pii.Id); - return pendingInvoiceItems; - } - - private async Task CheckInAppPurchaseMethod(ISubscriber subscriber) - { - var customerOptions = GetCustomerPaymentOptions(); - var customer = await _stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId, customerOptions); - var usingInAppPaymentMethod = customer.Metadata.ContainsKey("appleReceipt"); - if (usingInAppPaymentMethod) - { - throw new BadRequestException("Cannot perform this action with in-app purchase payment method. " + - "Contact support."); - } - - return customer; - } - - private string GetCardPaymentMethodId(long invoiceAmountDue, Customer customer, string cardPaymentMethodId) - { - try - { - if (invoiceAmountDue <= 0 || customer.Metadata.ContainsKey("btCustomerId")) return cardPaymentMethodId; - var hasDefaultCardPaymentMethod = customer.InvoiceSettings?.DefaultPaymentMethod?.Type == "card"; - var hasDefaultValidSource = customer.DefaultSource != null && - (customer.DefaultSource is Stripe.Card || - customer.DefaultSource is Stripe.BankAccount); - if (hasDefaultCardPaymentMethod || hasDefaultValidSource) return cardPaymentMethodId; - cardPaymentMethodId = GetLatestCardPaymentMethod(customer.Id)?.Id; - if (cardPaymentMethodId == null) - { - throw new BadRequestException("No payment method is available."); - } - } - catch (Exception e) - { - throw new BadRequestException("No payment method is available."); - } - - - return cardPaymentMethodId; - } - - private async Task GetUpcomingInvoiceAsync(ISubscriber subscriber, List subItemOptions) - { - var upcomingPreview = await _stripeAdapter.InvoiceUpcomingAsync(new Stripe.UpcomingInvoiceOptions - { - Customer = subscriber.GatewayCustomerId, - Subscription = subscriber.GatewaySubscriptionId, - SubscriptionItems = subItemOptions - }); - return upcomingPreview; - } - - private async Task RestoreInvoiceItemsAsync(Invoice invoice, Customer customer, IEnumerable pendingInvoiceItems) - { - invoice = await _stripeAdapter.InvoiceVoidInvoiceAsync(invoice.Id, new Stripe.InvoiceVoidOptions()); - if (invoice.StartingBalance != 0) - { - await _stripeAdapter.CustomerUpdateAsync(customer.Id, - new Stripe.CustomerUpdateOptions { Balance = customer.Balance }); - } - - // Restore invoice items that were brought in - foreach (var item in pendingInvoiceItems) - { - var i = new Stripe.InvoiceItemCreateOptions - { - Currency = item.Currency, - Description = item.Description, - Customer = item.CustomerId, - Subscription = item.SubscriptionId, - Discountable = item.Discountable, - Metadata = item.Metadata, - Quantity = item.Proration ? 1 : item.Quantity, - UnitAmount = item.UnitAmount - }; - await _stripeAdapter.InvoiceItemCreateAsync(i); - } - } - - private async Task InvoicePayAsync(InvoicePayOptions invoicePayOptions, Invoice invoice, string paymentIntentClientSecret) - { - try - { - await _stripeAdapter.InvoicePayAsync(invoice.Id, invoicePayOptions); - } - catch (Stripe.StripeException e) - { - if (e.HttpStatusCode == System.Net.HttpStatusCode.PaymentRequired && - e.StripeError?.Code == "invoice_payment_intent_requires_action") - { - // SCA required, get intent client secret - var invoiceGetOptions = new Stripe.InvoiceGetOptions(); - invoiceGetOptions.AddExpand("payment_intent"); - invoice = await _stripeAdapter.InvoiceGetAsync(invoice.Id, invoiceGetOptions); - paymentIntentClientSecret = invoice?.PaymentIntent?.ClientSecret; - } - else - { - throw new GatewayException("Unable to pay invoice."); - } - } - } - - private async Task CreateBrainTreeTransactionRequestAsync(ISubscriber subscriber, Invoice invoice, Customer customer, - InvoicePayOptions invoicePayOptions, string cardPaymentMethodId, Braintree.Transaction braintreeTransaction) - { - if (invoice.AmountDue > 0) - { - if (customer?.Metadata?.ContainsKey("btCustomerId") ?? false) - { - invoicePayOptions.PaidOutOfBand = true; - var btInvoiceAmount = (invoice.AmountDue / 100M); - var transactionResult = await _btGateway.Transaction.SaleAsync( - new Braintree.TransactionRequest - { - Amount = btInvoiceAmount, - CustomerId = customer.Metadata["btCustomerId"], - Options = new Braintree.TransactionOptionsRequest - { - SubmitForSettlement = true, - PayPal = new Braintree.TransactionOptionsPayPalRequest - { - CustomField = $"{subscriber.BraintreeIdField()}:{subscriber.Id}" - } - }, - CustomFields = new Dictionary - { - [subscriber.BraintreeIdField()] = subscriber.Id.ToString() - } - }); - - if (!transactionResult.IsSuccess()) - { - throw new GatewayException("Failed to charge PayPal customer."); - } - - braintreeTransaction = transactionResult.Target; - await _stripeAdapter.InvoiceUpdateAsync(invoice.Id, new Stripe.InvoiceUpdateOptions - { - Metadata = new Dictionary - { - ["btTransactionId"] = braintreeTransaction.Id, - ["btPayPalTransactionId"] = - braintreeTransaction.PayPalDetails.AuthorizationId - } - }); - } - else - { - invoicePayOptions.OffSession = true; - invoicePayOptions.PaymentMethod = cardPaymentMethodId; - } - } - } - - private async Task CreateInvoiceAsync(ISubscriber subscriber, string cardPaymentMethodId) - { - Invoice invoice; - invoice = await _stripeAdapter.InvoiceCreateAsync(new Stripe.InvoiceCreateOptions - { - CollectionMethod = "send_invoice", - DaysUntilDue = 1, - Customer = subscriber.GatewayCustomerId, - Subscription = subscriber.GatewaySubscriptionId, - DefaultPaymentMethod = cardPaymentMethodId - }); - return invoice; - } - - private async Task CreateInvoiceItemsAsync(ISubscriber subscriber, IEnumerable itemsForInvoice, - PendingInoviceItems pendingInvoiceItems, List createdInvoiceItems) - { - foreach (var invoiceLineItem in itemsForInvoice) - { - if (pendingInvoiceItems.PendingInvoiceItemsDict.ContainsKey(invoiceLineItem.Id)) - { - continue; - } - - var invoiceItem = await _stripeAdapter.InvoiceItemCreateAsync(new Stripe.InvoiceItemCreateOptions - { - Currency = invoiceLineItem.Currency, - Description = invoiceLineItem.Description, - Customer = subscriber.GatewayCustomerId, - Subscription = invoiceLineItem.Subscription, - Discountable = invoiceLineItem.Discountable, - Amount = invoiceLineItem.Amount - }); - createdInvoiceItems.Add(invoiceItem); - } - } - public async Task CancelSubscriptionAsync(ISubscriber subscriber, bool endOfPeriod = false, bool skipInAppPurchaseCheck = false) { diff --git a/test/Core.Test/Services/StripePaymentServiceTests.cs b/test/Core.Test/Services/StripePaymentServiceTests.cs index 9ef4b0233c..2133a14a97 100644 --- a/test/Core.Test/Services/StripePaymentServiceTests.cs +++ b/test/Core.Test/Services/StripePaymentServiceTests.cs @@ -739,300 +739,4 @@ public class StripePaymentServiceTests Assert.Null(result); } - - [Theory, BitAutoData] - public async Task PreviewUpcomingInvoiceAndPayAsync_WithInAppPaymentMethod_ThrowsBadRequestException(SutProvider sutProvider, - Organization subscriber, List subItemOptions) - { - var stripeAdapter = sutProvider.GetDependency(); - stripeAdapter.CustomerGetAsync(Arg.Any(), Arg.Any()) - .Returns(new Stripe.Customer { Metadata = new Dictionary { { "appleReceipt", "dummyData" } } }); - - var ex = await Assert.ThrowsAsync(() => sutProvider.Sut.PreviewUpcomingInvoiceAndPayAsync(subscriber, subItemOptions)); - Assert.Equal("Cannot perform this action with in-app purchase payment method. Contact support.", ex.Message); - } - - [Theory, BitAutoData] - public async void PreviewUpcomingInvoiceAndPayAsync_UpcomingInvoiceBelowThreshold_DoesNotInvoiceNow(SutProvider sutProvider, - Organization subscriber, List subItemOptions) - { - var prorateThreshold = 50000; - var invoiceAmountBelowThreshold = prorateThreshold - 100; - var customer = MockStripeCustomer(subscriber); - sutProvider.GetDependency().CustomerGetAsync(default, default).ReturnsForAnyArgs(customer); - var invoiceItem = MockInoviceItemList(subscriber, "planId", invoiceAmountBelowThreshold, customer); - sutProvider.GetDependency().InvoiceItemListAsync(new Stripe.InvoiceItemListOptions - { - Customer = subscriber.GatewayCustomerId - }).ReturnsForAnyArgs(invoiceItem); - - var invoiceLineItem = CreateInvoiceLineTime(subscriber, "planId", invoiceAmountBelowThreshold); - sutProvider.GetDependency().InvoiceUpcomingAsync(new Stripe.UpcomingInvoiceOptions - { - Customer = subscriber.GatewayCustomerId, - Subscription = subscriber.GatewaySubscriptionId, - SubscriptionItems = subItemOptions - }).ReturnsForAnyArgs(invoiceLineItem); - - sutProvider.GetDependency().InvoiceCreateAsync(Arg.Is(options => - options.CollectionMethod == "send_invoice" && - options.DaysUntilDue == 1 && - options.Customer == subscriber.GatewayCustomerId && - options.Subscription == subscriber.GatewaySubscriptionId && - options.DefaultPaymentMethod == customer.InvoiceSettings.DefaultPaymentMethod.Id - )).ReturnsForAnyArgs(new Stripe.Invoice - { - Id = "mockInvoiceId", - CollectionMethod = "send_invoice", - DueDate = DateTime.Now.AddDays(1), - Customer = customer, - Subscription = new Stripe.Subscription - { - Id = "mockSubscriptionId", - Customer = customer, - Status = "active", - CurrentPeriodStart = DateTime.UtcNow, - CurrentPeriodEnd = DateTime.UtcNow.AddMonths(1), - CollectionMethod = "charge_automatically", - }, - DefaultPaymentMethod = customer.InvoiceSettings.DefaultPaymentMethod, - AmountDue = invoiceAmountBelowThreshold, - Currency = "usd", - Status = "draft", - }); - - var result = await sutProvider.Sut.PreviewUpcomingInvoiceAndPayAsync(subscriber, new List(), prorateThreshold); - - Assert.False(result.IsInvoicedNow); - Assert.Null(result.PaymentIntentClientSecret); - } - - [Theory, BitAutoData] - public async void PreviewUpcomingInvoiceAndPayAsync_NoPaymentMethod_ThrowsBadRequestException(SutProvider sutProvider, - Organization subscriber, List subItemOptions, string planId) - { - var prorateThreshold = 120000; - var invoiceAmountBelowThreshold = prorateThreshold; - var customer = new Stripe.Customer - { - Metadata = new Dictionary(), - Id = subscriber.GatewayCustomerId, - DefaultSource = null, - InvoiceSettings = new Stripe.CustomerInvoiceSettings - { - DefaultPaymentMethod = null - } - }; - sutProvider.GetDependency().CustomerGetAsync(default, default).ReturnsForAnyArgs(customer); - var invoiceItem = MockInoviceItemList(subscriber, planId, invoiceAmountBelowThreshold, customer); - sutProvider.GetDependency().InvoiceItemListAsync(new Stripe.InvoiceItemListOptions - { - Customer = subscriber.GatewayCustomerId - }).ReturnsForAnyArgs(invoiceItem); - - var invoiceLineItem = CreateInvoiceLineTime(subscriber, planId, invoiceAmountBelowThreshold); - sutProvider.GetDependency().InvoiceUpcomingAsync(new Stripe.UpcomingInvoiceOptions - { - Customer = subscriber.GatewayCustomerId, - Subscription = subscriber.GatewaySubscriptionId, - SubscriptionItems = subItemOptions - }).ReturnsForAnyArgs(invoiceLineItem); - - var ex = await Assert.ThrowsAsync(() => sutProvider.Sut.PreviewUpcomingInvoiceAndPayAsync(subscriber, subItemOptions)); - Assert.Equal("No payment method is available.", ex.Message); - } - - [Theory, BitAutoData] - public async void PreviewUpcomingInvoiceAndPayAsync_UpcomingInvoiceAboveThreshold_DoesInvoiceNow(SutProvider sutProvider, - Organization subscriber, List subItemOptions, string planId) - { - var prorateThreshold = 50000; - var invoiceAmountBelowThreshold = 100000; - var customer = MockStripeCustomer(subscriber); - sutProvider.GetDependency().CustomerGetAsync(default, default).ReturnsForAnyArgs(customer); - var invoiceItem = MockInoviceItemList(subscriber, planId, invoiceAmountBelowThreshold, customer); - sutProvider.GetDependency().InvoiceItemListAsync(new Stripe.InvoiceItemListOptions - { - Customer = subscriber.GatewayCustomerId - }).ReturnsForAnyArgs(invoiceItem); - - var invoiceLineItem = CreateInvoiceLineTime(subscriber, planId, invoiceAmountBelowThreshold); - sutProvider.GetDependency().InvoiceUpcomingAsync(new Stripe.UpcomingInvoiceOptions - { - Customer = subscriber.GatewayCustomerId, - Subscription = subscriber.GatewaySubscriptionId, - SubscriptionItems = subItemOptions - }).ReturnsForAnyArgs(invoiceLineItem); - - var invoice = MockInVoice(customer, invoiceAmountBelowThreshold); - sutProvider.GetDependency().InvoiceCreateAsync(Arg.Is(options => - options.CollectionMethod == "send_invoice" && - options.DaysUntilDue == 1 && - options.Customer == subscriber.GatewayCustomerId && - options.Subscription == subscriber.GatewaySubscriptionId && - options.DefaultPaymentMethod == customer.InvoiceSettings.DefaultPaymentMethod.Id - )).ReturnsForAnyArgs(invoice); - - var result = await sutProvider.Sut.PreviewUpcomingInvoiceAndPayAsync(subscriber, new List(), prorateThreshold); - - await sutProvider.GetDependency().Received(1).InvoicePayAsync(invoice.Id, - Arg.Is((options => - options.OffSession == true - ))); - - - Assert.True(result.IsInvoicedNow); - Assert.Null(result.PaymentIntentClientSecret); - } - - private static Stripe.Invoice MockInVoice(Stripe.Customer customer, int invoiceAmountBelowThreshold) => - new() - { - Id = "mockInvoiceId", - CollectionMethod = "send_invoice", - DueDate = DateTime.Now.AddDays(1), - Customer = customer, - Subscription = new Stripe.Subscription - { - Id = "mockSubscriptionId", - Customer = customer, - Status = "active", - CurrentPeriodStart = DateTime.UtcNow, - CurrentPeriodEnd = DateTime.UtcNow.AddMonths(1), - CollectionMethod = "charge_automatically", - }, - DefaultPaymentMethod = customer.InvoiceSettings.DefaultPaymentMethod, - AmountDue = invoiceAmountBelowThreshold, - Currency = "usd", - Status = "draft", - }; - - private static List MockInoviceItemList(Organization subscriber, string planId, int invoiceAmountBelowThreshold, Stripe.Customer customer) => - new() - { - new Stripe.InvoiceItem - { - Id = "ii_1234567890", - Amount = invoiceAmountBelowThreshold, - Currency = "usd", - CustomerId = subscriber.GatewayCustomerId, - Description = "Sample invoice item 1", - Date = DateTime.UtcNow, - Discountable = true, - InvoiceId = "548458365" - }, - new Stripe.InvoiceItem - { - Id = "ii_0987654321", - Amount = invoiceAmountBelowThreshold, - Currency = "usd", - CustomerId = customer.Id, - Description = "Sample invoice item 2", - Date = DateTime.UtcNow.AddDays(-5), - Discountable = false, - InvoiceId = null, - Proration = true, - Plan = new Stripe.Plan - { - Id = planId, - Amount = invoiceAmountBelowThreshold, - Currency = "usd", - Interval = "month", - IntervalCount = 1, - }, - } - }; - - private static Stripe.Customer MockStripeCustomer(Organization subscriber) - { - var customer = new Stripe.Customer - { - Metadata = new Dictionary(), - Id = subscriber.GatewayCustomerId, - DefaultSource = new Stripe.Card - { - Id = "card_12345", - Last4 = "1234", - Brand = "Visa", - ExpYear = 2025, - ExpMonth = 12 - }, - InvoiceSettings = new Stripe.CustomerInvoiceSettings - { - DefaultPaymentMethod = new Stripe.PaymentMethod - { - Id = "pm_12345", - Type = "card", - Card = new Stripe.PaymentMethodCard - { - Last4 = "1234", - Brand = "Visa", - ExpYear = 2025, - ExpMonth = 12 - } - } - } - }; - return customer; - } - - private static Stripe.Invoice CreateInvoiceLineTime(Organization subscriber, string planId, int invoiceAmountBelowThreshold) => - new() - { - AmountDue = invoiceAmountBelowThreshold, - AmountPaid = 0, - AmountRemaining = invoiceAmountBelowThreshold, - CustomerId = subscriber.GatewayCustomerId, - SubscriptionId = subscriber.GatewaySubscriptionId, - ApplicationFeeAmount = 0, - Currency = "usd", - Description = "Upcoming Invoice", - Discount = null, - DueDate = DateTime.UtcNow.AddDays(1), - EndingBalance = 0, - Number = "INV12345", - Paid = false, - PeriodStart = DateTime.UtcNow, - PeriodEnd = DateTime.UtcNow.AddMonths(1), - ReceiptNumber = null, - StartingBalance = 0, - Status = "draft", - Id = "ii_0987654321", - Total = invoiceAmountBelowThreshold, - Lines = new Stripe.StripeList - { - Data = new List - { - new Stripe.InvoiceLineItem - { - Amount = invoiceAmountBelowThreshold, - Currency = "usd", - Description = "Sample line item", - Id = "ii_0987654321", - Livemode = false, - Object = "line_item", - Discountable = false, - Period = new Stripe.InvoiceLineItemPeriod() - { - Start = DateTime.UtcNow, - End = DateTime.UtcNow.AddMonths(1) - }, - Plan = new Stripe.Plan - { - Id = planId, - Amount = invoiceAmountBelowThreshold, - Currency = "usd", - Interval = "month", - IntervalCount = 1, - }, - Proration = true, - Quantity = 1, - Subscription = subscriber.GatewaySubscriptionId, - SubscriptionItem = "si_12345", - Type = "subscription", - UnitAmountExcludingTax = invoiceAmountBelowThreshold, - } - } - } - }; } From 87fd4ad97d552b8e2014b7039482e04e82287161 Mon Sep 17 00:00:00 2001 From: Matt Bishop Date: Mon, 20 Nov 2023 16:32:23 -0500 Subject: [PATCH 10/20] [PM-3569] Upgrade to Duende.Identity (#3185) * Upgrade to Duende.Identity * Linting * Get rid of last IdentityServer4 package * Fix identity test since Duende returns additional configuration * Use Configure PostConfigure is ran after ASP.NET's PostConfigure so ConfigurationManager was already configured and our HttpHandler wasn't being respected. * Regenerate lockfiles * Move to 6.0.4 for patches * fixes with testing * Add additional grant type supported in 6.0.4 and beautify * Lockfile refresh * Reapply lockfiles * Apply change to new WebAuthn logic * When automated merging fails me --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> Co-authored-by: Kyle Spearrin --- .../src/Commercial.Core/packages.lock.json | 76 +++++++------------ .../packages.lock.json | 76 +++++++------------ bitwarden_license/src/Scim/packages.lock.json | 76 +++++++------------ .../src/Sso/Controllers/AccountController.cs | 11 +-- .../src/Sso/Controllers/HomeController.cs | 2 +- .../Sso/IdentityServer/OidcIdentityClient.cs | 4 +- .../src/Sso/Models/ErrorViewModel.cs | 2 +- bitwarden_license/src/Sso/Startup.cs | 2 +- .../Utilities/DiscoveryResponseGenerator.cs | 11 +-- .../DynamicAuthenticationSchemeProvider.cs | 12 +-- .../Utilities/ServiceCollectionExtensions.cs | 5 +- bitwarden_license/src/Sso/packages.lock.json | 76 +++++++------------ .../Commercial.Core.Test/packages.lock.json | 76 +++++++------------ .../Scim.IntegrationTest/packages.lock.json | 76 +++++++------------ .../test/Scim.Test/packages.lock.json | 76 +++++++------------ perf/MicroBenchmarks/packages.lock.json | 76 +++++++------------ src/Admin/packages.lock.json | 76 +++++++------------ src/Api/Program.cs | 4 +- src/Api/packages.lock.json | 76 +++++++------------ src/Billing/packages.lock.json | 76 +++++++------------ src/Core/Core.csproj | 3 +- src/Core/IdentityServer/ApiScopes.cs | 2 +- ...onfigureOpenIdConnectDistributedOptions.cs | 2 +- src/Core/packages.lock.json | 76 +++++++------------ src/Events/Program.cs | 4 +- src/Events/packages.lock.json | 76 +++++++------------ src/EventsProcessor/packages.lock.json | 76 +++++++------------ src/Icons/packages.lock.json | 76 +++++++------------ src/Identity/Controllers/SsoController.cs | 6 +- src/Identity/IdentityServer/ApiClient.cs | 2 +- src/Identity/IdentityServer/ApiResources.cs | 2 +- .../IdentityServer/AuthorizationCodeStore.cs | 13 ++-- .../IdentityServer/BaseRequestValidator.cs | 2 +- src/Identity/IdentityServer/ClientStore.cs | 4 +- .../CustomTokenRequestValidator.cs | 4 +- .../IdentityServer/PersistedGrantStore.cs | 4 +- src/Identity/IdentityServer/ProfileService.cs | 4 +- .../ResourceOwnerPasswordValidator.cs | 4 +- .../IdentityServer/StaticClientStore.cs | 2 +- .../IdentityServer/VaultCorsPolicyService.cs | 2 +- .../IdentityServer/WebAuthnGrantValidator.cs | 4 +- src/Identity/Program.cs | 4 +- src/Identity/Startup.cs | 2 +- .../Utilities/DiscoveryResponseGenerator.cs | 10 +-- .../Utilities/ServiceCollectionExtensions.cs | 7 +- src/Identity/packages.lock.json | 76 +++++++------------ src/Infrastructure.Dapper/packages.lock.json | 76 +++++++------------ .../packages.lock.json | 76 +++++++------------ src/Notifications/Program.cs | 4 +- src/Notifications/packages.lock.json | 76 +++++++------------ .../Utilities/ServiceCollectionExtensions.cs | 24 ++++-- src/SharedWeb/packages.lock.json | 76 +++++++------------ .../Factories/ApiApplicationFactory.cs | 8 +- test/Api.IntegrationTest/packages.lock.json | 76 +++++++------------ test/Api.Test/packages.lock.json | 76 +++++++------------ test/Billing.Test/packages.lock.json | 76 +++++++------------ test/Common/packages.lock.json | 76 +++++++------------ test/Core.Test/packages.lock.json | 76 +++++++------------ test/Icons.Test/packages.lock.json | 76 +++++++------------ .../Endpoints/IdentityServerSsoTests.cs | 6 +- .../openid-configuration.json | 21 ++++- .../packages.lock.json | 76 +++++++------------ test/Identity.Test/packages.lock.json | 76 +++++++------------ .../packages.lock.json | 76 +++++++------------ .../packages.lock.json | 76 +++++++------------ test/IntegrationTestCommon/packages.lock.json | 76 +++++++------------ util/Migrator/packages.lock.json | 76 +++++++------------ util/MsSqlMigratorUtility/packages.lock.json | 76 +++++++------------ util/MySqlMigrations/packages.lock.json | 76 +++++++------------ util/PostgresMigrations/packages.lock.json | 76 +++++++------------ util/Setup/packages.lock.json | 76 +++++++------------ util/SqlServerEFScaffold/packages.lock.json | 76 +++++++------------ util/SqliteMigrations/packages.lock.json | 76 +++++++------------ 73 files changed, 1104 insertions(+), 1987 deletions(-) diff --git a/bitwarden_license/src/Commercial.Core/packages.lock.json b/bitwarden_license/src/Commercial.Core/packages.lock.json index e87e310e8c..a432e7ac38 100644 --- a/bitwarden_license/src/Commercial.Core/packages.lock.json +++ b/bitwarden_license/src/Commercial.Core/packages.lock.json @@ -162,6 +162,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -198,49 +216,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -318,10 +295,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -354,8 +331,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2450,10 +2427,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json b/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json index 7fc67e1eb7..86b2eec18d 100644 --- a/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json +++ b/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json @@ -180,6 +180,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -216,49 +234,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -350,10 +327,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -386,8 +363,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2613,10 +2590,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/bitwarden_license/src/Scim/packages.lock.json b/bitwarden_license/src/Scim/packages.lock.json index e3b83c4ed4..152fab7bf3 100644 --- a/bitwarden_license/src/Scim/packages.lock.json +++ b/bitwarden_license/src/Scim/packages.lock.json @@ -184,6 +184,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -220,49 +238,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -354,10 +331,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -390,8 +367,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2617,10 +2594,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/bitwarden_license/src/Sso/Controllers/AccountController.cs b/bitwarden_license/src/Sso/Controllers/AccountController.cs index 40d4d1f42a..0df6894175 100644 --- a/bitwarden_license/src/Sso/Controllers/AccountController.cs +++ b/bitwarden_license/src/Sso/Controllers/AccountController.cs @@ -16,14 +16,15 @@ using Bit.Core.Tokens; using Bit.Core.Utilities; using Bit.Sso.Models; using Bit.Sso.Utilities; +using Duende.IdentityServer; +using Duende.IdentityServer.Extensions; +using Duende.IdentityServer.Services; +using Duende.IdentityServer.Stores; using IdentityModel; -using IdentityServer4; -using IdentityServer4.Extensions; -using IdentityServer4.Services; -using IdentityServer4.Stores; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using DIM = Duende.IdentityServer.Models; namespace Bit.Sso.Controllers; @@ -717,7 +718,7 @@ public class AccountController : Controller return (logoutId, logout?.PostLogoutRedirectUri, externalAuthenticationScheme); } - public bool IsNativeClient(IdentityServer4.Models.AuthorizationRequest context) + public bool IsNativeClient(DIM.AuthorizationRequest context) { return !context.RedirectUri.StartsWith("https", StringComparison.Ordinal) && !context.RedirectUri.StartsWith("http", StringComparison.Ordinal); diff --git a/bitwarden_license/src/Sso/Controllers/HomeController.cs b/bitwarden_license/src/Sso/Controllers/HomeController.cs index ee15fefc90..7be9d86215 100644 --- a/bitwarden_license/src/Sso/Controllers/HomeController.cs +++ b/bitwarden_license/src/Sso/Controllers/HomeController.cs @@ -1,6 +1,6 @@ using System.Diagnostics; using Bit.Sso.Models; -using IdentityServer4.Services; +using Duende.IdentityServer.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Mvc; diff --git a/bitwarden_license/src/Sso/IdentityServer/OidcIdentityClient.cs b/bitwarden_license/src/Sso/IdentityServer/OidcIdentityClient.cs index 8629da07e7..ce835e378b 100644 --- a/bitwarden_license/src/Sso/IdentityServer/OidcIdentityClient.cs +++ b/bitwarden_license/src/Sso/IdentityServer/OidcIdentityClient.cs @@ -1,6 +1,6 @@ using Bit.Core.Settings; -using IdentityServer4; -using IdentityServer4.Models; +using Duende.IdentityServer; +using Duende.IdentityServer.Models; namespace Bit.Sso.IdentityServer; diff --git a/bitwarden_license/src/Sso/Models/ErrorViewModel.cs b/bitwarden_license/src/Sso/Models/ErrorViewModel.cs index 46ae8edd90..1f6e9735e7 100644 --- a/bitwarden_license/src/Sso/Models/ErrorViewModel.cs +++ b/bitwarden_license/src/Sso/Models/ErrorViewModel.cs @@ -1,4 +1,4 @@ -using IdentityServer4.Models; +using Duende.IdentityServer.Models; namespace Bit.Sso.Models; diff --git a/bitwarden_license/src/Sso/Startup.cs b/bitwarden_license/src/Sso/Startup.cs index 635c91f441..f6be418bd8 100644 --- a/bitwarden_license/src/Sso/Startup.cs +++ b/bitwarden_license/src/Sso/Startup.cs @@ -6,7 +6,7 @@ using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.SharedWeb.Utilities; using Bit.Sso.Utilities; -using IdentityServer4.Extensions; +using Duende.IdentityServer.Extensions; using Microsoft.IdentityModel.Logging; using Stripe; diff --git a/bitwarden_license/src/Sso/Utilities/DiscoveryResponseGenerator.cs b/bitwarden_license/src/Sso/Utilities/DiscoveryResponseGenerator.cs index 7a7f569638..73ac789ea7 100644 --- a/bitwarden_license/src/Sso/Utilities/DiscoveryResponseGenerator.cs +++ b/bitwarden_license/src/Sso/Utilities/DiscoveryResponseGenerator.cs @@ -1,13 +1,14 @@ using Bit.Core.Settings; using Bit.Core.Utilities; -using IdentityServer4.Configuration; -using IdentityServer4.Services; -using IdentityServer4.Stores; -using IdentityServer4.Validation; +using Duende.IdentityServer.Configuration; +using Duende.IdentityServer.Services; +using Duende.IdentityServer.Stores; +using Duende.IdentityServer.Validation; +using DIR = Duende.IdentityServer.ResponseHandling; namespace Bit.Sso.Utilities; -public class DiscoveryResponseGenerator : IdentityServer4.ResponseHandling.DiscoveryResponseGenerator +public class DiscoveryResponseGenerator : DIR.DiscoveryResponseGenerator { private readonly GlobalSettings _globalSettings; diff --git a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs index 1487697279..17a7b9e8c7 100644 --- a/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs +++ b/bitwarden_license/src/Sso/Utilities/DynamicAuthenticationSchemeProvider.cs @@ -7,9 +7,9 @@ using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.Sso.Models; using Bit.Sso.Utilities; +using Duende.IdentityServer; +using Duende.IdentityServer.Infrastructure; using IdentityModel; -using IdentityServer4; -using IdentityServer4.Infrastructure; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.Extensions.Options; @@ -34,7 +34,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider private readonly Dictionary _cachedSchemes; private readonly Dictionary _cachedHandlerSchemes; private readonly SemaphoreSlim _semaphore; - private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IServiceProvider _serviceProvider; private DateTime? _lastSchemeLoad; private IEnumerable _schemesCopy = Array.Empty(); @@ -50,7 +50,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider ILogger logger, GlobalSettings globalSettings, SamlEnvironment samlEnvironment, - IHttpContextAccessor httpContextAccessor) + IServiceProvider serviceProvider) : base(options) { _oidcPostConfigureOptions = oidcPostConfigureOptions; @@ -77,7 +77,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider _cachedSchemes = new Dictionary(); _cachedHandlerSchemes = new Dictionary(); _semaphore = new SemaphoreSlim(1); - _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); } private bool CacheIsValid @@ -324,7 +324,7 @@ public class DynamicAuthenticationSchemeProvider : AuthenticationSchemeProvider oidcOptions.Scope.AddIfNotExists(OpenIdConnectScopes.Acr); } - oidcOptions.StateDataFormat = new DistributedCacheStateDataFormatter(_httpContextAccessor, name); + oidcOptions.StateDataFormat = new DistributedCacheStateDataFormatter(_serviceProvider, name); // see: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest (acr_values) if (!string.IsNullOrWhiteSpace(config.AcrValues)) diff --git a/bitwarden_license/src/Sso/Utilities/ServiceCollectionExtensions.cs b/bitwarden_license/src/Sso/Utilities/ServiceCollectionExtensions.cs index cd4aa707d6..a64374b652 100644 --- a/bitwarden_license/src/Sso/Utilities/ServiceCollectionExtensions.cs +++ b/bitwarden_license/src/Sso/Utilities/ServiceCollectionExtensions.cs @@ -4,8 +4,8 @@ using Bit.Core.Utilities; using Bit.SharedWeb.Utilities; using Bit.Sso.IdentityServer; using Bit.Sso.Models; -using IdentityServer4.Models; -using IdentityServer4.ResponseHandling; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.ResponseHandling; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Sustainsys.Saml2.AspNetCore2; @@ -59,6 +59,7 @@ public static class ServiceCollectionExtensions options.UserInteraction.ErrorIdParameter = "errorId"; } options.InputLengthRestrictions.UserName = 256; + options.KeyManagement.Enabled = false; }) .AddInMemoryCaching() .AddInMemoryClients(new List diff --git a/bitwarden_license/src/Sso/packages.lock.json b/bitwarden_license/src/Sso/packages.lock.json index d428050d50..ce589b096b 100644 --- a/bitwarden_license/src/Sso/packages.lock.json +++ b/bitwarden_license/src/Sso/packages.lock.json @@ -209,6 +209,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -245,49 +263,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -421,10 +398,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -457,8 +434,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.AspNetCore.Http.Abstractions": { "type": "Transitive", @@ -2777,10 +2754,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/bitwarden_license/test/Commercial.Core.Test/packages.lock.json b/bitwarden_license/test/Commercial.Core.Test/packages.lock.json index 7b4ee1f8ce..4b2b6fdd5e 100644 --- a/bitwarden_license/test/Commercial.Core.Test/packages.lock.json +++ b/bitwarden_license/test/Commercial.Core.Test/packages.lock.json @@ -239,6 +239,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -283,49 +301,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -412,10 +389,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -448,8 +425,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2710,10 +2687,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json b/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json index 529d7d8377..3f5575a874 100644 --- a/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json +++ b/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json @@ -282,6 +282,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -326,49 +344,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -469,10 +446,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -505,8 +482,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.AspNetCore.TestHost": { "type": "Transitive", @@ -3019,10 +2996,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/bitwarden_license/test/Scim.Test/packages.lock.json b/bitwarden_license/test/Scim.Test/packages.lock.json index c74090345c..d7f1ce34b2 100644 --- a/bitwarden_license/test/Scim.Test/packages.lock.json +++ b/bitwarden_license/test/Scim.Test/packages.lock.json @@ -270,6 +270,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -314,49 +332,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -457,10 +434,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -493,8 +470,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2872,10 +2849,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/perf/MicroBenchmarks/packages.lock.json b/perf/MicroBenchmarks/packages.lock.json index aa71419abb..f8fabd2ea6 100644 --- a/perf/MicroBenchmarks/packages.lock.json +++ b/perf/MicroBenchmarks/packages.lock.json @@ -192,6 +192,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -233,49 +251,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -353,10 +330,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -389,8 +366,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2557,10 +2534,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Admin/packages.lock.json b/src/Admin/packages.lock.json index 2282e9217b..a7edbdf763 100644 --- a/src/Admin/packages.lock.json +++ b/src/Admin/packages.lock.json @@ -223,6 +223,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -259,49 +277,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -393,10 +370,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -429,8 +406,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2834,10 +2811,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Api/Program.cs b/src/Api/Program.cs index b44ffa835f..2fd25eaefa 100644 --- a/src/Api/Program.cs +++ b/src/Api/Program.cs @@ -31,8 +31,8 @@ public class Program return e.Level >= globalSettings.MinLogLevel.ApiSettings.IpRateLimit; } - if (context.Contains("IdentityServer4.Validation.TokenValidator") || - context.Contains("IdentityServer4.Validation.TokenRequestValidator")) + if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") || + context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator")) { return e.Level >= globalSettings.MinLogLevel.ApiSettings.IdentityToken; } diff --git a/src/Api/packages.lock.json b/src/Api/packages.lock.json index 3ad880ecb3..432d80cab6 100644 --- a/src/Api/packages.lock.json +++ b/src/Api/packages.lock.json @@ -307,6 +307,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -343,49 +361,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -477,10 +454,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -513,8 +490,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2814,10 +2791,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Billing/packages.lock.json b/src/Billing/packages.lock.json index e3b83c4ed4..152fab7bf3 100644 --- a/src/Billing/packages.lock.json +++ b/src/Billing/packages.lock.json @@ -184,6 +184,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -220,49 +238,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -354,10 +331,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -390,8 +367,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2617,10 +2594,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 28415e8c03..1b06babb7c 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -31,7 +31,6 @@ - @@ -48,7 +47,7 @@ - + diff --git a/src/Core/IdentityServer/ApiScopes.cs b/src/Core/IdentityServer/ApiScopes.cs index ad2f242f73..6e3ce0d140 100644 --- a/src/Core/IdentityServer/ApiScopes.cs +++ b/src/Core/IdentityServer/ApiScopes.cs @@ -1,4 +1,4 @@ -using IdentityServer4.Models; +using Duende.IdentityServer.Models; namespace Bit.Core.IdentityServer; diff --git a/src/Core/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs b/src/Core/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs index 084f98a275..476159b760 100644 --- a/src/Core/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs +++ b/src/Core/IdentityServer/ConfigureOpenIdConnectDistributedOptions.cs @@ -1,5 +1,5 @@ using Bit.Core.Settings; -using IdentityServer4.Configuration; +using Duende.IdentityServer.Configuration; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.StackExchangeRedis; diff --git a/src/Core/packages.lock.json b/src/Core/packages.lock.json index 42e7ee5b6f..a716238631 100644 --- a/src/Core/packages.lock.json +++ b/src/Core/packages.lock.json @@ -131,6 +131,16 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, "Fido2.AspNet": { "type": "Direct", "requested": "[3.0.1, )", @@ -150,29 +160,6 @@ "Microsoft.CSharp": "4.7.0" } }, - "IdentityServer4": { - "type": "Direct", - "requested": "[4.1.2, )", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Direct", - "requested": "[3.0.1, )", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, "LaunchDarkly.ServerSdk": { "type": "Direct", "requested": "[8.0.0, )", @@ -465,6 +452,15 @@ "resolved": "2.2.1", "contentHash": "A6Zr52zVqJKt18ZBsTnX0qhG0kwIQftVAjLmszmkiR/trSp8H+xj1gUOzk7XHwaKgyREMSV1v9XaKrBUeIOdvQ==" }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -484,28 +480,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -554,10 +530,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -590,8 +566,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", diff --git a/src/Events/Program.cs b/src/Events/Program.cs index e09cfc17e6..6b53e4b18c 100644 --- a/src/Events/Program.cs +++ b/src/Events/Program.cs @@ -16,8 +16,8 @@ public class Program logging.AddSerilog(hostingContext, (e, globalSettings) => { var context = e.Properties["SourceContext"].ToString(); - if (context.Contains("IdentityServer4.Validation.TokenValidator") || - context.Contains("IdentityServer4.Validation.TokenRequestValidator")) + if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") || + context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator")) { return e.Level >= globalSettings.MinLogLevel.EventsSettings.IdentityToken; } diff --git a/src/Events/packages.lock.json b/src/Events/packages.lock.json index e3b83c4ed4..152fab7bf3 100644 --- a/src/Events/packages.lock.json +++ b/src/Events/packages.lock.json @@ -184,6 +184,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -220,49 +238,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -354,10 +331,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -390,8 +367,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2617,10 +2594,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/EventsProcessor/packages.lock.json b/src/EventsProcessor/packages.lock.json index e3b83c4ed4..152fab7bf3 100644 --- a/src/EventsProcessor/packages.lock.json +++ b/src/EventsProcessor/packages.lock.json @@ -184,6 +184,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -220,49 +238,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -354,10 +331,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -390,8 +367,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2617,10 +2594,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Icons/packages.lock.json b/src/Icons/packages.lock.json index 0d79d90e31..705ea80ff8 100644 --- a/src/Icons/packages.lock.json +++ b/src/Icons/packages.lock.json @@ -193,6 +193,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -229,49 +247,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -363,10 +340,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -399,8 +376,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2626,10 +2603,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Identity/Controllers/SsoController.cs b/src/Identity/Controllers/SsoController.cs index e5fc6a0eb4..e5dfc0ac60 100644 --- a/src/Identity/Controllers/SsoController.cs +++ b/src/Identity/Controllers/SsoController.cs @@ -5,9 +5,9 @@ using Bit.Core.Entities; using Bit.Core.Models.Api; using Bit.Core.Repositories; using Bit.Identity.Models; +using Duende.IdentityServer; +using Duende.IdentityServer.Services; using IdentityModel; -using IdentityServer4; -using IdentityServer4.Services; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; @@ -267,7 +267,7 @@ public class SsoController : Controller } } - private bool IsNativeClient(IdentityServer4.Models.AuthorizationRequest context) + private bool IsNativeClient(Duende.IdentityServer.Models.AuthorizationRequest context) { return !context.RedirectUri.StartsWith("https", StringComparison.Ordinal) && !context.RedirectUri.StartsWith("http", StringComparison.Ordinal); diff --git a/src/Identity/IdentityServer/ApiClient.cs b/src/Identity/IdentityServer/ApiClient.cs index 7457a8d0e9..d4eafe1d48 100644 --- a/src/Identity/IdentityServer/ApiClient.cs +++ b/src/Identity/IdentityServer/ApiClient.cs @@ -1,5 +1,5 @@ using Bit.Core.Settings; -using IdentityServer4.Models; +using Duende.IdentityServer.Models; namespace Bit.Identity.IdentityServer; diff --git a/src/Identity/IdentityServer/ApiResources.cs b/src/Identity/IdentityServer/ApiResources.cs index d23c06d7db..aa4104127c 100644 --- a/src/Identity/IdentityServer/ApiResources.cs +++ b/src/Identity/IdentityServer/ApiResources.cs @@ -1,7 +1,7 @@ using Bit.Core.Identity; using Bit.Core.IdentityServer; +using Duende.IdentityServer.Models; using IdentityModel; -using IdentityServer4.Models; namespace Bit.Identity.IdentityServer; diff --git a/src/Identity/IdentityServer/AuthorizationCodeStore.cs b/src/Identity/IdentityServer/AuthorizationCodeStore.cs index da63d9c4ad..8215532ba8 100644 --- a/src/Identity/IdentityServer/AuthorizationCodeStore.cs +++ b/src/Identity/IdentityServer/AuthorizationCodeStore.cs @@ -1,13 +1,12 @@ -using IdentityServer4; -using IdentityServer4.Extensions; -using IdentityServer4.Models; -using IdentityServer4.Services; -using IdentityServer4.Stores; -using IdentityServer4.Stores.Serialization; +using Duende.IdentityServer; +using Duende.IdentityServer.Extensions; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Services; +using Duende.IdentityServer.Stores; +using Duende.IdentityServer.Stores.Serialization; namespace Bit.Identity.IdentityServer; -// ref: https://raw.githubusercontent.com/IdentityServer/IdentityServer4/3.1.3/src/IdentityServer4/src/Stores/Default/DefaultAuthorizationCodeStore.cs public class AuthorizationCodeStore : DefaultGrantStore, IAuthorizationCodeStore { public AuthorizationCodeStore( diff --git a/src/Identity/IdentityServer/BaseRequestValidator.cs b/src/Identity/IdentityServer/BaseRequestValidator.cs index c01dc22303..40db804be3 100644 --- a/src/Identity/IdentityServer/BaseRequestValidator.cs +++ b/src/Identity/IdentityServer/BaseRequestValidator.cs @@ -22,7 +22,7 @@ using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Tokens; using Bit.Core.Utilities; -using IdentityServer4.Validation; +using Duende.IdentityServer.Validation; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Caching.Distributed; diff --git a/src/Identity/IdentityServer/ClientStore.cs b/src/Identity/IdentityServer/ClientStore.cs index 259898f209..19a4f8ffa8 100644 --- a/src/Identity/IdentityServer/ClientStore.cs +++ b/src/Identity/IdentityServer/ClientStore.cs @@ -11,9 +11,9 @@ using Bit.Core.SecretsManager.Repositories; using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Utilities; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Stores; using IdentityModel; -using IdentityServer4.Models; -using IdentityServer4.Stores; namespace Bit.Identity.IdentityServer; diff --git a/src/Identity/IdentityServer/CustomTokenRequestValidator.cs b/src/Identity/IdentityServer/CustomTokenRequestValidator.cs index 00f563154f..0ebd6f8ae7 100644 --- a/src/Identity/IdentityServer/CustomTokenRequestValidator.cs +++ b/src/Identity/IdentityServer/CustomTokenRequestValidator.cs @@ -10,9 +10,9 @@ using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Tokens; +using Duende.IdentityServer.Extensions; +using Duende.IdentityServer.Validation; using IdentityModel; -using IdentityServer4.Extensions; -using IdentityServer4.Validation; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Caching.Distributed; diff --git a/src/Identity/IdentityServer/PersistedGrantStore.cs b/src/Identity/IdentityServer/PersistedGrantStore.cs index 5a3b15f627..9d8ebffd0d 100644 --- a/src/Identity/IdentityServer/PersistedGrantStore.cs +++ b/src/Identity/IdentityServer/PersistedGrantStore.cs @@ -1,6 +1,6 @@ using Bit.Core.Auth.Repositories; -using IdentityServer4.Models; -using IdentityServer4.Stores; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Stores; using Grant = Bit.Core.Auth.Entities.Grant; namespace Bit.Identity.IdentityServer; diff --git a/src/Identity/IdentityServer/ProfileService.cs b/src/Identity/IdentityServer/ProfileService.cs index bbec6739ba..09866c6b57 100644 --- a/src/Identity/IdentityServer/ProfileService.cs +++ b/src/Identity/IdentityServer/ProfileService.cs @@ -5,8 +5,8 @@ using Bit.Core.Identity; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Utilities; -using IdentityServer4.Models; -using IdentityServer4.Services; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Services; namespace Bit.Identity.IdentityServer; diff --git a/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs index 52e39e64a6..8db6aab7cd 100644 --- a/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs +++ b/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs @@ -11,8 +11,8 @@ using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Tokens; using Bit.Core.Utilities; -using IdentityServer4.Models; -using IdentityServer4.Validation; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Validation; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Caching.Distributed; diff --git a/src/Identity/IdentityServer/StaticClientStore.cs b/src/Identity/IdentityServer/StaticClientStore.cs index 537f389925..811880dde2 100644 --- a/src/Identity/IdentityServer/StaticClientStore.cs +++ b/src/Identity/IdentityServer/StaticClientStore.cs @@ -1,6 +1,6 @@ using Bit.Core.Enums; using Bit.Core.Settings; -using IdentityServer4.Models; +using Duende.IdentityServer.Models; namespace Bit.Identity.IdentityServer; diff --git a/src/Identity/IdentityServer/VaultCorsPolicyService.cs b/src/Identity/IdentityServer/VaultCorsPolicyService.cs index 867644c54b..f8e76dd527 100644 --- a/src/Identity/IdentityServer/VaultCorsPolicyService.cs +++ b/src/Identity/IdentityServer/VaultCorsPolicyService.cs @@ -1,6 +1,6 @@ using Bit.Core.Settings; using Bit.Core.Utilities; -using IdentityServer4.Services; +using Duende.IdentityServer.Services; namespace Bit.Identity.IdentityServer; diff --git a/src/Identity/IdentityServer/WebAuthnGrantValidator.cs b/src/Identity/IdentityServer/WebAuthnGrantValidator.cs index 8d3761d6c0..a959b63840 100644 --- a/src/Identity/IdentityServer/WebAuthnGrantValidator.cs +++ b/src/Identity/IdentityServer/WebAuthnGrantValidator.cs @@ -11,9 +11,9 @@ using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Tokens; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Validation; using Fido2NetLib; -using IdentityServer4.Models; -using IdentityServer4.Validation; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Caching.Distributed; diff --git a/src/Identity/Program.cs b/src/Identity/Program.cs index 2ca52bffe7..31a69975ad 100644 --- a/src/Identity/Program.cs +++ b/src/Identity/Program.cs @@ -29,8 +29,8 @@ public class Program return e.Level >= globalSettings.MinLogLevel.IdentitySettings.IpRateLimit; } - if (context.Contains("IdentityServer4.Validation.TokenValidator") || - context.Contains("IdentityServer4.Validation.TokenRequestValidator")) + if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") || + context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator")) { return e.Level >= globalSettings.MinLogLevel.IdentitySettings.IdentityToken; } diff --git a/src/Identity/Startup.cs b/src/Identity/Startup.cs index 472dad809f..9a7874820d 100644 --- a/src/Identity/Startup.cs +++ b/src/Identity/Startup.cs @@ -10,7 +10,7 @@ using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.Identity.Utilities; using Bit.SharedWeb.Utilities; -using IdentityServer4.Extensions; +using Duende.IdentityServer.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.IdentityModel.Logging; using Microsoft.OpenApi.Models; diff --git a/src/Identity/Utilities/DiscoveryResponseGenerator.cs b/src/Identity/Utilities/DiscoveryResponseGenerator.cs index da06180989..58d9252f2d 100644 --- a/src/Identity/Utilities/DiscoveryResponseGenerator.cs +++ b/src/Identity/Utilities/DiscoveryResponseGenerator.cs @@ -1,13 +1,13 @@ using Bit.Core.Settings; using Bit.Core.Utilities; -using IdentityServer4.Configuration; -using IdentityServer4.Services; -using IdentityServer4.Stores; -using IdentityServer4.Validation; +using Duende.IdentityServer.Configuration; +using Duende.IdentityServer.Services; +using Duende.IdentityServer.Stores; +using Duende.IdentityServer.Validation; namespace Bit.Identity.Utilities; -public class DiscoveryResponseGenerator : IdentityServer4.ResponseHandling.DiscoveryResponseGenerator +public class DiscoveryResponseGenerator : Duende.IdentityServer.ResponseHandling.DiscoveryResponseGenerator { private readonly GlobalSettings _globalSettings; diff --git a/src/Identity/Utilities/ServiceCollectionExtensions.cs b/src/Identity/Utilities/ServiceCollectionExtensions.cs index 53b9c49e90..e1dd510ecc 100644 --- a/src/Identity/Utilities/ServiceCollectionExtensions.cs +++ b/src/Identity/Utilities/ServiceCollectionExtensions.cs @@ -2,9 +2,9 @@ using Bit.Core.Settings; using Bit.Identity.IdentityServer; using Bit.SharedWeb.Utilities; -using IdentityServer4.ResponseHandling; -using IdentityServer4.Services; -using IdentityServer4.Stores; +using Duende.IdentityServer.ResponseHandling; +using Duende.IdentityServer.Services; +using Duende.IdentityServer.Stores; namespace Bit.Identity.Utilities; @@ -35,6 +35,7 @@ public static class ServiceCollectionExtensions options.Authentication.CookieSameSiteMode = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified; } options.InputLengthRestrictions.UserName = 256; + options.KeyManagement.Enabled = false; }) .AddInMemoryCaching() .AddInMemoryApiResources(ApiResources.GetApiResources()) diff --git a/src/Identity/packages.lock.json b/src/Identity/packages.lock.json index 39d46d594b..76b71301d4 100644 --- a/src/Identity/packages.lock.json +++ b/src/Identity/packages.lock.json @@ -193,6 +193,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -229,49 +247,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -363,10 +340,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -399,8 +376,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2639,10 +2616,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Infrastructure.Dapper/packages.lock.json b/src/Infrastructure.Dapper/packages.lock.json index 54c4ee47e3..a1e930670e 100644 --- a/src/Infrastructure.Dapper/packages.lock.json +++ b/src/Infrastructure.Dapper/packages.lock.json @@ -168,6 +168,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -204,49 +222,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -324,10 +301,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -360,8 +337,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2456,10 +2433,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Infrastructure.EntityFramework/packages.lock.json b/src/Infrastructure.EntityFramework/packages.lock.json index 4726641520..11b1e49bcb 100644 --- a/src/Infrastructure.EntityFramework/packages.lock.json +++ b/src/Infrastructure.EntityFramework/packages.lock.json @@ -242,6 +242,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -278,49 +296,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -403,10 +380,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -439,8 +416,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2619,10 +2596,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/Notifications/Program.cs b/src/Notifications/Program.cs index 48221c2c4e..072c2404c4 100644 --- a/src/Notifications/Program.cs +++ b/src/Notifications/Program.cs @@ -17,8 +17,8 @@ public class Program logging.AddSerilog(hostingContext, (e, globalSettings) => { var context = e.Properties["SourceContext"].ToString(); - if (context.Contains("IdentityServer4.Validation.TokenValidator") || - context.Contains("IdentityServer4.Validation.TokenRequestValidator")) + if (context.Contains("Duende.IdentityServer.Validation.TokenValidator") || + context.Contains("Duende.IdentityServer.Validation.TokenRequestValidator")) { return e.Level >= globalSettings.MinLogLevel.NotificationsSettings.IdentityToken; } diff --git a/src/Notifications/packages.lock.json b/src/Notifications/packages.lock.json index 093b338ca5..945466f30f 100644 --- a/src/Notifications/packages.lock.json +++ b/src/Notifications/packages.lock.json @@ -205,6 +205,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -241,49 +259,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -394,10 +371,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Connections.Abstractions": { @@ -439,8 +416,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.AspNetCore.SignalR.Common": { "type": "Transitive", @@ -2667,10 +2644,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs index 2a2a06efe0..a526ee7420 100644 --- a/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs +++ b/src/SharedWeb/Utilities/ServiceCollectionExtensions.cs @@ -33,10 +33,10 @@ using Bit.Core.Vault.Services; using Bit.Infrastructure.Dapper; using Bit.Infrastructure.EntityFramework; using DnsClient; +using Duende.IdentityServer.Configuration; using IdentityModel; -using IdentityServer4.AccessTokenValidation; -using IdentityServer4.Configuration; using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; @@ -435,16 +435,24 @@ public static class ServiceCollectionExtensions this IServiceCollection services, GlobalSettings globalSettings, IWebHostEnvironment environment, Action addAuthorization) { - services - .AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) - .AddIdentityServerAuthentication(options => + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => { + options.MapInboundClaims = false; options.Authority = globalSettings.BaseServiceUri.InternalIdentity; options.RequireHttpsMetadata = !environment.IsDevelopment() && globalSettings.BaseServiceUri.InternalIdentity.StartsWith("https"); - options.TokenRetriever = TokenRetrieval.FromAuthorizationHeaderOrQueryString(); - options.NameClaimType = ClaimTypes.Email; - options.SupportedTokens = SupportedTokens.Jwt; + options.TokenValidationParameters.ValidateAudience = false; + options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" }; + options.TokenValidationParameters.NameClaimType = ClaimTypes.Email; + options.Events = new JwtBearerEvents + { + OnMessageReceived = (context) => + { + context.Token = TokenRetrieval.FromAuthorizationHeaderOrQueryString()(context.Request); + return Task.CompletedTask; + } + }; }); if (addAuthorization != null) diff --git a/src/SharedWeb/packages.lock.json b/src/SharedWeb/packages.lock.json index 1eb437f1e9..49f69e5168 100644 --- a/src/SharedWeb/packages.lock.json +++ b/src/SharedWeb/packages.lock.json @@ -184,6 +184,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -220,49 +238,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -354,10 +331,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -390,8 +367,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2617,10 +2594,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs b/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs index dc27ad5068..90a2335c22 100644 --- a/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs +++ b/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs @@ -1,6 +1,6 @@ using Bit.Core.Auth.Models.Api.Request.Accounts; using Bit.IntegrationTestCommon.Factories; -using IdentityServer4.AccessTokenValidation; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.TestHost; using Microsoft.Data.Sqlite; @@ -27,12 +27,12 @@ public class ApiApplicationFactory : WebApplicationFactoryBase builder.ConfigureTestServices(services => { // Remove scheduled background jobs to prevent errors in parallel test execution - var jobService = services.First(sd => sd.ServiceType == typeof(Microsoft.Extensions.Hosting.IHostedService) && sd.ImplementationType == typeof(Bit.Api.Jobs.JobsHostedService)); + var jobService = services.First(sd => sd.ServiceType == typeof(IHostedService) && sd.ImplementationType == typeof(Jobs.JobsHostedService)); services.Remove(jobService); - services.PostConfigure(IdentityServerAuthenticationDefaults.AuthenticationScheme, options => + services.Configure(JwtBearerDefaults.AuthenticationScheme, options => { - options.JwtBackChannelHandler = _identityApplicationFactory.Server.CreateHandler(); + options.BackchannelHttpHandler = _identityApplicationFactory.Server.CreateHandler(); }); }); } diff --git a/test/Api.IntegrationTest/packages.lock.json b/test/Api.IntegrationTest/packages.lock.json index f9546c72f3..d6a2819d25 100644 --- a/test/Api.IntegrationTest/packages.lock.json +++ b/test/Api.IntegrationTest/packages.lock.json @@ -364,6 +364,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -408,49 +426,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -551,10 +528,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -587,8 +564,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.AspNetCore.Mvc.Testing": { "type": "Transitive", @@ -3202,10 +3179,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Api.Test/packages.lock.json b/test/Api.Test/packages.lock.json index 2021ff15c1..b693e7a651 100644 --- a/test/Api.Test/packages.lock.json +++ b/test/Api.Test/packages.lock.json @@ -374,6 +374,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -418,49 +436,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -561,10 +538,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -597,8 +574,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -3079,10 +3056,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Billing.Test/packages.lock.json b/test/Billing.Test/packages.lock.json index a96af9daaa..6b13d059d9 100644 --- a/test/Billing.Test/packages.lock.json +++ b/test/Billing.Test/packages.lock.json @@ -280,6 +280,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -324,49 +342,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -467,10 +444,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -503,8 +480,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2889,10 +2866,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Common/packages.lock.json b/test/Common/packages.lock.json index 73363ce175..4884fdbc15 100644 --- a/test/Common/packages.lock.json +++ b/test/Common/packages.lock.json @@ -254,6 +254,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -298,49 +316,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -418,10 +395,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -454,8 +431,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2690,10 +2667,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Core.Test/packages.lock.json b/test/Core.Test/packages.lock.json index 323fe132db..0a6178c3e3 100644 --- a/test/Core.Test/packages.lock.json +++ b/test/Core.Test/packages.lock.json @@ -260,6 +260,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -304,49 +322,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -424,10 +401,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -460,8 +437,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2708,10 +2685,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Icons.Test/packages.lock.json b/test/Icons.Test/packages.lock.json index f0262577a7..01fe4b7877 100644 --- a/test/Icons.Test/packages.lock.json +++ b/test/Icons.Test/packages.lock.json @@ -278,6 +278,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -322,49 +340,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -465,10 +442,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -501,8 +478,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2880,10 +2857,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Identity.IntegrationTest/Endpoints/IdentityServerSsoTests.cs b/test/Identity.IntegrationTest/Endpoints/IdentityServerSsoTests.cs index 8e9e82c6b7..d9d8d17886 100644 --- a/test/Identity.IntegrationTest/Endpoints/IdentityServerSsoTests.cs +++ b/test/Identity.IntegrationTest/Endpoints/IdentityServerSsoTests.cs @@ -15,9 +15,9 @@ using Bit.Core.Services; using Bit.Core.Utilities; using Bit.IntegrationTestCommon.Factories; using Bit.Test.Common.Helpers; +using Duende.IdentityServer.Models; +using Duende.IdentityServer.Stores; using IdentityModel; -using IdentityServer4.Models; -using IdentityServer4.Stores; using Microsoft.EntityFrameworkCore; using NSubstitute; using Xunit; @@ -564,7 +564,7 @@ public class IdentityServerSsoTests new Claim(JwtClaimTypes.SessionId, "SOMETHING"), new Claim(JwtClaimTypes.AuthenticationMethod, "external"), new Claim(JwtClaimTypes.AuthenticationTime, DateTime.UtcNow.AddMinutes(-1).ToEpochTime().ToString()) - }, "IdentityServer4", JwtClaimTypes.Name, JwtClaimTypes.Role)); + }, "Duende.IdentityServer", JwtClaimTypes.Name, JwtClaimTypes.Role)); authorizationCode.Subject = subject; diff --git a/test/Identity.IntegrationTest/openid-configuration.json b/test/Identity.IntegrationTest/openid-configuration.json index 97e8105f48..e593a93007 100644 --- a/test/Identity.IntegrationTest/openid-configuration.json +++ b/test/Identity.IntegrationTest/openid-configuration.json @@ -4,6 +4,7 @@ "authorization_endpoint": "http://localhost:33656/connect/authorize", "token_endpoint": "http://localhost:33656/connect/token", "device_authorization_endpoint": "http://localhost:33656/connect/deviceauthorization", + "backchannel_authentication_endpoint": "http://localhost:33656/connect/ciba", "scopes_supported": [ "api", "api.push", @@ -39,6 +40,7 @@ "implicit", "password", "urn:ietf:params:oauth:grant-type:device_code", + "urn:openid:params:grant-type:ciba", "webauthn" ], "response_types_supported": [ @@ -58,5 +60,22 @@ "id_token_signing_alg_values_supported": ["RS256"], "subject_types_supported": ["public"], "code_challenge_methods_supported": ["plain", "S256"], - "request_parameter_supported": true + "request_parameter_supported": true, + "request_object_signing_alg_values_supported": [ + "RS256", + "RS384", + "RS512", + "PS256", + "PS384", + "PS512", + "ES256", + "ES384", + "ES512", + "HS256", + "HS384", + "HS512" + ], + "authorization_response_iss_parameter_supported": true, + "backchannel_token_delivery_modes_supported": ["poll"], + "backchannel_user_code_parameter_supported": true } diff --git a/test/Identity.IntegrationTest/packages.lock.json b/test/Identity.IntegrationTest/packages.lock.json index ea0971bf85..987f1dd8ed 100644 --- a/test/Identity.IntegrationTest/packages.lock.json +++ b/test/Identity.IntegrationTest/packages.lock.json @@ -282,6 +282,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -326,49 +344,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -469,10 +446,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -505,8 +482,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.AspNetCore.TestHost": { "type": "Transitive", @@ -3019,10 +2996,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Identity.Test/packages.lock.json b/test/Identity.Test/packages.lock.json index 46c741ee13..e75c99c888 100644 --- a/test/Identity.Test/packages.lock.json +++ b/test/Identity.Test/packages.lock.json @@ -271,6 +271,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -315,49 +333,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -458,10 +435,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -494,8 +471,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2894,10 +2871,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Infrastructure.EFIntegration.Test/packages.lock.json b/test/Infrastructure.EFIntegration.Test/packages.lock.json index 25b11c6713..681f903f63 100644 --- a/test/Infrastructure.EFIntegration.Test/packages.lock.json +++ b/test/Infrastructure.EFIntegration.Test/packages.lock.json @@ -272,6 +272,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -316,49 +334,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -459,10 +436,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -495,8 +472,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2874,10 +2851,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/Infrastructure.IntegrationTest/packages.lock.json b/test/Infrastructure.IntegrationTest/packages.lock.json index 760c2e0a17..19af74e817 100644 --- a/test/Infrastructure.IntegrationTest/packages.lock.json +++ b/test/Infrastructure.IntegrationTest/packages.lock.json @@ -254,6 +254,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -290,49 +308,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -424,10 +401,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -460,8 +437,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2732,10 +2709,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/test/IntegrationTestCommon/packages.lock.json b/test/IntegrationTestCommon/packages.lock.json index 7057b9d5c8..efd3418b75 100644 --- a/test/IntegrationTestCommon/packages.lock.json +++ b/test/IntegrationTestCommon/packages.lock.json @@ -249,6 +249,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fare": { "type": "Transitive", "resolved": "2.1.1", @@ -293,49 +311,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "Kralizek.AutoFixture.Extensions.MockHttp": { "type": "Transitive", @@ -436,10 +413,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -472,8 +449,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.AspNetCore.TestHost": { "type": "Transitive", @@ -3004,10 +2981,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/util/Migrator/packages.lock.json b/util/Migrator/packages.lock.json index 0996e6bb86..af385f825f 100644 --- a/util/Migrator/packages.lock.json +++ b/util/Migrator/packages.lock.json @@ -195,6 +195,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -231,49 +249,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -351,10 +328,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -387,8 +364,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2654,10 +2631,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/util/MsSqlMigratorUtility/packages.lock.json b/util/MsSqlMigratorUtility/packages.lock.json index 10f060423a..8920d9d057 100644 --- a/util/MsSqlMigratorUtility/packages.lock.json +++ b/util/MsSqlMigratorUtility/packages.lock.json @@ -217,6 +217,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -253,49 +271,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -373,10 +350,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -409,8 +386,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2692,10 +2669,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/util/MySqlMigrations/packages.lock.json b/util/MySqlMigrations/packages.lock.json index 928d2b5bac..6ed5a13382 100644 --- a/util/MySqlMigrations/packages.lock.json +++ b/util/MySqlMigrations/packages.lock.json @@ -191,6 +191,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -232,49 +250,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -366,10 +343,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -402,8 +379,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2642,10 +2619,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/util/PostgresMigrations/packages.lock.json b/util/PostgresMigrations/packages.lock.json index 928d2b5bac..6ed5a13382 100644 --- a/util/PostgresMigrations/packages.lock.json +++ b/util/PostgresMigrations/packages.lock.json @@ -191,6 +191,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -232,49 +250,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -366,10 +343,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -402,8 +379,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2642,10 +2619,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/util/Setup/packages.lock.json b/util/Setup/packages.lock.json index 65d2baadff..e4a9d303b6 100644 --- a/util/Setup/packages.lock.json +++ b/util/Setup/packages.lock.json @@ -209,6 +209,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -237,49 +255,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -357,10 +334,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -393,8 +370,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2660,10 +2637,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/util/SqlServerEFScaffold/packages.lock.json b/util/SqlServerEFScaffold/packages.lock.json index 3955596862..f0316096f5 100644 --- a/util/SqlServerEFScaffold/packages.lock.json +++ b/util/SqlServerEFScaffold/packages.lock.json @@ -299,6 +299,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -340,49 +358,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -474,10 +451,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -510,8 +487,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2853,10 +2830,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", diff --git a/util/SqliteMigrations/packages.lock.json b/util/SqliteMigrations/packages.lock.json index 928d2b5bac..6ed5a13382 100644 --- a/util/SqliteMigrations/packages.lock.json +++ b/util/SqliteMigrations/packages.lock.json @@ -191,6 +191,24 @@ "Microsoft.Win32.Registry": "5.0.0" } }, + "Duende.IdentityServer": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "4HVjzx1F8v5J+U7oa8RGAQGj2QzmzNSu87r18Sh+dlh10uyZZL8teAaT/FaVLDObnfItGdPFvN8mwpF/HkI3Xw==", + "dependencies": { + "Duende.IdentityServer.Storage": "6.0.4", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "6.0.0" + } + }, + "Duende.IdentityServer.Storage": { + "type": "Transitive", + "resolved": "6.0.4", + "contentHash": "s5gAjfbpr2IMgI+fU2Nx+2AZdzstmbt9gpo13iX7GwvqSeSaBVqj9ZskAN0R2KF1OemPdZuGnfaTcevdXMUrrw==", + "dependencies": { + "IdentityModel": "6.0.0", + "Microsoft.AspNetCore.DataProtection.Abstractions": "6.0.0" + } + }, "Fido2": { "type": "Transitive", "resolved": "3.0.1", @@ -232,49 +250,8 @@ }, "IdentityModel": { "type": "Transitive", - "resolved": "4.4.0", - "contentHash": "b18wrIx5wnZlMxAX7oVsE+nDtAJ4hajYlH0xPlaRvo4r/fz08K6pPeZvbiqS9nfNbzfIgLFmNX+FL9qR9ZR5PA==", - "dependencies": { - "Newtonsoft.Json": "11.0.2", - "System.Text.Encodings.Web": "4.7.0" - } - }, - "IdentityModel.AspNetCore.OAuth2Introspection": { - "type": "Transitive", - "resolved": "4.0.1", - "contentHash": "ZNdMZMaj9fqR3j50vYsu+1U3QGd6n8+fqwf+a8mCTcmXGor+HgFDfdq0mM34bsmD6uEgAQup7sv2ZW5kR36dbA==", - "dependencies": { - "IdentityModel": "4.0.0" - } - }, - "IdentityServer4": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "blaxxGuOA7v/w1q+fxn97wZ+x2ecG1ZD4mc/N/ZOXMNeFZZhqv+4LF26Gecyik3nWrJPmbMEtQbLmRsKG8k61w==", - "dependencies": { - "IdentityModel": "4.4.0", - "IdentityServer4.Storage": "4.1.2", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "3.1.0", - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.6.0", - "Newtonsoft.Json": "12.0.2" - } - }, - "IdentityServer4.AccessTokenValidation": { - "type": "Transitive", - "resolved": "3.0.1", - "contentHash": "qu/M6UyN4o9NVep7q545Ms7hYAnsQqSdLbN1Fjjrn4m35lyBfeQPSSNzDryAKHbodyWOQfHaOqKEyMEJQ5Rpgw==", - "dependencies": { - "IdentityModel.AspNetCore.OAuth2Introspection": "4.0.1", - "Microsoft.AspNetCore.Authentication.JwtBearer": "3.0.0" - } - }, - "IdentityServer4.Storage": { - "type": "Transitive", - "resolved": "4.1.2", - "contentHash": "KoSffyZyyeCNTIyJiZnCuPakJ1QbCHlpty6gbWUj/7yl+w0PXIchgmmJnJSvddzBb8iZ2xew/vGlxWUIP17P2g==", - "dependencies": { - "IdentityModel": "4.4.0" - } + "resolved": "6.0.0", + "contentHash": "eVHCR7a6m/dm5RFcBzE3qs/Jg5j9R5Rjpu8aTOv9e4AFvaQtBXb5ah7kmwU+YwA0ufRwz4wf1hnIvsD2hSnI4g==" }, "LaunchDarkly.Cache": { "type": "Transitive", @@ -366,10 +343,10 @@ }, "Microsoft.AspNetCore.Authentication.OpenIdConnect": { "type": "Transitive", - "resolved": "3.1.0", - "contentHash": "O1cAQYUTU8EfRqwc5/rfTns4E4hKlFlg59fuKRrST+PzsxI6H07KqRN/JjdYhAuVYxF8jPnIGbj+zuc5paOWUw==", + "resolved": "6.0.0", + "contentHash": "cJxdro36spFzk/K2OFCddM6vZ+yoj6ug8mTFRH3Gdv1Pul/buSuCtfb/FSCp31UmS5S4C1315dU7wX3ErLFuDg==", "dependencies": { - "Microsoft.IdentityModel.Protocols.OpenIdConnect": "5.5.0" + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.10.0" } }, "Microsoft.AspNetCore.Cryptography.Internal": { @@ -402,8 +379,8 @@ }, "Microsoft.AspNetCore.DataProtection.Abstractions": { "type": "Transitive", - "resolved": "3.1.32", - "contentHash": "MPL4iVyiaRxnOUY5VATHjvhDWaAEFb77KFiUxVRklv3Z3v+STofUr1UG/aCt1O9cgN7FVTDaC5A7U+zsLub8Xg==" + "resolved": "6.0.0", + "contentHash": "Z/UU4NEBm5UgNufJmw+j5baW26ytCOIZ0G7sZocPaOzsUeBon1bkM3lSMNZQG2GmDjAIVP2XMSODf2jzSGbibw==" }, "Microsoft.Azure.Amqp": { "type": "Transitive", @@ -2642,10 +2619,9 @@ "BitPay.Light": "[1.0.1907, )", "Braintree": "[5.19.0, )", "DnsClient": "[1.7.0, )", + "Duende.IdentityServer": "[6.0.4, )", "Fido2.AspNet": "[3.0.1, )", "Handlebars.Net": "[2.1.2, )", - "IdentityServer4": "[4.1.2, )", - "IdentityServer4.AccessTokenValidation": "[3.0.1, )", "LaunchDarkly.ServerSdk": "[8.0.0, )", "MailKit": "[4.2.0, )", "Microsoft.AspNetCore.Authentication.JwtBearer": "[6.0.4, )", From 636a7646a3499699589e834bee5abf0cfd0f047d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:43:57 -0500 Subject: [PATCH 11/20] Bumped version to 2023.10.3 (#3462) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- Directory.Build.props | 2 +- .../packages.lock.json | 2 +- bitwarden_license/src/Scim/packages.lock.json | 10 +++--- bitwarden_license/src/Sso/packages.lock.json | 10 +++--- .../Commercial.Core.Test/packages.lock.json | 8 ++--- .../Scim.IntegrationTest/packages.lock.json | 24 ++++++------- .../test/Scim.Test/packages.lock.json | 16 ++++----- src/Admin/packages.lock.json | 30 ++++++++-------- src/Api/packages.lock.json | 16 ++++----- src/Billing/packages.lock.json | 10 +++--- src/Events/packages.lock.json | 10 +++--- src/EventsProcessor/packages.lock.json | 10 +++--- src/Icons/packages.lock.json | 10 +++--- src/Identity/packages.lock.json | 10 +++--- src/Notifications/packages.lock.json | 10 +++--- src/SharedWeb/packages.lock.json | 4 +-- test/Api.IntegrationTest/packages.lock.json | 34 +++++++++---------- test/Api.Test/packages.lock.json | 30 ++++++++-------- test/Billing.Test/packages.lock.json | 16 ++++----- test/Core.Test/packages.lock.json | 2 +- test/Icons.Test/packages.lock.json | 16 ++++----- .../packages.lock.json | 20 +++++------ test/Identity.Test/packages.lock.json | 16 ++++----- .../packages.lock.json | 10 +++--- .../packages.lock.json | 4 +-- test/IntegrationTestCommon/packages.lock.json | 16 ++++----- util/MsSqlMigratorUtility/packages.lock.json | 2 +- util/MySqlMigrations/packages.lock.json | 2 +- util/PostgresMigrations/packages.lock.json | 2 +- util/Setup/packages.lock.json | 2 +- util/SqlServerEFScaffold/packages.lock.json | 24 ++++++------- util/SqliteMigrations/packages.lock.json | 2 +- 32 files changed, 190 insertions(+), 190 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index e6be6fa772..d83db2eabe 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ net6.0 - 2023.10.2 + 2023.10.3 Bit.$(MSBuildProjectName) true enable diff --git a/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json b/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json index 86b2eec18d..ad8c027175 100644 --- a/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json +++ b/bitwarden_license/src/Commercial.Infrastructure.EntityFramework/packages.lock.json @@ -2621,7 +2621,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", diff --git a/bitwarden_license/src/Scim/packages.lock.json b/bitwarden_license/src/Scim/packages.lock.json index 152fab7bf3..8db5c0eb8e 100644 --- a/bitwarden_license/src/Scim/packages.lock.json +++ b/bitwarden_license/src/Scim/packages.lock.json @@ -2624,7 +2624,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2632,7 +2632,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2644,9 +2644,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/bitwarden_license/src/Sso/packages.lock.json b/bitwarden_license/src/Sso/packages.lock.json index ce589b096b..3d1dd5ff0d 100644 --- a/bitwarden_license/src/Sso/packages.lock.json +++ b/bitwarden_license/src/Sso/packages.lock.json @@ -2784,7 +2784,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2792,7 +2792,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2804,9 +2804,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/bitwarden_license/test/Commercial.Core.Test/packages.lock.json b/bitwarden_license/test/Commercial.Core.Test/packages.lock.json index 4b2b6fdd5e..aeb2ea4dde 100644 --- a/bitwarden_license/test/Commercial.Core.Test/packages.lock.json +++ b/bitwarden_license/test/Commercial.Core.Test/packages.lock.json @@ -2657,7 +2657,7 @@ "commercial.core": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )" + "Core": "[2023.10.3, )" } }, "common": { @@ -2665,7 +2665,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -2719,8 +2719,8 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Common": "[2023.10.2, )", - "Core": "[2023.10.2, )", + "Common": "[2023.10.3, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", diff --git a/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json b/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json index 3f5575a874..4b680747e5 100644 --- a/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json +++ b/bitwarden_license/test/Scim.IntegrationTest/packages.lock.json @@ -2974,7 +2974,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -3026,15 +3026,15 @@ "identity": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore.SwaggerGen": "[6.5.0, )" } }, "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -3042,7 +3042,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -3054,8 +3054,8 @@ "integrationtestcommon": { "type": "Project", "dependencies": { - "Common": "[2023.10.2, )", - "Identity": "[2023.10.2, )", + "Common": "[2023.10.3, )", + "Identity": "[2023.10.3, )", "Microsoft.AspNetCore.Mvc.Testing": "[6.0.5, )", "Microsoft.Extensions.Configuration": "[6.0.1, )" } @@ -3063,16 +3063,16 @@ "scim": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )" } }, "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/bitwarden_license/test/Scim.Test/packages.lock.json b/bitwarden_license/test/Scim.Test/packages.lock.json index d7f1ce34b2..7710a7aa60 100644 --- a/bitwarden_license/test/Scim.Test/packages.lock.json +++ b/bitwarden_license/test/Scim.Test/packages.lock.json @@ -2827,7 +2827,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -2879,7 +2879,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2887,7 +2887,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2899,16 +2899,16 @@ "scim": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )" } }, "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/Admin/packages.lock.json b/src/Admin/packages.lock.json index a7edbdf763..b50a7f9dbf 100644 --- a/src/Admin/packages.lock.json +++ b/src/Admin/packages.lock.json @@ -2785,15 +2785,15 @@ "commercial.core": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )" + "Core": "[2023.10.3, )" } }, "commercial.infrastructure.entityframework": { "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "core": { @@ -2841,7 +2841,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2849,7 +2849,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2861,7 +2861,7 @@ "migrator": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.Extensions.Logging": "[6.0.0, )", "dbup-sqlserver": "[5.0.8, )" } @@ -2869,30 +2869,30 @@ "mysqlmigrations": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "postgresmigrations": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "sqlitemigrations": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/Api/packages.lock.json b/src/Api/packages.lock.json index 432d80cab6..b24c4205f9 100644 --- a/src/Api/packages.lock.json +++ b/src/Api/packages.lock.json @@ -2765,15 +2765,15 @@ "commercial.core": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )" + "Core": "[2023.10.3, )" } }, "commercial.infrastructure.entityframework": { "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "core": { @@ -2821,7 +2821,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2829,7 +2829,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2841,9 +2841,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/Billing/packages.lock.json b/src/Billing/packages.lock.json index 152fab7bf3..8db5c0eb8e 100644 --- a/src/Billing/packages.lock.json +++ b/src/Billing/packages.lock.json @@ -2624,7 +2624,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2632,7 +2632,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2644,9 +2644,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/Events/packages.lock.json b/src/Events/packages.lock.json index 152fab7bf3..8db5c0eb8e 100644 --- a/src/Events/packages.lock.json +++ b/src/Events/packages.lock.json @@ -2624,7 +2624,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2632,7 +2632,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2644,9 +2644,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/EventsProcessor/packages.lock.json b/src/EventsProcessor/packages.lock.json index 152fab7bf3..8db5c0eb8e 100644 --- a/src/EventsProcessor/packages.lock.json +++ b/src/EventsProcessor/packages.lock.json @@ -2624,7 +2624,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2632,7 +2632,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2644,9 +2644,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/Icons/packages.lock.json b/src/Icons/packages.lock.json index 705ea80ff8..8a2fda13e5 100644 --- a/src/Icons/packages.lock.json +++ b/src/Icons/packages.lock.json @@ -2633,7 +2633,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2641,7 +2641,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2653,9 +2653,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/Identity/packages.lock.json b/src/Identity/packages.lock.json index 76b71301d4..97e4f820c5 100644 --- a/src/Identity/packages.lock.json +++ b/src/Identity/packages.lock.json @@ -2646,7 +2646,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2654,7 +2654,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2666,9 +2666,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/Notifications/packages.lock.json b/src/Notifications/packages.lock.json index 945466f30f..38c5b97637 100644 --- a/src/Notifications/packages.lock.json +++ b/src/Notifications/packages.lock.json @@ -2674,7 +2674,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2682,7 +2682,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2694,9 +2694,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/src/SharedWeb/packages.lock.json b/src/SharedWeb/packages.lock.json index 49f69e5168..da8cacb2d1 100644 --- a/src/SharedWeb/packages.lock.json +++ b/src/SharedWeb/packages.lock.json @@ -2624,7 +2624,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2632,7 +2632,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", diff --git a/test/Api.IntegrationTest/packages.lock.json b/test/Api.IntegrationTest/packages.lock.json index d6a2819d25..e02aac6c5e 100644 --- a/test/Api.IntegrationTest/packages.lock.json +++ b/test/Api.IntegrationTest/packages.lock.json @@ -3131,25 +3131,25 @@ "AspNetCore.HealthChecks.SqlServer": "[6.0.2, )", "AspNetCore.HealthChecks.Uris": "[6.0.3, )", "Azure.Messaging.EventGrid": "[4.10.0, )", - "Commercial.Core": "[2023.10.2, )", - "Commercial.Infrastructure.EntityFramework": "[2023.10.2, )", - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Commercial.Core": "[2023.10.3, )", + "Commercial.Infrastructure.EntityFramework": "[2023.10.3, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore": "[6.5.0, )" } }, "commercial.core": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )" + "Core": "[2023.10.3, )" } }, "commercial.infrastructure.entityframework": { "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "common": { @@ -3157,7 +3157,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -3209,15 +3209,15 @@ "identity": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore.SwaggerGen": "[6.5.0, )" } }, "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -3225,7 +3225,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -3237,8 +3237,8 @@ "integrationtestcommon": { "type": "Project", "dependencies": { - "Common": "[2023.10.2, )", - "Identity": "[2023.10.2, )", + "Common": "[2023.10.3, )", + "Identity": "[2023.10.3, )", "Microsoft.AspNetCore.Mvc.Testing": "[6.0.5, )", "Microsoft.Extensions.Configuration": "[6.0.1, )" } @@ -3246,9 +3246,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/test/Api.Test/packages.lock.json b/test/Api.Test/packages.lock.json index b693e7a651..a94a8a92f0 100644 --- a/test/Api.Test/packages.lock.json +++ b/test/Api.Test/packages.lock.json @@ -3008,25 +3008,25 @@ "AspNetCore.HealthChecks.SqlServer": "[6.0.2, )", "AspNetCore.HealthChecks.Uris": "[6.0.3, )", "Azure.Messaging.EventGrid": "[4.10.0, )", - "Commercial.Core": "[2023.10.2, )", - "Commercial.Infrastructure.EntityFramework": "[2023.10.2, )", - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Commercial.Core": "[2023.10.3, )", + "Commercial.Infrastructure.EntityFramework": "[2023.10.3, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore": "[6.5.0, )" } }, "commercial.core": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )" + "Core": "[2023.10.3, )" } }, "commercial.infrastructure.entityframework": { "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "common": { @@ -3034,7 +3034,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -3088,8 +3088,8 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Common": "[2023.10.2, )", - "Core": "[2023.10.2, )", + "Common": "[2023.10.3, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -3099,7 +3099,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -3107,7 +3107,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -3119,9 +3119,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/test/Billing.Test/packages.lock.json b/test/Billing.Test/packages.lock.json index 6b13d059d9..b0240161c9 100644 --- a/test/Billing.Test/packages.lock.json +++ b/test/Billing.Test/packages.lock.json @@ -2835,8 +2835,8 @@ "billing": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )" } }, "common": { @@ -2844,7 +2844,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -2896,7 +2896,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2904,7 +2904,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2916,9 +2916,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/test/Core.Test/packages.lock.json b/test/Core.Test/packages.lock.json index 0a6178c3e3..f81e5fe8d2 100644 --- a/test/Core.Test/packages.lock.json +++ b/test/Core.Test/packages.lock.json @@ -2663,7 +2663,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", diff --git a/test/Icons.Test/packages.lock.json b/test/Icons.Test/packages.lock.json index 01fe4b7877..0c6ba2e685 100644 --- a/test/Icons.Test/packages.lock.json +++ b/test/Icons.Test/packages.lock.json @@ -2835,7 +2835,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -2888,14 +2888,14 @@ "type": "Project", "dependencies": { "AngleSharp": "[1.0.4, )", - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )" } }, "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2903,7 +2903,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2915,9 +2915,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/test/Identity.IntegrationTest/packages.lock.json b/test/Identity.IntegrationTest/packages.lock.json index 987f1dd8ed..a509210826 100644 --- a/test/Identity.IntegrationTest/packages.lock.json +++ b/test/Identity.IntegrationTest/packages.lock.json @@ -2974,7 +2974,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -3026,15 +3026,15 @@ "identity": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore.SwaggerGen": "[6.5.0, )" } }, "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -3042,7 +3042,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -3054,8 +3054,8 @@ "integrationtestcommon": { "type": "Project", "dependencies": { - "Common": "[2023.10.2, )", - "Identity": "[2023.10.2, )", + "Common": "[2023.10.3, )", + "Identity": "[2023.10.3, )", "Microsoft.AspNetCore.Mvc.Testing": "[6.0.5, )", "Microsoft.Extensions.Configuration": "[6.0.1, )" } @@ -3063,9 +3063,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/test/Identity.Test/packages.lock.json b/test/Identity.Test/packages.lock.json index e75c99c888..ef3fa76ef6 100644 --- a/test/Identity.Test/packages.lock.json +++ b/test/Identity.Test/packages.lock.json @@ -2849,7 +2849,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -2901,15 +2901,15 @@ "identity": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore.SwaggerGen": "[6.5.0, )" } }, "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2917,7 +2917,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2929,9 +2929,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/test/Infrastructure.EFIntegration.Test/packages.lock.json b/test/Infrastructure.EFIntegration.Test/packages.lock.json index 681f903f63..4d4e99dc14 100644 --- a/test/Infrastructure.EFIntegration.Test/packages.lock.json +++ b/test/Infrastructure.EFIntegration.Test/packages.lock.json @@ -2829,7 +2829,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -2883,8 +2883,8 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Common": "[2023.10.2, )", - "Core": "[2023.10.2, )", + "Common": "[2023.10.3, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -2894,7 +2894,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2902,7 +2902,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", diff --git a/test/Infrastructure.IntegrationTest/packages.lock.json b/test/Infrastructure.IntegrationTest/packages.lock.json index 19af74e817..e865ff92ec 100644 --- a/test/Infrastructure.IntegrationTest/packages.lock.json +++ b/test/Infrastructure.IntegrationTest/packages.lock.json @@ -2739,7 +2739,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2747,7 +2747,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", diff --git a/test/IntegrationTestCommon/packages.lock.json b/test/IntegrationTestCommon/packages.lock.json index efd3418b75..f510727702 100644 --- a/test/IntegrationTestCommon/packages.lock.json +++ b/test/IntegrationTestCommon/packages.lock.json @@ -2959,7 +2959,7 @@ "dependencies": { "AutoFixture.AutoNSubstitute": "[4.17.0, )", "AutoFixture.Xunit2": "[4.17.0, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Kralizek.AutoFixture.Extensions.MockHttp": "[1.2.0, )", "Microsoft.NET.Test.Sdk": "[17.1.0, )", "NSubstitute": "[4.3.0, )", @@ -3011,15 +3011,15 @@ "identity": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore.SwaggerGen": "[6.5.0, )" } }, "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -3027,7 +3027,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -3039,9 +3039,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/util/MsSqlMigratorUtility/packages.lock.json b/util/MsSqlMigratorUtility/packages.lock.json index 8920d9d057..04efaa157c 100644 --- a/util/MsSqlMigratorUtility/packages.lock.json +++ b/util/MsSqlMigratorUtility/packages.lock.json @@ -2699,7 +2699,7 @@ "migrator": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.Extensions.Logging": "[6.0.0, )", "dbup-sqlserver": "[5.0.8, )" } diff --git a/util/MySqlMigrations/packages.lock.json b/util/MySqlMigrations/packages.lock.json index 6ed5a13382..6645715d9b 100644 --- a/util/MySqlMigrations/packages.lock.json +++ b/util/MySqlMigrations/packages.lock.json @@ -2650,7 +2650,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", diff --git a/util/PostgresMigrations/packages.lock.json b/util/PostgresMigrations/packages.lock.json index 6ed5a13382..6645715d9b 100644 --- a/util/PostgresMigrations/packages.lock.json +++ b/util/PostgresMigrations/packages.lock.json @@ -2650,7 +2650,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", diff --git a/util/Setup/packages.lock.json b/util/Setup/packages.lock.json index e4a9d303b6..b298124e64 100644 --- a/util/Setup/packages.lock.json +++ b/util/Setup/packages.lock.json @@ -2667,7 +2667,7 @@ "migrator": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.Extensions.Logging": "[6.0.0, )", "dbup-sqlserver": "[5.0.8, )" } diff --git a/util/SqlServerEFScaffold/packages.lock.json b/util/SqlServerEFScaffold/packages.lock.json index f0316096f5..8df3275387 100644 --- a/util/SqlServerEFScaffold/packages.lock.json +++ b/util/SqlServerEFScaffold/packages.lock.json @@ -2794,25 +2794,25 @@ "AspNetCore.HealthChecks.SqlServer": "[6.0.2, )", "AspNetCore.HealthChecks.Uris": "[6.0.3, )", "Azure.Messaging.EventGrid": "[4.10.0, )", - "Commercial.Core": "[2023.10.2, )", - "Commercial.Infrastructure.EntityFramework": "[2023.10.2, )", - "Core": "[2023.10.2, )", - "SharedWeb": "[2023.10.2, )", + "Commercial.Core": "[2023.10.3, )", + "Commercial.Infrastructure.EntityFramework": "[2023.10.3, )", + "Core": "[2023.10.3, )", + "SharedWeb": "[2023.10.3, )", "Swashbuckle.AspNetCore": "[6.5.0, )" } }, "commercial.core": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )" + "Core": "[2023.10.3, )" } }, "commercial.infrastructure.entityframework": { "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } }, "core": { @@ -2860,7 +2860,7 @@ "infrastructure.dapper": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Dapper": "[2.0.123, )" } }, @@ -2868,7 +2868,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", @@ -2880,9 +2880,9 @@ "sharedweb": { "type": "Project", "dependencies": { - "Core": "[2023.10.2, )", - "Infrastructure.Dapper": "[2023.10.2, )", - "Infrastructure.EntityFramework": "[2023.10.2, )" + "Core": "[2023.10.3, )", + "Infrastructure.Dapper": "[2023.10.3, )", + "Infrastructure.EntityFramework": "[2023.10.3, )" } } } diff --git a/util/SqliteMigrations/packages.lock.json b/util/SqliteMigrations/packages.lock.json index 6ed5a13382..6645715d9b 100644 --- a/util/SqliteMigrations/packages.lock.json +++ b/util/SqliteMigrations/packages.lock.json @@ -2650,7 +2650,7 @@ "type": "Project", "dependencies": { "AutoMapper.Extensions.Microsoft.DependencyInjection": "[12.0.1, )", - "Core": "[2023.10.2, )", + "Core": "[2023.10.3, )", "Microsoft.EntityFrameworkCore.Relational": "[7.0.5, )", "Microsoft.EntityFrameworkCore.SqlServer": "[7.0.5, )", "Microsoft.EntityFrameworkCore.Sqlite": "[7.0.5, )", From dba7a79ad248ed6ebb494cffd570b4ea3a6c1b3d Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Tue, 21 Nov 2023 18:09:27 -0800 Subject: [PATCH 12/20] [AC-1696] Fix Provider permissions for Flexible Collections (#3381) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [AC-1117] Add manage permission (#3126) * Update sql files to add Manage permission * Add migration script * Rename collection manage migration file to remove duplicate migration date * Migrations * Add manage to models * Add manage to repository * Add constraint to Manage columns * Migration lint fixes * Add manage to OrganizationUserUserDetails_ReadWithCollectionsById * Add missing manage fields * Add 'Manage' to UserCollectionDetails * Use CREATE OR ALTER where possible * [AC-1374] Limit collection creation/deletion to Owner/Admin (#3145) * feat: update org table with new column, write migration, refs AC-1374 * feat: update views with new column, refs AC-1374 * feat: Alter sprocs (org create/update) to include new column, refs AC-1374 * feat: update entity/data/request/response models to handle new column, refs AC-1374 * feat: update necessary Provider related views during migration, refs AC-1374 * fix: update org create to default new column to false, refs AC-1374 * feat: added new API/request model for collection management and removed property from update request model, refs AC-1374 * fix: renamed migration script to be after secrets manage beta column changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: add ef migrations to reflect mssql changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: update API signature to accept Guid and explain Cd verbiage, refs AC-1374 * fix: merge conflict resolution * [AC-1174] CollectionUser and CollectionGroup authorization handlers (#3194) * [AC-1174] Introduce BulkAuthorizationHandler.cs * [AC-1174] Introduce CollectionUserAuthorizationHandler * [AC-1174] Add CreateForNewCollection CollectionUser requirement * [AC-1174] Add some more details to CollectionCustomization * [AC-1174] Formatting * [AC-1174] Add CollectionGroupOperation.cs * [AC-1174] Introduce CollectionGroupAuthorizationHandler.cs * [AC-1174] Cleanup CollectionFixture customization Implement and use re-usable extension method to support seeded Guids * [AC-1174] Introduce WithValueFromList AutoFixtureExtensions Modify CollectionCustomization to use multiple organization Ids for auto generated test data * [AC-1174] Simplify CollectionUserAuthorizationHandler.cs Modify the authorization handler to only perform authorization logic. Validation logic will need to be handled by any calling commands/controllers instead. * [AC-1174] Introduce shared CollectionAccessAuthorizationHandlerBase A shared base authorization handler was created for both CollectionUser and CollectionGroup resources, as they share the same underlying management authorization logic. * [AC-1174] Update CollectionUserAuthorizationHandler and CollectionGroupAuthorizationHandler to use the new CollectionAccessAuthorizationHandlerBase class * [AC-1174] Formatting * [AC-1174] Cleanup typo and redundant ToList() call * [AC-1174] Add check for provider users * [AC-1174] Reduce nested loops * [AC-1174] Introduce ICollectionAccess.cs * [AC-1174] Remove individual CollectionGroup and CollectionUser auth handlers and use base class instead * [AC-1174] Tweak unit test to fail minimally * [AC-1174] Reorganize authorization handlers in Core project * [AC-1174] Introduce new AddCoreAuthorizationHandlers() extension method * [AC-1174] Move CollectionAccessAuthorizationHandler into Api project * [AC-1174] Move CollectionFixture to Vault folder * [AC-1174] Rename operation to CreateUpdateDelete * [AC-1174] Require single organization for collection access authorization handler - Add requirement that all target collections must belong to the same organization - Simplify logic related to multiple organizations - Update tests and helpers - Use ToHashSet to improve lookup time * [AC-1174] Fix null reference exception * [AC-1174] Throw bad request exception when collections belong to different organizations * [AC-1174] Switch to CollectionAuthorizationHandler instead of CollectionAccessAuthorizationHandler to reduce complexity * Fix improper merge conflict resolution * fix: add permission check for collection management api, refs AC-1647 (#3252) * [AC-1125] Enforce org setting for creating/deleting collections (#3241) * [AC-1117] Add manage permission (#3126) * Update sql files to add Manage permission * Add migration script * Rename collection manage migration file to remove duplicate migration date * Migrations * Add manage to models * Add manage to repository * Add constraint to Manage columns * Migration lint fixes * Add manage to OrganizationUserUserDetails_ReadWithCollectionsById * Add missing manage fields * Add 'Manage' to UserCollectionDetails * Use CREATE OR ALTER where possible * [AC-1374] Limit collection creation/deletion to Owner/Admin (#3145) * feat: update org table with new column, write migration, refs AC-1374 * feat: update views with new column, refs AC-1374 * feat: Alter sprocs (org create/update) to include new column, refs AC-1374 * feat: update entity/data/request/response models to handle new column, refs AC-1374 * feat: update necessary Provider related views during migration, refs AC-1374 * fix: update org create to default new column to false, refs AC-1374 * feat: added new API/request model for collection management and removed property from update request model, refs AC-1374 * fix: renamed migration script to be after secrets manage beta column changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: add ef migrations to reflect mssql changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: update API signature to accept Guid and explain Cd verbiage, refs AC-1374 * feat: created collection auth handler/operations, added LimitCollectionCdOwnerAdmin to CurrentContentOrganization, refs AC-1125 * feat: create vault service collection extensions and register with base services, refs AC-1125 * feat: deprecated CurrentContext.CreateNewCollections, refs AC-1125 * feat: deprecate DeleteAnyCollection for single resource usages, refs AC-1125 * feat: move service registration to api, update references, refs AC-1125 * feat: add bulk delete authorization handler, refs AC-1125 * feat: always assign user and give manage access on create, refs AC-1125 * fix: updated CurrentContextOrganization type, refs AC-1125 * feat: combined existing collection authorization handlers/operations, refs AC-1125 * fix: OrganizationServiceTests -> CurrentContentOrganization typo, refs AC-1125 * fix: format, refs AC-1125 * fix: update collection controller tests, refs AC-1125 * fix: dotnet format, refs AC-1125 * feat: removed extra BulkAuthorizationHandler, refs AC-1125 * fix: dotnet format, refs AC-1125 * fix: change string to guid for org id, update bulk delete request model, refs AC-1125 * fix: remove delete many collection check, refs AC-1125 * fix: clean up collection auth handler, refs AC-1125 * fix: format fix for CollectionOperations, refs AC-1125 * fix: removed unnecessary owner check, add org null check to custom permission validation, refs AC-1125 * fix: remove unused methods in CurrentContext, refs AC-1125 * fix: removed obsolete test, fixed failling delete many test, refs AC-1125 * fix: CollectionAuthorizationHandlerTests fixes, refs AC-1125 * fix: OrganizationServiceTests fix broken test by mocking GetOrganization, refs AC-1125 * fix: CollectionAuthorizationHandler - remove unused repository, refs AC-1125 * feat: moved UserId null check to common method, refs AC-1125 * fix: updated auth handler tests to remove dependency on requirement for common code checks, refs AC-1125 * feat: updated conditionals/comments for create/delete methods within colleciton auth handler, refs AC-1125 * feat: added create/delete collection auth handler success methods, refs AC-1125 * fix: new up permissions to prevent excessive null checks, refs AC-1125 * fix: remove old reference to CreateNewCollections, refs AC-1125 * fix: typo within ViewAssignedCollections method, refs AC-1125 --------- Co-authored-by: Robyn MacCallum * refactor: remove organizationId from CollectionBulkDeleteRequestModel, refs AC-1649 (#3282) * [AC-1174] Bulk Collection Management (#3229) * [AC-1174] Update SelectionReadOnlyRequestModel to use Guid for Id property * [AC-1174] Introduce initial bulk-access collection endpoint * [AC-1174] Introduce BulkAddCollectionAccessCommand and validation logic/tests * [AC-1174] Add CreateOrUpdateAccessMany method to CollectionRepository * [AC-1174] Add event logs for bulk add collection access command * [AC-1174] Add User_BumpAccountRevisionDateByCollectionIds and database migration script * [AC-1174] Implement EF repository method * [AC-1174] Improve null checks * [AC-1174] Remove unnecessary BulkCollectionAccessRequestModel helpers * [AC-1174] Add unit tests for new controller endpoint * [AC-1174] Fix formatting * [AC-1174] Remove comment * [AC-1174] Remove redundant organizationId parameter * [AC-1174] Ensure user and group Ids are distinct * [AC-1174] Cleanup tests based on PR feedback * [AC-1174] Formatting * [AC-1174] Update CollectionGroup alias in the sproc * [AC-1174] Add some additional comments to SQL sproc * [AC-1174] Add comment explaining additional SaveChangesAsync call --------- Co-authored-by: Thomas Rittson * [AC-1646] Rename LimitCollectionCdOwnerAdmin column (#3300) * Rename LimitCollectionCdOwnerAdmin -> LimitCollectionCreationDeletion * Rename and bump migration script * [AC-1666] Removed EditAnyCollection from Create/Delete permission checks (#3301) * fix: remove EditAnyCollection from Create/Delete permission check, refs AC-1666 * fix: updated comment, refs AC-1666 * [AC-1669] Bug - Remove obsolete assignUserId from CollectionService.SaveAsync(...) (#3312) * fix: remove AssignUserId from CollectionService.SaveAsync, refs AC-1669 * fix: add manage access conditional before creating collection, refs AC-1669 * fix: move access logic for create/update, fix all tests, refs AC-1669 * fix: add CollectionAccessSelection fixture, update tests, update bad reqeuest message, refs AC-1669 * fix: format, refs AC-1669 * fix: update null params with specific arg.is null checks, refs Ac-1669 * fix: update attribute class name, refs AC-1669 * [AC-1713] [Flexible collections] Add feature flags to server (#3334) * Add feature flags for FlexibleCollections and BulkCollectionAccess * Flag new routes and behaviour --------- Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com> * Add joint codeownership for auth handlers (#3346) * [AC-1717] Update default values for LimitCollectionCreationDeletion (#3365) * Change default value in organization create sproc to 1 * Drop old column name still present in some QA instances * Set LimitCollectionCreationDeletion value in code based on feature flag * Fix: add missing namespace after merging in master * Fix: add missing namespace after merging in master * [AC-1683] Fix DB migrations for new Manage permission (#3307) * [AC-1683] Update migration script and introduce V2 procedures and types * [AC-1683] Update repository calls to use new V2 procedures / types * [AC-1684] Update bulk add collection migration script to use new V2 type * [AC-1683] Undo Manage changes to more original procedures * [AC-1683] Restore whitespace changes * [AC-1683] Clarify comments regarding explicit column lists * [AC-1683] Update migration script dates * [AC-1683] Split the migration script for readability * [AC-1683] Re-name SelectReadOnlyArray_V2 to CollectionAccessSelectionType * [AC-1648] [Flexible Collections] Bump migration scripts before feature branch merge (#3371) * Bump dates on sql migration scripts * Bump date on ef migrations * [AC-1696] Rework collection auth handler to account for provider users - Add additional check for providers only if the org membership is null, and if the user is a provider, do not early return - Modify conditionals to use pattern matching to allow for null organization contexts from provider users - Save the target organization id as a private field to avoid additional parameter passing because org can now be null * [AC-1696] Add unit tests to collection auth handler for provider users Includes helper test method/enum for creating an xUnit theory for each collection operation. * [AC-1696] Further refactor private methods and remove provider check from public method Updates logic in private methods to only use context.Succeed() to allow for fallback permission checking for provider access. * [AC-1696] Ensure the correct organization id is provided when testing * [AC-1696] Refactor provider test to remove additional operation enum * [AC-1696] Formatting --------- Co-authored-by: Robyn MacCallum Co-authored-by: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Co-authored-by: Vincent Salucci Co-authored-by: Thomas Rittson Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com> --- .../CollectionAuthorizationHandler.cs | 127 +++++++++--------- .../CollectionAuthorizationHandlerTests.cs | 43 +++++- test/Common/AutoFixture/SutProvider.cs | 6 + 3 files changed, 108 insertions(+), 68 deletions(-) diff --git a/src/Api/Vault/AuthorizationHandlers/Collections/CollectionAuthorizationHandler.cs b/src/Api/Vault/AuthorizationHandlers/Collections/CollectionAuthorizationHandler.cs index 626402f715..9bbfc94ff2 100644 --- a/src/Api/Vault/AuthorizationHandlers/Collections/CollectionAuthorizationHandler.cs +++ b/src/Api/Vault/AuthorizationHandlers/Collections/CollectionAuthorizationHandler.cs @@ -1,4 +1,5 @@ -using Bit.Core; +#nullable enable +using Bit.Core; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Enums; @@ -19,6 +20,7 @@ public class CollectionAuthorizationHandler : BulkAuthorizationHandler resources) + CollectionOperationRequirement requirement, ICollection? resources) { if (!_featureService.IsEnabled(FeatureFlagKeys.FlexibleCollections, _currentContext)) { @@ -50,21 +52,15 @@ public class CollectionAuthorizationHandler : BulkAuthorizationHandler tc.OrganizationId != targetOrganizationId)) + if (resources.Any(tc => tc.OrganizationId != _targetOrganizationId)) { throw new BadRequestException("Requested collections must belong to the same organization."); } - // Acting user is not a member of the target organization, fail - var org = _currentContext.GetOrganization(targetOrganizationId); - if (org == null) - { - context.Fail(); - return; - } + var org = _currentContext.GetOrganization(_targetOrganizationId); switch (requirement) { @@ -83,95 +79,100 @@ public class CollectionAuthorizationHandler : BulkAuthorizationHandler resources, CurrentContextOrganization org) + ICollection resources, CurrentContextOrganization? org) { - // Owners, Admins, Providers, and users with DeleteAnyCollection permission can always delete collections - if ( - org.Type is OrganizationUserType.Owner or OrganizationUserType.Admin || - org.Permissions is { DeleteAnyCollection: true } || - await _currentContext.ProviderUserForOrgAsync(org.Id)) + // Owners, Admins, and users with DeleteAnyCollection permission can always delete collections + if (org is + { Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or + { Permissions.DeleteAnyCollection: true }) { context.Succeed(requirement); return; } - // The limit collection management setting is enabled and we are not an Admin (above condition), fail - if (org.LimitCollectionCreationDeletion) + // The limit collection management setting is disabled, + // ensure acting user has manage permissions for all collections being deleted + if (org is { LimitCollectionCreationDeletion: false }) { - context.Fail(); - return; + var manageableCollectionIds = + (await _collectionRepository.GetManyByUserIdAsync(_currentContext.UserId!.Value)) + .Where(c => c.Manage && c.OrganizationId == org.Id) + .Select(c => c.Id) + .ToHashSet(); + + // The acting user has permission to manage all target collections, succeed + if (resources.All(c => manageableCollectionIds.Contains(c.Id))) + { + context.Succeed(requirement); + return; + } } - // Other members types should have the Manage capability for all collections being deleted - var manageableCollectionIds = - (await _collectionRepository.GetManyByUserIdAsync(_currentContext.UserId!.Value)) - .Where(c => c.Manage && c.OrganizationId == org.Id) - .Select(c => c.Id) - .ToHashSet(); - - // The acting user does not have permission to manage all target collections, fail - if (resources.Any(c => !manageableCollectionIds.Contains(c.Id))) + // Allow providers to delete collections if they are a provider for the target organization + if (await _currentContext.ProviderUserForOrgAsync(_targetOrganizationId)) { - context.Fail(); - return; + context.Succeed(requirement); } - - context.Succeed(requirement); } /// /// Ensures the acting user is allowed to manage access permissions for the target collections. /// private async Task CanManageCollectionAccessAsync(AuthorizationHandlerContext context, - IAuthorizationRequirement requirement, ICollection targetCollections, CurrentContextOrganization org) + IAuthorizationRequirement requirement, ICollection targetCollections, + CurrentContextOrganization? org) { - // Owners, Admins, Providers, and users with EditAnyCollection permission can always manage collection access - if ( - org.Permissions is { EditAnyCollection: true } || - org.Type is OrganizationUserType.Owner or OrganizationUserType.Admin || - await _currentContext.ProviderUserForOrgAsync(org.Id)) + // Owners, Admins, and users with EditAnyCollection permission can always manage collection access + if (org is + { Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or + { Permissions.EditAnyCollection: true }) { context.Succeed(requirement); return; } - // List of collection Ids the acting user is allowed to manage - var manageableCollectionIds = - (await _collectionRepository.GetManyByUserIdAsync(_currentContext.UserId!.Value)) - .Where(c => c.Manage && c.OrganizationId == org.Id) - .Select(c => c.Id) - .ToHashSet(); - - // The acting user does not have permission to manage all target collections, fail - if (targetCollections.Any(tc => !manageableCollectionIds.Contains(tc.Id))) + // Only check collection management permissions if the user is a member of the target organization (org != null) + if (org is not null) { - context.Fail(); - return; + var manageableCollectionIds = + (await _collectionRepository.GetManyByUserIdAsync(_currentContext.UserId!.Value)) + .Where(c => c.Manage && c.OrganizationId == org.Id) + .Select(c => c.Id) + .ToHashSet(); + + // The acting user has permission to manage all target collections, succeed + if (targetCollections.All(c => manageableCollectionIds.Contains(c.Id))) + { + context.Succeed(requirement); + return; + } } - context.Succeed(requirement); + // Allow providers to manage collections if they are a provider for the target organization + if (await _currentContext.ProviderUserForOrgAsync(_targetOrganizationId)) + { + context.Succeed(requirement); + } } } diff --git a/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs b/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs index aaaa3076b0..6dc63b69e5 100644 --- a/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs +++ b/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs @@ -143,7 +143,7 @@ public class CollectionAuthorizationHandlerTests } [Theory, BitAutoData, CollectionCustomization] - public async Task HandleRequirementAsync_TargetCollectionsMultipleOrgs_Failure( + public async Task HandleRequirementAsync_TargetCollectionsMultipleOrgs_Exception( SutProvider sutProvider, IList collections) { @@ -166,7 +166,7 @@ public class CollectionAuthorizationHandlerTests } [Theory, BitAutoData, CollectionCustomization] - public async Task HandleRequirementAsync_MissingOrg_Failure( + public async Task HandleRequirementAsync_MissingOrg_NoSuccess( SutProvider sutProvider, ICollection collections) { @@ -182,11 +182,44 @@ public class CollectionAuthorizationHandlerTests sutProvider.GetDependency().GetOrganization(Arg.Any()).Returns((CurrentContextOrganization)null); await sutProvider.Sut.HandleAsync(context); - Assert.True(context.HasFailed); + Assert.False(context.HasSucceeded); } [Theory, BitAutoData, CollectionCustomization] - public async Task CanManageCollectionAccessAsync_MissingManageCollectionPermission_Failure( + public async Task HandleRequirementAsync_Provider_Success( + SutProvider sutProvider, + ICollection collections) + { + var operationsToTest = new[] + { + CollectionOperations.Create, CollectionOperations.Delete, CollectionOperations.ModifyAccess + }; + + foreach (var op in operationsToTest) + { + var actingUserId = Guid.NewGuid(); + var context = new AuthorizationHandlerContext( + new[] { op }, + new ClaimsPrincipal(), + collections + ); + var orgId = collections.First().OrganizationId; + + sutProvider.GetDependency().UserId.Returns(actingUserId); + sutProvider.GetDependency().GetOrganization(orgId).Returns((CurrentContextOrganization)null); + sutProvider.GetDependency().ProviderUserForOrgAsync(Arg.Any()).Returns(true); + + await sutProvider.Sut.HandleAsync(context); + Assert.True(context.HasSucceeded); + await sutProvider.GetDependency().Received().ProviderUserForOrgAsync(orgId); + + // Recreate the SUT to reset the mocks/dependencies between tests + sutProvider.Recreate(); + } + } + + [Theory, BitAutoData, CollectionCustomization] + public async Task CanManageCollectionAccessAsync_MissingManageCollectionPermission_NoSuccess( SutProvider sutProvider, ICollection collections, ICollection collectionDetails, @@ -216,7 +249,7 @@ public class CollectionAuthorizationHandlerTests sutProvider.GetDependency().GetManyByUserIdAsync(actingUserId).Returns(collectionDetails); await sutProvider.Sut.HandleAsync(context); - Assert.True(context.HasFailed); + Assert.False(context.HasSucceeded); sutProvider.GetDependency().ReceivedWithAnyArgs().GetOrganization(default); await sutProvider.GetDependency().ReceivedWithAnyArgs() .GetManyByUserIdAsync(default); diff --git a/test/Common/AutoFixture/SutProvider.cs b/test/Common/AutoFixture/SutProvider.cs index 3a3d6409ba..ac953965bd 100644 --- a/test/Common/AutoFixture/SutProvider.cs +++ b/test/Common/AutoFixture/SutProvider.cs @@ -72,6 +72,12 @@ public class SutProvider : ISutProvider Sut = default; } + public void Recreate() + { + _dependencies = new Dictionary>(); + Sut = _fixture.Create(); + } + ISutProvider ISutProvider.Create() => Create(); public SutProvider Create() { From ef50e4dbcd1debc8a615971c72717929ec565705 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 22 Nov 2023 19:24:19 +0100 Subject: [PATCH 13/20] [PM-2041] Finish adding FIDO2 Authentication (#3467) --- src/Identity/Controllers/AccountsController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Identity/Controllers/AccountsController.cs b/src/Identity/Controllers/AccountsController.cs index a686afa533..4abbbab482 100644 --- a/src/Identity/Controllers/AccountsController.cs +++ b/src/Identity/Controllers/AccountsController.cs @@ -81,9 +81,9 @@ public class AccountsController : Controller return new PreloginResponseModel(kdfInformation); } - [HttpPost("webauthn/assertion-options")] + [HttpGet("webauthn/assertion-options")] [RequireFeature(FeatureFlagKeys.PasswordlessLogin)] - public WebAuthnLoginAssertionOptionsResponseModel PostWebAuthnLoginAssertionOptions() + public WebAuthnLoginAssertionOptionsResponseModel GetWebAuthnLoginAssertionOptions() { var options = _userService.StartWebAuthnLoginAssertion(); From 8e5598a1dd361346a647718b82c1d538f48d3655 Mon Sep 17 00:00:00 2001 From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Date: Wed, 22 Nov 2023 12:48:59 -0600 Subject: [PATCH 14/20] [AC-1179][AC-1737] Event log for collection management setting (#3377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [AC-1117] Add manage permission (#3126) * Update sql files to add Manage permission * Add migration script * Rename collection manage migration file to remove duplicate migration date * Migrations * Add manage to models * Add manage to repository * Add constraint to Manage columns * Migration lint fixes * Add manage to OrganizationUserUserDetails_ReadWithCollectionsById * Add missing manage fields * Add 'Manage' to UserCollectionDetails * Use CREATE OR ALTER where possible * [AC-1374] Limit collection creation/deletion to Owner/Admin (#3145) * feat: update org table with new column, write migration, refs AC-1374 * feat: update views with new column, refs AC-1374 * feat: Alter sprocs (org create/update) to include new column, refs AC-1374 * feat: update entity/data/request/response models to handle new column, refs AC-1374 * feat: update necessary Provider related views during migration, refs AC-1374 * fix: update org create to default new column to false, refs AC-1374 * feat: added new API/request model for collection management and removed property from update request model, refs AC-1374 * fix: renamed migration script to be after secrets manage beta column changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: add ef migrations to reflect mssql changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: update API signature to accept Guid and explain Cd verbiage, refs AC-1374 * fix: merge conflict resolution * [AC-1174] CollectionUser and CollectionGroup authorization handlers (#3194) * [AC-1174] Introduce BulkAuthorizationHandler.cs * [AC-1174] Introduce CollectionUserAuthorizationHandler * [AC-1174] Add CreateForNewCollection CollectionUser requirement * [AC-1174] Add some more details to CollectionCustomization * [AC-1174] Formatting * [AC-1174] Add CollectionGroupOperation.cs * [AC-1174] Introduce CollectionGroupAuthorizationHandler.cs * [AC-1174] Cleanup CollectionFixture customization Implement and use re-usable extension method to support seeded Guids * [AC-1174] Introduce WithValueFromList AutoFixtureExtensions Modify CollectionCustomization to use multiple organization Ids for auto generated test data * [AC-1174] Simplify CollectionUserAuthorizationHandler.cs Modify the authorization handler to only perform authorization logic. Validation logic will need to be handled by any calling commands/controllers instead. * [AC-1174] Introduce shared CollectionAccessAuthorizationHandlerBase A shared base authorization handler was created for both CollectionUser and CollectionGroup resources, as they share the same underlying management authorization logic. * [AC-1174] Update CollectionUserAuthorizationHandler and CollectionGroupAuthorizationHandler to use the new CollectionAccessAuthorizationHandlerBase class * [AC-1174] Formatting * [AC-1174] Cleanup typo and redundant ToList() call * [AC-1174] Add check for provider users * [AC-1174] Reduce nested loops * [AC-1174] Introduce ICollectionAccess.cs * [AC-1174] Remove individual CollectionGroup and CollectionUser auth handlers and use base class instead * [AC-1174] Tweak unit test to fail minimally * [AC-1174] Reorganize authorization handlers in Core project * [AC-1174] Introduce new AddCoreAuthorizationHandlers() extension method * [AC-1174] Move CollectionAccessAuthorizationHandler into Api project * [AC-1174] Move CollectionFixture to Vault folder * [AC-1174] Rename operation to CreateUpdateDelete * [AC-1174] Require single organization for collection access authorization handler - Add requirement that all target collections must belong to the same organization - Simplify logic related to multiple organizations - Update tests and helpers - Use ToHashSet to improve lookup time * [AC-1174] Fix null reference exception * [AC-1174] Throw bad request exception when collections belong to different organizations * [AC-1174] Switch to CollectionAuthorizationHandler instead of CollectionAccessAuthorizationHandler to reduce complexity * Fix improper merge conflict resolution * fix: add permission check for collection management api, refs AC-1647 (#3252) * [AC-1125] Enforce org setting for creating/deleting collections (#3241) * [AC-1117] Add manage permission (#3126) * Update sql files to add Manage permission * Add migration script * Rename collection manage migration file to remove duplicate migration date * Migrations * Add manage to models * Add manage to repository * Add constraint to Manage columns * Migration lint fixes * Add manage to OrganizationUserUserDetails_ReadWithCollectionsById * Add missing manage fields * Add 'Manage' to UserCollectionDetails * Use CREATE OR ALTER where possible * [AC-1374] Limit collection creation/deletion to Owner/Admin (#3145) * feat: update org table with new column, write migration, refs AC-1374 * feat: update views with new column, refs AC-1374 * feat: Alter sprocs (org create/update) to include new column, refs AC-1374 * feat: update entity/data/request/response models to handle new column, refs AC-1374 * feat: update necessary Provider related views during migration, refs AC-1374 * fix: update org create to default new column to false, refs AC-1374 * feat: added new API/request model for collection management and removed property from update request model, refs AC-1374 * fix: renamed migration script to be after secrets manage beta column changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: add ef migrations to reflect mssql changes, refs AC-1374 * fix: dotnet format, refs AC-1374 * feat: update API signature to accept Guid and explain Cd verbiage, refs AC-1374 * feat: created collection auth handler/operations, added LimitCollectionCdOwnerAdmin to CurrentContentOrganization, refs AC-1125 * feat: create vault service collection extensions and register with base services, refs AC-1125 * feat: deprecated CurrentContext.CreateNewCollections, refs AC-1125 * feat: deprecate DeleteAnyCollection for single resource usages, refs AC-1125 * feat: move service registration to api, update references, refs AC-1125 * feat: add bulk delete authorization handler, refs AC-1125 * feat: always assign user and give manage access on create, refs AC-1125 * fix: updated CurrentContextOrganization type, refs AC-1125 * feat: combined existing collection authorization handlers/operations, refs AC-1125 * fix: OrganizationServiceTests -> CurrentContentOrganization typo, refs AC-1125 * fix: format, refs AC-1125 * fix: update collection controller tests, refs AC-1125 * fix: dotnet format, refs AC-1125 * feat: removed extra BulkAuthorizationHandler, refs AC-1125 * fix: dotnet format, refs AC-1125 * fix: change string to guid for org id, update bulk delete request model, refs AC-1125 * fix: remove delete many collection check, refs AC-1125 * fix: clean up collection auth handler, refs AC-1125 * fix: format fix for CollectionOperations, refs AC-1125 * fix: removed unnecessary owner check, add org null check to custom permission validation, refs AC-1125 * fix: remove unused methods in CurrentContext, refs AC-1125 * fix: removed obsolete test, fixed failling delete many test, refs AC-1125 * fix: CollectionAuthorizationHandlerTests fixes, refs AC-1125 * fix: OrganizationServiceTests fix broken test by mocking GetOrganization, refs AC-1125 * fix: CollectionAuthorizationHandler - remove unused repository, refs AC-1125 * feat: moved UserId null check to common method, refs AC-1125 * fix: updated auth handler tests to remove dependency on requirement for common code checks, refs AC-1125 * feat: updated conditionals/comments for create/delete methods within colleciton auth handler, refs AC-1125 * feat: added create/delete collection auth handler success methods, refs AC-1125 * fix: new up permissions to prevent excessive null checks, refs AC-1125 * fix: remove old reference to CreateNewCollections, refs AC-1125 * fix: typo within ViewAssignedCollections method, refs AC-1125 --------- Co-authored-by: Robyn MacCallum * refactor: remove organizationId from CollectionBulkDeleteRequestModel, refs AC-1649 (#3282) * [AC-1174] Bulk Collection Management (#3229) * [AC-1174] Update SelectionReadOnlyRequestModel to use Guid for Id property * [AC-1174] Introduce initial bulk-access collection endpoint * [AC-1174] Introduce BulkAddCollectionAccessCommand and validation logic/tests * [AC-1174] Add CreateOrUpdateAccessMany method to CollectionRepository * [AC-1174] Add event logs for bulk add collection access command * [AC-1174] Add User_BumpAccountRevisionDateByCollectionIds and database migration script * [AC-1174] Implement EF repository method * [AC-1174] Improve null checks * [AC-1174] Remove unnecessary BulkCollectionAccessRequestModel helpers * [AC-1174] Add unit tests for new controller endpoint * [AC-1174] Fix formatting * [AC-1174] Remove comment * [AC-1174] Remove redundant organizationId parameter * [AC-1174] Ensure user and group Ids are distinct * [AC-1174] Cleanup tests based on PR feedback * [AC-1174] Formatting * [AC-1174] Update CollectionGroup alias in the sproc * [AC-1174] Add some additional comments to SQL sproc * [AC-1174] Add comment explaining additional SaveChangesAsync call --------- Co-authored-by: Thomas Rittson * [AC-1646] Rename LimitCollectionCdOwnerAdmin column (#3300) * Rename LimitCollectionCdOwnerAdmin -> LimitCollectionCreationDeletion * Rename and bump migration script * [AC-1666] Removed EditAnyCollection from Create/Delete permission checks (#3301) * fix: remove EditAnyCollection from Create/Delete permission check, refs AC-1666 * fix: updated comment, refs AC-1666 * [AC-1669] Bug - Remove obsolete assignUserId from CollectionService.SaveAsync(...) (#3312) * fix: remove AssignUserId from CollectionService.SaveAsync, refs AC-1669 * fix: add manage access conditional before creating collection, refs AC-1669 * fix: move access logic for create/update, fix all tests, refs AC-1669 * fix: add CollectionAccessSelection fixture, update tests, update bad reqeuest message, refs AC-1669 * fix: format, refs AC-1669 * fix: update null params with specific arg.is null checks, refs Ac-1669 * fix: update attribute class name, refs AC-1669 * [AC-1713] [Flexible collections] Add feature flags to server (#3334) * Add feature flags for FlexibleCollections and BulkCollectionAccess * Flag new routes and behaviour --------- Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com> * Add joint codeownership for auth handlers (#3346) * feat: create new event type for collection management updates, refs AC-1179 * feat: add optional event type argument to update async service call, refs AC-1179 * feat: update put management collection call to update async with explicit event type, refs AC-1179 * [AC-1717] Update default values for LimitCollectionCreationDeletion (#3365) * Change default value in organization create sproc to 1 * Drop old column name still present in some QA instances * Set LimitCollectionCreationDeletion value in code based on feature flag * Fix: add missing namespace after merging in master * Fix: add missing namespace after merging in master * [AC-1683] Fix DB migrations for new Manage permission (#3307) * [AC-1683] Update migration script and introduce V2 procedures and types * [AC-1683] Update repository calls to use new V2 procedures / types * [AC-1684] Update bulk add collection migration script to use new V2 type * [AC-1683] Undo Manage changes to more original procedures * [AC-1683] Restore whitespace changes * [AC-1683] Clarify comments regarding explicit column lists * [AC-1683] Update migration script dates * [AC-1683] Split the migration script for readability * [AC-1683] Re-name SelectReadOnlyArray_V2 to CollectionAccessSelectionType * [AC-1648] [Flexible Collections] Bump migration scripts before feature branch merge (#3371) * Bump dates on sql migration scripts * Bump date on ef migrations --------- Co-authored-by: Robyn MacCallum Co-authored-by: Shane Melton Co-authored-by: Thomas Rittson Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com> --- src/Api/AdminConsole/Controllers/OrganizationsController.cs | 2 +- src/Core/Enums/EventType.cs | 1 + src/Core/Services/IOrganizationService.cs | 2 +- src/Core/Services/Implementations/OrganizationService.cs | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Api/AdminConsole/Controllers/OrganizationsController.cs b/src/Api/AdminConsole/Controllers/OrganizationsController.cs index 632230ebcd..aa5efd12cb 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationsController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationsController.cs @@ -794,7 +794,7 @@ public class OrganizationsController : Controller throw new NotFoundException(); } - await _organizationService.UpdateAsync(model.ToOrganization(organization)); + await _organizationService.UpdateAsync(model.ToOrganization(organization), eventType: EventType.Organization_CollectionManagement_Updated); return new OrganizationResponseModel(organization); } diff --git a/src/Core/Enums/EventType.cs b/src/Core/Enums/EventType.cs index f03ce71a52..af3673f10e 100644 --- a/src/Core/Enums/EventType.cs +++ b/src/Core/Enums/EventType.cs @@ -67,6 +67,7 @@ public enum EventType : int Organization_EnabledKeyConnector = 1606, Organization_DisabledKeyConnector = 1607, Organization_SponsorshipsSynced = 1608, + Organization_CollectionManagement_Updated = 1609, Policy_Updated = 1700, diff --git a/src/Core/Services/IOrganizationService.cs b/src/Core/Services/IOrganizationService.cs index 6da6d8fd73..a2e23e48d5 100644 --- a/src/Core/Services/IOrganizationService.cs +++ b/src/Core/Services/IOrganizationService.cs @@ -27,7 +27,7 @@ public interface IOrganizationService Task DisableAsync(Guid organizationId, DateTime? expirationDate); Task UpdateExpirationDateAsync(Guid organizationId, DateTime? expirationDate); Task EnableAsync(Guid organizationId); - Task UpdateAsync(Organization organization, bool updateBilling = false); + Task UpdateAsync(Organization organization, bool updateBilling = false, EventType eventType = EventType.Organization_Updated); Task UpdateTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type); Task DisableTwoFactorProviderAsync(Organization organization, TwoFactorProviderType type); Task> InviteUsersAsync(Guid organizationId, Guid? invitingUserId, diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index be5eabb6e7..60e2cd1f68 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -739,7 +739,7 @@ public class OrganizationService : IOrganizationService } } - public async Task UpdateAsync(Organization organization, bool updateBilling = false) + public async Task UpdateAsync(Organization organization, bool updateBilling = false, EventType eventType = EventType.Organization_Updated) { if (organization.Id == default(Guid)) { @@ -755,7 +755,7 @@ public class OrganizationService : IOrganizationService } } - await ReplaceAndUpdateCacheAsync(organization, EventType.Organization_Updated); + await ReplaceAndUpdateCacheAsync(organization, eventType); if (updateBilling && !string.IsNullOrWhiteSpace(organization.GatewayCustomerId)) { From 98c12d3f417a8c623fcc92dea075fbd9e9df3a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=A8=20Audrey=20=E2=9C=A8?= Date: Wed, 22 Nov 2023 15:44:25 -0500 Subject: [PATCH 15/20] Tools - Make Entities and Repositories nullable (#3313) * support nullability in tools' entities and repositories * enables C# nullability checks in these files * includes documentation for affected files * refine documentation per code review * improve comments on SendFileData structure * fix ReferenceEvent.MaxAccessCount documentation * add value notation to SendFileData.FileName --- src/Core/Tools/Entities/IReferenceable.cs | 25 ++- src/Core/Tools/Entities/Send.cs | 104 +++++++++- .../Tools/Models/Business/ReferenceEvent.cs | 178 +++++++++++++++++- src/Core/Tools/Models/Data/SendData.cs | 26 ++- src/Core/Tools/Models/Data/SendFileData.cs | 54 +++++- src/Core/Tools/Models/Data/SendTextData.cs | 32 +++- .../Tools/Repositories/ISendRepository.cs | 28 ++- .../Tools/Repositories/SendRepository.cs | 7 +- .../Tools/Repositories/SendRepository.cs | 22 ++- 9 files changed, 447 insertions(+), 29 deletions(-) diff --git a/src/Core/Tools/Entities/IReferenceable.cs b/src/Core/Tools/Entities/IReferenceable.cs index 39d473c657..4b38ec6ccc 100644 --- a/src/Core/Tools/Entities/IReferenceable.cs +++ b/src/Core/Tools/Entities/IReferenceable.cs @@ -1,8 +1,29 @@ -namespace Bit.Core.Tools.Entities; +#nullable enable +using Bit.Core.Tools.Models.Business; +namespace Bit.Core.Tools.Entities; + +/// +/// An entity that can be referenced by a . +/// public interface IReferenceable { + /// + /// Identifies the entity that generated the event. + /// Guid Id { get; set; } - string ReferenceData { get; set; } + + /// + /// Contextual information included in the event. + /// + /// + /// Do not store secrets in this field. + /// + string? ReferenceData { get; set; } + + /// + /// Returns when the entity is a user. + /// Otherwise returns . + /// bool IsUser(); } diff --git a/src/Core/Tools/Entities/Send.cs b/src/Core/Tools/Entities/Send.cs index ae30201e86..9f09ae6bde 100644 --- a/src/Core/Tools/Entities/Send.cs +++ b/src/Core/Tools/Entities/Send.cs @@ -1,29 +1,125 @@ -using System.ComponentModel.DataAnnotations; +#nullable enable + +using System.ComponentModel.DataAnnotations; using Bit.Core.Entities; using Bit.Core.Tools.Enums; using Bit.Core.Utilities; namespace Bit.Core.Tools.Entities; +/// +/// An end-to-end encrypted secret accessible to arbitrary +/// entities through a fixed URI. +/// public class Send : ITableObject { + /// + /// Uniquely identifies this send. + /// public Guid Id { get; set; } + + /// + /// Identifies the user that created this send. + /// public Guid? UserId { get; set; } + + /// + /// Identifies the organization that created this send. + /// + /// + /// Not presently in-use by client applications. + /// public Guid? OrganizationId { get; set; } + + /// + /// Describes the data being sent. This field determines how + /// the field is interpreted. + /// public SendType Type { get; set; } - public string Data { get; set; } - public string Key { get; set; } + + /// + /// Stores data containing or pointing to the transmitted secret. JSON. + /// + /// + /// Must be nullable due to several database column configuration. + /// The application and all other databases assume this is not nullable. + /// Tech debt ticket: PM-4128 + /// + public string? Data { get; set; } + + /// + /// Stores the data's encryption key. Encrypted. + /// + /// + /// Must be nullable due to MySql database column configuration. + /// The application and all other databases assume this is not nullable. + /// Tech debt ticket: PM-4128 + /// + public string? Key { get; set; } + + /// + /// Password provided by the user. Protected with pbkdf2. + /// [MaxLength(300)] - public string Password { get; set; } + public string? Password { get; set; } + + /// + /// The send becomes unavailable to API callers when + /// >= . + /// public int? MaxAccessCount { get; set; } + + /// + /// Number of times the content was accessed. + /// + /// + /// This value is owned by the server. Clients cannot alter it. + /// public int AccessCount { get; set; } + + /// + /// The date this send was created. + /// public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; + + /// + /// The date this send was last modified. + /// public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; + + /// + /// The date this send becomes unavailable to API callers. + /// public DateTime? ExpirationDate { get; set; } + + /// + /// The date this send will be unconditionally deleted. + /// + /// + /// This is set by server-side when the user doesn't specify a deletion date. + /// public DateTime DeletionDate { get; set; } + + /// + /// When this is true the send is not available to API callers, + /// unless they're the creator. + /// public bool Disabled { get; set; } + + /// + /// Whether the creator's email address should be shown to the recipient. + /// + /// + /// indicates the email may be shown. + /// indicates the email should be hidden. + /// indicates the client doesn't set the field and + /// the email should be hidden. + /// public bool? HideEmail { get; set; } + /// + /// Generates the send's + /// public void SetNewId() { Id = CoreHelpers.GenerateComb(); diff --git a/src/Core/Tools/Models/Business/ReferenceEvent.cs b/src/Core/Tools/Models/Business/ReferenceEvent.cs index 393708668a..ac21c92e44 100644 --- a/src/Core/Tools/Models/Business/ReferenceEvent.cs +++ b/src/Core/Tools/Models/Business/ReferenceEvent.cs @@ -1,4 +1,6 @@ -using System.Text.Json.Serialization; +#nullable enable + +using System.Text.Json.Serialization; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Tools.Entities; @@ -6,10 +8,23 @@ using Bit.Core.Tools.Enums; namespace Bit.Core.Tools.Models.Business; +/// +/// Product support monitoring. +/// +/// +/// Do not store secrets in this type. +/// public class ReferenceEvent { + /// + /// Instantiates a . + /// public ReferenceEvent() { } + /// + /// Monitored event type. + /// Entity that created the event. + /// The conditions in which the event occurred. public ReferenceEvent(ReferenceEventType type, IReferenceable source, ICurrentContext currentContext) { Type = type; @@ -26,48 +41,197 @@ public class ReferenceEvent } } + /// + /// Monitored event type. + /// [JsonConverter(typeof(JsonStringEnumConverter))] public ReferenceEventType Type { get; set; } + /// + /// The kind of entity that created the event. + /// [JsonConverter(typeof(JsonStringEnumConverter))] public ReferenceEventSource Source { get; set; } + /// public Guid Id { get; set; } - public string ReferenceData { get; set; } + /// + public string? ReferenceData { get; set; } + /// + /// Moment the event occurred. + /// public DateTime EventDate { get; set; } = DateTime.UtcNow; + /// + /// Number of users sent invitations by an organization. + /// + /// + /// Should contain a value only on events. + /// Otherwise the value should be . + /// public int? Users { get; set; } + /// + /// Whether or not a subscription was canceled immediately or at the end of the billing period. + /// + /// + /// when a cancellation occurs immediately. + /// when a cancellation occurs at the end of a customer's billing period. + /// Should contain a value only on events. + /// Otherwise the value should be . + /// public bool? EndOfPeriod { get; set; } - public string PlanName { get; set; } + /// + /// Branded name of the subscription. + /// + /// + /// Should contain a value only for subscription management events. + /// Otherwise the value should be . + /// + public string? PlanName { get; set; } + /// + /// Identifies a subscription. + /// + /// + /// Should contain a value only for subscription management events. + /// Otherwise the value should be . + /// public PlanType? PlanType { get; set; } - public string OldPlanName { get; set; } + /// + /// The branded name of the prior plan. + /// + /// + /// Should contain a value only on events + /// initiated by organizations. + /// Otherwise the value should be . + /// + public string? OldPlanName { get; set; } + /// + /// Identifies the prior plan + /// + /// + /// Should contain a value only on events + /// initiated by organizations. + /// Otherwise the value should be . + /// public PlanType? OldPlanType { get; set; } + /// + /// Seat count when a billable action occurs. When adjusting seats, contains + /// the new seat count. + /// + /// + /// Should contain a value only on , + /// , , + /// and events initiated by organizations. + /// Otherwise the value should be . + /// public int? Seats { get; set; } + + /// + /// Seat count when a seat adjustment occurs. + /// + /// + /// Should contain a value only on + /// events initiated by organizations. + /// Otherwise the value should be . + /// public int? PreviousSeats { get; set; } + /// + /// Qty in GB of storage. When adjusting storage, contains the adjusted + /// storage qty. Otherwise contains the total storage quantity. + /// + /// + /// Should contain a value only on , + /// , , + /// and events. + /// Otherwise the value should be . + /// public short? Storage { get; set; } + /// + /// The type of send created or accessed. + /// + /// + /// Should contain a value only on + /// and events. + /// Otherwise the value should be . + /// [JsonConverter(typeof(JsonStringEnumConverter))] public SendType? SendType { get; set; } + /// + /// Whether the send has private notes. + /// + /// + /// when the send has private notes, otherwise . + /// Should contain a value only on + /// and events. + /// Otherwise the value should be . + /// public bool? SendHasNotes { get; set; } + /// + /// The send expires after its access count exceeds this value. + /// + /// + /// This field only contains a value when the send has a max access count + /// and is + /// or events. + /// Otherwise, the value should be . + /// public int? MaxAccessCount { get; set; } + /// + /// Whether the created send has a password. + /// + /// + /// Should contain a value only on + /// and events. + /// Otherwise the value should be . + /// public bool? HasPassword { get; set; } - public string EventRaisedByUser { get; set; } + /// + /// The administrator that performed the action. + /// + /// + /// Should contain a value only on + /// and events. + /// Otherwise the value should be . + /// + public string? EventRaisedByUser { get; set; } + /// + /// Whether or not an organization's trial period was started by a sales person. + /// + /// + /// Should contain a value only on + /// and events. + /// Otherwise the value should be . + /// public bool? SalesAssistedTrialStarted { get; set; } - public string ClientId { get; set; } - public Version ClientVersion { get; set; } + /// + /// The installation id of the application that originated the event. + /// + /// + /// when the event was not originated by an application. + /// + public string? ClientId { get; set; } + + /// + /// The version of the client application that originated the event. + /// + /// + /// when the event was not originated by an application. + /// + public Version? ClientVersion { get; set; } } diff --git a/src/Core/Tools/Models/Data/SendData.cs b/src/Core/Tools/Models/Data/SendData.cs index bdddb84822..c780cccb9c 100644 --- a/src/Core/Tools/Models/Data/SendData.cs +++ b/src/Core/Tools/Models/Data/SendData.cs @@ -1,15 +1,33 @@ -namespace Bit.Core.Tools.Models.Data; +#nullable enable +namespace Bit.Core.Tools.Models.Data; + +/// +/// Shared data for a send +/// public abstract class SendData { + /// + /// Instantiates a . + /// public SendData() { } - public SendData(string name, string notes) + /// + /// User-provided name of the send. + /// User-provided private notes of the send. + public SendData(string name, string? notes) { Name = name; Notes = notes; } - public string Name { get; set; } - public string Notes { get; set; } + /// + /// User-provided name of the send. + /// + public string Name { get; set; } = string.Empty; + + /// + /// User-provided private notes of the send. + /// + public string? Notes { get; set; } = null; } diff --git a/src/Core/Tools/Models/Data/SendFileData.cs b/src/Core/Tools/Models/Data/SendFileData.cs index 6cf1fa3da5..11379bef58 100644 --- a/src/Core/Tools/Models/Data/SendFileData.cs +++ b/src/Core/Tools/Models/Data/SendFileData.cs @@ -1,22 +1,64 @@ -using System.Text.Json.Serialization; +#nullable enable + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; +using static System.Text.Json.Serialization.JsonNumberHandling; namespace Bit.Core.Tools.Models.Data; +/// +/// A file secret being sent. +/// public class SendFileData : SendData { + /// + /// Instantiates a . + /// public SendFileData() { } - public SendFileData(string name, string notes, string fileName) + /// + /// Attached file name. + /// User-provided private notes of the send. + /// Attached file name. + public SendFileData(string name, string? notes, string fileName) : base(name, notes) { FileName = fileName; } - // We serialize Size as a string since JSON (or Javascript) doesn't support full precision for long numbers - [JsonNumberHandling(JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowReadingFromString)] + /// + /// Size of the attached file in bytes. + /// + /// + /// Serialized as a string since JSON (or Javascript) doesn't support + /// full precision for long numbers + /// + [JsonNumberHandling(WriteAsString | AllowReadingFromString)] public long Size { get; set; } - public string Id { get; set; } - public string FileName { get; set; } + /// + /// Uniquely identifies an uploaded file. + /// + /// + /// Should contain only when a file + /// upload is pending. Should never contain null once the + /// file upload completes. + /// + [DisallowNull] + public string? Id { get; set; } + + /// + /// Attached file name. + /// + /// + /// Should contain a non-empty string once the file upload completes. + /// + public string FileName { get; set; } = string.Empty; + + /// + /// When true the uploaded file's length was confirmed within + /// the expected tolerance and below the maximum supported + /// file size. + /// public bool Validated { get; set; } = true; } diff --git a/src/Core/Tools/Models/Data/SendTextData.cs b/src/Core/Tools/Models/Data/SendTextData.cs index 41c6b042ae..5a1b8e9f3a 100644 --- a/src/Core/Tools/Models/Data/SendTextData.cs +++ b/src/Core/Tools/Models/Data/SendTextData.cs @@ -1,16 +1,42 @@ -namespace Bit.Core.Tools.Models.Data; +#nullable enable +namespace Bit.Core.Tools.Models.Data; + +/// +/// A text secret being sent. +/// public class SendTextData : SendData { + /// + /// Instantiates a . + /// public SendTextData() { } - public SendTextData(string name, string notes, string text, bool hidden) + /// + /// Attached file name. + /// User-provided private notes of the send. + /// The secret being sent. + /// + /// Indicates whether the secret should be concealed when opening the send. + /// + public SendTextData(string name, string? notes, string? text, bool hidden) : base(name, notes) { Text = text; Hidden = hidden; } - public string Text { get; set; } + /// + /// The secret being sent. + /// + public string? Text { get; set; } + + /// + /// Indicates whether the secret should be concealed when opening the send. + /// + /// + /// when the secret should be concealed. + /// Otherwise . + /// public bool Hidden { get; set; } } diff --git a/src/Core/Tools/Repositories/ISendRepository.cs b/src/Core/Tools/Repositories/ISendRepository.cs index 3d67c990ff..421a5f4aaf 100644 --- a/src/Core/Tools/Repositories/ISendRepository.cs +++ b/src/Core/Tools/Repositories/ISendRepository.cs @@ -1,10 +1,36 @@ -using Bit.Core.Repositories; +#nullable enable + +using Bit.Core.Repositories; using Bit.Core.Tools.Entities; namespace Bit.Core.Tools.Repositories; +/// +/// Service for saving and loading s in persistent storage. +/// public interface ISendRepository : IRepository { + /// + /// Loads all s created by a user. + /// + /// + /// Identifies the user. + /// + /// + /// A task that completes once the s have been loaded. + /// The task's result contains the loaded s. + /// Task> GetManyByUserIdAsync(Guid userId); + + /// + /// Loads s scheduled for deletion. + /// + /// + /// Load sends whose is < this date. + /// + /// + /// A task that completes once the s have been loaded. + /// The task's result contains the loaded s. + /// Task> GetManyByDeletionDateAsync(DateTime deletionDateBefore); } diff --git a/src/Infrastructure.Dapper/Tools/Repositories/SendRepository.cs b/src/Infrastructure.Dapper/Tools/Repositories/SendRepository.cs index 24cdcbf77b..0522cee672 100644 --- a/src/Infrastructure.Dapper/Tools/Repositories/SendRepository.cs +++ b/src/Infrastructure.Dapper/Tools/Repositories/SendRepository.cs @@ -1,4 +1,6 @@ -using System.Data; +#nullable enable + +using System.Data; using Bit.Core.Settings; using Bit.Core.Tools.Entities; using Bit.Core.Tools.Repositories; @@ -8,6 +10,7 @@ using Microsoft.Data.SqlClient; namespace Bit.Infrastructure.Dapper.Tools.Repositories; +/// public class SendRepository : Repository, ISendRepository { public SendRepository(GlobalSettings globalSettings) @@ -18,6 +21,7 @@ public class SendRepository : Repository, ISendRepository : base(connectionString, readOnlyConnectionString) { } + /// public async Task> GetManyByUserIdAsync(Guid userId) { using (var connection = new SqlConnection(ConnectionString)) @@ -31,6 +35,7 @@ public class SendRepository : Repository, ISendRepository } } + /// public async Task> GetManyByDeletionDateAsync(DateTime deletionDateBefore) { using (var connection = new SqlConnection(ConnectionString)) diff --git a/src/Infrastructure.EntityFramework/Tools/Repositories/SendRepository.cs b/src/Infrastructure.EntityFramework/Tools/Repositories/SendRepository.cs index 3207ec9e90..4c0c866606 100644 --- a/src/Infrastructure.EntityFramework/Tools/Repositories/SendRepository.cs +++ b/src/Infrastructure.EntityFramework/Tools/Repositories/SendRepository.cs @@ -1,4 +1,6 @@ -using AutoMapper; +#nullable enable + +using AutoMapper; using Bit.Core.Tools.Repositories; using Bit.Infrastructure.EntityFramework.Models; using Bit.Infrastructure.EntityFramework.Repositories; @@ -7,12 +9,28 @@ using Microsoft.Extensions.DependencyInjection; namespace Bit.Infrastructure.EntityFramework.Tools.Repositories; +/// public class SendRepository : Repository, ISendRepository { + /// + /// Initializes the + /// + /// An IoC service locator. + /// An automapper service. public SendRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) : base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Sends) { } + /// + /// Saves a in the database. + /// + /// + /// The send being saved. + /// + /// + /// A task that completes once the save is complete. + /// The task result contains the saved . + /// public override async Task CreateAsync(Core.Tools.Entities.Send send) { send = await base.CreateAsync(send); @@ -30,6 +48,7 @@ public class SendRepository : Repository, return send; } + /// public async Task> GetManyByDeletionDateAsync(DateTime deletionDateBefore) { using (var scope = ServiceScopeFactory.CreateScope()) @@ -40,6 +59,7 @@ public class SendRepository : Repository, } } + /// public async Task> GetManyByUserIdAsync(Guid userId) { using (var scope = ServiceScopeFactory.CreateScope()) From 42cec31d07078fb12b83fd32a4eab746474d1035 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Thu, 23 Nov 2023 07:07:37 +1000 Subject: [PATCH 16/20] [AC-1287] AC Team code ownership moves: Policies (1/2) (#3383) * note: IPolicyData and EntityFramework Policy.cs are moved without any changes to namespace or content in order to preserve git history. --- .../src/Sso/Controllers/AccountController.cs | 2 + .../OrganizationUsersController.cs | 3 +- .../Controllers/OrganizationsController.cs | 3 +- .../Controllers/PoliciesController.cs | 5 +- .../Models/Request/PolicyRequestModel.cs | 4 +- .../Public/Controllers/PoliciesController.cs | 5 +- .../Request/PolicyUpdateRequestModel.cs | 2 +- .../Models/Response/PolicyResponseModel.cs | 4 +- .../Controllers/EmergencyAccessController.cs | 4 +- .../Auth/Controllers/WebAuthnController.cs | 3 +- src/Api/Controllers/AccountsController.cs | 1 + src/Api/Vault/Controllers/SyncController.cs | 1 + .../Models/Response/SyncResponseModel.cs | 3 +- .../{ => AdminConsole}/Entities/Policy.cs | 5 +- .../{ => AdminConsole}/Enums/PolicyType.cs | 2 +- .../Api/Response/PolicyResponseModel.cs | 7 +-- .../Policies/IPolicyDataModel.cs | 0 .../Policies/MasterPasswordPolicyData.cs | 4 +- .../Policies/ResetPasswordDataModel.cs | 3 +- .../Policies/SendOptionsPolicyData.cs | 3 +- .../Repositories/IPolicyRepository.cs | 7 +-- .../Services/IPolicyService.cs | 9 ++-- .../Services/Implementations/PolicyService.cs | 20 ++++---- .../Auth/Services/IEmergencyAccessService.cs | 3 +- .../Implementations/EmergencyAccessService.cs | 4 +- .../Implementations/SsoConfigService.cs | 8 +++- .../MasterPasswordPolicyResponseModel.cs | 2 +- .../OrganizationUserPolicyDetails.cs | 3 +- .../SelfHostedOrganizationDetails.cs | 4 +- .../UpgradeOrganizationPlanCommand.cs | 3 +- .../OrganizationUsers/AcceptOrgUserCommand.cs | 4 +- .../IOrganizationUserRepository.cs | 3 +- .../Implementations/OrganizationService.cs | 4 +- .../Services/Implementations/UserService.cs | 2 + .../Services/Implementations/SendService.cs | 6 ++- .../Services/Implementations/CipherService.cs | 2 + .../IdentityServer/BaseRequestValidator.cs | 2 + .../CustomTokenRequestValidator.cs | 1 + .../ResourceOwnerPasswordValidator.cs | 1 + .../IdentityServer/WebAuthnGrantValidator.cs | 1 + .../Repositories/PolicyRepository.cs | 9 ++-- .../Repositories/OrganizationRepository.cs | 1 + .../OrganizationUserRepository.cs | 1 + .../{ => AdminConsole}/Models/Policy.cs | 4 +- .../Repositories/PolicyRepository.cs | 24 +++++----- .../Queries/PolicyReadByUserIdQuery.cs | 4 +- .../OrganizationUserRepository.cs | 1 + .../OrganizationUsersControllerTests.cs | 7 ++- .../Controllers/WebAuthnControllerTests.cs | 3 +- .../Controllers/AccountsControllerTests.cs | 1 + .../Controllers/PoliciesControllerTests.cs | 6 ++- .../Vault/Controllers/SyncControllerTests.cs | 1 + .../AutoFixture/PolicyFixtures.cs | 6 +-- .../Services/PolicyServiceTests.cs | 48 ++++++++++--------- .../Auth/Services/SsoConfigServiceTests.cs | 20 ++++---- .../SelfHostedOrganizationDetailsTests.cs | 4 +- .../AcceptOrgUserCommandTests.cs | 4 +- .../Services/OrganizationServiceTests.cs | 5 +- test/Core.Test/Services/UserServiceTests.cs | 1 + .../Tools/Services/SendServiceTests.cs | 6 ++- .../Endpoints/IdentityServerTests.cs | 5 +- .../Repositories/PolicyRepositoryTests.cs | 10 ++-- .../AutoFixture/PolicyFixtures.cs | 2 +- .../EqualityComparers/PolicyCompare.cs | 2 +- .../OrganizationUserRepositoryTests.cs | 7 ++- 65 files changed, 214 insertions(+), 121 deletions(-) rename src/Core/{ => AdminConsole}/Entities/Policy.cs (88%) rename src/Core/{ => AdminConsole}/Enums/PolicyType.cs (89%) rename src/Core/{ => AdminConsole}/Models/Api/Response/PolicyResponseModel.cs (83%) rename src/Core/{ => AdminConsole}/Models/Data/Organizations/Policies/IPolicyDataModel.cs (100%) rename src/Core/{ => AdminConsole}/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs (92%) rename src/Core/{ => AdminConsole}/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs (64%) rename src/Core/{ => AdminConsole}/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs (62%) rename src/Core/{ => AdminConsole}/Repositories/IPolicyRepository.cs (66%) rename src/Core/{ => AdminConsole}/Services/IPolicyService.cs (77%) rename src/Core/{ => AdminConsole}/Services/Implementations/PolicyService.cs (93%) rename src/Infrastructure.Dapper/{ => AdminConsole}/Repositories/PolicyRepository.cs (89%) rename src/Infrastructure.EntityFramework/{ => AdminConsole}/Models/Policy.cs (63%) rename src/Infrastructure.EntityFramework/{ => AdminConsole}/Repositories/PolicyRepository.cs (55%) rename src/Infrastructure.EntityFramework/{ => AdminConsole}/Repositories/Queries/PolicyReadByUserIdQuery.cs (80%) rename test/Core.Test/{ => AdminConsole}/AutoFixture/PolicyFixtures.cs (86%) rename test/Core.Test/{ => AdminConsole}/Services/PolicyServiceTests.cs (93%) rename test/Infrastructure.EFIntegration.Test/{ => AdminConsole}/Repositories/PolicyRepositoryTests.cs (80%) diff --git a/bitwarden_license/src/Sso/Controllers/AccountController.cs b/bitwarden_license/src/Sso/Controllers/AccountController.cs index 0df6894175..11a42e3cb1 100644 --- a/bitwarden_license/src/Sso/Controllers/AccountController.cs +++ b/bitwarden_license/src/Sso/Controllers/AccountController.cs @@ -1,5 +1,7 @@ using System.Security.Claims; using Bit.Core; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Repositories; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models; diff --git a/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs b/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs index 73140cea4e..5ca1003fd4 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs @@ -2,6 +2,8 @@ using Bit.Api.AdminConsole.Models.Response.Organizations; using Bit.Api.Models.Request.Organizations; using Bit.Api.Models.Response; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Context; @@ -9,7 +11,6 @@ using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Business; using Bit.Core.Models.Data.Organizations.OrganizationUsers; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.Repositories; diff --git a/src/Api/AdminConsole/Controllers/OrganizationsController.cs b/src/Api/AdminConsole/Controllers/OrganizationsController.cs index aa5efd12cb..db02097421 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationsController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationsController.cs @@ -11,6 +11,8 @@ using Bit.Api.Models.Request.Accounts; using Bit.Api.Models.Request.Organizations; using Bit.Api.Models.Response; using Bit.Core; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationApiKeys.Interfaces; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Auth.Enums; @@ -20,7 +22,6 @@ using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Business; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.OrganizationFeatures.OrganizationLicenses.Interfaces; using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; using Bit.Core.Repositories; diff --git a/src/Api/AdminConsole/Controllers/PoliciesController.cs b/src/Api/AdminConsole/Controllers/PoliciesController.cs index 60257814e9..5668031d24 100644 --- a/src/Api/AdminConsole/Controllers/PoliciesController.cs +++ b/src/Api/AdminConsole/Controllers/PoliciesController.cs @@ -1,10 +1,13 @@ using Bit.Api.AdminConsole.Models.Request; using Bit.Api.Models.Response; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Api.Response; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; -using Bit.Core.Models.Api.Response; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; diff --git a/src/Api/AdminConsole/Models/Request/PolicyRequestModel.cs b/src/Api/AdminConsole/Models/Request/PolicyRequestModel.cs index b3ba3a6bca..db191194d7 100644 --- a/src/Api/AdminConsole/Models/Request/PolicyRequestModel.cs +++ b/src/Api/AdminConsole/Models/Request/PolicyRequestModel.cs @@ -1,7 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.Text.Json; -using Bit.Core.Entities; -using Bit.Core.Enums; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; namespace Bit.Api.AdminConsole.Models.Request; diff --git a/src/Api/AdminConsole/Public/Controllers/PoliciesController.cs b/src/Api/AdminConsole/Public/Controllers/PoliciesController.cs index bcabb969c6..1d7eb65185 100644 --- a/src/Api/AdminConsole/Public/Controllers/PoliciesController.cs +++ b/src/Api/AdminConsole/Public/Controllers/PoliciesController.cs @@ -2,9 +2,10 @@ using Bit.Api.AdminConsole.Public.Models.Request; using Bit.Api.AdminConsole.Public.Models.Response; using Bit.Api.Models.Public.Response; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Context; -using Bit.Core.Enums; -using Bit.Core.Repositories; using Bit.Core.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/src/Api/AdminConsole/Public/Models/Request/PolicyUpdateRequestModel.cs b/src/Api/AdminConsole/Public/Models/Request/PolicyUpdateRequestModel.cs index 1866da6eca..80b7874a0b 100644 --- a/src/Api/AdminConsole/Public/Models/Request/PolicyUpdateRequestModel.cs +++ b/src/Api/AdminConsole/Public/Models/Request/PolicyUpdateRequestModel.cs @@ -1,5 +1,5 @@ using System.Text.Json; -using Bit.Core.Entities; +using Bit.Core.AdminConsole.Entities; namespace Bit.Api.AdminConsole.Public.Models.Request; diff --git a/src/Api/AdminConsole/Public/Models/Response/PolicyResponseModel.cs b/src/Api/AdminConsole/Public/Models/Response/PolicyResponseModel.cs index 3b196874d5..27da5cc561 100644 --- a/src/Api/AdminConsole/Public/Models/Response/PolicyResponseModel.cs +++ b/src/Api/AdminConsole/Public/Models/Response/PolicyResponseModel.cs @@ -1,8 +1,8 @@ using System.ComponentModel.DataAnnotations; using System.Text.Json; using Bit.Api.Models.Public.Response; -using Bit.Core.Entities; -using Bit.Core.Enums; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; namespace Bit.Api.AdminConsole.Public.Models.Response; diff --git a/src/Api/Auth/Controllers/EmergencyAccessController.cs b/src/Api/Auth/Controllers/EmergencyAccessController.cs index ec2a9fc6b7..95fac234c8 100644 --- a/src/Api/Auth/Controllers/EmergencyAccessController.cs +++ b/src/Api/Auth/Controllers/EmergencyAccessController.cs @@ -3,10 +3,10 @@ using Bit.Api.Auth.Models.Request; using Bit.Api.Auth.Models.Response; using Bit.Api.Models.Response; using Bit.Api.Vault.Models.Response; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Models.Api.Response; using Bit.Core.Auth.Services; -using Bit.Core.Entities; using Bit.Core.Exceptions; -using Bit.Core.Models.Api.Response; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; diff --git a/src/Api/Auth/Controllers/WebAuthnController.cs b/src/Api/Auth/Controllers/WebAuthnController.cs index e62d1a95ba..a30e83a5e0 100644 --- a/src/Api/Auth/Controllers/WebAuthnController.cs +++ b/src/Api/Auth/Controllers/WebAuthnController.cs @@ -3,9 +3,10 @@ using Bit.Api.Auth.Models.Request.Webauthn; using Bit.Api.Auth.Models.Response.WebAuthn; using Bit.Api.Models.Response; using Bit.Core; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Repositories; -using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Services; using Bit.Core.Tokens; diff --git a/src/Api/Controllers/AccountsController.cs b/src/Api/Controllers/AccountsController.cs index 7dbcf07d06..d699f09ec6 100644 --- a/src/Api/Controllers/AccountsController.cs +++ b/src/Api/Controllers/AccountsController.cs @@ -7,6 +7,7 @@ using Bit.Api.Utilities; using Bit.Core; using Bit.Core.AdminConsole.Enums.Provider; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Models.Api.Request.Accounts; using Bit.Core.Auth.Models.Api.Response.Accounts; using Bit.Core.Auth.Models.Data; diff --git a/src/Api/Vault/Controllers/SyncController.cs b/src/Api/Vault/Controllers/SyncController.cs index ac7ef9acdc..0d75235111 100644 --- a/src/Api/Vault/Controllers/SyncController.cs +++ b/src/Api/Vault/Controllers/SyncController.cs @@ -1,4 +1,5 @@ using Bit.Api.Vault.Models.Response; +using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Enums.Provider; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Entities; diff --git a/src/Api/Vault/Models/Response/SyncResponseModel.cs b/src/Api/Vault/Models/Response/SyncResponseModel.cs index 817f233e11..ca833738a1 100644 --- a/src/Api/Vault/Models/Response/SyncResponseModel.cs +++ b/src/Api/Vault/Models/Response/SyncResponseModel.cs @@ -1,9 +1,10 @@ using Bit.Api.Models.Response; using Bit.Api.Tools.Models.Response; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Models.Api.Response; using Bit.Core.AdminConsole.Models.Data.Provider; using Bit.Core.Entities; using Bit.Core.Models.Api; -using Bit.Core.Models.Api.Response; using Bit.Core.Models.Data; using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.Settings; diff --git a/src/Core/Entities/Policy.cs b/src/Core/AdminConsole/Entities/Policy.cs similarity index 88% rename from src/Core/Entities/Policy.cs rename to src/Core/AdminConsole/Entities/Policy.cs index 4863b8ccc8..75d67c1021 100644 --- a/src/Core/Entities/Policy.cs +++ b/src/Core/AdminConsole/Entities/Policy.cs @@ -1,8 +1,9 @@ -using Bit.Core.Enums; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.Entities; using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Utilities; -namespace Bit.Core.Entities; +namespace Bit.Core.AdminConsole.Entities; public class Policy : ITableObject { diff --git a/src/Core/Enums/PolicyType.cs b/src/Core/AdminConsole/Enums/PolicyType.cs similarity index 89% rename from src/Core/Enums/PolicyType.cs rename to src/Core/AdminConsole/Enums/PolicyType.cs index 30dac3d917..583d1187e8 100644 --- a/src/Core/Enums/PolicyType.cs +++ b/src/Core/AdminConsole/Enums/PolicyType.cs @@ -1,4 +1,4 @@ -namespace Bit.Core.Enums; +namespace Bit.Core.AdminConsole.Enums; public enum PolicyType : byte { diff --git a/src/Core/Models/Api/Response/PolicyResponseModel.cs b/src/Core/AdminConsole/Models/Api/Response/PolicyResponseModel.cs similarity index 83% rename from src/Core/Models/Api/Response/PolicyResponseModel.cs rename to src/Core/AdminConsole/Models/Api/Response/PolicyResponseModel.cs index 997e918d09..7ef6b15737 100644 --- a/src/Core/Models/Api/Response/PolicyResponseModel.cs +++ b/src/Core/AdminConsole/Models/Api/Response/PolicyResponseModel.cs @@ -1,8 +1,9 @@ using System.Text.Json; -using Bit.Core.Entities; -using Bit.Core.Enums; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.Models.Api; -namespace Bit.Core.Models.Api.Response; +namespace Bit.Core.AdminConsole.Models.Api.Response; public class PolicyResponseModel : ResponseModel { diff --git a/src/Core/Models/Data/Organizations/Policies/IPolicyDataModel.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/IPolicyDataModel.cs similarity index 100% rename from src/Core/Models/Data/Organizations/Policies/IPolicyDataModel.cs rename to src/Core/AdminConsole/Models/Data/Organizations/Policies/IPolicyDataModel.cs diff --git a/src/Core/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs similarity index 92% rename from src/Core/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs rename to src/Core/AdminConsole/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs index 30294620bf..1ace6204df 100644 --- a/src/Core/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs @@ -1,4 +1,6 @@ -namespace Bit.Core.Models.Data.Organizations.Policies; +using Bit.Core.Models.Data.Organizations.Policies; + +namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; public class MasterPasswordPolicyData : IPolicyDataModel { diff --git a/src/Core/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs similarity index 64% rename from src/Core/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs rename to src/Core/AdminConsole/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs index 1931cc5b79..e3a921d87c 100644 --- a/src/Core/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; +using Bit.Core.Models.Data.Organizations.Policies; -namespace Bit.Core.Models.Data.Organizations.Policies; +namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; public class ResetPasswordDataModel : IPolicyDataModel { diff --git a/src/Core/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs similarity index 62% rename from src/Core/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs rename to src/Core/AdminConsole/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs index aa9f651665..903d63176d 100644 --- a/src/Core/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; +using Bit.Core.Models.Data.Organizations.Policies; -namespace Bit.Core.Models.Data.Organizations.Policies; +namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; public class SendOptionsPolicyData : IPolicyDataModel { diff --git a/src/Core/Repositories/IPolicyRepository.cs b/src/Core/AdminConsole/Repositories/IPolicyRepository.cs similarity index 66% rename from src/Core/Repositories/IPolicyRepository.cs rename to src/Core/AdminConsole/Repositories/IPolicyRepository.cs index 389d116c40..6050a7f69f 100644 --- a/src/Core/Repositories/IPolicyRepository.cs +++ b/src/Core/AdminConsole/Repositories/IPolicyRepository.cs @@ -1,7 +1,8 @@ -using Bit.Core.Entities; -using Bit.Core.Enums; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.Repositories; -namespace Bit.Core.Repositories; +namespace Bit.Core.AdminConsole.Repositories; public interface IPolicyRepository : IRepository { diff --git a/src/Core/Services/IPolicyService.cs b/src/Core/AdminConsole/Services/IPolicyService.cs similarity index 77% rename from src/Core/Services/IPolicyService.cs rename to src/Core/AdminConsole/Services/IPolicyService.cs index 51867ec966..e2f2fa7942 100644 --- a/src/Core/Services/IPolicyService.cs +++ b/src/Core/AdminConsole/Services/IPolicyService.cs @@ -1,9 +1,12 @@ -using Bit.Core.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Models.Data.Organizations.OrganizationUsers; -using Bit.Core.Models.Data.Organizations.Policies; +using Bit.Core.Services; -namespace Bit.Core.Services; +namespace Bit.Core.AdminConsole.Services; public interface IPolicyService { diff --git a/src/Core/Services/Implementations/PolicyService.cs b/src/Core/AdminConsole/Services/Implementations/PolicyService.cs similarity index 93% rename from src/Core/Services/Implementations/PolicyService.cs rename to src/Core/AdminConsole/Services/Implementations/PolicyService.cs index 2c9b6c73e1..4726de0160 100644 --- a/src/Core/Services/Implementations/PolicyService.cs +++ b/src/Core/AdminConsole/Services/Implementations/PolicyService.cs @@ -1,14 +1,18 @@ -using Bit.Core.Auth.Enums; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Auth.Enums; using Bit.Core.Auth.Repositories; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Data.Organizations.OrganizationUsers; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Repositories; +using Bit.Core.Services; using Bit.Core.Settings; -namespace Bit.Core.Services; +namespace Bit.Core.AdminConsole.Services.Implementations; public class PolicyService : IPolicyService { @@ -114,12 +118,12 @@ public class PolicyService : IPolicyService var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync( policy.OrganizationId); var removableOrgUsers = orgUsers.Where(ou => - ou.Status != Enums.OrganizationUserStatusType.Invited && ou.Status != Enums.OrganizationUserStatusType.Revoked && - ou.Type != Enums.OrganizationUserType.Owner && ou.Type != Enums.OrganizationUserType.Admin && + ou.Status != OrganizationUserStatusType.Invited && ou.Status != OrganizationUserStatusType.Revoked && + ou.Type != OrganizationUserType.Owner && ou.Type != OrganizationUserType.Admin && ou.UserId != savingUserId); switch (policy.Type) { - case Enums.PolicyType.TwoFactorAuthentication: + case PolicyType.TwoFactorAuthentication: foreach (var orgUser in removableOrgUsers) { if (!await userService.TwoFactorIsEnabledAsync(orgUser)) @@ -131,7 +135,7 @@ public class PolicyService : IPolicyService } } break; - case Enums.PolicyType.SingleOrg: + case PolicyType.SingleOrg: var userOrgs = await _organizationUserRepository.GetManyByManyUsersAsync( removableOrgUsers.Select(ou => ou.UserId.Value)); foreach (var orgUser in removableOrgUsers) @@ -154,7 +158,7 @@ public class PolicyService : IPolicyService } policy.RevisionDate = now; await _policyRepository.UpsertAsync(policy); - await _eventService.LogPolicyEventAsync(policy, Enums.EventType.Policy_Updated); + await _eventService.LogPolicyEventAsync(policy, EventType.Policy_Updated); } public async Task GetMasterPasswordPolicyForUserAsync(User user) diff --git a/src/Core/Auth/Services/IEmergencyAccessService.cs b/src/Core/Auth/Services/IEmergencyAccessService.cs index d8abedb37f..2c94632510 100644 --- a/src/Core/Auth/Services/IEmergencyAccessService.cs +++ b/src/Core/Auth/Services/IEmergencyAccessService.cs @@ -1,4 +1,5 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Data; using Bit.Core.Entities; diff --git a/src/Core/Auth/Services/Implementations/EmergencyAccessService.cs b/src/Core/Auth/Services/Implementations/EmergencyAccessService.cs index c992bb9f13..98db32bbdd 100644 --- a/src/Core/Auth/Services/Implementations/EmergencyAccessService.cs +++ b/src/Core/Auth/Services/Implementations/EmergencyAccessService.cs @@ -1,4 +1,6 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models; using Bit.Core.Auth.Models.Business.Tokenables; diff --git a/src/Core/Auth/Services/Implementations/SsoConfigService.cs b/src/Core/Auth/Services/Implementations/SsoConfigService.cs index a7e4784f49..aac77613f6 100644 --- a/src/Core/Auth/Services/Implementations/SsoConfigService.cs +++ b/src/Core/Auth/Services/Implementations/SsoConfigService.cs @@ -1,10 +1,14 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; +using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Repositories; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Exceptions; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Repositories; using Bit.Core.Services; diff --git a/src/Core/Models/Api/Response/MasterPasswordPolicyResponseModel.cs b/src/Core/Models/Api/Response/MasterPasswordPolicyResponseModel.cs index 6a2753e769..0f45bc8e86 100644 --- a/src/Core/Models/Api/Response/MasterPasswordPolicyResponseModel.cs +++ b/src/Core/Models/Api/Response/MasterPasswordPolicyResponseModel.cs @@ -1,4 +1,4 @@ -using Bit.Core.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; namespace Bit.Core.Models.Api.Response; diff --git a/src/Core/Models/Data/Organizations/OrganizationUsers/OrganizationUserPolicyDetails.cs b/src/Core/Models/Data/Organizations/OrganizationUsers/OrganizationUserPolicyDetails.cs index 1ae93ccf53..84939ecf79 100644 --- a/src/Core/Models/Data/Organizations/OrganizationUsers/OrganizationUserPolicyDetails.cs +++ b/src/Core/Models/Data/Organizations/OrganizationUsers/OrganizationUserPolicyDetails.cs @@ -1,4 +1,5 @@ -using Bit.Core.Enums; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.Enums; namespace Bit.Core.Models.Data.Organizations.OrganizationUsers; diff --git a/src/Core/Models/Data/Organizations/SelfHostedOrganizationDetails.cs b/src/Core/Models/Data/Organizations/SelfHostedOrganizationDetails.cs index d501263f4e..b0498e6c89 100644 --- a/src/Core/Models/Data/Organizations/SelfHostedOrganizationDetails.cs +++ b/src/Core/Models/Data/Organizations/SelfHostedOrganizationDetails.cs @@ -1,4 +1,6 @@ -using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Entities; diff --git a/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpgradeOrganizationPlanCommand.cs b/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpgradeOrganizationPlanCommand.cs index b9e3c74da7..8486807c46 100644 --- a/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpgradeOrganizationPlanCommand.cs +++ b/src/Core/OrganizationFeatures/OrganizationSubscriptions/UpgradeOrganizationPlanCommand.cs @@ -1,4 +1,5 @@ -using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Repositories; diff --git a/src/Core/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommand.cs b/src/Core/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommand.cs index 5baff54634..e0c2bada48 100644 --- a/src/Core/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommand.cs +++ b/src/Core/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommand.cs @@ -1,4 +1,6 @@ -using Bit.Core.Auth.Models.Business.Tokenables; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Services; +using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Exceptions; diff --git a/src/Core/Repositories/IOrganizationUserRepository.cs b/src/Core/Repositories/IOrganizationUserRepository.cs index f9dfa12c2c..751bfdc4aa 100644 --- a/src/Core/Repositories/IOrganizationUserRepository.cs +++ b/src/Core/Repositories/IOrganizationUserRepository.cs @@ -1,4 +1,5 @@ -using Bit.Core.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Models.Data; using Bit.Core.Models.Data.Organizations.OrganizationUsers; diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index 60e2cd1f68..51caf4c316 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -1,10 +1,13 @@ using System.Security.Claims; 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.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Business; using Bit.Core.Auth.Models.Business.Tokenables; @@ -15,7 +18,6 @@ using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Business; using Bit.Core.Models.Data; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; using Bit.Core.Repositories; using Bit.Core.Settings; diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs index 1d7f95f1f9..81ce697622 100644 --- a/src/Core/Services/Implementations/UserService.cs +++ b/src/Core/Services/Implementations/UserService.cs @@ -1,6 +1,8 @@ using System.Security.Claims; using System.Text.Json; +using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models; diff --git a/src/Core/Tools/Services/Implementations/SendService.cs b/src/Core/Tools/Services/Implementations/SendService.cs index 1c1cfab4e6..fad941362b 100644 --- a/src/Core/Tools/Services/Implementations/SendService.cs +++ b/src/Core/Tools/Services/Implementations/SendService.cs @@ -1,9 +1,11 @@ using System.Text.Json; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Context; using Bit.Core.Entities; -using Bit.Core.Enums; using Bit.Core.Exceptions; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; diff --git a/src/Core/Vault/Services/Implementations/CipherService.cs b/src/Core/Vault/Services/Implementations/CipherService.cs index 82a6753a9d..72437ec1b6 100644 --- a/src/Core/Vault/Services/Implementations/CipherService.cs +++ b/src/Core/Vault/Services/Implementations/CipherService.cs @@ -1,4 +1,6 @@ using System.Text.Json; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Services; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Enums; diff --git a/src/Identity/IdentityServer/BaseRequestValidator.cs b/src/Identity/IdentityServer/BaseRequestValidator.cs index 40db804be3..0f319fbc84 100644 --- a/src/Identity/IdentityServer/BaseRequestValidator.cs +++ b/src/Identity/IdentityServer/BaseRequestValidator.cs @@ -3,6 +3,8 @@ using System.Reflection; using System.Security.Claims; using System.Text.Json; using Bit.Core; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Identity; diff --git a/src/Identity/IdentityServer/CustomTokenRequestValidator.cs b/src/Identity/IdentityServer/CustomTokenRequestValidator.cs index 0ebd6f8ae7..4710184f78 100644 --- a/src/Identity/IdentityServer/CustomTokenRequestValidator.cs +++ b/src/Identity/IdentityServer/CustomTokenRequestValidator.cs @@ -1,4 +1,5 @@ using System.Security.Claims; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Identity; using Bit.Core.Auth.Models.Api.Response; using Bit.Core.Auth.Models.Business.Tokenables; diff --git a/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs b/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs index 8db6aab7cd..1d71508519 100644 --- a/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs +++ b/src/Identity/IdentityServer/ResourceOwnerPasswordValidator.cs @@ -1,5 +1,6 @@ using System.Security.Claims; using Bit.Core; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Identity; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Repositories; diff --git a/src/Identity/IdentityServer/WebAuthnGrantValidator.cs b/src/Identity/IdentityServer/WebAuthnGrantValidator.cs index a959b63840..f11ebea111 100644 --- a/src/Identity/IdentityServer/WebAuthnGrantValidator.cs +++ b/src/Identity/IdentityServer/WebAuthnGrantValidator.cs @@ -1,6 +1,7 @@ using System.Security.Claims; using System.Text.Json; using Bit.Core; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Identity; using Bit.Core.Auth.Models.Business.Tokenables; diff --git a/src/Infrastructure.Dapper/Repositories/PolicyRepository.cs b/src/Infrastructure.Dapper/AdminConsole/Repositories/PolicyRepository.cs similarity index 89% rename from src/Infrastructure.Dapper/Repositories/PolicyRepository.cs rename to src/Infrastructure.Dapper/AdminConsole/Repositories/PolicyRepository.cs index 8329a8a82b..1a59c501af 100644 --- a/src/Infrastructure.Dapper/Repositories/PolicyRepository.cs +++ b/src/Infrastructure.Dapper/AdminConsole/Repositories/PolicyRepository.cs @@ -1,12 +1,13 @@ using System.Data; -using Bit.Core.Entities; -using Bit.Core.Enums; -using Bit.Core.Repositories; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Repositories; using Bit.Core.Settings; +using Bit.Infrastructure.Dapper.Repositories; using Dapper; using Microsoft.Data.SqlClient; -namespace Bit.Infrastructure.Dapper.Repositories; +namespace Bit.Infrastructure.Dapper.AdminConsole.Repositories; public class PolicyRepository : Repository, IPolicyRepository { diff --git a/src/Infrastructure.Dapper/Repositories/OrganizationRepository.cs b/src/Infrastructure.Dapper/Repositories/OrganizationRepository.cs index 9329e23790..467fb8f8a8 100644 --- a/src/Infrastructure.Dapper/Repositories/OrganizationRepository.cs +++ b/src/Infrastructure.Dapper/Repositories/OrganizationRepository.cs @@ -1,4 +1,5 @@ using System.Data; +using Bit.Core.AdminConsole.Entities; using Bit.Core.Auth.Entities; using Bit.Core.Entities; using Bit.Core.Models.Data.Organizations; diff --git a/src/Infrastructure.Dapper/Repositories/OrganizationUserRepository.cs b/src/Infrastructure.Dapper/Repositories/OrganizationUserRepository.cs index 2a2f0e340a..517b737ee3 100644 --- a/src/Infrastructure.Dapper/Repositories/OrganizationUserRepository.cs +++ b/src/Infrastructure.Dapper/Repositories/OrganizationUserRepository.cs @@ -1,6 +1,7 @@ using System.Data; using System.Text.Json; using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Models.Data; diff --git a/src/Infrastructure.EntityFramework/Models/Policy.cs b/src/Infrastructure.EntityFramework/AdminConsole/Models/Policy.cs similarity index 63% rename from src/Infrastructure.EntityFramework/Models/Policy.cs rename to src/Infrastructure.EntityFramework/AdminConsole/Models/Policy.cs index 22b17c6f6d..d5213f8827 100644 --- a/src/Infrastructure.EntityFramework/Models/Policy.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Models/Policy.cs @@ -2,7 +2,7 @@ namespace Bit.Infrastructure.EntityFramework.Models; -public class Policy : Core.Entities.Policy +public class Policy : Core.AdminConsole.Entities.Policy { public virtual Organization Organization { get; set; } } @@ -11,6 +11,6 @@ public class PolicyMapperProfile : Profile { public PolicyMapperProfile() { - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } diff --git a/src/Infrastructure.EntityFramework/Repositories/PolicyRepository.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/PolicyRepository.cs similarity index 55% rename from src/Infrastructure.EntityFramework/Repositories/PolicyRepository.cs rename to src/Infrastructure.EntityFramework/AdminConsole/Repositories/PolicyRepository.cs index 5dfe2b3bbb..ffcb7bdd19 100644 --- a/src/Infrastructure.EntityFramework/Repositories/PolicyRepository.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/PolicyRepository.cs @@ -1,31 +1,33 @@ using AutoMapper; -using Bit.Core.Enums; -using Bit.Core.Repositories; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Repositories; +using Bit.Infrastructure.EntityFramework.AdminConsole.Repositories.Queries; using Bit.Infrastructure.EntityFramework.Models; -using Bit.Infrastructure.EntityFramework.Repositories.Queries; +using Bit.Infrastructure.EntityFramework.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using AdminConsoleEntities = Bit.Core.AdminConsole.Entities; -namespace Bit.Infrastructure.EntityFramework.Repositories; +namespace Bit.Infrastructure.EntityFramework.AdminConsole.Repositories; -public class PolicyRepository : Repository, IPolicyRepository +public class PolicyRepository : Repository, IPolicyRepository { public PolicyRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) : base(serviceScopeFactory, mapper, (DatabaseContext context) => context.Policies) { } - public async Task GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type) + public async Task GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type) { using (var scope = ServiceScopeFactory.CreateScope()) { var dbContext = GetDatabaseContext(scope); var results = await dbContext.Policies .FirstOrDefaultAsync(p => p.OrganizationId == organizationId && p.Type == type); - return Mapper.Map(results); + return Mapper.Map(results); } } - public async Task> GetManyByOrganizationIdAsync(Guid organizationId) + public async Task> GetManyByOrganizationIdAsync(Guid organizationId) { using (var scope = ServiceScopeFactory.CreateScope()) { @@ -33,11 +35,11 @@ public class PolicyRepository : Repository, var results = await dbContext.Policies .Where(p => p.OrganizationId == organizationId) .ToListAsync(); - return Mapper.Map>(results); + return Mapper.Map>(results); } } - public async Task> GetManyByUserIdAsync(Guid userId) + public async Task> GetManyByUserIdAsync(Guid userId) { using (var scope = ServiceScopeFactory.CreateScope()) { @@ -45,7 +47,7 @@ public class PolicyRepository : Repository, var query = new PolicyReadByUserIdQuery(userId); var results = await query.Run(dbContext).ToListAsync(); - return Mapper.Map>(results); + return Mapper.Map>(results); } } } diff --git a/src/Infrastructure.EntityFramework/Repositories/Queries/PolicyReadByUserIdQuery.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/PolicyReadByUserIdQuery.cs similarity index 80% rename from src/Infrastructure.EntityFramework/Repositories/Queries/PolicyReadByUserIdQuery.cs rename to src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/PolicyReadByUserIdQuery.cs index 9da530b01b..fc9e067999 100644 --- a/src/Infrastructure.EntityFramework/Repositories/Queries/PolicyReadByUserIdQuery.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/PolicyReadByUserIdQuery.cs @@ -1,7 +1,9 @@ using Bit.Core.Enums; using Bit.Infrastructure.EntityFramework.Models; +using Bit.Infrastructure.EntityFramework.Repositories; +using Bit.Infrastructure.EntityFramework.Repositories.Queries; -namespace Bit.Infrastructure.EntityFramework.Repositories.Queries; +namespace Bit.Infrastructure.EntityFramework.AdminConsole.Repositories.Queries; public class PolicyReadByUserIdQuery : IQuery { diff --git a/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs b/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs index 5e005a5593..ed86bae040 100644 --- a/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/OrganizationUserRepository.cs @@ -1,4 +1,5 @@ using AutoMapper; +using Bit.Core.AdminConsole.Enums; using Bit.Core.Enums; using Bit.Core.Models.Data; using Bit.Core.Models.Data.Organizations.OrganizationUsers; diff --git a/test/Api.Test/AdminConsole/Controllers/OrganizationUsersControllerTests.cs b/test/Api.Test/AdminConsole/Controllers/OrganizationUsersControllerTests.cs index b62027919c..baf23bb9c1 100644 --- a/test/Api.Test/AdminConsole/Controllers/OrganizationUsersControllerTests.cs +++ b/test/Api.Test/AdminConsole/Controllers/OrganizationUsersControllerTests.cs @@ -1,7 +1,10 @@ using Bit.Api.AdminConsole.Controllers; using Bit.Api.AdminConsole.Models.Request.Organizations; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Repositories; using Bit.Core.Entities; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.Repositories; using Bit.Core.Services; @@ -82,7 +85,7 @@ public class OrganizationUsersControllerTests }; sutProvider.GetDependency().GetUserByPrincipalAsync(default).ReturnsForAnyArgs(user); sutProvider.GetDependency().GetByOrganizationIdTypeAsync(orgId, - Core.Enums.PolicyType.ResetPassword).Returns(policy); + PolicyType.ResetPassword).Returns(policy); await sutProvider.Sut.Accept(orgId, orgUserId, model); diff --git a/test/Api.Test/Auth/Controllers/WebAuthnControllerTests.cs b/test/Api.Test/Auth/Controllers/WebAuthnControllerTests.cs index 26265f5c41..c8d2ea905c 100644 --- a/test/Api.Test/Auth/Controllers/WebAuthnControllerTests.cs +++ b/test/Api.Test/Auth/Controllers/WebAuthnControllerTests.cs @@ -1,9 +1,10 @@ using Bit.Api.Auth.Controllers; using Bit.Api.Auth.Models.Request.Accounts; using Bit.Api.Auth.Models.Request.Webauthn; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Entities; -using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Services; using Bit.Core.Tokens; diff --git a/test/Api.Test/Controllers/AccountsControllerTests.cs b/test/Api.Test/Controllers/AccountsControllerTests.cs index aa3cca0b4f..d6e8cacbe6 100644 --- a/test/Api.Test/Controllers/AccountsControllerTests.cs +++ b/test/Api.Test/Controllers/AccountsControllerTests.cs @@ -2,6 +2,7 @@ using Bit.Api.Auth.Models.Request.Accounts; using Bit.Api.Controllers; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Models.Api.Request.Accounts; using Bit.Core.Auth.Services; using Bit.Core.Auth.UserFeatures.UserKey; diff --git a/test/Api.Test/Controllers/PoliciesControllerTests.cs b/test/Api.Test/Controllers/PoliciesControllerTests.cs index 0d2f004b17..ec69104e52 100644 --- a/test/Api.Test/Controllers/PoliciesControllerTests.cs +++ b/test/Api.Test/Controllers/PoliciesControllerTests.cs @@ -1,10 +1,12 @@ using System.Security.Claims; using System.Text.Json; using Bit.Api.AdminConsole.Controllers; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Repositories; using Bit.Core.Entities; -using Bit.Core.Enums; using Bit.Core.Exceptions; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Test.Common.AutoFixture; diff --git a/test/Api.Test/Vault/Controllers/SyncControllerTests.cs b/test/Api.Test/Vault/Controllers/SyncControllerTests.cs index e1a9c15629..2f29ba6109 100644 --- a/test/Api.Test/Vault/Controllers/SyncControllerTests.cs +++ b/test/Api.Test/Vault/Controllers/SyncControllerTests.cs @@ -3,6 +3,7 @@ using System.Text.Json; using AutoFixture; using Bit.Api.Vault.Controllers; using Bit.Api.Vault.Models.Response; +using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Enums.Provider; using Bit.Core.AdminConsole.Models.Data.Provider; using Bit.Core.AdminConsole.Repositories; diff --git a/test/Core.Test/AutoFixture/PolicyFixtures.cs b/test/Core.Test/AdminConsole/AutoFixture/PolicyFixtures.cs similarity index 86% rename from test/Core.Test/AutoFixture/PolicyFixtures.cs rename to test/Core.Test/AdminConsole/AutoFixture/PolicyFixtures.cs index fb8109baf9..f70fd579e3 100644 --- a/test/Core.Test/AutoFixture/PolicyFixtures.cs +++ b/test/Core.Test/AdminConsole/AutoFixture/PolicyFixtures.cs @@ -1,10 +1,10 @@ using System.Reflection; using AutoFixture; using AutoFixture.Xunit2; -using Bit.Core.Entities; -using Bit.Core.Enums; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; -namespace Bit.Core.Test.AutoFixture.PolicyFixtures; +namespace Bit.Core.Test.AdminConsole.AutoFixture; internal class PolicyCustomization : ICustomization { diff --git a/test/Core.Test/Services/PolicyServiceTests.cs b/test/Core.Test/AdminConsole/Services/PolicyServiceTests.cs similarity index 93% rename from test/Core.Test/Services/PolicyServiceTests.cs rename to test/Core.Test/AdminConsole/Services/PolicyServiceTests.cs index aedc3cc587..65e0815cc9 100644 --- a/test/Core.Test/Services/PolicyServiceTests.cs +++ b/test/Core.Test/AdminConsole/Services/PolicyServiceTests.cs @@ -1,4 +1,9 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services.Implementations; +using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Data; using Bit.Core.Auth.Repositories; @@ -6,24 +11,23 @@ using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Data.Organizations.OrganizationUsers; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using NSubstitute; using Xunit; +using AdminConsoleFixtures = Bit.Core.Test.AdminConsole.AutoFixture; using GlobalSettings = Bit.Core.Settings.GlobalSettings; -using PolicyFixtures = Bit.Core.Test.AutoFixture.PolicyFixtures; -namespace Bit.Core.Test.Services; +namespace Bit.Core.Test.AdminConsole.Services; [SutProviderCustomize] public class PolicyServiceTests { [Theory, BitAutoData] public async Task SaveAsync_OrganizationDoesNotExist_ThrowsBadRequest( - [PolicyFixtures.Policy(PolicyType.DisableSend)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.DisableSend)] Policy policy, SutProvider sutProvider) { SetupOrg(sutProvider, policy.OrganizationId, null); @@ -46,7 +50,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_OrganizationCannotUsePolicies_ThrowsBadRequest( - [PolicyFixtures.Policy(PolicyType.DisableSend)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.DisableSend)] Policy policy, SutProvider sutProvider) { var orgId = Guid.NewGuid(); @@ -74,7 +78,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_SingleOrg_RequireSsoEnabled_ThrowsBadRequest( - [PolicyFixtures.Policy(PolicyType.SingleOrg)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.SingleOrg)] Policy policy, SutProvider sutProvider) { policy.Enabled = false; @@ -106,7 +110,7 @@ public class PolicyServiceTests } [Theory, BitAutoData] - public async Task SaveAsync_SingleOrg_VaultTimeoutEnabled_ThrowsBadRequest([PolicyFixtures.Policy(Enums.PolicyType.SingleOrg)] Policy policy, SutProvider sutProvider) + public async Task SaveAsync_SingleOrg_VaultTimeoutEnabled_ThrowsBadRequest([AdminConsoleFixtures.Policy(PolicyType.SingleOrg)] Policy policy, SutProvider sutProvider) { policy.Enabled = false; @@ -117,7 +121,7 @@ public class PolicyServiceTests }); sutProvider.GetDependency() - .GetByOrganizationIdTypeAsync(policy.OrganizationId, Enums.PolicyType.MaximumVaultTimeout) + .GetByOrganizationIdTypeAsync(policy.OrganizationId, PolicyType.MaximumVaultTimeout) .Returns(new Policy { Enabled = true }); var badRequestException = await Assert.ThrowsAsync( @@ -137,7 +141,7 @@ public class PolicyServiceTests [BitAutoData(PolicyType.SingleOrg)] [BitAutoData(PolicyType.RequireSso)] public async Task SaveAsync_PolicyRequiredByKeyConnector_DisablePolicy_ThrowsBadRequest( - Enums.PolicyType policyType, + PolicyType policyType, Policy policy, SutProvider sutProvider) { @@ -173,7 +177,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_RequireSsoPolicy_NotEnabled_ThrowsBadRequestAsync( - [PolicyFixtures.Policy(Enums.PolicyType.RequireSso)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.RequireSso)] Policy policy, SutProvider sutProvider) { policy.Enabled = true; @@ -206,7 +210,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_NewPolicy_Created( - [PolicyFixtures.Policy(PolicyType.ResetPassword)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.ResetPassword)] Policy policy, SutProvider sutProvider) { policy.Id = default; policy.Data = null; @@ -218,7 +222,7 @@ public class PolicyServiceTests }); sutProvider.GetDependency() - .GetByOrganizationIdTypeAsync(policy.OrganizationId, Enums.PolicyType.SingleOrg) + .GetByOrganizationIdTypeAsync(policy.OrganizationId, PolicyType.SingleOrg) .Returns(Task.FromResult(new Policy { Enabled = true })); var utcNow = DateTime.UtcNow; @@ -237,7 +241,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_VaultTimeoutPolicy_NotEnabled_ThrowsBadRequestAsync( - [PolicyFixtures.Policy(PolicyType.MaximumVaultTimeout)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.MaximumVaultTimeout)] Policy policy, SutProvider sutProvider) { policy.Enabled = true; @@ -248,7 +252,7 @@ public class PolicyServiceTests }); sutProvider.GetDependency() - .GetByOrganizationIdTypeAsync(policy.OrganizationId, Enums.PolicyType.SingleOrg) + .GetByOrganizationIdTypeAsync(policy.OrganizationId, PolicyType.SingleOrg) .Returns(Task.FromResult(new Policy { Enabled = false })); var badRequestException = await Assert.ThrowsAsync( @@ -270,7 +274,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_ExistingPolicy_UpdateTwoFactor( - [PolicyFixtures.Policy(PolicyType.TwoFactorAuthentication)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.TwoFactorAuthentication)] Policy policy, SutProvider sutProvider) { // If the policy that this is updating isn't enabled then do some work now that the current one is enabled @@ -340,7 +344,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_ExistingPolicy_UpdateSingleOrg( - [PolicyFixtures.Policy(PolicyType.TwoFactorAuthentication)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.TwoFactorAuthentication)] Policy policy, SutProvider sutProvider) { // If the policy that this is updating isn't enabled then do some work now that the current one is enabled @@ -409,7 +413,7 @@ public class PolicyServiceTests public async Task SaveAsync_ResetPasswordPolicyRequiredByTrustedDeviceEncryption_DisablePolicyOrDisableAutomaticEnrollment_ThrowsBadRequest( bool policyEnabled, bool autoEnrollEnabled, - [PolicyFixtures.Policy(PolicyType.ResetPassword)] Policy policy, + [AdminConsoleFixtures.Policy(PolicyType.ResetPassword)] Policy policy, SutProvider sutProvider) { policy.Enabled = policyEnabled; @@ -450,7 +454,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_RequireSsoPolicyRequiredByTrustedDeviceEncryption_DisablePolicy_ThrowsBadRequest( - [PolicyFixtures.Policy(PolicyType.RequireSso)] Policy policy, + [AdminConsoleFixtures.Policy(PolicyType.RequireSso)] Policy policy, SutProvider sutProvider) { policy.Enabled = false; @@ -487,7 +491,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_PolicyRequiredForAccountRecovery_NotEnabled_ThrowsBadRequestAsync( - [PolicyFixtures.Policy(Enums.PolicyType.ResetPassword)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.ResetPassword)] Policy policy, SutProvider sutProvider) { policy.Enabled = true; policy.SetDataModel(new ResetPasswordDataModel()); @@ -522,7 +526,7 @@ public class PolicyServiceTests [Theory, BitAutoData] public async Task SaveAsync_SingleOrg_AccountRecoveryEnabled_ThrowsBadRequest( - [PolicyFixtures.Policy(Enums.PolicyType.SingleOrg)] Policy policy, SutProvider sutProvider) + [AdminConsoleFixtures.Policy(PolicyType.SingleOrg)] Policy policy, SutProvider sutProvider) { policy.Enabled = false; @@ -533,7 +537,7 @@ public class PolicyServiceTests }); sutProvider.GetDependency() - .GetByOrganizationIdTypeAsync(policy.OrganizationId, Enums.PolicyType.ResetPassword) + .GetByOrganizationIdTypeAsync(policy.OrganizationId, PolicyType.ResetPassword) .Returns(new Policy { Enabled = true }); var badRequestException = await Assert.ThrowsAsync( diff --git a/test/Core.Test/Auth/Services/SsoConfigServiceTests.cs b/test/Core.Test/Auth/Services/SsoConfigServiceTests.cs index 7886d6f9e8..c4324ff227 100644 --- a/test/Core.Test/Auth/Services/SsoConfigServiceTests.cs +++ b/test/Core.Test/Auth/Services/SsoConfigServiceTests.cs @@ -1,4 +1,9 @@ -using Bit.Core.Auth.Entities; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; +using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Data; using Bit.Core.Auth.Repositories; @@ -6,7 +11,6 @@ using Bit.Core.Auth.Services; using Bit.Core.Entities; using Bit.Core.Exceptions; using Bit.Core.Models.Data.Organizations.OrganizationUsers; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Test.Common.AutoFixture; @@ -205,7 +209,7 @@ public class SsoConfigServiceTests }; sutProvider.GetDependency().GetByOrganizationIdTypeAsync( - Arg.Any(), Enums.PolicyType.SingleOrg).Returns(new Policy + Arg.Any(), PolicyType.SingleOrg).Returns(new Policy { Enabled = true }); @@ -239,7 +243,7 @@ public class SsoConfigServiceTests }; sutProvider.GetDependency().GetByOrganizationIdTypeAsync( - Arg.Any(), Arg.Any()).Returns(new Policy + Arg.Any(), Arg.Any()).Returns(new Policy { Enabled = true }); @@ -274,7 +278,7 @@ public class SsoConfigServiceTests }; sutProvider.GetDependency().GetByOrganizationIdTypeAsync( - Arg.Any(), Arg.Any()).Returns(new Policy + Arg.Any(), Arg.Any()).Returns(new Policy { Enabled = true, }); @@ -309,7 +313,7 @@ public class SsoConfigServiceTests }; sutProvider.GetDependency().GetByOrganizationIdTypeAsync( - Arg.Any(), Arg.Any()).Returns(new Policy + Arg.Any(), Arg.Any()).Returns(new Policy { Enabled = true, }); @@ -338,7 +342,7 @@ public class SsoConfigServiceTests await sutProvider.GetDependency().Received(1) .SaveAsync( - Arg.Is(t => t.Type == Enums.PolicyType.SingleOrg), + Arg.Is(t => t.Type == PolicyType.SingleOrg), Arg.Any(), Arg.Any(), null @@ -346,7 +350,7 @@ public class SsoConfigServiceTests await sutProvider.GetDependency().Received(1) .SaveAsync( - Arg.Is(t => t.Type == Enums.PolicyType.ResetPassword && t.GetDataModel().AutoEnrollEnabled), + Arg.Is(t => t.Type == PolicyType.ResetPassword && t.GetDataModel().AutoEnrollEnabled), Arg.Any(), Arg.Any(), null diff --git a/test/Core.Test/Models/Data/SelfHostedOrganizationDetailsTests.cs b/test/Core.Test/Models/Data/SelfHostedOrganizationDetailsTests.cs index a46981ee9b..4d961bef35 100644 --- a/test/Core.Test/Models/Data/SelfHostedOrganizationDetailsTests.cs +++ b/test/Core.Test/Models/Data/SelfHostedOrganizationDetailsTests.cs @@ -1,4 +1,6 @@ -using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.OrganizationConnectionConfigs; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Data; diff --git a/test/Core.Test/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommandTests.cs b/test/Core.Test/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommandTests.cs index 33ad63d02e..0d2d7b56e8 100644 --- a/test/Core.Test/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommandTests.cs +++ b/test/Core.Test/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommandTests.cs @@ -1,4 +1,6 @@ -using Bit.Core.Auth.Models.Business.Tokenables; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Services; +using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Exceptions; diff --git a/test/Core.Test/Services/OrganizationServiceTests.cs b/test/Core.Test/Services/OrganizationServiceTests.cs index a169a0093e..9e25a2bcbe 100644 --- a/test/Core.Test/Services/OrganizationServiceTests.cs +++ b/test/Core.Test/Services/OrganizationServiceTests.cs @@ -1,5 +1,6 @@ using System.Text.Json; using Bit.Core.AdminConsole.Entities.Provider; +using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Enums.Provider; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.AdminConsole.Repositories; @@ -21,9 +22,9 @@ using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; +using Bit.Core.Test.AdminConsole.AutoFixture; using Bit.Core.Test.AutoFixture.OrganizationFixtures; using Bit.Core.Test.AutoFixture.OrganizationUserFixtures; -using Bit.Core.Test.AutoFixture.PolicyFixtures; using Bit.Core.Tokens; using Bit.Core.Tools.Enums; using Bit.Core.Tools.Models.Business; @@ -38,7 +39,7 @@ using NSubstitute.ReturnsExtensions; using Xunit; using Organization = Bit.Core.Entities.Organization; using OrganizationUser = Bit.Core.Entities.OrganizationUser; -using Policy = Bit.Core.Entities.Policy; +using Policy = Bit.Core.AdminConsole.Entities.Policy; namespace Bit.Core.Test.Services; diff --git a/test/Core.Test/Services/UserServiceTests.cs b/test/Core.Test/Services/UserServiceTests.cs index c3bd1b2830..e95aa9d28a 100644 --- a/test/Core.Test/Services/UserServiceTests.cs +++ b/test/Core.Test/Services/UserServiceTests.cs @@ -2,6 +2,7 @@ using System.Text.Json; using AutoFixture; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Services; using Bit.Core.Auth.Entities; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models; diff --git a/test/Core.Test/Tools/Services/SendServiceTests.cs b/test/Core.Test/Tools/Services/SendServiceTests.cs index 6b59429cd8..d3a4159a59 100644 --- a/test/Core.Test/Tools/Services/SendServiceTests.cs +++ b/test/Core.Test/Tools/Services/SendServiceTests.cs @@ -1,10 +1,12 @@ using System.Text; using System.Text.Json; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.Services; using Bit.Core.Entities; -using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.Data.Organizations.OrganizationUsers; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Test.AutoFixture.CurrentContextFixtures; diff --git a/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs b/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs index cae6ed172c..6a8a5db361 100644 --- a/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs +++ b/test/Identity.IntegrationTest/Endpoints/IdentityServerTests.cs @@ -1,4 +1,7 @@ using System.Text.Json; +using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Repositories; using Bit.Core.Auth.Models.Api.Request.Accounts; using Bit.Core.Enums; using Bit.Core.Repositories; @@ -569,7 +572,7 @@ public class IdentityServerTests : IClassFixture }; await organizationUserRepository.CreateAsync(organizationUser); - var ssoPolicy = new Bit.Core.Entities.Policy { OrganizationId = organization.Id, Type = PolicyType.RequireSso, Enabled = ssoPolicyEnabled }; + var ssoPolicy = new Policy { OrganizationId = organization.Id, Type = PolicyType.RequireSso, Enabled = ssoPolicyEnabled }; await policyRepository.CreateAsync(ssoPolicy); } diff --git a/test/Infrastructure.EFIntegration.Test/Repositories/PolicyRepositoryTests.cs b/test/Infrastructure.EFIntegration.Test/AdminConsole/Repositories/PolicyRepositoryTests.cs similarity index 80% rename from test/Infrastructure.EFIntegration.Test/Repositories/PolicyRepositoryTests.cs rename to test/Infrastructure.EFIntegration.Test/AdminConsole/Repositories/PolicyRepositoryTests.cs index db05c52a32..d398284c28 100644 --- a/test/Infrastructure.EFIntegration.Test/Repositories/PolicyRepositoryTests.cs +++ b/test/Infrastructure.EFIntegration.Test/AdminConsole/Repositories/PolicyRepositoryTests.cs @@ -3,11 +3,13 @@ using Bit.Core.Test.AutoFixture.Attributes; using Bit.Infrastructure.EFIntegration.Test.AutoFixture; using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers; using Xunit; +using EfAdminConsoleRepo = Bit.Infrastructure.EntityFramework.AdminConsole.Repositories; using EfRepo = Bit.Infrastructure.EntityFramework.Repositories; -using Policy = Bit.Core.Entities.Policy; +using Policy = Bit.Core.AdminConsole.Entities.Policy; +using SqlAdminConsoleRepo = Bit.Infrastructure.Dapper.AdminConsole.Repositories; using SqlRepo = Bit.Infrastructure.Dapper.Repositories; -namespace Bit.Infrastructure.EFIntegration.Test.Repositories; +namespace Bit.Infrastructure.EFIntegration.Test.AdminConsole.Repositories; public class PolicyRepositoryTests { @@ -16,9 +18,9 @@ public class PolicyRepositoryTests Policy policy, Organization organization, PolicyCompare equalityComparer, - List suts, + List suts, List efOrganizationRepos, - SqlRepo.PolicyRepository sqlPolicyRepo, + SqlAdminConsoleRepo.PolicyRepository sqlPolicyRepo, SqlRepo.OrganizationRepository sqlOrganizationRepo ) { diff --git a/test/Infrastructure.EFIntegration.Test/AutoFixture/PolicyFixtures.cs b/test/Infrastructure.EFIntegration.Test/AutoFixture/PolicyFixtures.cs index 5ecd31f9c6..8ca48190cd 100644 --- a/test/Infrastructure.EFIntegration.Test/AutoFixture/PolicyFixtures.cs +++ b/test/Infrastructure.EFIntegration.Test/AutoFixture/PolicyFixtures.cs @@ -1,6 +1,6 @@ using AutoFixture; using AutoFixture.Kernel; -using Bit.Core.Entities; +using Bit.Core.AdminConsole.Entities; using Bit.Infrastructure.EntityFramework.AdminConsole.Repositories; using Bit.Infrastructure.EntityFramework.Repositories; using Bit.Test.Common.AutoFixture; diff --git a/test/Infrastructure.EFIntegration.Test/Repositories/EqualityComparers/PolicyCompare.cs b/test/Infrastructure.EFIntegration.Test/Repositories/EqualityComparers/PolicyCompare.cs index f3bd7dc7a9..2cd01d1396 100644 --- a/test/Infrastructure.EFIntegration.Test/Repositories/EqualityComparers/PolicyCompare.cs +++ b/test/Infrastructure.EFIntegration.Test/Repositories/EqualityComparers/PolicyCompare.cs @@ -1,5 +1,5 @@ using System.Diagnostics.CodeAnalysis; -using Bit.Core.Entities; +using Bit.Core.AdminConsole.Entities; namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers; diff --git a/test/Infrastructure.EFIntegration.Test/Repositories/OrganizationUserRepositoryTests.cs b/test/Infrastructure.EFIntegration.Test/Repositories/OrganizationUserRepositoryTests.cs index 67b199b35a..c29fd28b22 100644 --- a/test/Infrastructure.EFIntegration.Test/Repositories/OrganizationUserRepositoryTests.cs +++ b/test/Infrastructure.EFIntegration.Test/Repositories/OrganizationUserRepositoryTests.cs @@ -1,5 +1,7 @@ using System.Text.Json; +using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Entities.Provider; +using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Entities; using Bit.Core.Enums; @@ -13,6 +15,7 @@ using Xunit; using EfAdminConsoleRepo = Bit.Infrastructure.EntityFramework.AdminConsole.Repositories; using EfRepo = Bit.Infrastructure.EntityFramework.Repositories; using OrganizationUser = Bit.Core.Entities.OrganizationUser; +using SqlAdminConsoleRepo = Bit.Infrastructure.Dapper.AdminConsole.Repositories; using SqlRepo = Bit.Infrastructure.Dapper.Repositories; namespace Bit.Infrastructure.EFIntegration.Test.Repositories; @@ -182,7 +185,7 @@ public class OrganizationUserRepositoryTests OrganizationUserPolicyDetailsCompare equalityComparer, // Auto data - EF repos - List efPolicyRepository, + List efPolicyRepository, List efUserRepository, List efOrganizationRepository, List suts, @@ -191,7 +194,7 @@ public class OrganizationUserRepositoryTests List efProviderUserRepository, // Auto data - SQL repos - SqlRepo.PolicyRepository sqlPolicyRepo, + SqlAdminConsoleRepo.PolicyRepository sqlPolicyRepo, SqlRepo.UserRepository sqlUserRepo, SqlRepo.OrganizationRepository sqlOrganizationRepo, EfAdminConsoleRepo.ProviderRepository sqlProviderRepo, From c2dbeb46085ae0f51f746ed8fed7d8dc41257723 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Thu, 23 Nov 2023 07:59:49 +1000 Subject: [PATCH 17/20] AC Team code ownership moves: Policies (2/2) (#3470) * this updates namespace and content for IPolicyData.cs and Entityframework Policy.cs as a separate commit to maintain git history. --- src/Core/AdminConsole/Entities/Policy.cs | 2 +- .../Models/Data/Organizations/Policies/IPolicyDataModel.cs | 2 +- .../Data/Organizations/Policies/MasterPasswordPolicyData.cs | 4 +--- .../Data/Organizations/Policies/ResetPasswordDataModel.cs | 1 - .../Data/Organizations/Policies/SendOptionsPolicyData.cs | 1 - .../AdminConsole/Models/Policy.cs | 3 ++- .../AdminConsole/Repositories/PolicyRepository.cs | 2 +- .../Repositories/Queries/PolicyReadByUserIdQuery.cs | 2 +- src/Infrastructure.EntityFramework/Models/Organization.cs | 1 + .../Repositories/DatabaseContext.cs | 1 + .../AutoFixture/EntityFrameworkRepositoryFixtures.cs | 1 + 11 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Core/AdminConsole/Entities/Policy.cs b/src/Core/AdminConsole/Entities/Policy.cs index 75d67c1021..daf0699145 100644 --- a/src/Core/AdminConsole/Entities/Policy.cs +++ b/src/Core/AdminConsole/Entities/Policy.cs @@ -1,6 +1,6 @@ using Bit.Core.AdminConsole.Enums; +using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; using Bit.Core.Entities; -using Bit.Core.Models.Data.Organizations.Policies; using Bit.Core.Utilities; namespace Bit.Core.AdminConsole.Entities; diff --git a/src/Core/AdminConsole/Models/Data/Organizations/Policies/IPolicyDataModel.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/IPolicyDataModel.cs index ef8789d483..9e666f5a10 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/Policies/IPolicyDataModel.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/Policies/IPolicyDataModel.cs @@ -1,4 +1,4 @@ -namespace Bit.Core.Models.Data.Organizations.Policies; +namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; public interface IPolicyDataModel { diff --git a/src/Core/AdminConsole/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs index 1ace6204df..f2f275b708 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/Policies/MasterPasswordPolicyData.cs @@ -1,6 +1,4 @@ -using Bit.Core.Models.Data.Organizations.Policies; - -namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; public class MasterPasswordPolicyData : IPolicyDataModel { diff --git a/src/Core/AdminConsole/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs index e3a921d87c..62c8473612 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/Policies/ResetPasswordDataModel.cs @@ -1,5 +1,4 @@ using System.ComponentModel.DataAnnotations; -using Bit.Core.Models.Data.Organizations.Policies; namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; diff --git a/src/Core/AdminConsole/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs b/src/Core/AdminConsole/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs index 903d63176d..57a8544b40 100644 --- a/src/Core/AdminConsole/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs +++ b/src/Core/AdminConsole/Models/Data/Organizations/Policies/SendOptionsPolicyData.cs @@ -1,5 +1,4 @@ using System.ComponentModel.DataAnnotations; -using Bit.Core.Models.Data.Organizations.Policies; namespace Bit.Core.AdminConsole.Models.Data.Organizations.Policies; diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Models/Policy.cs b/src/Infrastructure.EntityFramework/AdminConsole/Models/Policy.cs index d5213f8827..ac06416a49 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Models/Policy.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Models/Policy.cs @@ -1,6 +1,7 @@ using AutoMapper; +using Bit.Infrastructure.EntityFramework.Models; -namespace Bit.Infrastructure.EntityFramework.Models; +namespace Bit.Infrastructure.EntityFramework.AdminConsole.Models; public class Policy : Core.AdminConsole.Entities.Policy { diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/PolicyRepository.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/PolicyRepository.cs index ffcb7bdd19..3eb4ac934b 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/PolicyRepository.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/PolicyRepository.cs @@ -1,8 +1,8 @@ using AutoMapper; using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Repositories; +using Bit.Infrastructure.EntityFramework.AdminConsole.Models; using Bit.Infrastructure.EntityFramework.AdminConsole.Repositories.Queries; -using Bit.Infrastructure.EntityFramework.Models; using Bit.Infrastructure.EntityFramework.Repositories; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; diff --git a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/PolicyReadByUserIdQuery.cs b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/PolicyReadByUserIdQuery.cs index fc9e067999..d81e38426a 100644 --- a/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/PolicyReadByUserIdQuery.cs +++ b/src/Infrastructure.EntityFramework/AdminConsole/Repositories/Queries/PolicyReadByUserIdQuery.cs @@ -1,5 +1,5 @@ using Bit.Core.Enums; -using Bit.Infrastructure.EntityFramework.Models; +using Bit.Infrastructure.EntityFramework.AdminConsole.Models; using Bit.Infrastructure.EntityFramework.Repositories; using Bit.Infrastructure.EntityFramework.Repositories.Queries; diff --git a/src/Infrastructure.EntityFramework/Models/Organization.cs b/src/Infrastructure.EntityFramework/Models/Organization.cs index d7410cf4a7..b8d13e273e 100644 --- a/src/Infrastructure.EntityFramework/Models/Organization.cs +++ b/src/Infrastructure.EntityFramework/Models/Organization.cs @@ -1,6 +1,7 @@ using AutoMapper; using Bit.Core.Enums; using Bit.Core.Models.Data.Organizations; +using Bit.Infrastructure.EntityFramework.AdminConsole.Models; using Bit.Infrastructure.EntityFramework.Auth.Models; using Bit.Infrastructure.EntityFramework.Vault.Models; diff --git a/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs b/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs index f0275d5760..f89f9dd8fb 100644 --- a/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs +++ b/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs @@ -1,4 +1,5 @@ using Bit.Core; +using Bit.Infrastructure.EntityFramework.AdminConsole.Models; using Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider; using Bit.Infrastructure.EntityFramework.Auth.Models; using Bit.Infrastructure.EntityFramework.Converters; diff --git a/test/Infrastructure.EFIntegration.Test/AutoFixture/EntityFrameworkRepositoryFixtures.cs b/test/Infrastructure.EFIntegration.Test/AutoFixture/EntityFrameworkRepositoryFixtures.cs index b610f51da2..17c013d964 100644 --- a/test/Infrastructure.EFIntegration.Test/AutoFixture/EntityFrameworkRepositoryFixtures.cs +++ b/test/Infrastructure.EFIntegration.Test/AutoFixture/EntityFrameworkRepositoryFixtures.cs @@ -4,6 +4,7 @@ using AutoFixture.Kernel; using AutoMapper; using Bit.Core.Settings; using Bit.Infrastructure.EFIntegration.Test.Helpers; +using Bit.Infrastructure.EntityFramework.AdminConsole.Models; using Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider; using Bit.Infrastructure.EntityFramework.Auth.Models; using Bit.Infrastructure.EntityFramework.Models; From 4e8284cf81b36108ab095df1d2e25644bc0b96d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Thu, 23 Nov 2023 10:27:43 +0100 Subject: [PATCH 18/20] PM-4881: Added UserName to server models. (#3459) --- src/Api/Vault/Models/CipherFido2CredentialModel.cs | 5 +++++ src/Core/Vault/Models/Data/CipherLoginFido2CredentialData.cs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/Api/Vault/Models/CipherFido2CredentialModel.cs b/src/Api/Vault/Models/CipherFido2CredentialModel.cs index 32f6104a9a..09d66a22e5 100644 --- a/src/Api/Vault/Models/CipherFido2CredentialModel.cs +++ b/src/Api/Vault/Models/CipherFido2CredentialModel.cs @@ -18,6 +18,7 @@ public class CipherFido2CredentialModel RpId = data.RpId; RpName = data.RpName; UserHandle = data.UserHandle; + UserName = data.UserName; UserDisplayName = data.UserDisplayName; Counter = data.Counter; Discoverable = data.Discoverable; @@ -50,6 +51,9 @@ public class CipherFido2CredentialModel public string UserHandle { get; set; } [EncryptedString] [EncryptedStringLength(1000)] + public string UserName { get; set; } + [EncryptedString] + [EncryptedStringLength(1000)] public string UserDisplayName { get; set; } [EncryptedString] [EncryptedStringLength(1000)] @@ -72,6 +76,7 @@ public class CipherFido2CredentialModel RpId = RpId, RpName = RpName, UserHandle = UserHandle, + UserName = UserName, UserDisplayName = UserDisplayName, Counter = Counter, Discoverable = Discoverable, diff --git a/src/Core/Vault/Models/Data/CipherLoginFido2CredentialData.cs b/src/Core/Vault/Models/Data/CipherLoginFido2CredentialData.cs index c0801d2a6c..eefb7ec6ad 100644 --- a/src/Core/Vault/Models/Data/CipherLoginFido2CredentialData.cs +++ b/src/Core/Vault/Models/Data/CipherLoginFido2CredentialData.cs @@ -12,6 +12,7 @@ public class CipherLoginFido2CredentialData public string RpId { get; set; } public string RpName { get; set; } public string UserHandle { get; set; } + public string UserName { get; set; } public string UserDisplayName { get; set; } public string Counter { get; set; } public string Discoverable { get; set; } From e2d644f1365f93b43d51ac964e37b75fe6c6368a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Tom=C3=A9?= <108268980+r-tome@users.noreply.github.com> Date: Thu, 23 Nov 2023 12:21:20 +0000 Subject: [PATCH 19/20] [AC-1116] Assign new imported collections to the importing user with Manage permission (#3424) * [AC-1116] Assigning imported collections to the importing user with Manage permission * [AC-1116] Added unit tests --- .../Vault/Repositories/ICipherRepository.cs | 2 +- .../Services/Implementations/CipherService.cs | 23 +++++-- .../Vault/Repositories/CipherRepository.cs | 59 +++++++++++++++++- .../Vault/Repositories/CipherRepository.cs | 12 +++- .../Vault/Services/CipherServiceTests.cs | 61 +++++++++++++++++++ 5 files changed, 148 insertions(+), 9 deletions(-) diff --git a/src/Core/Vault/Repositories/ICipherRepository.cs b/src/Core/Vault/Repositories/ICipherRepository.cs index 401add13da..0ba80857d6 100644 --- a/src/Core/Vault/Repositories/ICipherRepository.cs +++ b/src/Core/Vault/Repositories/ICipherRepository.cs @@ -32,7 +32,7 @@ public interface ICipherRepository : IRepository Task UpdateCiphersAsync(Guid userId, IEnumerable ciphers); Task CreateAsync(IEnumerable ciphers, IEnumerable folders); Task CreateAsync(IEnumerable ciphers, IEnumerable collections, - IEnumerable collectionCiphers); + IEnumerable collectionCiphers, IEnumerable collectionUsers); Task SoftDeleteAsync(IEnumerable ids, Guid userId); Task SoftDeleteByIdsOrganizationIdAsync(IEnumerable ids, Guid organizationId); Task RestoreAsync(IEnumerable ids, Guid userId); diff --git a/src/Core/Vault/Services/Implementations/CipherService.cs b/src/Core/Vault/Services/Implementations/CipherService.cs index 72437ec1b6..6e5b15de0d 100644 --- a/src/Core/Vault/Services/Implementations/CipherService.cs +++ b/src/Core/Vault/Services/Implementations/CipherService.cs @@ -27,6 +27,7 @@ public class CipherService : ICipherService private readonly ICollectionRepository _collectionRepository; private readonly IUserRepository _userRepository; private readonly IOrganizationRepository _organizationRepository; + private readonly IOrganizationUserRepository _organizationUserRepository; private readonly ICollectionCipherRepository _collectionCipherRepository; private readonly IPushNotificationService _pushService; private readonly IAttachmentStorageService _attachmentStorageService; @@ -34,7 +35,7 @@ public class CipherService : ICipherService private readonly IUserService _userService; private readonly IPolicyService _policyService; private readonly GlobalSettings _globalSettings; - private const long _fileSizeLeeway = 1024L * 1024L; // 1MB + private const long _fileSizeLeeway = 1024L * 1024L; // 1MB private readonly IReferenceEventService _referenceEventService; private readonly ICurrentContext _currentContext; @@ -44,6 +45,7 @@ public class CipherService : ICipherService ICollectionRepository collectionRepository, IUserRepository userRepository, IOrganizationRepository organizationRepository, + IOrganizationUserRepository organizationUserRepository, ICollectionCipherRepository collectionCipherRepository, IPushNotificationService pushService, IAttachmentStorageService attachmentStorageService, @@ -59,6 +61,7 @@ public class CipherService : ICipherService _collectionRepository = collectionRepository; _userRepository = userRepository; _organizationRepository = organizationRepository; + _organizationUserRepository = organizationUserRepository; _collectionCipherRepository = collectionCipherRepository; _pushService = pushService; _attachmentStorageService = attachmentStorageService; @@ -652,7 +655,7 @@ public class CipherService : ICipherService cipher.RevisionDate = DateTime.UtcNow; - // The sprocs will validate that all collections belong to this org/user and that they have + // The sprocs will validate that all collections belong to this org/user and that they have // proper write permissions. if (orgAdmin) { @@ -747,6 +750,7 @@ public class CipherService : ICipherService var org = collections.Count > 0 ? await _organizationRepository.GetByIdAsync(collections[0].OrganizationId) : await _organizationRepository.GetByIdAsync(ciphers.FirstOrDefault(c => c.OrganizationId.HasValue).OrganizationId.Value); + var importingOrgUser = await _organizationUserRepository.GetByOrganizationAsync(org.Id, importingUserId); if (collections.Count > 0 && org != null && org.MaxCollections.HasValue) { @@ -764,18 +768,25 @@ public class CipherService : ICipherService cipher.SetNewId(); } - var userCollectionsIds = (await _collectionRepository.GetManyByOrganizationIdAsync(org.Id)).Select(c => c.Id).ToList(); + var organizationCollectionsIds = (await _collectionRepository.GetManyByOrganizationIdAsync(org.Id)).Select(c => c.Id).ToList(); //Assign id to the ones that don't exist in DB //Need to keep the list order to create the relationships - List newCollections = new List(); + var newCollections = new List(); + var newCollectionUsers = new List(); foreach (var collection in collections) { - if (!userCollectionsIds.Contains(collection.Id)) + if (!organizationCollectionsIds.Contains(collection.Id)) { collection.SetNewId(); newCollections.Add(collection); + newCollectionUsers.Add(new CollectionUser + { + CollectionId = collection.Id, + OrganizationUserId = importingOrgUser.Id, + Manage = true + }); } } @@ -799,7 +810,7 @@ public class CipherService : ICipherService } // Create it all - await _cipherRepository.CreateAsync(ciphers, newCollections, collectionCiphers); + await _cipherRepository.CreateAsync(ciphers, newCollections, collectionCiphers, newCollectionUsers); // push await _pushService.PushSyncVaultAsync(importingUserId); diff --git a/src/Infrastructure.Dapper/Vault/Repositories/CipherRepository.cs b/src/Infrastructure.Dapper/Vault/Repositories/CipherRepository.cs index dfc62f3049..4f6c8e25f7 100644 --- a/src/Infrastructure.Dapper/Vault/Repositories/CipherRepository.cs +++ b/src/Infrastructure.Dapper/Vault/Repositories/CipherRepository.cs @@ -589,7 +589,7 @@ public class CipherRepository : Repository, ICipherRepository } public async Task CreateAsync(IEnumerable ciphers, IEnumerable collections, - IEnumerable collectionCiphers) + IEnumerable collectionCiphers, IEnumerable collectionUsers) { if (!ciphers.Any()) { @@ -631,6 +631,16 @@ public class CipherRepository : Repository, ICipherRepository } } + if (collectionUsers.Any()) + { + using (var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction)) + { + bulkCopy.DestinationTableName = "[dbo].[CollectionUser]"; + var dataTable = BuildCollectionUsersTable(bulkCopy, collectionUsers); + bulkCopy.WriteToServer(dataTable); + } + } + await connection.ExecuteAsync( $"[{Schema}].[User_BumpAccountRevisionDateByOrganizationId]", new { OrganizationId = ciphers.First().OrganizationId }, @@ -896,6 +906,53 @@ public class CipherRepository : Repository, ICipherRepository return collectionCiphersTable; } + private DataTable BuildCollectionUsersTable(SqlBulkCopy bulkCopy, IEnumerable collectionUsers) + { + var cu = collectionUsers.FirstOrDefault(); + if (cu == null) + { + throw new ApplicationException("Must have some collectionUsers to bulk import."); + } + + var collectionUsersTable = new DataTable("CollectionUserDataTable"); + + var collectionIdColumn = new DataColumn(nameof(cu.CollectionId), cu.CollectionId.GetType()); + collectionUsersTable.Columns.Add(collectionIdColumn); + var organizationUserIdColumn = new DataColumn(nameof(cu.OrganizationUserId), cu.OrganizationUserId.GetType()); + collectionUsersTable.Columns.Add(organizationUserIdColumn); + var readOnlyColumn = new DataColumn(nameof(cu.ReadOnly), cu.ReadOnly.GetType()); + collectionUsersTable.Columns.Add(readOnlyColumn); + var hidePasswordsColumn = new DataColumn(nameof(cu.HidePasswords), cu.HidePasswords.GetType()); + collectionUsersTable.Columns.Add(hidePasswordsColumn); + var manageColumn = new DataColumn(nameof(cu.Manage), cu.Manage.GetType()); + collectionUsersTable.Columns.Add(manageColumn); + + foreach (DataColumn col in collectionUsersTable.Columns) + { + bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName); + } + + var keys = new DataColumn[2]; + keys[0] = collectionIdColumn; + keys[1] = organizationUserIdColumn; + collectionUsersTable.PrimaryKey = keys; + + foreach (var collectionUser in collectionUsers) + { + var row = collectionUsersTable.NewRow(); + + row[collectionIdColumn] = collectionUser.CollectionId; + row[organizationUserIdColumn] = collectionUser.OrganizationUserId; + row[readOnlyColumn] = collectionUser.ReadOnly; + row[hidePasswordsColumn] = collectionUser.HidePasswords; + row[manageColumn] = collectionUser.Manage; + + collectionUsersTable.Rows.Add(row); + } + + return collectionUsersTable; + } + private DataTable BuildSendsTable(SqlBulkCopy bulkCopy, IEnumerable sends) { var s = sends.FirstOrDefault(); diff --git a/src/Infrastructure.EntityFramework/Vault/Repositories/CipherRepository.cs b/src/Infrastructure.EntityFramework/Vault/Repositories/CipherRepository.cs index c575838362..573e4fc3bd 100644 --- a/src/Infrastructure.EntityFramework/Vault/Repositories/CipherRepository.cs +++ b/src/Infrastructure.EntityFramework/Vault/Repositories/CipherRepository.cs @@ -161,7 +161,10 @@ public class CipherRepository : Repository ciphers, IEnumerable collections, IEnumerable collectionCiphers) + public async Task CreateAsync(IEnumerable ciphers, + IEnumerable collections, + IEnumerable collectionCiphers, + IEnumerable collectionUsers) { if (!ciphers.Any()) { @@ -184,6 +187,13 @@ public class CipherRepository : Repository>(collectionCiphers); await dbContext.BulkCopyAsync(base.DefaultBulkCopyOptions, collectionCipherEntities); } + + if (collectionUsers.Any()) + { + var collectionUserEntities = Mapper.Map>(collectionUsers); + await dbContext.BulkCopyAsync(base.DefaultBulkCopyOptions, collectionUserEntities); + } + await dbContext.UserBumpAccountRevisionDateByOrganizationIdAsync(ciphers.First().OrganizationId.Value); await dbContext.SaveChangesAsync(); } diff --git a/test/Core.Test/Vault/Services/CipherServiceTests.cs b/test/Core.Test/Vault/Services/CipherServiceTests.cs index ea3309fc69..d299084c9c 100644 --- a/test/Core.Test/Vault/Services/CipherServiceTests.cs +++ b/test/Core.Test/Vault/Services/CipherServiceTests.cs @@ -4,6 +4,9 @@ using Bit.Core.Exceptions; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Test.AutoFixture.CipherFixtures; +using Bit.Core.Tools.Enums; +using Bit.Core.Tools.Models.Business; +using Bit.Core.Tools.Services; using Bit.Core.Utilities; using Bit.Core.Vault.Entities; using Bit.Core.Vault.Models.Data; @@ -21,6 +24,64 @@ namespace Bit.Core.Test.Services; [SutProviderCustomize] public class CipherServiceTests { + [Theory, BitAutoData] + public async Task ImportCiphersAsync_IntoOrganization_Success( + Organization organization, + Guid importingUserId, + OrganizationUser importingOrganizationUser, + List collections, + List ciphers, + SutProvider sutProvider) + { + organization.MaxCollections = null; + importingOrganizationUser.OrganizationId = organization.Id; + + foreach (var collection in collections) + { + collection.OrganizationId = organization.Id; + } + + foreach (var cipher in ciphers) + { + cipher.OrganizationId = organization.Id; + } + + KeyValuePair[] collectionRelationships = { + new(0, 0), + new(1, 1), + new(2, 2) + }; + + sutProvider.GetDependency() + .GetByIdAsync(organization.Id) + .Returns(organization); + + sutProvider.GetDependency() + .GetByOrganizationAsync(organization.Id, importingUserId) + .Returns(importingOrganizationUser); + + // Set up a collection that already exists in the organization + sutProvider.GetDependency() + .GetManyByOrganizationIdAsync(organization.Id) + .Returns(new List { collections[0] }); + + await sutProvider.Sut.ImportCiphersAsync(collections, ciphers, collectionRelationships, importingUserId); + + await sutProvider.GetDependency().Received(1).CreateAsync( + ciphers, + Arg.Is>(cols => cols.Count() == collections.Count - 1 && + !cols.Any(c => c.Id == collections[0].Id) && // Check that the collection that already existed in the organization was not added + cols.All(c => collections.Any(x => c.Name == x.Name))), + Arg.Is>(c => c.Count() == ciphers.Count), + Arg.Is>(cus => + cus.Count() == collections.Count - 1 && + !cus.Any(cu => cu.CollectionId == collections[0].Id) && // Check that access was not added for the collection that already existed in the organization + cus.All(cu => cu.OrganizationUserId == importingOrganizationUser.Id && cu.Manage == true))); + await sutProvider.GetDependency().Received(1).PushSyncVaultAsync(importingUserId); + await sutProvider.GetDependency().Received(1).RaiseEventAsync( + Arg.Is(e => e.Type == ReferenceEventType.VaultImported)); + } + [Theory, BitAutoData] public async Task SaveAsync_WrongRevisionDate_Throws(SutProvider sutProvider, Cipher cipher) { From eab0838edf0b4aa8e1ec0167c8b2125416dd4e36 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Thu, 23 Nov 2023 15:17:34 +0100 Subject: [PATCH 20/20] [PM-4316] Use byte for GlobalEvalentDomainsType in DomainsResponseModel (#3343) --- src/Api/Models/Response/DomainsResponseModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Api/Models/Response/DomainsResponseModel.cs b/src/Api/Models/Response/DomainsResponseModel.cs index b7f1028458..5b6b4e59c8 100644 --- a/src/Api/Models/Response/DomainsResponseModel.cs +++ b/src/Api/Models/Response/DomainsResponseModel.cs @@ -43,12 +43,12 @@ public class DomainsResponseModel : ResponseModel IEnumerable excludedDomains, bool excluded) { - Type = globalDomain; + Type = (byte)globalDomain; Domains = domains; Excluded = excluded && (excludedDomains?.Contains(globalDomain) ?? false); } - public GlobalEquivalentDomainsType Type { get; set; } + public byte Type { get; set; } public IEnumerable Domains { get; set; } public bool Excluded { get; set; } }