From bddfdb74be1524ac8595701d6e15325a42debf9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Mon, 27 Nov 2017 01:00:28 +0100 Subject: [PATCH] Add "state" parameters to the GetAsync()/ListAsync() stores methods to avoid closure allocations --- build/common.props | 1 + .../Managers/OpenIddictApplicationManager.cs | 42 +++++- .../OpenIddictAuthorizationManager.cs | 42 +++++- .../Managers/OpenIddictScopeManager.cs | 42 +++++- .../Managers/OpenIddictTokenManager.cs | 42 +++++- .../Stores/IOpenIddictApplicationStore.cs | 13 +- .../Stores/IOpenIddictAuthorizationStore.cs | 12 +- .../Stores/IOpenIddictScopeStore.cs | 12 +- .../Stores/IOpenIddictTokenStore.cs | 12 +- .../Stores/OpenIddictApplicationStore.cs | 74 +++++----- .../Stores/OpenIddictAuthorizationStore.cs | 87 ++++++------ .../Stores/OpenIddictScopeStore.cs | 24 ++-- .../Stores/OpenIddictTokenStore.cs | 134 ++++++++---------- .../Stores/OpenIddictApplicationStore.cs | 32 +++-- .../Stores/OpenIddictAuthorizationStore.cs | 24 ++-- .../Stores/OpenIddictScopeStore.cs | 16 ++- .../Stores/OpenIddictTokenStore.cs | 16 ++- .../Stores/OpenIddictApplicationStore.cs | 32 +++-- .../Stores/OpenIddictAuthorizationStore.cs | 43 +++--- .../Stores/OpenIddictScopeStore.cs | 16 ++- .../Stores/OpenIddictTokenStore.cs | 52 +++---- src/OpenIddict.Mvc/OpenIddictModelBinder.cs | 4 +- .../OpenIddictProvider.Introspection.cs | 4 +- src/OpenIddict/OpenIddictProvider.Userinfo.cs | 2 +- .../OpenIddictProviderTests.cs | 2 +- 25 files changed, 501 insertions(+), 279 deletions(-) diff --git a/build/common.props b/build/common.props index 9df4a916..6953ae7b 100644 --- a/build/common.props +++ b/build/common.props @@ -4,6 +4,7 @@ + latest $(NoWarn);CS1591 true true diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs index 83d6eef3..4aaa35d3 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -302,13 +302,32 @@ namespace OpenIddict.Core /// whose result returns the first element returned when executing the query. /// public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return GetAsync((applications, state) => state(applications), query, cancellationToken); + } + + /// + /// Executes the specified query and returns the first element. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the first element returned when executing the query. + /// + public virtual Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.GetAsync(query, cancellationToken); + return Store.GetAsync(query, state, cancellationToken); } /// @@ -491,13 +510,32 @@ namespace OpenIddict.Core /// whose result returns all the elements returned when executing the specified query. /// public virtual Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return ListAsync((applications, state) => state(applications), query, cancellationToken); + } + + /// + /// Executes the specified query and returns all the corresponding elements. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns all the elements returned when executing the specified query. + /// + public virtual Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.ListAsync(query, cancellationToken); + return Store.ListAsync(query, state, cancellationToken); } /// diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs index 2d167745..2f11180e 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs @@ -235,13 +235,32 @@ namespace OpenIddict.Core /// whose result returns the first element returned when executing the query. /// public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return GetAsync((authorizations, state) => state(authorizations), query, cancellationToken); + } + + /// + /// Executes the specified query and returns the first element. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the first element returned when executing the query. + /// + public virtual Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.GetAsync(query, cancellationToken); + return Store.GetAsync(query, state, cancellationToken); } /// @@ -352,13 +371,32 @@ namespace OpenIddict.Core /// whose result returns all the elements returned when executing the specified query. /// public virtual Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return ListAsync((authorizations, state) => state(authorizations), query, cancellationToken); + } + + /// + /// Executes the specified query and returns all the corresponding elements. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns all the elements returned when executing the specified query. + /// + public virtual Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.ListAsync(query, cancellationToken); + return Store.ListAsync(query, state, cancellationToken); } /// diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs index 40b7f67e..48cd9add 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs @@ -163,13 +163,32 @@ namespace OpenIddict.Core /// whose result returns the first element returned when executing the query. /// public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return GetAsync((scopes, state) => state(scopes), query, cancellationToken); + } + + /// + /// Executes the specified query and returns the first element. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the first element returned when executing the query. + /// + public virtual Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.GetAsync(query, cancellationToken); + return Store.GetAsync(query, state, cancellationToken); } /// @@ -198,13 +217,32 @@ namespace OpenIddict.Core /// whose result returns all the elements returned when executing the specified query. /// public virtual Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return ListAsync((scopes, state) => state(scopes), query, cancellationToken); + } + + /// + /// Executes the specified query and returns all the corresponding elements. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns all the elements returned when executing the specified query. + /// + public virtual Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.ListAsync(query, cancellationToken); + return Store.ListAsync(query, state, cancellationToken); } /// diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs index 39cd95b4..3f0377f2 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs @@ -299,13 +299,32 @@ namespace OpenIddict.Core /// whose result returns the first element returned when executing the query. /// public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return GetAsync((tokens, state) => state(tokens), query, cancellationToken); + } + + /// + /// Executes the specified query and returns the first element. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the first element returned when executing the query. + /// + public virtual Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.GetAsync(query, cancellationToken); + return Store.GetAsync(query, state, cancellationToken); } /// @@ -533,13 +552,32 @@ namespace OpenIddict.Core /// whose result returns all the elements returned when executing the specified query. /// public virtual Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + return ListAsync((tokens, state) => state(tokens), query, cancellationToken); + } + + /// + /// Executes the specified query and returns all the corresponding elements. + /// + /// The state type. + /// The result type. + /// The query to execute. + /// The optional state. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns all the elements returned when executing the specified query. + /// + public virtual Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return Store.ListAsync(query, cancellationToken); + return Store.ListAsync(query, state, cancellationToken); } /// diff --git a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs index ea5f5645..78a99c69 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs @@ -5,7 +5,6 @@ */ using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -109,14 +108,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the client identifier associated with an application. @@ -222,14 +225,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Sets the client identifier associated with an application. diff --git a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs index 1310b146..44058868 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs @@ -99,14 +99,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the unique identifier associated with an authorization. @@ -188,14 +192,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Lists the ad-hoc authorizations that are marked as invalid or have no diff --git a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs index f71c1afd..4460c2d5 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs @@ -64,14 +64,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the description associated with a scope. @@ -120,14 +124,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Sets the description associated with a scope. diff --git a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs index 75007225..dc53ff1d 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs @@ -128,14 +128,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the optional authorization identifier associated with a token. @@ -261,14 +265,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Lists the tokens that are marked as expired or invalid diff --git a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs index 0ea6b27c..ce4f50e9 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs @@ -90,16 +90,12 @@ namespace OpenIddict.Core throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } - IQueryable Query(IQueryable applications) - { - var key = ConvertIdentifierFromString(identifier); - - return from application in applications - where application.Id.Equals(key) - select application; - } + IQueryable Query(IQueryable applications, TKey key) + => from application in applications + where application.Id.Equals(key) + select application; - return GetAsync(Query, cancellationToken); + return GetAsync((applications, key) => Query(applications, key), ConvertIdentifierFromString(identifier), cancellationToken); } /// @@ -118,14 +114,12 @@ namespace OpenIddict.Core throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } - IQueryable Query(IQueryable applications) - { - return from application in applications - where application.ClientId == identifier - select application; - } + IQueryable Query(IQueryable applications, string id) + => from application in applications + where application.ClientId == id + select application; - return GetAsync(Query, cancellationToken); + return GetAsync((applications, id) => Query(applications, id), identifier, cancellationToken); } /// @@ -147,14 +141,12 @@ namespace OpenIddict.Core // To optimize the efficiency of the query, only applications whose stringified // LogoutRedirectUris property contains the specified address are returned. Once the // applications are retrieved, the LogoutRedirectUri property is manually split. - IQueryable Query(IQueryable applications) - { - return from application in applications - where application.PostLogoutRedirectUris.Contains(address) - select application; - } + IQueryable Query(IQueryable applications, string uri) + => from application in applications + where application.PostLogoutRedirectUris.Contains(uri) + select application; - var candidates = await ListAsync(Query, cancellationToken); + var candidates = await ListAsync((applications, uri) => Query(applications, uri), address, cancellationToken); if (candidates.IsDefaultOrEmpty) { return ImmutableArray.Create(); @@ -208,14 +200,12 @@ namespace OpenIddict.Core // To optimize the efficiency of the query, only applications whose stringified // RedirectUris property contains the specified address are returned. Once the // applications are retrieved, the RedirectUri property is manually split. - IQueryable Query(IQueryable applications) - { - return from application in applications - where application.RedirectUris.Contains(address) - select application; - } + IQueryable Query(IQueryable applications, string uri) + => from application in applications + where application.RedirectUris.Contains(uri) + select application; - var candidates = await ListAsync(Query, cancellationToken); + var candidates = await ListAsync((applications, uri) => Query(applications, uri), address, cancellationToken); if (candidates.IsDefaultOrEmpty) { return ImmutableArray.Create(); @@ -253,14 +243,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the client identifier associated with an application. @@ -437,37 +431,41 @@ namespace OpenIddict.Core /// public virtual Task> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) { - IQueryable Query(IQueryable applications) + IQueryable Query(IQueryable applications, int? skip, int? take) { var query = applications.OrderBy(application => application.Id).AsQueryable(); - if (offset.HasValue) + if (skip.HasValue) { - query = query.Skip(offset.Value); + query = query.Skip(skip.Value); } - if (count.HasValue) + if (take.HasValue) { - query = query.Take(count.Value); + query = query.Take(take.Value); } return query; } - return ListAsync(Query, cancellationToken); + return ListAsync((applications, state) => Query(applications, state.offset, state.count), (offset, count), cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public abstract Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Sets the client identifier associated with an application. diff --git a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs index 8b0cf132..a3b7d98a 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs @@ -97,18 +97,16 @@ namespace OpenIddict.Core throw new ArgumentException("The client cannot be null or empty.", nameof(client)); } - IQueryable Query(IQueryable authorizations) - { - var key = ConvertIdentifierFromString(client); - - return from authorization in authorizations - where authorization.Application != null - where authorization.Application.Id.Equals(key) - where authorization.Subject == subject - select authorization; - } - - return ListAsync(Query, cancellationToken); + IQueryable Query(IQueryable authorizations, TKey key, string principal) + => from authorization in authorizations + where authorization.Application != null + where authorization.Application.Id.Equals(key) + where authorization.Subject == principal + select authorization; + + return ListAsync( + (authorizations, state) => Query(authorizations, state.key, state.principal), + (key: ConvertIdentifierFromString(client), principal: subject), cancellationToken); } /// @@ -127,16 +125,12 @@ namespace OpenIddict.Core throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } - IQueryable Query(IQueryable authorizations) - { - var key = ConvertIdentifierFromString(identifier); + IQueryable Query(IQueryable authorizations, TKey key) + => from authorization in authorizations + where authorization.Id.Equals(key) + select authorization; - return from authorization in authorizations - where authorization.Id.Equals(key) - select authorization; - } - - return GetAsync(Query, cancellationToken); + return GetAsync((authorizations, key) => Query(authorizations, key), ConvertIdentifierFromString(identifier), cancellationToken); } /// @@ -160,28 +154,31 @@ namespace OpenIddict.Core return ConvertIdentifierToString(authorization.Application.Id); } - IQueryable Query(IQueryable authorizations) - { - return from element in authorizations - where element.Id.Equals(authorization.Id) - where element.Application != null - select element.Application.Id; - } + IQueryable Query(IQueryable authorizations, TKey key) + => from element in authorizations + where element.Id.Equals(key) + where element.Application != null + select element.Application.Id; - return ConvertIdentifierToString(await GetAsync(Query, cancellationToken)); + return ConvertIdentifierToString(await GetAsync( + (authorizations, key) => Query(authorizations, key), authorization.Id, cancellationToken)); } /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the unique identifier associated with an authorization. @@ -304,37 +301,41 @@ namespace OpenIddict.Core /// public virtual Task> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) { - IQueryable Query(IQueryable authorizations) + IQueryable Query(IQueryable authorizations, int? skip, int? take) { var query = authorizations.OrderBy(authorization => authorization.Id).AsQueryable(); - if (offset.HasValue) + if (skip.HasValue) { - query = query.Skip(offset.Value); + query = query.Skip(skip.Value); } - if (count.HasValue) + if (take.HasValue) { - query = query.Take(count.Value); + query = query.Take(take.Value); } return query; } - return ListAsync(Query, cancellationToken); + return ListAsync((authorizations, state) => Query(authorizations, state.offset, state.count), (offset, count), cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public abstract Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Lists the ad-hoc authorizations that are marked as invalid or have no @@ -349,7 +350,7 @@ namespace OpenIddict.Core /// public virtual Task> ListInvalidAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) { - IQueryable Query(IQueryable authorizations) + IQueryable Query(IQueryable authorizations, int? skip, int? take) { var query = (from authorization in authorizations where authorization.Status != OpenIddictConstants.Statuses.Valid || @@ -358,20 +359,20 @@ namespace OpenIddict.Core orderby authorization.Id select authorization).AsQueryable(); - if (offset.HasValue) + if (skip.HasValue) { - query = query.Skip(offset.Value); + query = query.Skip(skip.Value); } - if (count.HasValue) + if (take.HasValue) { - query = query.Take(count.Value); + query = query.Take(take.Value); } return query; } - return ListAsync(Query, cancellationToken); + return ListAsync((authorizations, state) => Query(authorizations, state.offset, state.count), (offset, count), cancellationToken); } /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs index b7cecf6f..d828c2bc 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs @@ -73,14 +73,18 @@ namespace OpenIddict.Core /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the description associated with a scope. @@ -142,37 +146,41 @@ namespace OpenIddict.Core /// public virtual Task> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) { - IQueryable Query(IQueryable scopes) + IQueryable Query(IQueryable scopes, int? skip, int? take) { var query = scopes.OrderBy(scope => scope.Id).AsQueryable(); - if (offset.HasValue) + if (skip.HasValue) { - query = query.Skip(offset.Value); + query = query.Skip(skip.Value); } - if (count.HasValue) + if (take.HasValue) { - query = query.Take(count.Value); + query = query.Take(take.Value); } return query; } - return ListAsync(Query, cancellationToken); + return ListAsync((scopes, state) => Query(scopes, state.offset, state.count), (offset, count), cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public abstract Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Sets the description associated with a scope. diff --git a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs index 8e069019..1f3cf4d8 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs @@ -88,17 +88,13 @@ namespace OpenIddict.Core throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } - IQueryable Query(IQueryable tokens) - { - var key = ConvertIdentifierFromString(identifier); - - return from token in tokens - where token.Application != null - where token.Application.Id.Equals(key) - select token; - } + IQueryable Query(IQueryable tokens, TKey key) + => from token in tokens + where token.Application != null + where token.Application.Id.Equals(key) + select token; - return ListAsync(Query, cancellationToken); + return ListAsync((tokens, key) => Query(tokens, key), ConvertIdentifierFromString(identifier), cancellationToken); } /// @@ -117,17 +113,13 @@ namespace OpenIddict.Core throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } - IQueryable Query(IQueryable tokens) - { - var key = ConvertIdentifierFromString(identifier); + IQueryable Query(IQueryable tokens, TKey key) + => from token in tokens + where token.Authorization != null + where token.Authorization.Id.Equals(key) + select token; - return from token in tokens - where token.Authorization != null - where token.Authorization.Id.Equals(key) - select token; - } - - return ListAsync(Query, cancellationToken); + return ListAsync((tokens, key) => Query(tokens, key), ConvertIdentifierFromString(identifier), cancellationToken); } /// @@ -146,14 +138,12 @@ namespace OpenIddict.Core throw new ArgumentException("The hash cannot be null or empty.", nameof(hash)); } - IQueryable Query(IQueryable tokens) - { - return from token in tokens - where token.Hash == hash - select token; - } + IQueryable Query(IQueryable tokens, string digest) + => from token in tokens + where token.Hash == digest + select token; - return GetAsync(Query, cancellationToken); + return GetAsync((tokens, digest) => Query(tokens, digest), hash, cancellationToken); } /// @@ -172,16 +162,12 @@ namespace OpenIddict.Core throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } - IQueryable Query(IQueryable tokens) - { - var key = ConvertIdentifierFromString(identifier); + IQueryable Query(IQueryable tokens, TKey key) + => from token in tokens + where token.Id.Equals(key) + select token; - return from token in tokens - where token.Id.Equals(key) - select token; - } - - return GetAsync(Query, cancellationToken); + return GetAsync((tokens, key) => Query(tokens, key), ConvertIdentifierFromString(identifier), cancellationToken); } /// @@ -200,27 +186,29 @@ namespace OpenIddict.Core throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); } - IQueryable Query(IQueryable tokens) - { - return from token in tokens - where token.Subject == subject - select token; - } + IQueryable Query(IQueryable tokens, string principal) + => from token in tokens + where token.Subject == principal + select token; - return ListAsync(Query, cancellationToken); + return ListAsync((tokens, principal) => Query(tokens, principal), subject, cancellationToken); } /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Retrieves the optional application identifier associated with a token. @@ -243,15 +231,13 @@ namespace OpenIddict.Core return ConvertIdentifierToString(token.Application.Id); } - IQueryable Query(IQueryable tokens) - { - return from element in tokens - where element.Id.Equals(token.Id) - where element.Application != null - select element.Application.Id; - } + IQueryable Query(IQueryable tokens, TKey key) + => from element in tokens + where element.Id.Equals(key) + where element.Application != null + select element.Application.Id; - return ConvertIdentifierToString(await GetAsync(Query, cancellationToken)); + return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken)); } /// @@ -275,15 +261,13 @@ namespace OpenIddict.Core return ConvertIdentifierToString(token.Authorization.Id); } - IQueryable Query(IQueryable tokens) - { - return from element in tokens - where element.Id.Equals(token.Id) - where element.Authorization != null - select element.Authorization.Id; - } + IQueryable Query(IQueryable tokens, TKey key) + => from element in tokens + where element.Id.Equals(key) + where element.Authorization != null + select element.Authorization.Id; - return ConvertIdentifierToString(await GetAsync(Query, cancellationToken)); + return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken)); } /// @@ -460,37 +444,41 @@ namespace OpenIddict.Core /// public virtual Task> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) { - IQueryable Query(IQueryable tokens) + IQueryable Query(IQueryable tokens, int? skip, int? take) { var query = tokens.OrderBy(token => token.Id).AsQueryable(); - if (offset.HasValue) + if (skip.HasValue) { - query = query.Skip(offset.Value); + query = query.Skip(skip.Value); } - if (count.HasValue) + if (take.HasValue) { - query = query.Take(count.Value); + query = query.Take(take.Value); } return query; } - return ListAsync(Query, cancellationToken); + return ListAsync((tokens, state) => Query(tokens, state.offset, state.count), (offset, count), cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public abstract Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + public abstract Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken); /// /// Lists the tokens that are marked as expired or invalid @@ -505,7 +493,7 @@ namespace OpenIddict.Core /// public virtual Task> ListInvalidAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) { - IQueryable Query(IQueryable tokens) + IQueryable Query(IQueryable tokens, int? skip, int? take) { var query = (from token in tokens where token.ExpirationDate < DateTimeOffset.UtcNow || @@ -513,20 +501,20 @@ namespace OpenIddict.Core orderby token.Id select token).AsQueryable(); - if (offset.HasValue) + if (skip.HasValue) { - query = query.Skip(offset.Value); + query = query.Skip(skip.Value); } - if (count.HasValue) + if (take.HasValue) { - query = query.Take(count.Value); + query = query.Take(take.Value); } return query; } - return ListAsync(Query, cancellationToken); + return ListAsync((tokens, state) => Query(tokens, state.offset, state.count), (offset, count), cancellationToken); } /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs index 98646dfc..adaaeb7b 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs @@ -150,18 +150,14 @@ namespace OpenIddict.EntityFramework } Task> ListAuthorizationsAsync() - { - return (from authorization in Authorizations.Include(authorization => authorization.Tokens) - where authorization.Application.Id.Equals(application.Id) - select authorization).ToListAsync(cancellationToken); - } + => (from authorization in Authorizations.Include(authorization => authorization.Tokens) + where authorization.Application.Id.Equals(application.Id) + select authorization).ToListAsync(cancellationToken); Task> ListTokensAsync() - { - return (from token in Tokens - where token.Application.Id.Equals(application.Id) - select token).ToListAsync(cancellationToken); - } + => (from token in Tokens + where token.Application.Id.Equals(application.Id) + select token).ToListAsync(cancellationToken); // Remove all the authorizations associated with the application and // the tokens attached to these implicit or explicit authorizations. @@ -208,41 +204,49 @@ namespace OpenIddict.EntityFramework /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return query(Applications).FirstOrDefaultAsync(cancellationToken); + return query(Applications, state).FirstOrDefaultAsync(cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return ImmutableArray.CreateRange(await query(Applications).ToListAsync(cancellationToken)); + return ImmutableArray.CreateRange(await query(Applications, state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs index efdb3847..00ca7ba5 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs @@ -150,11 +150,9 @@ namespace OpenIddict.EntityFramework } Task> ListTokensAsync() - { - return (from token in Tokens - where token.Application.Id.Equals(authorization.Id) - select token).ToListAsync(cancellationToken); - } + => (from token in Tokens + where token.Application.Id.Equals(authorization.Id) + select token).ToListAsync(cancellationToken); // Remove all the tokens associated with the application. foreach (var token in await ListTokensAsync()) @@ -235,34 +233,42 @@ namespace OpenIddict.EntityFramework /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return query(Authorizations.Include(authorization => authorization.Application)).FirstOrDefaultAsync(cancellationToken); + return query(Authorizations.Include(authorization => authorization.Application), state).FirstOrDefaultAsync(cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { @@ -270,7 +276,7 @@ namespace OpenIddict.EntityFramework } return ImmutableArray.CreateRange(await query( - Authorizations.Include(authorization => authorization.Application)).ToListAsync(cancellationToken)); + Authorizations.Include(authorization => authorization.Application), state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs index 7cd7492f..adad729a 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs @@ -137,41 +137,49 @@ namespace OpenIddict.EntityFramework /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return query(Scopes).FirstOrDefaultAsync(cancellationToken); + return query(Scopes, state).FirstOrDefaultAsync(cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return ImmutableArray.CreateRange(await query(Scopes).ToListAsync(cancellationToken)); + return ImmutableArray.CreateRange(await query(Scopes, state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs index 69cfe996..93404579 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs @@ -219,14 +219,18 @@ namespace OpenIddict.EntityFramework /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { @@ -235,7 +239,7 @@ namespace OpenIddict.EntityFramework return query( Tokens.Include(token => token.Application) - .Include(token => token.Authorization)).FirstOrDefaultAsync(cancellationToken); + .Include(token => token.Authorization), state).FirstOrDefaultAsync(cancellationToken); } /// @@ -277,14 +281,18 @@ namespace OpenIddict.EntityFramework /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { @@ -293,7 +301,7 @@ namespace OpenIddict.EntityFramework return ImmutableArray.CreateRange(await query( Tokens.Include(token => token.Application) - .Include(token => token.Authorization)).ToListAsync(cancellationToken)); + .Include(token => token.Authorization), state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs index 40ae1990..82734798 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs @@ -150,18 +150,14 @@ namespace OpenIddict.EntityFrameworkCore } Task> ListAuthorizationsAsync() - { - return (from authorization in Authorizations.Include(authorization => authorization.Tokens) - where authorization.Application.Id.Equals(application.Id) - select authorization).ToListAsync(cancellationToken); - } + => (from authorization in Authorizations.Include(authorization => authorization.Tokens) + where authorization.Application.Id.Equals(application.Id) + select authorization).ToListAsync(cancellationToken); Task> ListTokensAsync() - { - return (from token in Tokens - where token.Application.Id.Equals(application.Id) - select token).ToListAsync(cancellationToken); - } + => (from token in Tokens + where token.Application.Id.Equals(application.Id) + select token).ToListAsync(cancellationToken); // Remove all the authorizations associated with the application and // the tokens attached to these implicit or explicit authorizations. @@ -208,41 +204,49 @@ namespace OpenIddict.EntityFrameworkCore /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return query(Applications).FirstOrDefaultAsync(cancellationToken); + return query(Applications, state).FirstOrDefaultAsync(cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return ImmutableArray.CreateRange(await query(Applications).ToListAsync(cancellationToken)); + return ImmutableArray.CreateRange(await query(Applications, state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs index 07a1d217..d683d90c 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs @@ -150,11 +150,9 @@ namespace OpenIddict.EntityFrameworkCore } Task> ListTokensAsync() - { - return (from token in Tokens - where token.Application.Id.Equals(authorization.Id) - select token).ToListAsync(cancellationToken); - } + => (from token in Tokens + where token.Application.Id.Equals(authorization.Id) + select token).ToListAsync(cancellationToken); // Remove all the tokens associated with the application. foreach (var token in await ListTokensAsync()) @@ -195,18 +193,15 @@ namespace OpenIddict.EntityFrameworkCore // this method is overriden to use an explicit join before applying the equality check. // See https://github.com/openiddict/openiddict-core/issues/499 for more information. - IQueryable Query(IQueryable authorizations, IQueryable applications) - { - var key = ConvertIdentifierFromString(client); - - return from authorization in authorizations.Include(authorization => authorization.Application) - where authorization.Subject == subject - join application in applications on authorization.Application.Id equals application.Id - where application.Id.Equals(key) - select authorization; - } + IQueryable Query(IQueryable authorizations, IQueryable applications, TKey key, string principal) + => from authorization in authorizations.Include(authorization => authorization.Application) + where authorization.Subject == principal + join application in applications on authorization.Application.Id equals application.Id + where application.Id.Equals(key) + select authorization; - return ImmutableArray.CreateRange(await Query(Authorizations, Applications).ToListAsync(cancellationToken)); + return ImmutableArray.CreateRange(await Query( + Authorizations, Applications, ConvertIdentifierFromString(client), subject).ToListAsync(cancellationToken)); } /// @@ -277,34 +272,42 @@ namespace OpenIddict.EntityFrameworkCore /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return query(Authorizations.Include(authorization => authorization.Application)).FirstOrDefaultAsync(cancellationToken); + return query(Authorizations.Include(authorization => authorization.Application), state).FirstOrDefaultAsync(cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { @@ -312,7 +315,7 @@ namespace OpenIddict.EntityFrameworkCore } return ImmutableArray.CreateRange(await query( - Authorizations.Include(authorization => authorization.Application)).ToListAsync(cancellationToken)); + Authorizations.Include(authorization => authorization.Application), state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs index abe7cca1..b46276e8 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs @@ -137,41 +137,49 @@ namespace OpenIddict.EntityFrameworkCore /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return query(Scopes).FirstOrDefaultAsync(cancellationToken); + return query(Scopes, state).FirstOrDefaultAsync(cancellationToken); } /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { throw new ArgumentNullException(nameof(query)); } - return ImmutableArray.CreateRange(await query(Scopes).ToListAsync(cancellationToken)); + return ImmutableArray.CreateRange(await query(Scopes, state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs index dfcbad38..3aa667ae 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs @@ -172,17 +172,14 @@ namespace OpenIddict.EntityFrameworkCore // this method is overriden to use an explicit join before applying the equality check. // See https://github.com/openiddict/openiddict-core/issues/499 for more information. - IQueryable Query(IQueryable applications, IQueryable tokens) - { - var key = ConvertIdentifierFromString(identifier); - - return from token in tokens.Include(token => token.Application).Include(token => token.Authorization) - join application in applications on token.Application.Id equals application.Id - where application.Id.Equals(key) - select token; - } - - return ImmutableArray.CreateRange(await Query(Applications, Tokens).ToListAsync(cancellationToken)); + IQueryable Query(IQueryable applications, IQueryable tokens, TKey key) + => from token in tokens.Include(token => token.Application).Include(token => token.Authorization) + join application in applications on token.Application.Id equals application.Id + where application.Id.Equals(key) + select token; + + return ImmutableArray.CreateRange(await Query( + Applications, Tokens, ConvertIdentifierFromString(identifier)).ToListAsync(cancellationToken)); } /// @@ -206,17 +203,14 @@ namespace OpenIddict.EntityFrameworkCore // this method is overriden to use an explicit join before applying the equality check. // See https://github.com/openiddict/openiddict-core/issues/499 for more information. - IQueryable Query(IQueryable authorizations, IQueryable tokens) - { - var key = ConvertIdentifierFromString(identifier); - - return from token in tokens.Include(token => token.Application).Include(token => token.Authorization) - join authorization in authorizations on token.Authorization.Id equals authorization.Id - where authorization.Id.Equals(key) - select token; - } + IQueryable Query(IQueryable authorizations, IQueryable tokens, TKey key) + => from token in tokens.Include(token => token.Application).Include(token => token.Authorization) + join authorization in authorizations on token.Authorization.Id equals authorization.Id + where authorization.Id.Equals(key) + select token; - return ImmutableArray.CreateRange(await Query(Authorizations, Tokens).ToListAsync(cancellationToken)); + return ImmutableArray.CreateRange(await Query( + Authorizations, Tokens, ConvertIdentifierFromString(identifier)).ToListAsync(cancellationToken)); } /// @@ -287,14 +281,18 @@ namespace OpenIddict.EntityFrameworkCore /// /// Executes the specified query and returns the first element. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns the first element returned when executing the query. /// - public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override Task GetAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { @@ -303,7 +301,7 @@ namespace OpenIddict.EntityFrameworkCore return query( Tokens.Include(token => token.Application) - .Include(token => token.Authorization)).FirstOrDefaultAsync(cancellationToken); + .Include(token => token.Authorization), state).FirstOrDefaultAsync(cancellationToken); } /// @@ -345,14 +343,18 @@ namespace OpenIddict.EntityFrameworkCore /// /// Executes the specified query and returns all the corresponding elements. /// + /// The state type. /// The result type. /// The query to execute. + /// The optional state. /// The that can be used to abort the operation. /// /// A that can be used to monitor the asynchronous operation, /// whose result returns all the elements returned when executing the specified query. /// - public override async Task> ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + public override async Task> ListAsync( + [NotNull] Func, TState, IQueryable> query, + [CanBeNull] TState state, CancellationToken cancellationToken) { if (query == null) { @@ -361,7 +363,7 @@ namespace OpenIddict.EntityFrameworkCore return ImmutableArray.CreateRange(await query( Tokens.Include(token => token.Application) - .Include(token => token.Authorization)).ToListAsync(cancellationToken)); + .Include(token => token.Authorization), state).ToListAsync(cancellationToken)); } /// diff --git a/src/OpenIddict.Mvc/OpenIddictModelBinder.cs b/src/OpenIddict.Mvc/OpenIddictModelBinder.cs index 4ca753d2..3e314be0 100644 --- a/src/OpenIddict.Mvc/OpenIddictModelBinder.cs +++ b/src/OpenIddict.Mvc/OpenIddictModelBinder.cs @@ -47,7 +47,7 @@ namespace OpenIddict.Mvc context.Result = ModelBindingResult.Success(request); - return Task.FromResult(0); + return Task.CompletedTask; } else if (context.ModelType == typeof(OpenIdConnectResponse)) @@ -65,7 +65,7 @@ namespace OpenIddict.Mvc context.Result = ModelBindingResult.Success(response); - return Task.FromResult(0); + return Task.CompletedTask; } throw new InvalidOperationException("The specified model type is not supported by this binder."); diff --git a/src/OpenIddict/OpenIddictProvider.Introspection.cs b/src/OpenIddict/OpenIddictProvider.Introspection.cs index 12dc041a..bff6c072 100644 --- a/src/OpenIddict/OpenIddictProvider.Introspection.cs +++ b/src/OpenIddict/OpenIddictProvider.Introspection.cs @@ -28,10 +28,10 @@ namespace OpenIddict error: OpenIdConnectConstants.Errors.InvalidRequest, description: "The specified HTTP method is not valid."); - return Task.FromResult(0); + return Task.CompletedTask; } - return Task.FromResult(0); + return Task.CompletedTask; } public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context) diff --git a/src/OpenIddict/OpenIddictProvider.Userinfo.cs b/src/OpenIddict/OpenIddictProvider.Userinfo.cs index f6a8a72b..39145f07 100644 --- a/src/OpenIddict/OpenIddictProvider.Userinfo.cs +++ b/src/OpenIddict/OpenIddictProvider.Userinfo.cs @@ -25,7 +25,7 @@ namespace OpenIddict // the user code to handle the userinfo request. context.SkipHandler(); - return Task.FromResult(0); + return Task.CompletedTask; } } } \ No newline at end of file diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.cs index 27256a76..58a36378 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.cs @@ -1439,7 +1439,7 @@ namespace OpenIddict.Tests })); } - return Task.FromResult(0); + return Task.CompletedTask; }); });