|
|
|
@ -202,6 +202,165 @@ 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 Func<TContext, TKey, string, AsyncEnumerable<TToken>> 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.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="subject">The subject associated with the token.</param>
|
|
|
|
/// <param name="client">The client associated with the token.</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 tokens corresponding to the subject/client.
|
|
|
|
/// </returns>
|
|
|
|
public virtual async Task<ImmutableArray<TToken>> FindAsync([NotNull] string subject, |
|
|
|
[NotNull] string client, CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
if (string.IsNullOrEmpty(subject)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); |
|
|
|
} |
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(client)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The client cannot be null or empty.", nameof(client)); |
|
|
|
} |
|
|
|
|
|
|
|
return ImmutableArray.CreateRange(await FindBySubjectAndClient(Context, |
|
|
|
ConvertIdentifierFromString(client), subject).ToListAsync(cancellationToken)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the tokens matching the specified parameters.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly Func<TContext, TKey, string, string, AsyncEnumerable<TToken>> 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); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the tokens matching the specified parameters.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="subject">The subject associated with the token.</param>
|
|
|
|
/// <param name="client">The client associated with the token.</param>
|
|
|
|
/// <param name="status">The token status.</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 tokens corresponding to the criteria.
|
|
|
|
/// </returns>
|
|
|
|
public virtual async Task<ImmutableArray<TToken>> FindAsync( |
|
|
|
[NotNull] string subject, [NotNull] string client, |
|
|
|
[NotNull] string status, CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
if (string.IsNullOrEmpty(subject)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); |
|
|
|
} |
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(client)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client)); |
|
|
|
} |
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(status)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The status cannot be null or empty.", nameof(status)); |
|
|
|
} |
|
|
|
|
|
|
|
return ImmutableArray.CreateRange(await FindBySubjectClientAndStatus(Context, |
|
|
|
ConvertIdentifierFromString(client), subject, status).ToListAsync(cancellationToken)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the tokens matching the specified parameters.
|
|
|
|
/// </summary>
|
|
|
|
private static readonly Func<TContext, TKey, string, string, string, AsyncEnumerable<TToken>> 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); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the tokens matching the specified parameters.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="subject">The subject associated with the token.</param>
|
|
|
|
/// <param name="client">The client associated with the token.</param>
|
|
|
|
/// <param name="status">The token status.</param>
|
|
|
|
/// <param name="type">The token type.</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 tokens corresponding to the criteria.
|
|
|
|
/// </returns>
|
|
|
|
public virtual async Task<ImmutableArray<TToken>> FindAsync( |
|
|
|
[NotNull] string subject, [NotNull] string client, |
|
|
|
[NotNull] string status, [NotNull] string type, CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
if (string.IsNullOrEmpty(subject)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject)); |
|
|
|
} |
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(client)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client)); |
|
|
|
} |
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(status)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The status cannot be null or empty.", nameof(status)); |
|
|
|
} |
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(type)) |
|
|
|
{ |
|
|
|
throw new ArgumentException("The type cannot be null or empty.", nameof(type)); |
|
|
|
} |
|
|
|
|
|
|
|
return ImmutableArray.CreateRange(await FindBySubjectClientStatusAndType(Context, |
|
|
|
ConvertIdentifierFromString(client), subject, status, type).ToListAsync(cancellationToken)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Exposes a compiled query allowing to retrieve the list of
|
|
|
|
/// tokens corresponding to the specified application identifier.
|
|
|
|
|