|
|
|
@ -15,7 +15,6 @@ using System.Threading.Tasks; |
|
|
|
using JetBrains.Annotations; |
|
|
|
using Microsoft.EntityFrameworkCore; |
|
|
|
using Microsoft.EntityFrameworkCore.Infrastructure; |
|
|
|
using Microsoft.EntityFrameworkCore.Query; |
|
|
|
using Microsoft.EntityFrameworkCore.Storage; |
|
|
|
using Microsoft.Extensions.Caching.Memory; |
|
|
|
using Microsoft.Extensions.Options; |
|
|
|
@ -197,32 +196,6 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the tokens corresponding
|
|
|
|
/// to the specified subject and associated with the application identifier.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly |
|
|
|
#if SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
Func<TContext, TKey, string, IAsyncEnumerable<TToken>> |
|
|
|
#else
|
|
|
|
Func<TContext, TKey, string, AsyncEnumerable<TToken>> |
|
|
|
#endif
|
|
|
|
FindBySubjectAndClient = |
|
|
|
|
|
|
|
// Note: due to a bug in Entity Framework Core's query visitor, the authorizations can't be
|
|
|
|
// filtered using token.Application.Id.Equals(key). To work around this issue,
|
|
|
|
// this compiled query uses an explicit join before applying the equality check.
|
|
|
|
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
|
|
|
|
EF.CompileAsyncQuery((TContext context, TKey identifier, string subject) => |
|
|
|
from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
where token.Subject == subject |
|
|
|
join application in context.Set<TApplication>().AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(identifier) |
|
|
|
select token); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the tokens corresponding to the specified
|
|
|
|
/// subject and associated with the application identifier.
|
|
|
|
@ -244,37 +217,19 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
throw new ArgumentException("The client cannot be null or empty.", nameof(client)); |
|
|
|
} |
|
|
|
|
|
|
|
return FindBySubjectAndClient(Context, ConvertIdentifierFromString(client), subject) |
|
|
|
#if !SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
.AsAsyncEnumerable(cancellationToken) |
|
|
|
#endif
|
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the tokens matching the specified parameters.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly |
|
|
|
#if SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
Func<TContext, TKey, string, string, IAsyncEnumerable<TToken>> |
|
|
|
#else
|
|
|
|
Func<TContext, TKey, string, string, AsyncEnumerable<TToken>> |
|
|
|
#endif
|
|
|
|
FindBySubjectClientAndStatus = |
|
|
|
|
|
|
|
// Note: due to a bug in Entity Framework Core's query visitor, the authorizations can't be
|
|
|
|
// filtered using token.Application.Id.Equals(key). To work around this issue,
|
|
|
|
// this compiled query uses an explicit join before applying the equality check.
|
|
|
|
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
|
|
|
|
EF.CompileAsyncQuery((TContext context, TKey identifier, string subject, string status) => |
|
|
|
from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
where token.Subject == subject && token.Status == status |
|
|
|
join application in context.Set<TApplication>().AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(identifier) |
|
|
|
select token); |
|
|
|
|
|
|
|
var key = ConvertIdentifierFromString(client); |
|
|
|
|
|
|
|
return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
where token.Subject == subject |
|
|
|
join application in Applications.AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(key) |
|
|
|
select token).AsAsyncEnumerable(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the tokens matching the specified parameters.
|
|
|
|
@ -303,39 +258,20 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
throw new ArgumentException("The status cannot be null or empty.", nameof(status)); |
|
|
|
} |
|
|
|
|
|
|
|
return FindBySubjectClientAndStatus(Context, ConvertIdentifierFromString(client), subject, status) |
|
|
|
#if !SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
.AsAsyncEnumerable(cancellationToken) |
|
|
|
#endif
|
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the tokens matching the specified parameters.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly |
|
|
|
#if SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
Func<TContext, TKey, string, string, string, IAsyncEnumerable<TToken>> |
|
|
|
#else
|
|
|
|
Func<TContext, TKey, string, string, string, AsyncEnumerable<TToken>> |
|
|
|
#endif
|
|
|
|
FindBySubjectClientStatusAndType = |
|
|
|
|
|
|
|
// Note: due to a bug in Entity Framework Core's query visitor, the authorizations can't be
|
|
|
|
// filtered using token.Application.Id.Equals(key). To work around this issue,
|
|
|
|
// this compiled query uses an explicit join before applying the equality check.
|
|
|
|
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
|
|
|
|
EF.CompileAsyncQuery((TContext context, TKey identifier, string subject, string status, string type) => |
|
|
|
from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
where token.Subject == subject && |
|
|
|
token.Status == status && |
|
|
|
token.Type == type |
|
|
|
join application in context.Set<TApplication>().AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(identifier) |
|
|
|
select token); |
|
|
|
|
|
|
|
var key = ConvertIdentifierFromString(client); |
|
|
|
|
|
|
|
return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
where token.Subject == subject && |
|
|
|
token.Status == status |
|
|
|
join application in Applications.AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(key) |
|
|
|
select token).AsAsyncEnumerable(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the tokens matching the specified parameters.
|
|
|
|
@ -370,37 +306,21 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
throw new ArgumentException("The type cannot be null or empty.", nameof(type)); |
|
|
|
} |
|
|
|
|
|
|
|
return FindBySubjectClientStatusAndType(Context, ConvertIdentifierFromString(client), subject, status, type) |
|
|
|
#if !SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
.AsAsyncEnumerable(cancellationToken) |
|
|
|
#endif
|
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the list of
|
|
|
|
/// tokens corresponding to the specified application identifier.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly |
|
|
|
#if SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
Func<TContext, TKey, IAsyncEnumerable<TToken>> |
|
|
|
#else
|
|
|
|
Func<TContext, TKey, AsyncEnumerable<TToken>> |
|
|
|
#endif
|
|
|
|
FindByApplicationId = |
|
|
|
|
|
|
|
// Note: due to a bug in Entity Framework Core's query visitor, the tokens can't be
|
|
|
|
// Note: due to a bug in Entity Framework Core's query visitor, the authorizations can't be
|
|
|
|
// filtered using token.Application.Id.Equals(key). To work around this issue,
|
|
|
|
// this compiled query uses an explicit join before applying the equality check.
|
|
|
|
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
|
|
|
|
EF.CompileAsyncQuery((TContext context, TKey identifier) => |
|
|
|
from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
join application in context.Set<TApplication>().AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(identifier) |
|
|
|
select token); |
|
|
|
|
|
|
|
var key = ConvertIdentifierFromString(client); |
|
|
|
|
|
|
|
return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
where token.Subject == subject && |
|
|
|
token.Status == status && |
|
|
|
token.Type == type |
|
|
|
join application in Applications.AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(key) |
|
|
|
select token).AsAsyncEnumerable(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the list of tokens corresponding to the specified application identifier.
|
|
|
|
@ -415,37 +335,18 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); |
|
|
|
} |
|
|
|
|
|
|
|
return FindByApplicationId(Context, ConvertIdentifierFromString(identifier)) |
|
|
|
#if !SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
.AsAsyncEnumerable(cancellationToken) |
|
|
|
#endif
|
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the list of
|
|
|
|
/// tokens corresponding to the specified authorization identifier.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly |
|
|
|
#if SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
Func<TContext, TKey, IAsyncEnumerable<TToken>> |
|
|
|
#else
|
|
|
|
Func<TContext, TKey, AsyncEnumerable<TToken>> |
|
|
|
#endif
|
|
|
|
FindByAuthorizationId = |
|
|
|
|
|
|
|
// Note: due to a bug in Entity Framework Core's query visitor, the tokens can't be
|
|
|
|
// filtered using token.Authorization.Id.Equals(key). To work around this issue,
|
|
|
|
// this compiled query uses an explicit join before applying the equality check.
|
|
|
|
// filtered using token.Application.Id.Equals(key). To work around this issue,
|
|
|
|
// 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.
|
|
|
|
EF.CompileAsyncQuery((TContext context, TKey identifier) => |
|
|
|
from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
join authorization in context.Set<TAuthorization>().AsTracking() on token.Authorization.Id equals authorization.Id |
|
|
|
where authorization.Id.Equals(identifier) |
|
|
|
select token); |
|
|
|
|
|
|
|
var key = ConvertIdentifierFromString(identifier); |
|
|
|
|
|
|
|
return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
join application in Applications.AsTracking() on token.Application.Id equals application.Id |
|
|
|
where application.Id.Equals(key) |
|
|
|
select token).AsAsyncEnumerable(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the list of tokens corresponding to the specified authorization identifier.
|
|
|
|
@ -460,24 +361,18 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); |
|
|
|
} |
|
|
|
|
|
|
|
return FindByAuthorizationId(Context, ConvertIdentifierFromString(identifier)) |
|
|
|
#if !SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
.AsAsyncEnumerable(cancellationToken) |
|
|
|
#endif
|
|
|
|
; |
|
|
|
} |
|
|
|
// Note: due to a bug in Entity Framework Core's query visitor, the tokens can't be
|
|
|
|
// filtered using token.Authorization.Id.Equals(key). To work around this issue,
|
|
|
|
// 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.
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve a token using its unique identifier.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly Func<TContext, TKey, Task<TToken>> FindById = |
|
|
|
EF.CompileAsyncQuery((TContext context, TKey identifier) => |
|
|
|
(from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
where token.Id.Equals(identifier) |
|
|
|
select token).FirstOrDefault()); |
|
|
|
var key = ConvertIdentifierFromString(identifier); |
|
|
|
|
|
|
|
return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
join authorization in Authorizations.AsTracking() on token.Authorization.Id equals authorization.Id |
|
|
|
where authorization.Id.Equals(key) |
|
|
|
select token).AsAsyncEnumerable(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves a token using its unique identifier.
|
|
|
|
@ -488,28 +383,19 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation,
|
|
|
|
/// whose result returns the token corresponding to the unique identifier.
|
|
|
|
/// </returns>
|
|
|
|
public virtual ValueTask<TToken> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) |
|
|
|
public virtual async ValueTask<TToken> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
if (string.IsNullOrEmpty(identifier)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); |
|
|
|
} |
|
|
|
|
|
|
|
return new ValueTask<TToken>(FindById(Context, ConvertIdentifierFromString(identifier))); |
|
|
|
} |
|
|
|
var key = ConvertIdentifierFromString(identifier); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the list of
|
|
|
|
/// tokens corresponding to the specified reference identifier.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly Func<TContext, string, Task<TToken>> FindByReferenceId = |
|
|
|
EF.CompileAsyncQuery((TContext context, string identifier) => |
|
|
|
(from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
where token.ReferenceId == identifier |
|
|
|
select token).FirstOrDefault()); |
|
|
|
return await (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
where token.Id.Equals(key) |
|
|
|
select token).FirstOrDefaultAsync(cancellationToken); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the list of tokens corresponding to the specified reference identifier.
|
|
|
|
@ -521,34 +407,18 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation,
|
|
|
|
/// whose result returns the tokens corresponding to the specified reference identifier.
|
|
|
|
/// </returns>
|
|
|
|
public virtual ValueTask<TToken> FindByReferenceIdAsync([NotNull] string identifier, CancellationToken cancellationToken) |
|
|
|
public virtual async ValueTask<TToken> FindByReferenceIdAsync([NotNull] string identifier, CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
if (string.IsNullOrEmpty(identifier)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); |
|
|
|
} |
|
|
|
|
|
|
|
return new ValueTask<TToken>(FindByReferenceId(Context, identifier)); |
|
|
|
return await (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
where token.ReferenceId == identifier |
|
|
|
select token).FirstOrDefaultAsync(cancellationToken); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the
|
|
|
|
/// list of tokens corresponding to the specified subject.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly |
|
|
|
#if SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
Func<TContext, string, IAsyncEnumerable<TToken>> |
|
|
|
#else
|
|
|
|
Func<TContext, string, AsyncEnumerable<TToken>> |
|
|
|
#endif
|
|
|
|
FindBySubject = EF.CompileAsyncQuery((TContext context, string subject) => |
|
|
|
from token in context.Set<TToken>() |
|
|
|
.Include(token => token.Application) |
|
|
|
.Include(token => token.Authorization) |
|
|
|
.AsTracking() |
|
|
|
where token.Subject == subject |
|
|
|
select token); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the list of tokens corresponding to the specified subject.
|
|
|
|
/// </summary>
|
|
|
|
@ -562,11 +432,9 @@ namespace OpenIddict.EntityFrameworkCore |
|
|
|
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); |
|
|
|
} |
|
|
|
|
|
|
|
return FindBySubject(Context, subject) |
|
|
|
#if !SUPPORTS_BCL_ASYNC_ENUMERABLE
|
|
|
|
.AsAsyncEnumerable(cancellationToken) |
|
|
|
#endif
|
|
|
|
; |
|
|
|
return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() |
|
|
|
where token.Subject == subject |
|
|
|
select token).AsAsyncEnumerable(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|