Browse Source

Update the authorizations/tokens stores to eagerly load the associated applications/authorizations

pull/516/head
Kévin Chalet 9 years ago
parent
commit
02d5ff7100
  1. 13
      src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
  2. 26
      src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
  3. 57
      src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
  4. 100
      src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
  5. 59
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
  6. 104
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

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

@ -160,12 +160,15 @@ namespace OpenIddict.Core
return ConvertIdentifierToString(authorization.Application.Id);
}
var key = await GetAsync(authorizations =>
from element in authorizations
where element.Id.Equals(authorization.Id)
select element.Application.Id, cancellationToken);
IQueryable<TKey> Query(IQueryable<TAuthorization> authorizations)
{
return from element in authorizations
where element.Id.Equals(authorization.Id)
where element.Application != null
select element.Application.Id;
}
return ConvertIdentifierToString(key);
return ConvertIdentifierToString(await GetAsync(Query, cancellationToken));
}
/// <summary>

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

@ -243,12 +243,15 @@ namespace OpenIddict.Core
return ConvertIdentifierToString(token.Application.Id);
}
var key = await GetAsync(tokens =>
from element in tokens
where element.Id.Equals(token.Id)
select element.Application.Id, cancellationToken);
IQueryable<TKey> Query(IQueryable<TToken> tokens)
{
return from element in tokens
where element.Id.Equals(token.Id)
where element.Application != null
select element.Application.Id;
}
return ConvertIdentifierToString(key);
return ConvertIdentifierToString(await GetAsync(Query, cancellationToken));
}
/// <summary>
@ -272,12 +275,15 @@ namespace OpenIddict.Core
return ConvertIdentifierToString(token.Authorization.Id);
}
var key = await GetAsync(tokens =>
from element in tokens
where element.Id.Equals(token.Id)
select element.Authorization.Id, cancellationToken);
IQueryable<TKey> Query(IQueryable<TToken> tokens)
{
return from element in tokens
where element.Id.Equals(token.Id)
where element.Authorization != null
select element.Authorization.Id;
}
return ConvertIdentifierToString(key);
return ConvertIdentifierToString(await GetAsync(Query, cancellationToken));
}
/// <summary>

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

@ -183,7 +183,17 @@ namespace OpenIddict.EntityFramework
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Authorizations.FindAsync(cancellationToken, ConvertIdentifierFromString(identifier));
var authorization = (from entry in Context.ChangeTracker.Entries<TAuthorization>()
where entry.Entity != null
where entry.Entity.Id.Equals(ConvertIdentifierFromString(identifier))
select entry.Entity).FirstOrDefault();
if (authorization != null)
{
return Task.FromResult(authorization);
}
return base.FindByIdAsync(identifier, cancellationToken);
}
/// <summary>
@ -202,17 +212,21 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(authorization));
}
// If the application is not attached to the authorization instance (which is expected
// if the token was retrieved using the default FindBy*Async APIs as they don't
// eagerly load the application from the database), try to load it manually.
// If the application is not attached to the authorization, try to load it manually.
if (authorization.Application == null)
{
var reference = Context.Entry(authorization).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return null;
}
await reference.LoadAsync(cancellationToken);
}
if (authorization.Application == null)
{
return ConvertIdentifierToString(
await Context.Entry(authorization)
.Reference(entry => entry.Application)
.Query()
.Select(application => application.Id)
.FirstOrDefaultAsync());
return null;
}
return ConvertIdentifierToString(authorization.Application.Id);
@ -235,7 +249,7 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(query));
}
return query(Authorizations).FirstOrDefaultAsync(cancellationToken);
return query(Authorizations.Include(authorization => authorization.Application)).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -255,7 +269,8 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(query));
}
return ImmutableArray.CreateRange(await query(Authorizations).ToListAsync(cancellationToken));
return ImmutableArray.CreateRange(await query(
Authorizations.Include(authorization => authorization.Application)).ToListAsync(cancellationToken));
}
/// <summary>
@ -287,15 +302,19 @@ namespace OpenIddict.EntityFramework
else
{
var key = await GetIdAsync(authorization, cancellationToken);
// Try to retrieve the application associated with the authorization.
// If none can be found, assume that no application is attached.
var application = await Applications.FirstOrDefaultAsync(element => element.Authorizations.Any(t => t.Id.Equals(key)));
if (application != null)
// If the application is not attached to the authorization, try to load it manually.
if (authorization.Application == null)
{
application.Authorizations.Remove(authorization);
var reference = Context.Entry(authorization).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return;
}
await reference.LoadAsync(cancellationToken);
}
authorization.Application = null;
}
}

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

