Browse Source

Backport the stores changes to OpenIddict 1.x

pull/553/head
Kévin Chalet 9 years ago
parent
commit
412b53b71c
  1. 1
      build/common.props
  2. 42
      src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
  3. 42
      src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
  4. 42
      src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
  5. 42
      src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
  6. 13
      src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
  7. 12
      src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
  8. 12
      src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs
  9. 12
      src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
  10. 77
      src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
  11. 90
      src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
  12. 27
      src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs
  13. 139
      src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
  14. 32
      src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
  15. 24
      src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
  16. 16
      src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
  17. 16
      src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
  18. 32
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
  19. 43
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
  20. 16
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
  21. 52
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

1
build/common.props

@ -4,6 +4,7 @@
<Import Project="version.props" /> <Import Project="version.props" />
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion>
<NoWarn>$(NoWarn);CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>

42
src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs

@ -303,13 +303,32 @@ namespace OpenIddict.Core
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return GetAsync((applications, state) => state(applications), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns the first element.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query.
/// </returns>
public virtual Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.GetAsync(query, cancellationToken); return Store.GetAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>
@ -492,13 +511,32 @@ namespace OpenIddict.Core
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return ListAsync((applications, state) => state(applications), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns all the corresponding elements.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query.
/// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.ListAsync(query, cancellationToken); return Store.ListAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>

42
src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs

@ -235,13 +235,32 @@ namespace OpenIddict.Core
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return GetAsync((authorizations, state) => state(authorizations), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns the first element.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query.
/// </returns>
public virtual Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.GetAsync(query, cancellationToken); return Store.GetAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>
@ -352,13 +371,32 @@ namespace OpenIddict.Core
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return ListAsync((authorizations, state) => state(authorizations), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns all the corresponding elements.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query.
/// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.ListAsync(query, cancellationToken); return Store.ListAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>

42
src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs

@ -163,13 +163,32 @@ namespace OpenIddict.Core
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return GetAsync((scopes, state) => state(scopes), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns the first element.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query.
/// </returns>
public virtual Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.GetAsync(query, cancellationToken); return Store.GetAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>
@ -198,13 +217,32 @@ namespace OpenIddict.Core
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return ListAsync((scopes, state) => state(scopes), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns all the corresponding elements.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query.
/// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.ListAsync(query, cancellationToken); return Store.ListAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>

42
src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs

@ -299,13 +299,32 @@ namespace OpenIddict.Core
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return GetAsync((tokens, state) => state(tokens), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns the first element.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query.
/// </returns>
public virtual Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.GetAsync(query, cancellationToken); return Store.GetAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>
@ -533,13 +552,32 @@ namespace OpenIddict.Core
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken)
{
return ListAsync((tokens, state) => state(tokens), query, cancellationToken);
}
/// <summary>
/// Executes the specified query and returns all the corresponding elements.
/// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query.
/// </returns>
public virtual Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return Store.ListAsync(query, cancellationToken); return Store.ListAsync(query, state, cancellationToken);
} }
/// <summary> /// <summary>

13
src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs

@ -5,7 +5,6 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -109,14 +108,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the client identifier associated with an application. /// Retrieves the client identifier associated with an application.
@ -222,14 +225,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Sets the client identifier associated with an application. /// Sets the client identifier associated with an application.

12
src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs

@ -99,14 +99,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the unique identifier associated with an authorization. /// Retrieves the unique identifier associated with an authorization.
@ -188,14 +192,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Lists the ad-hoc authorizations that are marked as invalid or have no /// Lists the ad-hoc authorizations that are marked as invalid or have no

12
src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs

@ -64,14 +64,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the description associated with a scope. /// Retrieves the description associated with a scope.
@ -120,14 +124,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Sets the description associated with a scope. /// Sets the description associated with a scope.

12
src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs

@ -128,14 +128,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the optional authorization identifier associated with a token. /// Retrieves the optional authorization identifier associated with a token.
@ -261,14 +265,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken); Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Lists the tokens that are marked as expired or invalid /// Lists the tokens that are marked as expired or invalid

77
src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs

@ -5,6 +5,7 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -90,16 +91,12 @@ namespace OpenIddict.Core
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
} }
IQueryable<TApplication> Query(IQueryable<TApplication> applications) IQueryable<TApplication> Query(IQueryable<TApplication> applications, TKey key)
{ => from application in applications
var key = ConvertIdentifierFromString(identifier); where application.Id.Equals(key)
select application;
return 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);
} }
/// <summary> /// <summary>
@ -118,14 +115,12 @@ namespace OpenIddict.Core
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
} }
IQueryable<TApplication> Query(IQueryable<TApplication> applications) IQueryable<TApplication> Query(IQueryable<TApplication> applications, string id)
{ => from application in applications
return from application in applications where application.ClientId == id
where application.ClientId == identifier select application;
select application;
}
return GetAsync(Query, cancellationToken); return GetAsync((applications, id) => Query(applications, id), identifier, cancellationToken);
} }
/// <summary> /// <summary>
@ -147,14 +142,12 @@ namespace OpenIddict.Core
// To optimize the efficiency of the query, only applications whose stringified // To optimize the efficiency of the query, only applications whose stringified
// LogoutRedirectUris property contains the specified address are returned. Once the // LogoutRedirectUris property contains the specified address are returned. Once the
// applications are retrieved, the LogoutRedirectUri property is manually split. // applications are retrieved, the LogoutRedirectUri property is manually split.
IQueryable<TApplication> Query(IQueryable<TApplication> applications) IQueryable<TApplication> Query(IQueryable<TApplication> applications, string uri)
{ => from application in applications
return from application in applications where application.PostLogoutRedirectUris.Contains(uri)
where application.PostLogoutRedirectUris.Contains(address) select application;
select application;
}
var candidates = await ListAsync(Query, cancellationToken); var candidates = await ListAsync((applications, uri) => Query(applications, uri), address, cancellationToken);
if (candidates.IsDefaultOrEmpty) if (candidates.IsDefaultOrEmpty)
{ {
return ImmutableArray.Create<TApplication>(); return ImmutableArray.Create<TApplication>();
@ -208,14 +201,12 @@ namespace OpenIddict.Core
// To optimize the efficiency of the query, only applications whose stringified // To optimize the efficiency of the query, only applications whose stringified
// RedirectUris property contains the specified address are returned. Once the // RedirectUris property contains the specified address are returned. Once the
// applications are retrieved, the RedirectUri property is manually split. // applications are retrieved, the RedirectUri property is manually split.
IQueryable<TApplication> Query(IQueryable<TApplication> applications) IQueryable<TApplication> Query(IQueryable<TApplication> applications, string uri)
{ => from application in applications
return from application in applications where application.RedirectUris.Contains(uri)
where application.RedirectUris.Contains(address) select application;
select application;
}
var candidates = await ListAsync(Query, cancellationToken); var candidates = await ListAsync((applications, uri) => Query(applications, uri), address, cancellationToken);
if (candidates.IsDefaultOrEmpty) if (candidates.IsDefaultOrEmpty)
{ {
return ImmutableArray.Create<TApplication>(); return ImmutableArray.Create<TApplication>();
@ -253,14 +244,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public abstract Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the client identifier associated with an application. /// Retrieves the client identifier associated with an application.
@ -437,37 +432,43 @@ namespace OpenIddict.Core
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TApplication>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TApplication>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
IQueryable<TApplication> Query(IQueryable<TApplication> applications) IQueryable<TApplication> Query(IQueryable<TApplication> applications, int? skip, int? take)
{ {
var query = applications.OrderBy(application => application.Id).AsQueryable(); 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 query;
} }
return ListAsync(Query, cancellationToken); return ListAsync(
(applications, state) => Query(applications, state.Key, state.Value),
new KeyValuePair<int?, int?>(offset, count), cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public abstract Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Sets the client identifier associated with an application. /// Sets the client identifier associated with an application.

90
src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs

@ -5,6 +5,7 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -97,18 +98,16 @@ namespace OpenIddict.Core
throw new ArgumentException("The client cannot be null or empty.", nameof(client)); throw new ArgumentException("The client cannot be null or empty.", nameof(client));
} }
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations) IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations, TKey key, string principal)
{ => from authorization in authorizations
var key = ConvertIdentifierFromString(client); where authorization.Application != null
where authorization.Application.Id.Equals(key)
return from authorization in authorizations where authorization.Subject == principal
where authorization.Application != null select authorization;
where authorization.Application.Id.Equals(key)
where authorization.Subject == subject
select authorization;
}
return ListAsync(Query, cancellationToken); return ListAsync(
(authorizations, state) => Query(authorizations, state.Key, state.Value),
new KeyValuePair<TKey, string>(ConvertIdentifierFromString(client), subject), cancellationToken);
} }
/// <summary> /// <summary>
@ -127,16 +126,12 @@ namespace OpenIddict.Core
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
} }
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations) IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations, TKey key)
{ => from authorization in authorizations
var key = ConvertIdentifierFromString(identifier); 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);
} }
/// <summary> /// <summary>
@ -160,28 +155,31 @@ namespace OpenIddict.Core
return ConvertIdentifierToString(authorization.Application.Id); return ConvertIdentifierToString(authorization.Application.Id);
} }
IQueryable<TKey> Query(IQueryable<TAuthorization> authorizations) IQueryable<TKey> Query(IQueryable<TAuthorization> authorizations, TKey key)
{ => from element in authorizations
return from element in authorizations where element.Id.Equals(key)
where element.Id.Equals(authorization.Id) where element.Application != null
where element.Application != null select element.Application.Id;
select element.Application.Id;
}
return ConvertIdentifierToString(await GetAsync(Query, cancellationToken)); return ConvertIdentifierToString(await GetAsync(
(authorizations, key) => Query(authorizations, key), authorization.Id, cancellationToken));
} }
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public abstract Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the unique identifier associated with an authorization. /// Retrieves the unique identifier associated with an authorization.
@ -304,37 +302,43 @@ namespace OpenIddict.Core
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TAuthorization>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TAuthorization>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations) IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations, int? skip, int? take)
{ {
var query = authorizations.OrderBy(authorization => authorization.Id).AsQueryable(); 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 query;
} }
return ListAsync(Query, cancellationToken); return ListAsync(
(authorizations, state) => Query(authorizations, state.Key, state.Value),
new KeyValuePair<int?, int?>(offset, count), cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public abstract Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Lists the ad-hoc authorizations that are marked as invalid or have no /// Lists the ad-hoc authorizations that are marked as invalid or have no
@ -349,7 +353,7 @@ namespace OpenIddict.Core
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TAuthorization>> ListInvalidAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TAuthorization>> ListInvalidAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations) IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations, int? skip, int? take)
{ {
var query = (from authorization in authorizations var query = (from authorization in authorizations
where authorization.Status != OpenIddictConstants.Statuses.Valid || where authorization.Status != OpenIddictConstants.Statuses.Valid ||
@ -358,20 +362,22 @@ namespace OpenIddict.Core
orderby authorization.Id orderby authorization.Id
select authorization).AsQueryable(); 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 query;
} }
return ListAsync(Query, cancellationToken); return ListAsync(
(authorizations, state) => Query(authorizations, state.Key, state.Value),
new KeyValuePair<int?, int?>(offset, count), cancellationToken);
} }
/// <summary> /// <summary>

