diff --git a/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs b/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs
index de27f63d..9c8bd953 100644
--- a/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs
+++ b/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs
@@ -40,69 +40,74 @@ namespace OpenIddict.MongoDb
/// A that can be used to monitor the
/// asynchronous operation, whose result returns the MongoDB database.
///
- public async ValueTask GetDatabaseAsync(CancellationToken cancellationToken)
+ public ValueTask GetDatabaseAsync(CancellationToken cancellationToken)
{
if (_database != null)
{
- return _database;
+ return new ValueTask(_database);
}
- var options = _options.CurrentValue;
- if (options == null)
+ async Task ExecuteAsync()
{
- throw new InvalidOperationException("The OpenIddict MongoDB options cannot be retrieved.");
- }
-
- var database = options.Database;
- if (database == null)
- {
- database = _provider.GetService();
- }
+ var options = _options.CurrentValue;
+ if (options == null)
+ {
+ throw new InvalidOperationException("The OpenIddict MongoDB options cannot be retrieved.");
+ }
- if (database == null)
- {
- throw new InvalidOperationException(new StringBuilder()
- .AppendLine("No suitable MongoDB database service can be found.")
- .Append("To configure the OpenIddict MongoDB stores to use a specific database, use ")
- .Append("'services.AddOpenIddict().AddCore().UseMongoDb().UseDatabase()' or register an ")
- .Append("'IMongoDatabase' in the dependency injection container in 'ConfigureServices()'.")
- .ToString());
- }
+ var database = options.Database;
+ if (database == null)
+ {
+ database = _provider.GetService();
+ }
- // Note: the cancellation token passed as a parameter is deliberately not used here to ensure
- // the cancellation of a single store operation doesn't prevent the indexes from being created.
- var applications = database.GetCollection(options.ApplicationsCollectionName);
- await applications.Indexes.CreateOneAsync(
- Builders.IndexKeys.Ascending(application => application.ClientId),
- new CreateIndexOptions
+ if (database == null)
{
- Unique = true
- });
+ throw new InvalidOperationException(new StringBuilder()
+ .AppendLine("No suitable MongoDB database service can be found.")
+ .Append("To configure the OpenIddict MongoDB stores to use a specific database, use ")
+ .Append("'services.AddOpenIddict().AddCore().UseMongoDb().UseDatabase()' or register an ")
+ .Append("'IMongoDatabase' in the dependency injection container in 'ConfigureServices()'.")
+ .ToString());
+ }
- await applications.Indexes.CreateOneAsync(
- Builders.IndexKeys.Ascending(application => application.PostLogoutRedirectUris));
+ // Note: the cancellation token passed as a parameter is deliberately not used here to ensure
+ // the cancellation of a single store operation doesn't prevent the indexes from being created.
+ var applications = database.GetCollection(options.ApplicationsCollectionName);
+ await applications.Indexes.CreateOneAsync(
+ Builders.IndexKeys.Ascending(application => application.ClientId),
+ new CreateIndexOptions
+ {
+ Unique = true
+ });
- await applications.Indexes.CreateOneAsync(
- Builders.IndexKeys.Ascending(application => application.RedirectUris));
+ await applications.Indexes.CreateOneAsync(
+ Builders.IndexKeys.Ascending(application => application.PostLogoutRedirectUris));
- var scopes = database.GetCollection(options.ScopesCollectionName);
- await scopes.Indexes.CreateOneAsync(
- Builders.IndexKeys.Ascending(scope => scope.Name),
- new CreateIndexOptions
- {
- Unique = true
- });
+ await applications.Indexes.CreateOneAsync(
+ Builders.IndexKeys.Ascending(application => application.RedirectUris));
- var tokens = database.GetCollection(options.TokensCollectionName);
- await tokens.Indexes.CreateOneAsync(
- Builders.IndexKeys.Ascending(token => token.ReferenceId),
- new CreateIndexOptions
- {
- PartialFilterExpression = Builders.Filter.Exists(token => token.ReferenceId),
- Unique = true
- });
+ var scopes = database.GetCollection(options.ScopesCollectionName);
+ await scopes.Indexes.CreateOneAsync(
+ Builders.IndexKeys.Ascending(scope => scope.Name),
+ new CreateIndexOptions
+ {
+ Unique = true
+ });
+
+ var tokens = database.GetCollection(options.TokensCollectionName);
+ await tokens.Indexes.CreateOneAsync(
+ Builders.IndexKeys.Ascending(token => token.ReferenceId),
+ new CreateIndexOptions
+ {
+ PartialFilterExpression = Builders.Filter.Exists(token => token.ReferenceId),
+ Unique = true
+ });
+
+ return _database = database;
+ }
- return _database = database;
+ return new ValueTask(ExecuteAsync());
}
}
}
diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictApplicationStore.cs
index db2f49c3..cbde5016 100644
--- a/src/OpenIddict.MongoDb/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.MongoDb/Stores/OpenIddictApplicationStore.cs
@@ -794,6 +794,7 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it
// to the application before persisting the changes.
+ var timestamp = application.ConcurrencyToken;
application.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken);
@@ -801,7 +802,7 @@ namespace OpenIddict.MongoDb
if ((await collection.ReplaceOneAsync(entity =>
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()
.AppendLine("The application was concurrently updated and cannot be persisted in its current state.")
diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs
index 34321262..537a97ad 100644
--- a/src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.MongoDb/Stores/OpenIddictAuthorizationStore.cs
@@ -745,6 +745,7 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it
// to the authorization before persisting the changes.
+ var timestamp = authorization.ConcurrencyToken;
authorization.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken);
@@ -752,7 +753,7 @@ namespace OpenIddict.MongoDb
if ((await collection.ReplaceOneAsync(entity =>
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()
.AppendLine("The authorization was concurrently updated and cannot be persisted in its current state.")
diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictScopeStore.cs
index 456e179a..40646907 100644
--- a/src/OpenIddict.MongoDb/Stores/OpenIddictScopeStore.cs
+++ b/src/OpenIddict.MongoDb/Stores/OpenIddictScopeStore.cs
@@ -591,6 +591,7 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it
// to the scope before persisting the changes.
+ var timestamp = scope.ConcurrencyToken;
scope.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken);
@@ -598,7 +599,7 @@ namespace OpenIddict.MongoDb
if ((await collection.ReplaceOneAsync(entity =>
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()
.AppendLine("The scope was concurrently updated and cannot be persisted in its current state.")
diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictTokenStore.cs
index 49208e12..0fbf9f4a 100644
--- a/src/OpenIddict.MongoDb/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.MongoDb/Stores/OpenIddictTokenStore.cs
@@ -855,6 +855,7 @@ namespace OpenIddict.MongoDb
// Generate a new concurrency token and attach it
// to the token before persisting the changes.
+ var timestamp = token.ConcurrencyToken;
token.ConcurrencyToken = Guid.NewGuid().ToString();
var database = await Context.GetDatabaseAsync(cancellationToken);
@@ -862,7 +863,7 @@ namespace OpenIddict.MongoDb
if ((await collection.ReplaceOneAsync(entity =>
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()
.AppendLine("The token was concurrently updated and cannot be persisted in its current state.")