diff --git a/build/common.props b/build/common.props index 2ced2fd2..75ebe440 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 4ebdbed8..689f8b88 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -303,13 +303,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); } /// @@ -492,13 +511,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 02bd5ff6..bc272930 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 0a39576d..10228184 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 cf3f8277..46db936f 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 ccc0725f..d84e89e9 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs @@ -5,6 +5,7 @@ */ using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Linq; @@ -90,16 +91,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 +115,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 +142,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 +201,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 +244,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 +432,43 @@ 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.Key, state.Value), + new KeyValuePair(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 4c020296..8f1c1784 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs @@ -5,6 +5,7 @@ */ using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Linq; @@ -97,18 +98,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; - } + 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(Query, cancellationToken); + return ListAsync( + (authorizations, state) => Query(authorizations, state.Key, state.Value), + new KeyValuePair(ConvertIdentifierFromString(client), subject), cancellationToken); } /// @@ -127,16 +126,12 @@ namespace OpenIddict.Core throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } - IQueryable Query(IQueryable authorizations) - { - var key = ConvertIdentifierFromString(identifier); - - return from authorization in authorizations - where authorization.Id.Equals(key) - select authorization; - } + IQueryable Query(IQueryable authorizations, TKey key) + => 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 +155,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 +302,43 @@ 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.Key, state.Value), + new KeyValuePair(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 +353,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 +362,22 @@ 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.Key, state.Value), + new KeyValuePair(offset, count), cancellationToken); } /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs index 1596f9d8..24cfe3b7 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs @@ -5,6 +5,7 @@ */ using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Linq; @@ -73,14 +74,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 +147,43 @@ 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.Key, state.Value), + new KeyValuePair(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 7e4b651c..15f60f1d 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs @@ -5,6 +5,7 @@ */ using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Linq; @@ -88,17 +89,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 +114,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 +139,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 +163,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 +187,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 +232,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 +262,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 +445,43 @@ 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.Key, state.Value), + new KeyValuePair(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 +496,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 +504,22 @@ 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.Key, state.Value), + new KeyValuePair(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 d1e3ee69..2d0ed3e0 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. @@ -189,41 +185,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 855f93e9..1ff755bd 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)); } /// @@ -241,34 +236,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) { @@ -276,7 +279,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 a3a2e8dc..94f83da0 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)); } /// @@ -251,14 +245,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) { @@ -267,20 +265,24 @@ namespace OpenIddict.EntityFrameworkCore return query( Tokens.Include(token => token.Application) - .Include(token => token.Authorization)).FirstOrDefaultAsync(cancellationToken); + .Include(token => token.Authorization), 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) { @@ -289,7 +291,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)); } ///