27
src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs

@ -5,6 +5,7 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -73,14 +74,18 @@ namespace OpenIddict.Core
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public abstract Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the description associated with a scope. /// Retrieves the description associated with a scope.
@ -142,37 +147,43 @@ namespace OpenIddict.Core
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TScope>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TScope>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
IQueryable<TScope> Query(IQueryable<TScope> scopes) IQueryable<TScope> Query(IQueryable<TScope> scopes, int? skip, int? take)
{ {
var query = scopes.OrderBy(scope => scope.Id).AsQueryable(); 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 query;
} }
return ListAsync(Query, cancellationToken); return ListAsync(
(scopes, state) => Query(scopes, state.Key, state.Value),
new KeyValuePair<int?, int?>(offset, count), cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public abstract Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Sets the description associated with a scope. /// Sets the description associated with a scope.

139
src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs

@ -5,6 +5,7 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -88,17 +89,13 @@ namespace OpenIddict.Core
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
} }
IQueryable<TToken> Query(IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TToken> tokens, TKey key)
{ => from token in tokens
var key = ConvertIdentifierFromString(identifier); where token.Application != null
where token.Application.Id.Equals(key)
return from token in tokens select token;
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);
} }
/// <summary> /// <summary>
@ -117,17 +114,13 @@ namespace OpenIddict.Core
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
} }
IQueryable<TToken> Query(IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TToken> tokens, TKey key)
{ => from token in tokens
var key = ConvertIdentifierFromString(identifier); where token.Authorization != null
where token.Authorization.Id.Equals(key)
select token;
return from token in tokens return ListAsync((tokens, key) => Query(tokens, key), ConvertIdentifierFromString(identifier), cancellationToken);
where token.Authorization != null
where token.Authorization.Id.Equals(key)
select token;
}
return ListAsync(Query, cancellationToken);
} }
/// <summary> /// <summary>
@ -146,14 +139,12 @@ namespace OpenIddict.Core
throw new ArgumentException("The hash cannot be null or empty.", nameof(hash)); throw new ArgumentException("The hash cannot be null or empty.", nameof(hash));
} }
IQueryable<TToken> Query(IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TToken> tokens, string digest)
{ => from token in tokens
return from token in tokens where token.Hash == digest
where token.Hash == hash select token;
select token;
}
return GetAsync(Query, cancellationToken); return GetAsync((tokens, digest) => Query(tokens, digest), hash, cancellationToken);
} }
/// <summary> /// <summary>
@ -172,16 +163,12 @@ namespace OpenIddict.Core
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
} }
IQueryable<TToken> Query(IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TToken> tokens, TKey key)
{ => from token in tokens
var key = ConvertIdentifierFromString(identifier); where token.Id.Equals(key)
select token;
return from token in tokens return GetAsync((tokens, key) => Query(tokens, key), ConvertIdentifierFromString(identifier), cancellationToken);
where token.Id.Equals(key)
select token;
}
return GetAsync(Query, cancellationToken);
} }
/// <summary> /// <summary>
@ -200,27 +187,29 @@ namespace OpenIddict.Core
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
} }
IQueryable<TToken> Query(IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TToken> tokens, string principal)
{ => from token in tokens
return from token in tokens where token.Subject == principal
where token.Subject == subject select token;
select token;
}
return ListAsync(Query, cancellationToken); return ListAsync((tokens, principal) => Query(tokens, principal), subject, cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public abstract Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Retrieves the optional application identifier associated with a token. /// Retrieves the optional application identifier associated with a token.
@ -243,15 +232,13 @@ namespace OpenIddict.Core
return ConvertIdentifierToString(token.Application.Id); return ConvertIdentifierToString(token.Application.Id);
} }
IQueryable<TKey> Query(IQueryable<TToken> tokens) IQueryable<TKey> Query(IQueryable<TToken> tokens, TKey key)
{ => from element in tokens
return from element in tokens where element.Id.Equals(key)
where element.Id.Equals(token.Id) where element.Application != null
where element.Application != null select element.Application.Id;
select element.Application.Id;
}
return ConvertIdentifierToString(await GetAsync(Query, cancellationToken)); return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken));
} }
/// <summary> /// <summary>
@ -275,15 +262,13 @@ namespace OpenIddict.Core
return ConvertIdentifierToString(token.Authorization.Id); return ConvertIdentifierToString(token.Authorization.Id);
} }
IQueryable<TKey> Query(IQueryable<TToken> tokens) IQueryable<TKey> Query(IQueryable<TToken> tokens, TKey key)
{ => from element in tokens
return from element in tokens where element.Id.Equals(key)
where element.Id.Equals(token.Id) where element.Authorization != null
where element.Authorization != null select element.Authorization.Id;
select element.Authorization.Id;
}
return ConvertIdentifierToString(await GetAsync(Query, cancellationToken)); return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken));
} }
/// <summary> /// <summary>
@ -460,37 +445,43 @@ namespace OpenIddict.Core
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TToken>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TToken>> ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
IQueryable<TToken> Query(IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TToken> tokens, int? skip, int? take)
{ {
var query = tokens.OrderBy(token => token.Id).AsQueryable(); 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 query;
} }
return ListAsync(Query, cancellationToken); return ListAsync(
(tokens, state) => Query(tokens, state.Key, state.Value),
new KeyValuePair<int?, int?>(offset, count), cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public abstract Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken); public abstract Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Lists the tokens that are marked as expired or invalid /// Lists the tokens that are marked as expired or invalid
@ -505,7 +496,7 @@ namespace OpenIddict.Core
/// </returns> /// </returns>
public virtual Task<ImmutableArray<TToken>> ListInvalidAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) public virtual Task<ImmutableArray<TToken>> ListInvalidAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
IQueryable<TToken> Query(IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TToken> tokens, int? skip, int? take)
{ {
var query = (from token in tokens var query = (from token in tokens
where token.ExpirationDate < DateTimeOffset.UtcNow || where token.ExpirationDate < DateTimeOffset.UtcNow ||
@ -513,20 +504,22 @@ namespace OpenIddict.Core
orderby token.Id orderby token.Id
select token).AsQueryable(); 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 query;
} }
return ListAsync(Query, cancellationToken); return ListAsync(
(tokens, state) => Query(tokens, state.Key, state.Value),
new KeyValuePair<int?, int?>(offset, count), cancellationToken);
} }
/// <summary> /// <summary>

