From eff25f7fa11ba4c4eb25682e4f45b6c6088d1b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Mon, 18 Dec 2023 18:39:10 +0100 Subject: [PATCH] Migrate the OpenID module to OpenIddict 5.0 (#14808) --- src/OrchardCore.Build/Dependencies.props | 4 +- .../OpenIdApplicationSettings.cs | 4 +- .../Managers/OpenIdApplicationManager.cs | 2 +- .../YesSql/Models/OpenIdApplication.cs | 34 ++- .../YesSql/Models/OpenIdAuthorization.cs | 3 +- .../YesSql/Models/OpenIdScope.cs | 3 +- .../YesSql/Stores/OpenIdApplicationStore.cs | 241 +++++++--------- .../YesSql/Stores/OpenIdAuthorizationStore.cs | 190 ++++--------- .../YesSql/Stores/OpenIdScopeStore.cs | 115 ++------ .../YesSql/Stores/OpenIdTokenStore.cs | 269 ++++++------------ .../OpenIdApplicationStepTests.cs | 4 +- .../OpenIdApplicationStepTestsData.cs | 8 +- 12 files changed, 297 insertions(+), 580 deletions(-) diff --git a/src/OrchardCore.Build/Dependencies.props b/src/OrchardCore.Build/Dependencies.props index 250755955fc..a249dcc0f49 100644 --- a/src/OrchardCore.Build/Dependencies.props +++ b/src/OrchardCore.Build/Dependencies.props @@ -48,8 +48,8 @@ - - + + diff --git a/src/OrchardCore.Modules/OrchardCore.OpenId/OpenIdApplicationSettings.cs b/src/OrchardCore.Modules/OrchardCore.OpenId/OpenIdApplicationSettings.cs index 75cd1dcdce3..a800a56f3b8 100644 --- a/src/OrchardCore.Modules/OrchardCore.OpenId/OpenIdApplicationSettings.cs +++ b/src/OrchardCore.Modules/OrchardCore.OpenId/OpenIdApplicationSettings.cs @@ -44,14 +44,14 @@ public static async Task UpdateDescriptorFromSettings(this IOpenIdApplicationMan descriptor.ClientId = model.ClientId; descriptor.ConsentType = model.ConsentType; descriptor.DisplayName = model.DisplayName; - descriptor.Type = model.Type; + descriptor.ClientType = model.Type; if (!string.IsNullOrEmpty(model.ClientSecret)) { descriptor.ClientSecret = model.ClientSecret; } - if (string.Equals(descriptor.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(descriptor.ClientType, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) { descriptor.ClientSecret = null; } diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/Services/Managers/OpenIdApplicationManager.cs b/src/OrchardCore/OrchardCore.OpenId.Core/Services/Managers/OpenIdApplicationManager.cs index c88905b753f..2aed00ccb55 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/Services/Managers/OpenIdApplicationManager.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/Services/Managers/OpenIdApplicationManager.cs @@ -98,7 +98,7 @@ public virtual async ValueTask> GetRolesAsync( return builder.ToImmutable(); } - return ImmutableArray.Create(); + return []; } } diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdApplication.cs b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdApplication.cs index 9f5962d9e66..17f9e230bf1 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdApplication.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdApplication.cs @@ -16,6 +16,11 @@ public class OpenIdApplication /// public string ApplicationId { get; set; } + /// + /// Gets or sets the application type associated with the current application. + /// + public string ApplicationType { get; set; } + /// /// Gets or sets the client identifier associated with the current application. /// @@ -49,17 +54,21 @@ public class OpenIdApplication /// public long Id { get; set; } + /// + /// Gets or sets the JSON Web Key Set associated with the current application. + /// + // TODO: change the property type to JsonWebKeySet after migrating to System.Text.Json. + public JObject JsonWebKeySet { get; set; } + /// /// Gets or sets the permissions associated with the application. /// - public ImmutableArray Permissions { get; set; } - = ImmutableArray.Create(); + public ImmutableArray Permissions { get; set; } = []; /// /// Gets the logout callback URLs associated with the current application. /// - public ImmutableArray PostLogoutRedirectUris { get; set; } - = ImmutableArray.Create(); + public ImmutableArray PostLogoutRedirectUris { get; set; } = []; /// /// Gets or sets the additional properties associated with the current application. @@ -69,23 +78,26 @@ public class OpenIdApplication /// /// Gets or sets the callback URLs associated with the current application. /// - public ImmutableArray RedirectUris { get; set; } - = ImmutableArray.Create(); + public ImmutableArray RedirectUris { get; set; } = []; /// /// Gets or sets the requirements associated with the current application. /// - public ImmutableArray Requirements { get; set; } - = ImmutableArray.Create(); + public ImmutableArray Requirements { get; set; } = []; /// /// Gets or sets the roles associated with the application. /// - public ImmutableArray Roles { get; set; } - = ImmutableArray.Create(); + public ImmutableArray Roles { get; set; } = []; /// - /// Gets or sets the application type associated with the current application. + /// Gets or sets the settings associated with the application. + /// + public ImmutableDictionary Settings { get; set; } + = ImmutableDictionary.Create(); + + /// + /// Gets or sets the client type associated with the current application. /// public string Type { get; set; } } diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdAuthorization.cs b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdAuthorization.cs index 8f79929c381..bf52483bfce 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdAuthorization.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdAuthorization.cs @@ -40,8 +40,7 @@ public class OpenIdAuthorization /// /// Gets or sets the scopes associated with the current authorization. /// - public ImmutableArray Scopes { get; set; } - = ImmutableArray.Create(); + public ImmutableArray Scopes { get; set; } = []; /// /// Gets or sets the status of the current authorization. diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdScope.cs b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdScope.cs index 0a988051e2b..d7ebd35af5c 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdScope.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Models/OpenIdScope.cs @@ -56,7 +56,6 @@ public class OpenIdScope /// /// Gets or sets the resources associated with the current scope. /// - public ImmutableArray Resources { get; set; } - = ImmutableArray.Create(); + public ImmutableArray Resources { get; set; } = []; } } diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdApplicationStore.cs b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdApplicationStore.cs index c2ce2cb9282..86416ce3567 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdApplicationStore.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdApplicationStore.cs @@ -8,6 +8,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json.Linq; using OpenIddict.Abstractions; using OrchardCore.OpenId.Abstractions.Stores; @@ -43,10 +44,7 @@ public virtual ValueTask CountAsync(Func /// public virtual async ValueTask CreateAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); cancellationToken.ThrowIfCancellationRequested(); @@ -57,10 +55,7 @@ public virtual async ValueTask CreateAsync(TApplication application, Cancellatio /// public virtual async ValueTask DeleteAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); cancellationToken.ThrowIfCancellationRequested(); @@ -71,10 +66,7 @@ public virtual async ValueTask DeleteAsync(TApplication application, Cancellatio /// public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -84,10 +76,7 @@ public virtual async ValueTask FindByIdAsync(string identifier, Ca /// public virtual async ValueTask FindByClientIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -97,10 +86,7 @@ public virtual async ValueTask FindByClientIdAsync(string identifi /// public virtual async ValueTask FindByPhysicalIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -110,10 +96,7 @@ public virtual async ValueTask FindByPhysicalIdAsync(string identi /// public virtual IAsyncEnumerable FindByPostLogoutRedirectUriAsync(string uri, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(uri)) - { - throw new ArgumentException("The URI cannot be null or empty.", nameof(uri)); - } + ArgumentException.ThrowIfNullOrEmpty(uri); cancellationToken.ThrowIfCancellationRequested(); @@ -125,10 +108,7 @@ public virtual IAsyncEnumerable FindByPostLogoutRedirectUriAsync(s /// public virtual IAsyncEnumerable FindByRedirectUriAsync(string uri, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(uri)) - { - throw new ArgumentException("The URI cannot be null or empty.", nameof(uri)); - } + ArgumentException.ThrowIfNullOrEmpty(uri); cancellationToken.ThrowIfCancellationRequested(); @@ -137,6 +117,13 @@ public virtual IAsyncEnumerable FindByRedirectUriAsync(string uri, collection: OpenIdCollection).ToAsyncEnumerable(); } + public virtual ValueTask GetApplicationTypeAsync(TApplication application, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(application); + + return new ValueTask(application.ApplicationType); + } + /// public virtual ValueTask GetAsync( Func, TState, IQueryable> query, @@ -146,10 +133,7 @@ public virtual ValueTask GetAsync( /// public virtual ValueTask GetClientIdAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask(application.ClientId); } @@ -157,10 +141,7 @@ public virtual ValueTask GetClientIdAsync(TApplication application, Canc /// public virtual ValueTask GetClientSecretAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask(application.ClientSecret); } @@ -168,10 +149,7 @@ public virtual ValueTask GetClientSecretAsync(TApplication application, /// public virtual ValueTask GetClientTypeAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask(application.Type); } @@ -179,10 +157,7 @@ public virtual ValueTask GetClientTypeAsync(TApplication application, Ca /// public virtual ValueTask GetConsentTypeAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask(application.ConsentType); } @@ -190,10 +165,7 @@ public virtual ValueTask GetConsentTypeAsync(TApplication application, C /// public virtual ValueTask GetDisplayNameAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask(application.DisplayName); } @@ -202,10 +174,7 @@ public virtual ValueTask GetDisplayNameAsync(TApplication application, C public virtual ValueTask> GetDisplayNamesAsync( TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); if (application.DisplayNames == null) { @@ -218,21 +187,27 @@ public virtual ValueTask> GetDisplayNam /// public virtual ValueTask GetIdAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) + ArgumentNullException.ThrowIfNull(application); + + return new ValueTask(application.ApplicationId); + } + + public virtual ValueTask GetJsonWebKeySetAsync(TApplication application, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(application); + + if (application.JsonWebKeySet is null) { - throw new ArgumentNullException(nameof(application)); + return new ValueTask(result: null); } - return new ValueTask(application.ApplicationId); + return new ValueTask(JsonSerializer.Deserialize(application.JsonWebKeySet.ToString())); } /// public virtual ValueTask> GetPermissionsAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask>(application.Permissions); } @@ -240,10 +215,7 @@ public virtual ValueTask> GetPermissionsAsync(TApplicatio /// public virtual ValueTask GetPhysicalIdAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask(application.Id.ToString(CultureInfo.InvariantCulture)); } @@ -251,10 +223,7 @@ public virtual ValueTask GetPhysicalIdAsync(TApplication application, Ca /// public virtual ValueTask> GetPostLogoutRedirectUrisAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask>(application.PostLogoutRedirectUris); } @@ -262,10 +231,7 @@ public virtual ValueTask> GetPostLogoutRedirectUrisAsync( /// public virtual ValueTask> GetPropertiesAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); if (application.Properties == null) { @@ -279,10 +245,7 @@ public virtual ValueTask> GetProperties /// public virtual ValueTask> GetRedirectUrisAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask>(application.RedirectUris); } @@ -290,14 +253,19 @@ public virtual ValueTask> GetRedirectUrisAsync(TApplicati /// public virtual ValueTask> GetRequirementsAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask>(application.Requirements); } + /// + public virtual ValueTask> GetSettingsAsync(TApplication application, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(application); + + return new ValueTask>(application.Settings); + } + /// public virtual ValueTask InstantiateAsync(CancellationToken cancellationToken) => new(new TApplication { ApplicationId = Guid.NewGuid().ToString("n") }); @@ -326,14 +294,21 @@ public virtual IAsyncEnumerable ListAsync( TState state, CancellationToken cancellationToken) => throw new NotSupportedException(); + /// + public virtual ValueTask SetApplicationTypeAsync(TApplication application, string type, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(application); + + application.ApplicationType = type; + + return default; + } + /// public virtual ValueTask SetClientIdAsync(TApplication application, string identifier, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.ClientId = identifier; @@ -343,10 +318,7 @@ public virtual ValueTask SetClientIdAsync(TApplication application, /// public virtual ValueTask SetClientSecretAsync(TApplication application, string secret, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.ClientSecret = secret; @@ -356,10 +328,7 @@ public virtual ValueTask SetClientSecretAsync(TApplication application, string s /// public virtual ValueTask SetClientTypeAsync(TApplication application, string type, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.Type = type; @@ -369,10 +338,7 @@ public virtual ValueTask SetClientTypeAsync(TApplication application, string typ /// public virtual ValueTask SetConsentTypeAsync(TApplication application, string type, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.ConsentType = type; @@ -382,10 +348,7 @@ public virtual ValueTask SetConsentTypeAsync(TApplication application, string ty /// public virtual ValueTask SetDisplayNameAsync(TApplication application, string name, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.DisplayName = name; @@ -395,10 +358,7 @@ public virtual ValueTask SetDisplayNameAsync(TApplication application, string na /// public virtual ValueTask SetDisplayNamesAsync(TApplication application, ImmutableDictionary names, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.DisplayNames = names; @@ -406,13 +366,31 @@ public virtual ValueTask SetDisplayNamesAsync(TApplication application, Immutabl } /// - public virtual ValueTask SetPermissionsAsync(TApplication application, ImmutableArray permissions, CancellationToken cancellationToken) + public virtual ValueTask SetJsonWebKeySetAsync(TApplication application, JsonWebKeySet set, CancellationToken cancellationToken) { - if (application == null) + ArgumentNullException.ThrowIfNull(application); + + if (set is not null) { - throw new ArgumentNullException(nameof(application)); + application.JsonWebKeySet = JObject.Parse(JsonSerializer.Serialize(set, new JsonSerializerOptions + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + WriteIndented = false + })); + + return default; } + application.JsonWebKeySet = null; + + return default; + } + + /// + public virtual ValueTask SetPermissionsAsync(TApplication application, ImmutableArray permissions, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(application); + application.Permissions = permissions; return default; @@ -422,10 +400,7 @@ public virtual ValueTask SetPermissionsAsync(TApplication application, Immutable public virtual ValueTask SetPostLogoutRedirectUrisAsync(TApplication application, ImmutableArray uris, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.PostLogoutRedirectUris = uris; @@ -435,10 +410,7 @@ public virtual ValueTask SetPostLogoutRedirectUrisAsync(TApplication application /// public virtual ValueTask SetPropertiesAsync(TApplication application, ImmutableDictionary properties, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); if (properties == null || properties.IsEmpty) { @@ -460,10 +432,7 @@ public virtual ValueTask SetPropertiesAsync(TApplication application, ImmutableD public virtual ValueTask SetRedirectUrisAsync(TApplication application, ImmutableArray uris, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.RedirectUris = uris; @@ -474,23 +443,28 @@ public virtual ValueTask SetRedirectUrisAsync(TApplication application, public virtual ValueTask SetRequirementsAsync(TApplication application, ImmutableArray requirements, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.Requirements = requirements; return default; } + /// + public virtual ValueTask SetSettingsAsync(TApplication application, + ImmutableDictionary settings, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(application); + + application.Settings = settings; + + return default; + } + /// public virtual async ValueTask UpdateAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); cancellationToken.ThrowIfCancellationRequested(); @@ -512,10 +486,7 @@ public virtual async ValueTask UpdateAsync(TApplication application, Cancellatio /// public virtual ValueTask> GetRolesAsync(TApplication application, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); return new ValueTask>(application.Roles); } @@ -523,10 +494,7 @@ public virtual ValueTask> GetRolesAsync(TApplication appl /// public virtual IAsyncEnumerable ListInRoleAsync(string role, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(role)) - { - throw new ArgumentException("The role name cannot be null or empty.", nameof(role)); - } + ArgumentException.ThrowIfNullOrEmpty(role); return _session.Query(index => index.RoleName == role, collection: OpenIdCollection).ToAsyncEnumerable(); } @@ -534,10 +502,7 @@ public virtual IAsyncEnumerable ListInRoleAsync(string role, Cance /// public virtual ValueTask SetRolesAsync(TApplication application, ImmutableArray roles, CancellationToken cancellationToken) { - if (application == null) - { - throw new ArgumentNullException(nameof(application)); - } + ArgumentNullException.ThrowIfNull(application); application.Roles = roles; diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdAuthorizationStore.cs b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdAuthorizationStore.cs index e7b63e99e04..1a4a2e7f3dd 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdAuthorizationStore.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdAuthorizationStore.cs @@ -45,10 +45,7 @@ public virtual ValueTask CountAsync(Func public virtual async ValueTask CreateAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); cancellationToken.ThrowIfCancellationRequested(); @@ -59,10 +56,7 @@ public virtual async ValueTask CreateAsync(TAuthorization authorization, Cancell /// public virtual async ValueTask DeleteAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); cancellationToken.ThrowIfCancellationRequested(); @@ -74,15 +68,8 @@ public virtual async ValueTask DeleteAsync(TAuthorization authorization, Cancell public virtual IAsyncEnumerable FindAsync( string subject, string client, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } - - if (string.IsNullOrEmpty(client)) - { - throw new ArgumentException("The client cannot be null or empty.", nameof(client)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); + ArgumentException.ThrowIfNullOrEmpty(client); cancellationToken.ThrowIfCancellationRequested(); @@ -95,20 +82,9 @@ public virtual IAsyncEnumerable FindAsync( public virtual IAsyncEnumerable FindAsync( string subject, string client, string status, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } - - if (string.IsNullOrEmpty(client)) - { - throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client)); - } - - if (string.IsNullOrEmpty(status)) - { - throw new ArgumentException("The status cannot be null or empty.", nameof(client)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); + ArgumentException.ThrowIfNullOrEmpty(client); + ArgumentException.ThrowIfNullOrEmpty(status); cancellationToken.ThrowIfCancellationRequested(); @@ -122,25 +98,10 @@ public virtual IAsyncEnumerable FindAsync( string subject, string client, string status, string type, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } - - if (string.IsNullOrEmpty(client)) - { - throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client)); - } - - if (string.IsNullOrEmpty(status)) - { - throw new ArgumentException("The status cannot be null or empty.", nameof(client)); - } - - if (string.IsNullOrEmpty(type)) - { - throw new ArgumentException("The type cannot be null or empty.", nameof(client)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); + ArgumentException.ThrowIfNullOrEmpty(client); + ArgumentException.ThrowIfNullOrEmpty(status); + ArgumentException.ThrowIfNullOrEmpty(type); cancellationToken.ThrowIfCancellationRequested(); @@ -168,10 +129,7 @@ public virtual async IAsyncEnumerable FindAsync( public virtual IAsyncEnumerable FindByApplicationIdAsync( string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -183,10 +141,7 @@ public virtual IAsyncEnumerable FindByApplicationIdAsync( /// public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -198,10 +153,7 @@ public virtual async ValueTask FindByIdAsync(string identifier, /// public virtual async ValueTask FindByPhysicalIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -212,10 +164,7 @@ public virtual async ValueTask FindByPhysicalIdAsync(string iden public virtual IAsyncEnumerable FindBySubjectAsync( string subject, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); cancellationToken.ThrowIfCancellationRequested(); @@ -227,10 +176,7 @@ public virtual IAsyncEnumerable FindBySubjectAsync( /// public virtual ValueTask GetApplicationIdAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); return new ValueTask(authorization.ApplicationId); } @@ -244,10 +190,7 @@ public virtual ValueTask GetAsync( /// public virtual ValueTask GetCreationDateAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); if (authorization.CreationDate is null) { @@ -260,10 +203,7 @@ public virtual ValueTask GetAsync( /// public virtual ValueTask GetIdAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); return new ValueTask(authorization.AuthorizationId); } @@ -271,10 +211,7 @@ public virtual ValueTask GetIdAsync(TAuthorization authorization, Cancel /// public virtual ValueTask GetPhysicalIdAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); return new ValueTask(authorization.Id.ToString(CultureInfo.InvariantCulture)); } @@ -282,10 +219,7 @@ public virtual ValueTask GetPhysicalIdAsync(TAuthorization authorization /// public virtual ValueTask> GetPropertiesAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); if (authorization.Properties == null) { @@ -299,10 +233,7 @@ public virtual ValueTask> GetProperties /// public virtual ValueTask> GetScopesAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); return new ValueTask>(authorization.Scopes); } @@ -310,10 +241,7 @@ public virtual ValueTask> GetScopesAsync(TAuthorization a /// public virtual ValueTask GetStatusAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); return new ValueTask(authorization.Status); } @@ -321,10 +249,7 @@ public virtual ValueTask GetStatusAsync(TAuthorization authorization, Ca /// public virtual ValueTask GetSubjectAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); return new ValueTask(authorization.Subject); } @@ -332,10 +257,7 @@ public virtual ValueTask GetSubjectAsync(TAuthorization authorization, C /// public virtual ValueTask GetTypeAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); return new ValueTask(authorization.Type); } @@ -369,30 +291,32 @@ public virtual IAsyncEnumerable ListAsync( => throw new NotSupportedException(); /// - public virtual async ValueTask PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken) + public virtual async ValueTask PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken) { // Note: YesSql doesn't support set-based deletes, which prevents removing entities // in a single command without having to retrieve and materialize them first. // To work around this limitation, entities are manually listed and deleted using a batch logic. - IList exceptions = null; + List exceptions = null; + + var result = 0L; for (var i = 0; i < 1000; i++) { cancellationToken.ThrowIfCancellationRequested(); - var authorizations = await _session.Query( + var authorizations = (await _session.Query( authorization => authorization.CreationDate < threshold.UtcDateTime && (authorization.Status != OpenIddictConstants.Statuses.Valid || (authorization.Type == OpenIddictConstants.AuthorizationTypes.AdHoc && authorization.AuthorizationId.IsNotIn( token => token.AuthorizationId, token => token.Id != 0))), - collection: OpenIdCollection).Take(100).ListAsync(); + collection: OpenIdCollection).Take(100).ListAsync()).ToList(); - if (!authorizations.Any()) + if (authorizations.Count is 0) { - return; + break; } foreach (var authorization in authorizations) @@ -407,25 +331,27 @@ public virtual async ValueTask PruneAsync(DateTimeOffset threshold, Cancellation catch (Exception exception) { exceptions ??= new List(capacity: 1); - exceptions.Add(exception); + + continue; } + + result += authorizations.Count; } if (exceptions != null) { throw new AggregateException("An error occurred while pruning authorizations.", exceptions); } + + return result; } /// public virtual ValueTask SetApplicationIdAsync(TAuthorization authorization, string identifier, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); if (string.IsNullOrEmpty(identifier)) { @@ -439,12 +365,10 @@ public virtual ValueTask SetApplicationIdAsync(TAuthorization authorization, return default; } - public ValueTask SetCreationDateAsync(TAuthorization authorization, DateTimeOffset? date, CancellationToken cancellationToken) + /// + public virtual ValueTask SetCreationDateAsync(TAuthorization authorization, DateTimeOffset? date, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); authorization.CreationDate = date?.UtcDateTime; @@ -454,10 +378,7 @@ public ValueTask SetCreationDateAsync(TAuthorization authorization, DateTimeOffs /// public virtual ValueTask SetPropertiesAsync(TAuthorization authorization, ImmutableDictionary properties, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); if (properties == null || properties.IsEmpty) { @@ -479,10 +400,7 @@ public virtual ValueTask SetPropertiesAsync(TAuthorization authorization, Immuta public virtual ValueTask SetScopesAsync(TAuthorization authorization, ImmutableArray scopes, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); authorization.Scopes = scopes; @@ -493,10 +411,7 @@ public virtual ValueTask SetScopesAsync(TAuthorization authorization, public virtual ValueTask SetStatusAsync(TAuthorization authorization, string status, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); authorization.Status = status; @@ -507,10 +422,7 @@ public virtual ValueTask SetStatusAsync(TAuthorization authorization, public virtual ValueTask SetSubjectAsync(TAuthorization authorization, string subject, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); authorization.Subject = subject; @@ -521,10 +433,7 @@ public virtual ValueTask SetSubjectAsync(TAuthorization authorization, public virtual ValueTask SetTypeAsync(TAuthorization authorization, string type, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); authorization.Type = type; @@ -534,10 +443,7 @@ public virtual ValueTask SetTypeAsync(TAuthorization authorization, /// public virtual async ValueTask UpdateAsync(TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) - { - throw new ArgumentNullException(nameof(authorization)); - } + ArgumentNullException.ThrowIfNull(authorization); cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdScopeStore.cs b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdScopeStore.cs index 154d6eb6efd..ac03499c28b 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdScopeStore.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdScopeStore.cs @@ -44,10 +44,7 @@ public virtual ValueTask CountAsync(Func, IQue /// public virtual async ValueTask CreateAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); cancellationToken.ThrowIfCancellationRequested(); @@ -58,10 +55,7 @@ public virtual async ValueTask CreateAsync(TScope scope, CancellationToken cance /// public virtual async ValueTask DeleteAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); cancellationToken.ThrowIfCancellationRequested(); @@ -72,10 +66,7 @@ public virtual async ValueTask DeleteAsync(TScope scope, CancellationToken cance /// public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -85,10 +76,7 @@ public virtual async ValueTask FindByIdAsync(string identifier, Cancella /// public virtual async ValueTask FindByNameAsync(string name, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(name)) - { - throw new ArgumentException("The scope name cannot be null or empty.", nameof(name)); - } + ArgumentException.ThrowIfNullOrEmpty(name); cancellationToken.ThrowIfCancellationRequested(); @@ -112,10 +100,7 @@ public virtual IAsyncEnumerable FindByNamesAsync( /// public virtual async ValueTask FindByPhysicalIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -125,10 +110,7 @@ public virtual async ValueTask FindByPhysicalIdAsync(string identifier, /// public virtual IAsyncEnumerable FindByResourceAsync(string resource, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(resource)) - { - throw new ArgumentException("The resource cannot be null or empty.", nameof(resource)); - } + ArgumentException.ThrowIfNullOrEmpty(resource); cancellationToken.ThrowIfCancellationRequested(); @@ -146,10 +128,7 @@ public virtual ValueTask GetAsync( /// public virtual ValueTask GetDescriptionAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); return new ValueTask(scope.Description); } @@ -158,10 +137,7 @@ public virtual ValueTask GetDescriptionAsync(TScope scope, CancellationT public virtual ValueTask> GetDescriptionsAsync( TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); if (scope.Descriptions == null) { @@ -174,10 +150,7 @@ public virtual ValueTask> GetDescriptio /// public virtual ValueTask GetDisplayNameAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); return new ValueTask(scope.DisplayName); } @@ -186,10 +159,7 @@ public virtual ValueTask GetDisplayNameAsync(TScope scope, CancellationT public virtual ValueTask> GetDisplayNamesAsync( TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); if (scope.DisplayNames == null) { @@ -202,10 +172,7 @@ public virtual ValueTask> GetDisplayNam /// public virtual ValueTask GetIdAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); return new ValueTask(scope.ScopeId); } @@ -213,10 +180,7 @@ public virtual ValueTask GetIdAsync(TScope scope, CancellationToken canc /// public virtual ValueTask GetNameAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); return new ValueTask(scope.Name); } @@ -224,10 +188,7 @@ public virtual ValueTask GetNameAsync(TScope scope, CancellationToken ca /// public virtual ValueTask GetPhysicalIdAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); return new ValueTask(scope.Id.ToString(CultureInfo.InvariantCulture)); } @@ -235,10 +196,7 @@ public virtual ValueTask GetPhysicalIdAsync(TScope scope, CancellationTo /// public virtual ValueTask> GetPropertiesAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); if (scope.Properties == null) { @@ -252,10 +210,7 @@ public virtual ValueTask> GetProperties /// public virtual ValueTask> GetResourcesAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); return new ValueTask>(scope.Resources); } @@ -291,10 +246,7 @@ public virtual IAsyncEnumerable ListAsync( /// public virtual ValueTask SetDescriptionAsync(TScope scope, string description, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); scope.Description = description; @@ -305,10 +257,7 @@ public virtual ValueTask SetDescriptionAsync(TScope scope, string description, C public virtual ValueTask SetDescriptionsAsync(TScope scope, ImmutableDictionary descriptions, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); scope.Descriptions = descriptions; @@ -318,10 +267,7 @@ public virtual ValueTask SetDescriptionsAsync(TScope scope, /// public virtual ValueTask SetDisplayNameAsync(TScope scope, string name, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); scope.DisplayName = name; @@ -332,10 +278,7 @@ public virtual ValueTask SetDisplayNameAsync(TScope scope, string name, Cancella public virtual ValueTask SetDisplayNamesAsync(TScope scope, ImmutableDictionary names, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); scope.DisplayNames = names; @@ -345,10 +288,7 @@ public virtual ValueTask SetDisplayNamesAsync(TScope scope, /// public virtual ValueTask SetNameAsync(TScope scope, string name, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); scope.Name = name; @@ -358,10 +298,7 @@ public virtual ValueTask SetNameAsync(TScope scope, string name, CancellationTok /// public virtual ValueTask SetPropertiesAsync(TScope scope, ImmutableDictionary properties, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); if (properties == null || properties.IsEmpty) { @@ -382,10 +319,7 @@ public virtual ValueTask SetPropertiesAsync(TScope scope, ImmutableDictionary public virtual ValueTask SetResourcesAsync(TScope scope, ImmutableArray resources, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); scope.Resources = resources; @@ -395,10 +329,7 @@ public virtual ValueTask SetResourcesAsync(TScope scope, ImmutableArray /// public virtual async ValueTask UpdateAsync(TScope scope, CancellationToken cancellationToken) { - if (scope == null) - { - throw new ArgumentNullException(nameof(scope)); - } + ArgumentNullException.ThrowIfNull(scope); cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdTokenStore.cs b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdTokenStore.cs index e7bd643630f..1d6e7b1ee48 100644 --- a/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdTokenStore.cs +++ b/src/OrchardCore/OrchardCore.OpenId.Core/YesSql/Stores/OpenIdTokenStore.cs @@ -45,10 +45,7 @@ public virtual ValueTask CountAsync(Func, IQue /// public virtual async ValueTask CreateAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); cancellationToken.ThrowIfCancellationRequested(); @@ -59,10 +56,7 @@ public virtual async ValueTask CreateAsync(TToken token, CancellationToken cance /// public virtual async ValueTask DeleteAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); cancellationToken.ThrowIfCancellationRequested(); @@ -74,15 +68,8 @@ public virtual async ValueTask DeleteAsync(TToken token, CancellationToken cance public virtual IAsyncEnumerable FindAsync( string subject, string client, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } - - if (string.IsNullOrEmpty(client)) - { - throw new ArgumentException("The client cannot be null or empty.", nameof(client)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); + ArgumentException.ThrowIfNullOrEmpty(client); cancellationToken.ThrowIfCancellationRequested(); @@ -94,20 +81,9 @@ public virtual IAsyncEnumerable FindAsync( public virtual IAsyncEnumerable FindAsync( string subject, string client, string status, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } - - if (string.IsNullOrEmpty(client)) - { - throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client)); - } - - if (string.IsNullOrEmpty(status)) - { - throw new ArgumentException("The status cannot be null or empty.", nameof(status)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); + ArgumentException.ThrowIfNullOrEmpty(client); + ArgumentException.ThrowIfNullOrEmpty(status); cancellationToken.ThrowIfCancellationRequested(); @@ -119,25 +95,10 @@ public virtual IAsyncEnumerable FindAsync( public virtual IAsyncEnumerable FindAsync( string subject, string client, string status, string type, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } - - if (string.IsNullOrEmpty(client)) - { - throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client)); - } - - if (string.IsNullOrEmpty(status)) - { - throw new ArgumentException("The status cannot be null or empty.", nameof(status)); - } - - if (string.IsNullOrEmpty(type)) - { - throw new ArgumentException("The type cannot be null or empty.", nameof(type)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); + ArgumentException.ThrowIfNullOrEmpty(client); + ArgumentException.ThrowIfNullOrEmpty(status); + ArgumentException.ThrowIfNullOrEmpty(type); cancellationToken.ThrowIfCancellationRequested(); @@ -149,10 +110,7 @@ public virtual IAsyncEnumerable FindAsync( /// public virtual IAsyncEnumerable FindByApplicationIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -162,10 +120,7 @@ public virtual IAsyncEnumerable FindByApplicationIdAsync(string identifi /// public virtual IAsyncEnumerable FindByAuthorizationIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -175,10 +130,7 @@ public virtual IAsyncEnumerable FindByAuthorizationIdAsync(string identi /// public virtual async ValueTask FindByReferenceIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -188,10 +140,7 @@ public virtual async ValueTask FindByReferenceIdAsync(string identifier, /// public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -201,10 +150,7 @@ public virtual async ValueTask FindByIdAsync(string identifier, Cancella /// public virtual async ValueTask FindByPhysicalIdAsync(string identifier, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(identifier)) - { - throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); - } + ArgumentException.ThrowIfNullOrEmpty(identifier); cancellationToken.ThrowIfCancellationRequested(); @@ -214,10 +160,7 @@ public virtual async ValueTask FindByPhysicalIdAsync(string identifier, /// public virtual IAsyncEnumerable FindBySubjectAsync(string subject, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(subject)) - { - throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); - } + ArgumentException.ThrowIfNullOrEmpty(subject); cancellationToken.ThrowIfCancellationRequested(); @@ -233,10 +176,7 @@ public virtual ValueTask GetAsync( /// public virtual ValueTask GetApplicationIdAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.ApplicationId?.ToString(CultureInfo.InvariantCulture)); } @@ -244,10 +184,7 @@ public virtual ValueTask GetApplicationIdAsync(TToken token, Cancellatio /// public virtual ValueTask GetAuthorizationIdAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.AuthorizationId); } @@ -255,10 +192,7 @@ public virtual ValueTask GetAuthorizationIdAsync(TToken token, Cancellat /// public virtual ValueTask GetCreationDateAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); if (token.CreationDate is null) { @@ -271,10 +205,7 @@ public virtual ValueTask GetAuthorizationIdAsync(TToken token, Cancellat /// public virtual ValueTask GetExpirationDateAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); if (token.ExpirationDate is null) { @@ -287,10 +218,7 @@ public virtual ValueTask GetAuthorizationIdAsync(TToken token, Cancellat /// public virtual ValueTask GetIdAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.TokenId); } @@ -298,10 +226,7 @@ public virtual ValueTask GetIdAsync(TToken token, CancellationToken canc /// public virtual ValueTask GetPayloadAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.Payload); } @@ -309,10 +234,7 @@ public virtual ValueTask GetPayloadAsync(TToken token, CancellationToken /// public virtual ValueTask GetPhysicalIdAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.Id.ToString(CultureInfo.InvariantCulture)); } @@ -320,10 +242,7 @@ public virtual ValueTask GetPhysicalIdAsync(TToken token, CancellationTo /// public virtual ValueTask> GetPropertiesAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); if (token.Properties == null) { @@ -337,10 +256,7 @@ public virtual ValueTask> GetProperties /// public virtual ValueTask GetRedemptionDateAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); if (token.RedemptionDate is null) { @@ -353,10 +269,7 @@ public virtual ValueTask> GetProperties /// public virtual ValueTask GetReferenceIdAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.ReferenceId); } @@ -364,10 +277,7 @@ public virtual ValueTask GetReferenceIdAsync(TToken token, CancellationT /// public virtual ValueTask GetStatusAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.Status); } @@ -375,10 +285,7 @@ public virtual ValueTask GetStatusAsync(TToken token, CancellationToken /// public virtual ValueTask GetSubjectAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.Subject); } @@ -386,10 +293,7 @@ public virtual ValueTask GetSubjectAsync(TToken token, CancellationToken /// public virtual ValueTask GetTypeAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); return new ValueTask(token.Type); } @@ -423,28 +327,31 @@ public virtual IAsyncEnumerable ListAsync( => throw new NotSupportedException(); /// - public virtual async ValueTask PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken = default) + public virtual async ValueTask PruneAsync(DateTimeOffset threshold, CancellationToken cancellationToken = default) { - // Note: Entity Framework Core doesn't support set-based deletes, which prevents removing - // entities in a single command without having to retrieve and materialize them first. + // Note: YesSql doesn't support set-based deletes, which prevents removing entities + // in a single command without having to retrieve and materialize them first. // To work around this limitation, entities are manually listed and deleted using a batch logic. - IList exceptions = null; + List exceptions = null; + + var result = 0L; for (var i = 0; i < 1000; i++) { cancellationToken.ThrowIfCancellationRequested(); - var tokens = await _session.Query( + var tokens = (await _session.Query( token => token.CreationDate < threshold.UtcDateTime && ((token.Status != Statuses.Inactive && token.Status != Statuses.Valid) || token.AuthorizationId.IsNotIn( authorization => authorization.AuthorizationId, authorization => authorization.Status == Statuses.Valid) || - token.ExpirationDate < DateTime.UtcNow), collection: OpenIdCollection).Take(100).ListAsync(); - if (!tokens.Any()) + token.ExpirationDate < DateTime.UtcNow), collection: OpenIdCollection).Take(100).ListAsync()).ToList(); + + if (tokens.Count is 0) { - return; + break; } foreach (var token in tokens) @@ -459,25 +366,56 @@ public virtual async ValueTask PruneAsync(DateTimeOffset threshold, Cancellation catch (Exception exception) { exceptions ??= new List(capacity: 1); - exceptions.Add(exception); + + continue; } + + result += tokens.Count; } if (exceptions != null) { throw new AggregateException("An error occurred while pruning authorizations.", exceptions); } + + return result; } /// - public virtual ValueTask SetApplicationIdAsync(TToken token, string identifier, CancellationToken cancellationToken) + public virtual async ValueTask RevokeByAuthorizationIdAsync(string identifier, CancellationToken cancellationToken) { - if (token == null) + // Note: YesSql doesn't support set-based updates, which prevents updating entities + // in a single command without having to retrieve and materialize them first. + // To work around this limitation, entities are manually listed and updated. + + cancellationToken.ThrowIfCancellationRequested(); + + var tokens = (await _session.Query( + token => token.AuthorizationId == identifier, collection: OpenIdCollection).ListAsync()).ToList(); + + if (tokens.Count is 0) { - throw new ArgumentNullException(nameof(token)); + return 0; } + foreach (var token in tokens) + { + token.Status = Statuses.Revoked; + + _session.Save(token, checkConcurrency: false, collection: OpenIdCollection); + } + + await _session.SaveChangesAsync(); + + return tokens.Count; + } + + /// + public virtual ValueTask SetApplicationIdAsync(TToken token, string identifier, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(token); + if (string.IsNullOrEmpty(identifier)) { token.ApplicationId = null; @@ -493,10 +431,7 @@ public virtual ValueTask SetApplicationIdAsync(TToken token, string identifier, /// public virtual ValueTask SetAuthorizationIdAsync(TToken token, string identifier, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); if (string.IsNullOrEmpty(identifier)) { @@ -513,10 +448,7 @@ public virtual ValueTask SetAuthorizationIdAsync(TToken token, string identifier /// public virtual ValueTask SetCreationDateAsync(TToken token, DateTimeOffset? date, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.CreationDate = date?.UtcDateTime; @@ -526,10 +458,7 @@ public virtual ValueTask SetCreationDateAsync(TToken token, DateTimeOffset? date /// public virtual ValueTask SetExpirationDateAsync(TToken token, DateTimeOffset? date, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.ExpirationDate = date?.UtcDateTime; @@ -539,10 +468,7 @@ public virtual ValueTask SetExpirationDateAsync(TToken token, DateTimeOffset? da /// public virtual ValueTask SetPayloadAsync(TToken token, string payload, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.Payload = payload; @@ -552,10 +478,7 @@ public virtual ValueTask SetPayloadAsync(TToken token, string payload, Cancellat /// public virtual ValueTask SetPropertiesAsync(TToken token, ImmutableDictionary properties, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); if (properties == null || properties.IsEmpty) { @@ -576,10 +499,7 @@ public virtual ValueTask SetPropertiesAsync(TToken token, ImmutableDictionary public virtual ValueTask SetRedemptionDateAsync(TToken token, DateTimeOffset? date, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.RedemptionDate = date?.UtcDateTime; @@ -589,10 +509,7 @@ public virtual ValueTask SetRedemptionDateAsync(TToken token, DateTimeOffset? da /// public virtual ValueTask SetReferenceIdAsync(TToken token, string identifier, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.ReferenceId = identifier; @@ -602,10 +519,7 @@ public virtual ValueTask SetReferenceIdAsync(TToken token, string identifier, Ca /// public virtual ValueTask SetStatusAsync(TToken token, string status, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.Status = status; @@ -615,10 +529,7 @@ public virtual ValueTask SetStatusAsync(TToken token, string status, Cancellatio /// public virtual ValueTask SetSubjectAsync(TToken token, string subject, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.Subject = subject; @@ -628,10 +539,7 @@ public virtual ValueTask SetSubjectAsync(TToken token, string subject, Cancellat /// public virtual ValueTask SetTypeAsync(TToken token, string type, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); token.Type = type; @@ -641,10 +549,7 @@ public virtual ValueTask SetTypeAsync(TToken token, string type, CancellationTok /// public virtual async ValueTask UpdateAsync(TToken token, CancellationToken cancellationToken) { - if (token == null) - { - throw new ArgumentNullException(nameof(token)); - } + ArgumentNullException.ThrowIfNull(token); cancellationToken.ThrowIfCancellationRequested(); diff --git a/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTests.cs b/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTests.cs index 7a97537424b..62a25a39cf4 100644 --- a/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTests.cs +++ b/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTests.cs @@ -57,9 +57,9 @@ public async Task OpenIdApplicationCanBeParsed(string recipeName, OpenIdApplicat Assert.Equal(expected.ClientId, actual.ClientId); Assert.Equal(expected.ClientSecret, actual.ClientSecret); + Assert.Equal(expected.ClientType, actual.ClientType); Assert.Equal(expected.ConsentType, actual.ConsentType); Assert.Equal(expected.DisplayName, actual.DisplayName); - Assert.Equal(expected.Type, actual.Type); Assert.Equal(expected.Permissions, actual.Permissions); Assert.Equal(expected.PostLogoutRedirectUris, actual.PostLogoutRedirectUris); Assert.Equal(expected.RedirectUris, actual.RedirectUris); @@ -149,9 +149,9 @@ public async Task OpenIdApplicationCanBeUpdated() Assert.Equal(expected.ClientId, actual.ClientId); Assert.Equal(expected.ClientSecret, actual.ClientSecret); + Assert.Equal(expected.ClientType, actual.ClientType); Assert.Equal(expected.ConsentType, actual.ConsentType); Assert.Equal(expected.DisplayName, actual.DisplayName); - Assert.Equal(expected.Type, actual.Type); Assert.Equal(expected.Permissions, actual.Permissions); Assert.Equal(expected.PostLogoutRedirectUris, actual.PostLogoutRedirectUris); Assert.Equal(expected.RedirectUris, actual.RedirectUris); diff --git a/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTestsData.cs b/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTestsData.cs index 248a8b9cbf1..390189c499e 100644 --- a/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTestsData.cs +++ b/test/OrchardCore.Tests/Modules/OrchardCore.OpenId/OpenIdApplicationStepTestsData.cs @@ -13,9 +13,9 @@ public OpenIdApplicationStepTestsData() { ClientId = "a1", ClientSecret = "test-secret", + ClientType = "confidential", ConsentType = "explicit", - DisplayName = "Test Application", - Type = "confidential", + DisplayName = "Test Application" }, new[] { new Uri("https://localhost:111/logout-redirect"), new Uri("https://localhost:222/logout-redirect") }, new[] { new Uri("https://localhost:111/redirect"), new Uri("https://localhost:222/redirect") }, @@ -35,9 +35,9 @@ public OpenIdApplicationStepTestsData() { ClientId = "a2", ClientSecret = "test-secret", + ClientType = "confidential", ConsentType = "explicit", - DisplayName = "Test Application", - Type = "confidential", + DisplayName = "Test Application" }, new[] { new Uri("https://localhost/logout-redirect") }, new[] { new Uri("https://localhost/redirect") },