@ -167,7 +167,17 @@ namespace OpenIddict.EntityFramework
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Tokens.FindAsync(cancellationToken, ConvertIdentifierFromString(identifier));
var token = (from entry in Context.ChangeTracker.Entries<TToken>()
where entry.Entity != null
where entry.Entity.Id.Equals(ConvertIdentifierFromString(identifier))
select entry.Entity).FirstOrDefault();
if (token != null)
{
return Task.FromResult(token);
}
return base.FindByIdAsync(identifier, cancellationToken);
}
/// <summary>
@ -186,17 +196,21 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(token));
}
// If the application is not attached to the token instance (which is expected
// if the token was retrieved using the default FindBy*Async APIs as they don't
// eagerly load the application from the database), try to load it manually.
// If the application is not attached to the token, try to load it manually.
if (token.Application == null)
{
var reference = Context.Entry(token).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return null;
}
await reference.LoadAsync(cancellationToken);
}
if (token.Application == null)
{
return ConvertIdentifierToString(
await Context.Entry(token)
.Reference(entry => entry.Application)
.Query()
.Select(application => application.Id)
.FirstOrDefaultAsync());
return null;
}
return ConvertIdentifierToString(token.Application.Id);
@ -219,7 +233,9 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(query));
}
return query(Tokens).FirstOrDefaultAsync(cancellationToken);
return query(
Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -238,17 +254,21 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(token));
}
// If the authorization is not attached to the token instance (which is expected
// if the token was retrieved using the default FindBy*Async APIs as they don't
// eagerly load the authorization from the database), try to load it manually.
// If the authorization is not attached to the token, try to load it manually.
if (token.Authorization == null)
{
var reference = Context.Entry(token).Reference(entry => entry.Authorization);
if (reference.EntityEntry.State == EntityState.Detached)
{
return null;
}
await reference.LoadAsync(cancellationToken);
}
if (token.Authorization == null)
{
return ConvertIdentifierToString(
await Context.Entry(token)
.Reference(entry => entry.Authorization)
.Query()
.Select(authorization => authorization.Id)
.FirstOrDefaultAsync());
return null;
}
return ConvertIdentifierToString(token.Authorization.Id);
@ -271,7 +291,9 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(query));
}
return ImmutableArray.CreateRange(await query(Tokens).ToListAsync(cancellationToken));
return ImmutableArray.CreateRange(await query(
Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).ToListAsync(cancellationToken));
}
/// <summary>
@ -303,15 +325,19 @@ namespace OpenIddict.EntityFramework
else
{
var key = await GetIdAsync(token, cancellationToken);
// Try to retrieve the application associated with the token.
// If none can be found, assume that no application is attached.
var application = await Applications.FirstOrDefaultAsync(element => element.Tokens.Any(t => t.Id.Equals(key)));
if (application != null)
// If the application is not attached to the token, try to load it manually.
if (token.Application == null)
{
application.Tokens.Remove(token);
var reference = Context.Entry(token).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return;
}
await reference.LoadAsync(cancellationToken);
}
token.Application = null;
}
}
@ -344,15 +370,19 @@ namespace OpenIddict.EntityFramework
else
{
var key = await GetIdAsync(token, cancellationToken);
// Try to retrieve the authorization associated with the token.
// If none can be found, assume that no authorization is attached.
var authorization = await Authorizations.FirstOrDefaultAsync(element => element.Tokens.Any(t => t.Id.Equals(key)));
if (authorization != null)
// If the authorization is not attached to the token, try to load it manually.
if (token.Authorization == null)
{
authorization.Tokens.Remove(token);
var reference = Context.Entry(token).Reference(entry => entry.Authorization);
if (reference.EntityEntry.State == EntityState.Detached)
{
return;
}
await reference.LoadAsync(cancellationToken);
}
token.Authorization = null;
}
}

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

