Browse Source

Backport the MongoDB stores changes to OpenIddict 1.x

pull/670/head
Kévin Chalet 9 years ago
parent
commit
5a441014d3
  1. 16
      src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs
  2. 35
      src/OpenIddict.MongoDb/Stores/OpenIddictApplicationStore.cs
  3. 39
      src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs
  4. 31
      src/OpenIddict.MongoDb/Stores/OpenIddictScopeStore.cs
  5. 35
      src/OpenIddict.MongoDb/Stores/OpenIddictTokenStore.cs

16
src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs

@ -21,12 +21,12 @@ namespace OpenIddict.MongoDb
/// </summary> /// </summary>
public class OpenIddictMongoDbContext : IOpenIddictMongoDbContext public class OpenIddictMongoDbContext : IOpenIddictMongoDbContext
{ {
private readonly IOptionsMonitor<OpenIddictMongoDbOptions> _options; private readonly IOptions<OpenIddictMongoDbOptions> _options;
private readonly IServiceProvider _provider; private readonly IServiceProvider _provider;
private IMongoDatabase _database; private IMongoDatabase _database;
public OpenIddictMongoDbContext( public OpenIddictMongoDbContext(
[NotNull] IOptionsMonitor<OpenIddictMongoDbOptions> options, [NotNull] IOptions<OpenIddictMongoDbOptions> options,
[NotNull] IServiceProvider provider) [NotNull] IServiceProvider provider)
{ {
_options = options; _options = options;
@ -47,14 +47,14 @@ namespace OpenIddict.MongoDb
return new ValueTask<IMongoDatabase>(_database); return new ValueTask<IMongoDatabase>(_database);
} }
var options = _options.CurrentValue;
if (options == null)
{
throw new InvalidOperationException("The OpenIddict MongoDB options cannot be retrieved.");
}
async Task<IMongoDatabase> ExecuteAsync() async Task<IMongoDatabase> ExecuteAsync()
{ {
var options = _options.Value;
if (options == null)
{
throw new InvalidOperationException("The OpenIddict MongoDB options cannot be retrieved.");
}
var database = options.Database; var database = options.Database;
if (database == null) if (database == null)
{ {

35
src/OpenIddict.MongoDb/Stores/OpenIddictApplicationStore.cs

@ -33,7 +33,7 @@ namespace OpenIddict.MongoDb
public OpenIddictApplicationStore( public OpenIddictApplicationStore(
[NotNull] IMemoryCache cache, [NotNull] IMemoryCache cache,
[NotNull] IOpenIddictMongoDbContext context, [NotNull] IOpenIddictMongoDbContext context,
[NotNull] IOptionsMonitor<OpenIddictMongoDbOptions> options) [NotNull] IOptions<OpenIddictMongoDbOptions> options)
{ {
Cache = cache; Cache = cache;
Context = context; Context = context;
@ -53,7 +53,7 @@ namespace OpenIddict.MongoDb
/// <summary> /// <summary>
/// Gets the options associated with the current store. /// Gets the options associated with the current store.
/// </summary> /// </summary>
protected IOptionsMonitor<OpenIddictMongoDbOptions> Options { get; } protected IOptions<OpenIddictMongoDbOptions> Options { get; }
/// <summary> /// <summary>
/// Determines the number of applications that exist in the database. /// Determines the number of applications that exist in the database.
@ -66,7 +66,7 @@ namespace OpenIddict.MongoDb
public virtual async Task<long> CountAsync(CancellationToken cancellationToken) public virtual async Task<long> CountAsync(CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return await collection.CountAsync(FilterDefinition<TApplication>.Empty); return await collection.CountAsync(FilterDefinition<TApplication>.Empty);
} }
@ -89,7 +89,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return await ((IMongoQueryable<TApplication>) query(collection.AsQueryable())).LongCountAsync(); return await ((IMongoQueryable<TApplication>) query(collection.AsQueryable())).LongCountAsync();
} }
@ -110,7 +110,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
await collection.InsertOneAsync(application, null, cancellationToken); await collection.InsertOneAsync(application, null, cancellationToken);
} }
@ -131,7 +131,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
if ((await collection.DeleteOneAsync(entity => if ((await collection.DeleteOneAsync(entity =>
entity.Id == application.Id && entity.Id == application.Id &&
@ -144,11 +144,11 @@ namespace OpenIddict.MongoDb
} }
// Delete the authorizations associated with the application. // Delete the authorizations associated with the application.
await database.GetCollection<OpenIddictAuthorization>(Options.CurrentValue.AuthorizationsCollectionName) await database.GetCollection<OpenIddictAuthorization>(Options.Value.AuthorizationsCollectionName)
.DeleteManyAsync(authorization => authorization.ApplicationId == application.Id, cancellationToken); .DeleteManyAsync(authorization => authorization.ApplicationId == application.Id, cancellationToken);
// Delete the tokens associated with the application. // Delete the tokens associated with the application.
await database.GetCollection<OpenIddictToken>(Options.CurrentValue.TokensCollectionName) await database.GetCollection<OpenIddictToken>(Options.Value.TokensCollectionName)
.DeleteManyAsync(token => token.ApplicationId == application.Id, cancellationToken); .DeleteManyAsync(token => token.ApplicationId == application.Id, cancellationToken);
} }
@ -169,7 +169,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return await collection.Find(application => application.ClientId == identifier).FirstOrDefaultAsync(cancellationToken); return await collection.Find(application => application.ClientId == identifier).FirstOrDefaultAsync(cancellationToken);
} }
@ -191,7 +191,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return await collection.Find(application => application.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken); return await collection.Find(application => application.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken);
} }
@ -213,7 +213,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return ImmutableArray.CreateRange(await collection.Find(application => return ImmutableArray.CreateRange(await collection.Find(application =>
application.PostLogoutRedirectUris.Contains(address)).ToListAsync(cancellationToken)); application.PostLogoutRedirectUris.Contains(address)).ToListAsync(cancellationToken));
@ -236,7 +236,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return ImmutableArray.CreateRange(await collection.Find(application => return ImmutableArray.CreateRange(await collection.Find(application =>
application.RedirectUris.Contains(address)).ToListAsync(cancellationToken)); application.RedirectUris.Contains(address)).ToListAsync(cancellationToken));
@ -264,7 +264,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken); return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken);
} }
@ -506,7 +506,7 @@ namespace OpenIddict.MongoDb
[CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
var query = (IMongoQueryable<TApplication>) collection.AsQueryable().OrderBy(application => application.Id); var query = (IMongoQueryable<TApplication>) collection.AsQueryable().OrderBy(application => application.Id);
@ -545,7 +545,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
return ImmutableArray.CreateRange( return ImmutableArray.CreateRange(
await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken)); await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken));
@ -794,14 +794,15 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it // Generate a new concurrency token and attach it
// to the application before persisting the changes. // to the application before persisting the changes.
var timestamp = application.ConcurrencyToken;
application.ConcurrencyToken = Guid.NewGuid().ToString(); application.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName); var collection = database.GetCollection<TApplication>(Options.Value.ApplicationsCollectionName);
if ((await collection.ReplaceOneAsync(entity => if ((await collection.ReplaceOneAsync(entity =>
entity.Id == application.Id && entity.Id == application.Id &&
entity.ConcurrencyToken == application.ConcurrencyToken, application, null, cancellationToken)).MatchedCount == 0) entity.ConcurrencyToken == timestamp, application, null, cancellationToken)).MatchedCount == 0)
{ {
throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder() throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder()
.AppendLine("The application was concurrently updated and cannot be persisted in its current state.") .AppendLine("The application was concurrently updated and cannot be persisted in its current state.")

39
src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs

@ -33,7 +33,7 @@ namespace OpenIddict.MongoDb
public OpenIddictAuthorizationStore( public OpenIddictAuthorizationStore(
[NotNull] IMemoryCache cache, [NotNull] IMemoryCache cache,
[NotNull] IOpenIddictMongoDbContext context, [NotNull] IOpenIddictMongoDbContext context,
[NotNull] IOptionsMonitor<OpenIddictMongoDbOptions> options) [NotNull] IOptions<OpenIddictMongoDbOptions> options)
{ {
Cache = cache; Cache = cache;
Context = context; Context = context;
@ -53,7 +53,7 @@ namespace OpenIddict.MongoDb
/// <summary> /// <summary>
/// Gets the options associated with the current store. /// Gets the options associated with the current store.
/// </summary> /// </summary>
protected IOptionsMonitor<OpenIddictMongoDbOptions> Options { get; } protected IOptions<OpenIddictMongoDbOptions> Options { get; }
/// <summary> /// <summary>
/// Determines the number of authorizations that exist in the database. /// Determines the number of authorizations that exist in the database.
@ -66,7 +66,7 @@ namespace OpenIddict.MongoDb
public virtual async Task<long> CountAsync(CancellationToken cancellationToken) public virtual async Task<long> CountAsync(CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return await collection.CountAsync(FilterDefinition<TAuthorization>.Empty); return await collection.CountAsync(FilterDefinition<TAuthorization>.Empty);
} }
@ -89,7 +89,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return await ((IMongoQueryable<TAuthorization>) query(collection.AsQueryable())).LongCountAsync(); return await ((IMongoQueryable<TAuthorization>) query(collection.AsQueryable())).LongCountAsync();
} }
@ -110,7 +110,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
await collection.InsertOneAsync(authorization, null, cancellationToken); await collection.InsertOneAsync(authorization, null, cancellationToken);
} }
@ -131,7 +131,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
if ((await collection.DeleteOneAsync(entity => if ((await collection.DeleteOneAsync(entity =>
entity.Id == authorization.Id && entity.Id == authorization.Id &&
@ -144,7 +144,7 @@ namespace OpenIddict.MongoDb
} }
// Delete the tokens associated with the authorization. // Delete the tokens associated with the authorization.
await database.GetCollection<OpenIddictToken>(Options.CurrentValue.TokensCollectionName) await database.GetCollection<OpenIddictToken>(Options.Value.TokensCollectionName)
.DeleteManyAsync(token => token.AuthorizationId == authorization.Id, cancellationToken); .DeleteManyAsync(token => token.AuthorizationId == authorization.Id, cancellationToken);
} }
@ -173,7 +173,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return ImmutableArray.CreateRange(await collection.Find(authorization => return ImmutableArray.CreateRange(await collection.Find(authorization =>
authorization.Subject == subject && authorization.Subject == subject &&
@ -211,7 +211,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return ImmutableArray.CreateRange(await collection.Find(authorization => return ImmutableArray.CreateRange(await collection.Find(authorization =>
authorization.Subject == subject && authorization.Subject == subject &&
@ -256,7 +256,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return ImmutableArray.CreateRange(await collection.Find(authorization => return ImmutableArray.CreateRange(await collection.Find(authorization =>
authorization.Subject == subject && authorization.Subject == subject &&
@ -282,7 +282,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return await collection.Find(authorization => authorization.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken); return await collection.Find(authorization => authorization.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken);
} }
@ -305,7 +305,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return ImmutableArray.CreateRange(await collection.Find(authorization => authorization.Subject == subject).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await collection.Find(authorization => authorization.Subject == subject).ToListAsync(cancellationToken));
} }
@ -351,7 +351,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken); return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken);
} }
@ -505,7 +505,7 @@ namespace OpenIddict.MongoDb
[CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
var query = (IMongoQueryable<TAuthorization>) collection.AsQueryable().OrderBy(authorization => authorization.Id); var query = (IMongoQueryable<TAuthorization>) collection.AsQueryable().OrderBy(authorization => authorization.Id);
@ -544,7 +544,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
return ImmutableArray.CreateRange( return ImmutableArray.CreateRange(
await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken)); await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken));
@ -560,11 +560,11 @@ namespace OpenIddict.MongoDb
public virtual async Task PruneAsync(CancellationToken cancellationToken) public virtual async Task PruneAsync(CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
var identifiers = var identifiers =
await (from authorization in collection.AsQueryable() await (from authorization in collection.AsQueryable()
join token in database.GetCollection<OpenIddictToken>(Options.CurrentValue.TokensCollectionName).AsQueryable() join token in database.GetCollection<OpenIddictToken>(Options.Value.TokensCollectionName).AsQueryable()
on authorization.Id equals token.AuthorizationId into tokens on authorization.Id equals token.AuthorizationId into tokens
where authorization.Status != OpenIddictConstants.Statuses.Valid || where authorization.Status != OpenIddictConstants.Statuses.Valid ||
(authorization.Type == OpenIddictConstants.AuthorizationTypes.AdHoc && (authorization.Type == OpenIddictConstants.AuthorizationTypes.AdHoc &&
@ -745,14 +745,15 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it // Generate a new concurrency token and attach it
// to the authorization before persisting the changes. // to the authorization before persisting the changes.
var timestamp = authorization.ConcurrencyToken;
authorization.ConcurrencyToken = Guid.NewGuid().ToString(); authorization.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); var collection = database.GetCollection<TAuthorization>(Options.Value.AuthorizationsCollectionName);
if ((await collection.ReplaceOneAsync(entity => if ((await collection.ReplaceOneAsync(entity =>
entity.Id == authorization.Id && entity.Id == authorization.Id &&
entity.ConcurrencyToken == authorization.ConcurrencyToken, authorization, null, cancellationToken)).MatchedCount == 0) entity.ConcurrencyToken == timestamp, authorization, null, cancellationToken)).MatchedCount == 0)
{ {
throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder() throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder()
.AppendLine("The authorization was concurrently updated and cannot be persisted in its current state.") .AppendLine("The authorization was concurrently updated and cannot be persisted in its current state.")

31
src/OpenIddict.MongoDb/Stores/OpenIddictScopeStore.cs

@ -33,7 +33,7 @@ namespace OpenIddict.MongoDb
public OpenIddictScopeStore( public OpenIddictScopeStore(
[NotNull] IMemoryCache cache, [NotNull] IMemoryCache cache,
[NotNull] IOpenIddictMongoDbContext context, [NotNull] IOpenIddictMongoDbContext context,
[NotNull] IOptionsMonitor<OpenIddictMongoDbOptions> options) [NotNull] IOptions<OpenIddictMongoDbOptions> options)
{ {
Cache = cache; Cache = cache;
Context = context; Context = context;
@ -53,7 +53,7 @@ namespace OpenIddict.MongoDb
/// <summary> /// <summary>
/// Gets the options associated with the current store. /// Gets the options associated with the current store.
/// </summary> /// </summary>
protected IOptionsMonitor<OpenIddictMongoDbOptions> Options { get; } protected IOptions<OpenIddictMongoDbOptions> Options { get; }
/// <summary> /// <summary>
/// Determines the number of scopes that exist in the database. /// Determines the number of scopes that exist in the database.
@ -66,7 +66,7 @@ namespace OpenIddict.MongoDb
public virtual async Task<long> CountAsync(CancellationToken cancellationToken) public virtual async Task<long> CountAsync(CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return await collection.CountAsync(FilterDefinition<TScope>.Empty); return await collection.CountAsync(FilterDefinition<TScope>.Empty);
} }
@ -89,7 +89,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return await ((IMongoQueryable<TScope>) query(collection.AsQueryable())).LongCountAsync(); return await ((IMongoQueryable<TScope>) query(collection.AsQueryable())).LongCountAsync();
} }
@ -110,7 +110,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
await collection.InsertOneAsync(scope, null, cancellationToken); await collection.InsertOneAsync(scope, null, cancellationToken);
} }
@ -131,7 +131,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
if ((await collection.DeleteOneAsync(entity => if ((await collection.DeleteOneAsync(entity =>
entity.Id == scope.Id && entity.Id == scope.Id &&
@ -161,7 +161,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return await collection.Find(scope => scope.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken); return await collection.Find(scope => scope.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken);
} }
@ -183,7 +183,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return await collection.Find(scope => scope.Name == name).FirstOrDefaultAsync(cancellationToken); return await collection.Find(scope => scope.Name == name).FirstOrDefaultAsync(cancellationToken);
} }
@ -206,7 +206,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return ImmutableArray.CreateRange(await collection.Find(scope => names.Contains(scope.Name)).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await collection.Find(scope => names.Contains(scope.Name)).ToListAsync(cancellationToken));
} }
@ -229,7 +229,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return ImmutableArray.CreateRange(await collection.Find(scope => scope.Resources.Contains(resource)).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await collection.Find(scope => scope.Resources.Contains(resource)).ToListAsync(cancellationToken));
} }
@ -256,7 +256,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken); return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken);
} }
@ -410,7 +410,7 @@ namespace OpenIddict.MongoDb
[CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
var query = (IMongoQueryable<TScope>) collection.AsQueryable().OrderBy(scope => scope.Id); var query = (IMongoQueryable<TScope>) collection.AsQueryable().OrderBy(scope => scope.Id);
@ -449,7 +449,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
return ImmutableArray.CreateRange( return ImmutableArray.CreateRange(
await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken)); await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken));
@ -591,14 +591,15 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it // Generate a new concurrency token and attach it
// to the scope before persisting the changes. // to the scope before persisting the changes.
var timestamp = scope.ConcurrencyToken;
scope.ConcurrencyToken = Guid.NewGuid().ToString(); scope.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TScope>(Options.CurrentValue.ScopesCollectionName); var collection = database.GetCollection<TScope>(Options.Value.ScopesCollectionName);
if ((await collection.ReplaceOneAsync(entity => if ((await collection.ReplaceOneAsync(entity =>
entity.Id == scope.Id && entity.Id == scope.Id &&
entity.ConcurrencyToken == scope.ConcurrencyToken, scope, null, cancellationToken)).MatchedCount == 0) entity.ConcurrencyToken == timestamp, scope, null, cancellationToken)).MatchedCount == 0)
{ {
throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder() throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder()
.AppendLine("The scope was concurrently updated and cannot be persisted in its current state.") .AppendLine("The scope was concurrently updated and cannot be persisted in its current state.")

35
src/OpenIddict.MongoDb/Stores/OpenIddictTokenStore.cs

@ -33,7 +33,7 @@ namespace OpenIddict.MongoDb
public OpenIddictTokenStore( public OpenIddictTokenStore(
[NotNull] IMemoryCache cache, [NotNull] IMemoryCache cache,
[NotNull] IOpenIddictMongoDbContext context, [NotNull] IOpenIddictMongoDbContext context,
[NotNull] IOptionsMonitor<OpenIddictMongoDbOptions> options) [NotNull] IOptions<OpenIddictMongoDbOptions> options)
{ {
Cache = cache; Cache = cache;
Context = context; Context = context;
@ -53,7 +53,7 @@ namespace OpenIddict.MongoDb
/// <summary> /// <summary>
/// Gets the options associated with the current store. /// Gets the options associated with the current store.
/// </summary> /// </summary>
protected IOptionsMonitor<OpenIddictMongoDbOptions> Options { get; } protected IOptions<OpenIddictMongoDbOptions> Options { get; }
/// <summary> /// <summary>
/// Determines the number of tokens that exist in the database. /// Determines the number of tokens that exist in the database.
@ -66,7 +66,7 @@ namespace OpenIddict.MongoDb
public virtual async Task<long> CountAsync(CancellationToken cancellationToken) public virtual async Task<long> CountAsync(CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return await collection.CountAsync(FilterDefinition<TToken>.Empty); return await collection.CountAsync(FilterDefinition<TToken>.Empty);
} }
@ -89,7 +89,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return await ((IMongoQueryable<TToken>) query(collection.AsQueryable())).LongCountAsync(); return await ((IMongoQueryable<TToken>) query(collection.AsQueryable())).LongCountAsync();
} }
@ -110,7 +110,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
await collection.InsertOneAsync(token, null, cancellationToken); await collection.InsertOneAsync(token, null, cancellationToken);
} }
@ -131,7 +131,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
if ((await collection.DeleteOneAsync(entity => if ((await collection.DeleteOneAsync(entity =>
entity.Id == token.Id && entity.Id == token.Id &&
@ -161,7 +161,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return ImmutableArray.CreateRange(await collection.Find(token => token.ApplicationId == ObjectId.Parse(identifier)).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await collection.Find(token => token.ApplicationId == ObjectId.Parse(identifier)).ToListAsync(cancellationToken));
} }
@ -183,7 +183,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return ImmutableArray.CreateRange(await collection.Find(token => token.AuthorizationId == ObjectId.Parse(identifier)).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await collection.Find(token => token.AuthorizationId == ObjectId.Parse(identifier)).ToListAsync(cancellationToken));
} }
@ -205,7 +205,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return await collection.Find(token => token.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken); return await collection.Find(token => token.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken);
} }
@ -228,7 +228,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return await collection.Find(token => token.ReferenceId == identifier).FirstOrDefaultAsync(cancellationToken); return await collection.Find(token => token.ReferenceId == identifier).FirstOrDefaultAsync(cancellationToken);
} }
@ -250,7 +250,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return ImmutableArray.CreateRange(await collection.Find(token => token.Subject == subject).ToListAsync(cancellationToken)); return ImmutableArray.CreateRange(await collection.Find(token => token.Subject == subject).ToListAsync(cancellationToken));
} }
@ -296,7 +296,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken); return await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).FirstOrDefaultAsync(cancellationToken);
} }
@ -523,7 +523,7 @@ namespace OpenIddict.MongoDb
[CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
var query = (IMongoQueryable<TToken>) collection.AsQueryable().OrderBy(token => token.Id); var query = (IMongoQueryable<TToken>) collection.AsQueryable().OrderBy(token => token.Id);
@ -562,7 +562,7 @@ namespace OpenIddict.MongoDb
} }
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
return ImmutableArray.CreateRange( return ImmutableArray.CreateRange(
await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken)); await ((IMongoQueryable<TResult>) query(collection.AsQueryable(), state)).ToListAsync(cancellationToken));
@ -578,7 +578,7 @@ namespace OpenIddict.MongoDb
public virtual async Task PruneAsync(CancellationToken cancellationToken) public virtual async Task PruneAsync(CancellationToken cancellationToken)
{ {
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
await collection.DeleteManyAsync(token => token.ExpirationDate < DateTimeOffset.UtcNow || await collection.DeleteManyAsync(token => token.ExpirationDate < DateTimeOffset.UtcNow ||
token.Status != OpenIddictConstants.Statuses.Valid, cancellationToken); token.Status != OpenIddictConstants.Statuses.Valid, cancellationToken);
@ -855,14 +855,15 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it // Generate a new concurrency token and attach it
// to the token before persisting the changes. // to the token before persisting the changes.
var timestamp = token.ConcurrencyToken;
token.ConcurrencyToken = Guid.NewGuid().ToString(); token.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken); var database = await Context.GetDatabaseAsync(cancellationToken);
var collection = database.GetCollection<TToken>(Options.CurrentValue.TokensCollectionName); var collection = database.GetCollection<TToken>(Options.Value.TokensCollectionName);
if ((await collection.ReplaceOneAsync(entity => if ((await collection.ReplaceOneAsync(entity =>
entity.Id == token.Id && entity.Id == token.Id &&
entity.ConcurrencyToken == token.ConcurrencyToken, token, null, cancellationToken)).MatchedCount == 0) entity.ConcurrencyToken == timestamp, token, null, cancellationToken)).MatchedCount == 0)
{ {
throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder() throw new OpenIddictException(OpenIddictConstants.Exceptions.ConcurrencyError, new StringBuilder()
.AppendLine("The token was concurrently updated and cannot be persisted in its current state.") .AppendLine("The token was concurrently updated and cannot be persisted in its current state.")

Loading…
Cancel
Save