32
src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs

@ -150,18 +150,14 @@ namespace OpenIddict.EntityFramework
} }
Task<List<TAuthorization>> ListAuthorizationsAsync() Task<List<TAuthorization>> ListAuthorizationsAsync()
{ => (from authorization in Authorizations.Include(authorization => authorization.Tokens)
return (from authorization in Authorizations.Include(authorization => authorization.Tokens) where authorization.Application.Id.Equals(application.Id)
where authorization.Application.Id.Equals(application.Id) select authorization).ToListAsync(cancellationToken);
select authorization).ToListAsync(cancellationToken);
}
Task<List<TToken>> ListTokensAsync() Task<List<TToken>> ListTokensAsync()
{ => (from token in Tokens
return (from token in Tokens where token.Application.Id.Equals(application.Id)
where token.Application.Id.Equals(application.Id) select token).ToListAsync(cancellationToken);
select token).ToListAsync(cancellationToken);
}
// Remove all the authorizations associated with the application and // Remove all the authorizations associated with the application and
// the tokens attached to these implicit or explicit authorizations. // the tokens attached to these implicit or explicit authorizations.
@ -208,41 +204,49 @@ namespace OpenIddict.EntityFramework
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return query(Applications).FirstOrDefaultAsync(cancellationToken); return query(Applications, state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return ImmutableArray.CreateRange(await query(Applications).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await query(Applications, state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

24
src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs

@ -150,11 +150,9 @@ namespace OpenIddict.EntityFramework
} }
Task<List<TToken>> ListTokensAsync() Task<List<TToken>> ListTokensAsync()
{ => (from token in Tokens
return (from token in Tokens where token.Application.Id.Equals(authorization.Id)
where token.Application.Id.Equals(authorization.Id) select token).ToListAsync(cancellationToken);
select token).ToListAsync(cancellationToken);
}
// Remove all the tokens associated with the application. // Remove all the tokens associated with the application.
foreach (var token in await ListTokensAsync()) foreach (var token in await ListTokensAsync())
@ -235,34 +233,42 @@ namespace OpenIddict.EntityFramework
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return query(Authorizations.Include(authorization => authorization.Application)).FirstOrDefaultAsync(cancellationToken); return query(Authorizations.Include(authorization => authorization.Application), state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
@ -270,7 +276,7 @@ namespace OpenIddict.EntityFramework
} }
return ImmutableArray.CreateRange(await query( return ImmutableArray.CreateRange(await query(
Authorizations.Include(authorization => authorization.Application)).ToListAsync(cancellationToken)); Authorizations.Include(authorization => authorization.Application), state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

16
src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs

@ -137,41 +137,49 @@ namespace OpenIddict.EntityFramework
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return query(Scopes).FirstOrDefaultAsync(cancellationToken); return query(Scopes, state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return ImmutableArray.CreateRange(await query(Scopes).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await query(Scopes, state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

16
src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs

@ -219,14 +219,18 @@ namespace OpenIddict.EntityFramework
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
@ -235,7 +239,7 @@ namespace OpenIddict.EntityFramework
return query( return query(
Tokens.Include(token => token.Application) Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).FirstOrDefaultAsync(cancellationToken); .Include(token => token.Authorization), state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
@ -277,14 +281,18 @@ namespace OpenIddict.EntityFramework
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
@ -293,7 +301,7 @@ namespace OpenIddict.EntityFramework
return ImmutableArray.CreateRange(await query( return ImmutableArray.CreateRange(await query(
Tokens.Include(token => token.Application) Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).ToListAsync(cancellationToken)); .Include(token => token.Authorization), state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

32
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs

@ -150,18 +150,14 @@ namespace OpenIddict.EntityFrameworkCore
} }
Task<List<TAuthorization>> ListAuthorizationsAsync() Task<List<TAuthorization>> ListAuthorizationsAsync()
{ => (from authorization in Authorizations.Include(authorization => authorization.Tokens)
return (from authorization in Authorizations.Include(authorization => authorization.Tokens) where authorization.Application.Id.Equals(application.Id)
where authorization.Application.Id.Equals(application.Id) select authorization).ToListAsync(cancellationToken);
select authorization).ToListAsync(cancellationToken);
}
Task<List<TToken>> ListTokensAsync() Task<List<TToken>> ListTokensAsync()
{ => (from token in Tokens
return (from token in Tokens where token.Application.Id.Equals(application.Id)
where token.Application.Id.Equals(application.Id) select token).ToListAsync(cancellationToken);
select token).ToListAsync(cancellationToken);
}
// Remove all the authorizations associated with the application and // Remove all the authorizations associated with the application and
// the tokens attached to these implicit or explicit authorizations. // the tokens attached to these implicit or explicit authorizations.
@ -189,41 +185,49 @@ namespace OpenIddict.EntityFrameworkCore
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return query(Applications).FirstOrDefaultAsync(cancellationToken); return query(Applications, state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TApplication>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TApplication>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return ImmutableArray.CreateRange(await query(Applications).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await query(Applications, state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

43
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs

@ -150,11 +150,9 @@ namespace OpenIddict.EntityFrameworkCore
} }
Task<List<TToken>> ListTokensAsync() Task<List<TToken>> ListTokensAsync()
{ => (from token in Tokens
return (from token in Tokens where token.Application.Id.Equals(authorization.Id)
where token.Application.Id.Equals(authorization.Id) select token).ToListAsync(cancellationToken);
select token).ToListAsync(cancellationToken);
}
// Remove all the tokens associated with the application. // Remove all the tokens associated with the application.
foreach (var token in await ListTokensAsync()) 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. // 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. // See https://github.com/openiddict/openiddict-core/issues/499 for more information.
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations, IQueryable<TApplication> applications) IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations, IQueryable<TApplication> applications, TKey key, string principal)
{ => from authorization in authorizations.Include(authorization => authorization.Application)
var key = ConvertIdentifierFromString(client); where authorization.Subject == principal
join application in applications on authorization.Application.Id equals application.Id
return from authorization in authorizations.Include(authorization => authorization.Application) where application.Id.Equals(key)
where authorization.Subject == subject select authorization;
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));
} }
/// <summary> /// <summary>
@ -241,34 +236,42 @@ namespace OpenIddict.EntityFrameworkCore
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return query(Authorizations.Include(authorization => authorization.Application)).FirstOrDefaultAsync(cancellationToken); return query(Authorizations.Include(authorization => authorization.Application), state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TAuthorization>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TAuthorization>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
@ -276,7 +279,7 @@ namespace OpenIddict.EntityFrameworkCore
} }
return ImmutableArray.CreateRange(await query( return ImmutableArray.CreateRange(await query(
Authorizations.Include(authorization => authorization.Application)).ToListAsync(cancellationToken)); Authorizations.Include(authorization => authorization.Application), state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

16
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs

@ -137,41 +137,49 @@ namespace OpenIddict.EntityFrameworkCore
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return query(Scopes).FirstOrDefaultAsync(cancellationToken); return query(Scopes, state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TScope>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TScope>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
} }
return ImmutableArray.CreateRange(await query(Scopes).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await query(Scopes, state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

52
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. // 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. // See https://github.com/openiddict/openiddict-core/issues/499 for more information.
IQueryable<TToken> Query(IQueryable<TApplication> applications, IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TApplication> applications, IQueryable<TToken> tokens, TKey key)
{ => from token in tokens.Include(token => token.Application).Include(token => token.Authorization)
var key = ConvertIdentifierFromString(identifier); join application in applications on token.Application.Id equals application.Id
where application.Id.Equals(key)
return from token in tokens.Include(token => token.Application).Include(token => token.Authorization) select token;
join application in applications on token.Application.Id equals application.Id
where application.Id.Equals(key) return ImmutableArray.CreateRange(await Query(
select token; Applications, Tokens, ConvertIdentifierFromString(identifier)).ToListAsync(cancellationToken));
}
return ImmutableArray.CreateRange(await Query(Applications, Tokens).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>
@ -206,17 +203,14 @@ namespace OpenIddict.EntityFrameworkCore
// this method is overriden to use an explicit join before applying the equality check. // 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. // See https://github.com/openiddict/openiddict-core/issues/499 for more information.
IQueryable<TToken> Query(IQueryable<TAuthorization> authorizations, IQueryable<TToken> tokens) IQueryable<TToken> Query(IQueryable<TAuthorization> authorizations, IQueryable<TToken> tokens, TKey key)
{ => from token in tokens.Include(token => token.Application).Include(token => token.Authorization)
var key = ConvertIdentifierFromString(identifier); join authorization in authorizations on token.Authorization.Id equals authorization.Id
where authorization.Id.Equals(key)
return from token in tokens.Include(token => token.Application).Include(token => token.Authorization) select token;
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));
} }
/// <summary> /// <summary>
@ -251,14 +245,18 @@ namespace OpenIddict.EntityFrameworkCore
/// <summary> /// <summary>
/// Executes the specified query and returns the first element. /// Executes the specified query and returns the first element.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the first element returned when executing the query. /// whose result returns the first element returned when executing the query.
/// </returns> /// </returns>
public override Task<TResult> GetAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override Task<TResult> GetAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
@ -267,20 +265,24 @@ namespace OpenIddict.EntityFrameworkCore
return query( return query(
Tokens.Include(token => token.Application) Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).FirstOrDefaultAsync(cancellationToken); .Include(token => token.Authorization), state).FirstOrDefaultAsync(cancellationToken);
} }
/// <summary> /// <summary>
/// Executes the specified query and returns all the corresponding elements. /// Executes the specified query and returns all the corresponding elements.
/// </summary> /// </summary>
/// <typeparam name="TState">The state type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam> /// <typeparam name="TResult">The result type.</typeparam>
/// <param name="query">The query to execute.</param> /// <param name="query">The query to execute.</param>
/// <param name="state">The optional state.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns> /// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, /// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns all the elements returned when executing the specified query. /// whose result returns all the elements returned when executing the specified query.
/// </returns> /// </returns>
public override async Task<ImmutableArray<TResult>> ListAsync<TResult>([NotNull] Func<IQueryable<TToken>, IQueryable<TResult>> query, CancellationToken cancellationToken) public override async Task<ImmutableArray<TResult>> ListAsync<TState, TResult>(
[NotNull] Func<IQueryable<TToken>, TState, IQueryable<TResult>> query,
[CanBeNull] TState state, CancellationToken cancellationToken)
{ {
if (query == null) if (query == null)
{ {
@ -289,7 +291,7 @@ namespace OpenIddict.EntityFrameworkCore
return ImmutableArray.CreateRange(await query( return ImmutableArray.CreateRange(await query(
Tokens.Include(token => token.Application) Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).ToListAsync(cancellationToken)); .Include(token => token.Authorization), state).ToListAsync(cancellationToken));
} }
/// <summary> /// <summary>

Loading…
Cancel
Save