@ -199,7 +199,7 @@ namespace OpenIddict.EntityFrameworkCore
{
var key = ConvertIdentifierFromString(client);
return from authorization in authorizations
return from authorization in authorizations.Include(authorization => authorization.Application)
where authorization.Subject == subject
join application in applications on authorization.Application.Id equals application.Id
where application.Id.Equals(key)
@ -225,7 +225,17 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Authorizations.FindAsync(new object[] { ConvertIdentifierFromString(identifier) }, cancellationToken);
var authorization = (from entry in Context.ChangeTracker.Entries<TAuthorization>()
where entry.Entity != null
where entry.Entity.Id.Equals(ConvertIdentifierFromString(identifier))
select entry.Entity).FirstOrDefault();
if (authorization != null)
{
return Task.FromResult(authorization);
}
return base.FindByIdAsync(identifier, cancellationToken);
}
/// <summary>
@ -244,17 +254,21 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(authorization));
}
// If the application is not attached to the authorization instance (which is expected
// if the token was retrieved using the default FindBy*Async APIs as they don't
// eagerly load the application from the database), try to load it manually.
// If the application is not attached to the authorization, try to load it manually.
if (authorization.Application == null)
{
var reference = Context.Entry(authorization).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return null;
}
await reference.LoadAsync(cancellationToken);
}
if (authorization.Application == null)
{
return ConvertIdentifierToString(
await Context.Entry(authorization)
.Reference(entry => entry.Application)
.Query()
.Select(application => application.Id)
.FirstOrDefaultAsync());
return null;
}
return ConvertIdentifierToString(authorization.Application.Id);
@ -277,7 +291,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return query(Authorizations).FirstOrDefaultAsync(cancellationToken);
return query(Authorizations.Include(authorization => authorization.Application)).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -297,7 +311,8 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return ImmutableArray.CreateRange(await query(Authorizations).ToListAsync(cancellationToken));
return ImmutableArray.CreateRange(await query(
Authorizations.Include(authorization => authorization.Application)).ToListAsync(cancellationToken));
}
/// <summary>
@ -329,15 +344,19 @@ namespace OpenIddict.EntityFrameworkCore
else
{
var key = await GetIdAsync(authorization, cancellationToken);
// Try to retrieve the application associated with the authorization.
// If none can be found, assume that no application is attached.
var application = await Applications.FirstOrDefaultAsync(element => element.Authorizations.Any(t => t.Id.Equals(key)));
if (application != null)
// If the application is not attached to the authorization, try to load it manually.
if (authorization.Application == null)
{
application.Authorizations.Remove(authorization);
var reference = Context.Entry(authorization).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return;
}
await reference.LoadAsync(cancellationToken);
}
authorization.Application = null;
}
}

104
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

@ -176,7 +176,7 @@ namespace OpenIddict.EntityFrameworkCore
{
var key = ConvertIdentifierFromString(identifier);
return from token in tokens
return from token in tokens.Include(token => token.Application).Include(token => token.Authorization)
join application in applications on token.Application.Id equals application.Id
where application.Id.Equals(key)
select token;
@ -210,7 +210,7 @@ namespace OpenIddict.EntityFrameworkCore
{
var key = ConvertIdentifierFromString(identifier);
return from token in tokens
return from token in tokens.Include(token => token.Application).Include(token => token.Authorization)
join authorization in authorizations on token.Authorization.Id equals authorization.Id
where authorization.Id.Equals(key)
select token;
@ -235,7 +235,17 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Tokens.FindAsync(new object[] { ConvertIdentifierFromString(identifier) }, cancellationToken);
var token = (from entry in Context.ChangeTracker.Entries<TToken>()
where entry.Entity != null
where entry.Entity.Id.Equals(ConvertIdentifierFromString(identifier))
select entry.Entity).FirstOrDefault();
if (token != null)
{
return Task.FromResult(token);
}
return base.FindByIdAsync(identifier, cancellationToken);
}
/// <summary>
@ -254,17 +264,21 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(token));
}
// If the application is not attached to the token instance (which is expected
// if the token was retrieved using the default FindBy*Async APIs as they don't
// eagerly load the application from the database), try to load it manually.
// If the application is not attached to the token, try to load it manually.
if (token.Application == null)
{
var reference = Context.Entry(token).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return null;
}
await reference.LoadAsync(cancellationToken);
}
if (token.Application == null)
{
return ConvertIdentifierToString(
await Context.Entry(token)
.Reference(entry => entry.Application)
.Query()
.Select(application => application.Id)
.FirstOrDefaultAsync());
return null;
}
return ConvertIdentifierToString(token.Application.Id);
@ -287,7 +301,9 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return query(Tokens).FirstOrDefaultAsync(cancellationToken);
return query(
Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -306,17 +322,21 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(token));
}
// If the authorization is not attached to the token instance (which is expected
// if the token was retrieved using the default FindBy*Async APIs as they don't
// eagerly load the authorization from the database), try to load it manually.
// If the authorization is not attached to the token, try to load it manually.
if (token.Authorization == null)
{
var reference = Context.Entry(token).Reference(entry => entry.Authorization);
if (reference.EntityEntry.State == EntityState.Detached)
{
return null;
}
await reference.LoadAsync(cancellationToken);
}
if (token.Authorization == null)
{
return ConvertIdentifierToString(
await Context.Entry(token)
.Reference(entry => entry.Authorization)
.Query()
.Select(authorization => authorization.Id)
.FirstOrDefaultAsync());
return null;
}
return ConvertIdentifierToString(token.Authorization.Id);
@ -339,7 +359,9 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return ImmutableArray.CreateRange(await query(Tokens).ToListAsync(cancellationToken));
return ImmutableArray.CreateRange(await query(
Tokens.Include(token => token.Application)
.Include(token => token.Authorization)).ToListAsync(cancellationToken));
}
/// <summary>
@ -371,15 +393,19 @@ namespace OpenIddict.EntityFrameworkCore
else
{
var key = await GetIdAsync(token, cancellationToken);
// Try to retrieve the application associated with the token.
// If none can be found, assume that no application is attached.
var application = await Applications.FirstOrDefaultAsync(element => element.Tokens.Any(t => t.Id.Equals(key)));
if (application != null)
// If the application is not attached to the token, try to load it manually.
if (token.Application == null)
{
application.Tokens.Remove(token);
var reference = Context.Entry(token).Reference(entry => entry.Application);
if (reference.EntityEntry.State == EntityState.Detached)
{
return;
}
await reference.LoadAsync(cancellationToken);
}
token.Application = null;
}
}
@ -412,15 +438,19 @@ namespace OpenIddict.EntityFrameworkCore
else
{
var key = await GetIdAsync(token, cancellationToken);
// Try to retrieve the authorization associated with the token.
// If none can be found, assume that no authorization is attached.
var authorization = await Authorizations.FirstOrDefaultAsync(element => element.Tokens.Any(t => t.Id.Equals(key)));
if (authorization != null)
// If the authorization is not attached to the token, try to load it manually.
if (token.Authorization == null)
{
authorization.Tokens.Remove(token);
var reference = Context.Entry(token).Reference(entry => entry.Authorization);
if (reference.EntityEntry.State == EntityState.Detached)
{
return;
}
await reference.LoadAsync(cancellationToken);
}
token.Authorization = null;
}
}

Loading…
Cancel
Save