From 769fdefab6af5573bdcb2653c5e8acbe50465e08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sun, 19 Aug 2018 19:09:36 +0200 Subject: [PATCH] Introduce a new OpenIddictMongoDbOptions.DisableInitialization option --- .../OpenIddictMongoDbBuilder.cs | 8 +++ .../OpenIddictMongoDbContext.cs | 67 ++++++++++--------- .../OpenIddictMongoDbOptions.cs | 5 ++ .../OpenIddictMongoDbBuilderTests.cs | 17 +++++ .../OpenIddictMongoDbContextTests.cs | 26 +++++++ 5 files changed, 91 insertions(+), 32 deletions(-) diff --git a/src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs b/src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs index 314c3d01..be4018dd 100644 --- a/src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs +++ b/src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs @@ -57,6 +57,14 @@ namespace Microsoft.Extensions.DependencyInjection return this; } + /// + /// Disables initialization so that the MongoDB indexes used by OpenIddict + /// are not automatically created the first time the stores are invoked. + /// + /// The . + public OpenIddictMongoDbBuilder DisableInitialization() + => Configure(options => options.DisableInitialization = true); + /// /// Configures OpenIddict to use the specified entity as the default application entity. /// diff --git a/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs b/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs index d8f1105d..69c73a5a 100644 --- a/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs +++ b/src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs @@ -84,38 +84,41 @@ namespace OpenIddict.MongoDb .ToString()); } - // 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(new CreateIndexModel( - Builders.IndexKeys.Ascending(application => application.ClientId), - new CreateIndexOptions - { - Unique = true - })); - - await applications.Indexes.CreateOneAsync(new CreateIndexModel( - Builders.IndexKeys.Ascending(application => application.PostLogoutRedirectUris))); - - await applications.Indexes.CreateOneAsync(new CreateIndexModel( - Builders.IndexKeys.Ascending(application => application.RedirectUris))); - - var scopes = database.GetCollection(options.ScopesCollectionName); - await scopes.Indexes.CreateOneAsync(new CreateIndexModel( - Builders.IndexKeys.Ascending(scope => scope.Name), - new CreateIndexOptions - { - Unique = true - })); - - var tokens = database.GetCollection(options.TokensCollectionName); - await tokens.Indexes.CreateOneAsync(new CreateIndexModel( - Builders.IndexKeys.Ascending(token => token.ReferenceId), - new CreateIndexOptions - { - PartialFilterExpression = Builders.Filter.Exists(token => token.ReferenceId), - Unique = true - })); + if (!options.DisableInitialization) + { + // 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(new CreateIndexModel( + Builders.IndexKeys.Ascending(application => application.ClientId), + new CreateIndexOptions + { + Unique = true + })); + + await applications.Indexes.CreateOneAsync(new CreateIndexModel( + Builders.IndexKeys.Ascending(application => application.PostLogoutRedirectUris))); + + await applications.Indexes.CreateOneAsync(new CreateIndexModel( + Builders.IndexKeys.Ascending(application => application.RedirectUris))); + + var scopes = database.GetCollection(options.ScopesCollectionName); + await scopes.Indexes.CreateOneAsync(new CreateIndexModel( + Builders.IndexKeys.Ascending(scope => scope.Name), + new CreateIndexOptions + { + Unique = true + })); + + var tokens = database.GetCollection(options.TokensCollectionName); + await tokens.Indexes.CreateOneAsync(new CreateIndexModel( + Builders.IndexKeys.Ascending(token => token.ReferenceId), + new CreateIndexOptions + { + PartialFilterExpression = Builders.Filter.Exists(token => token.ReferenceId), + Unique = true + })); + } return _database = database; } diff --git a/src/OpenIddict.MongoDb/OpenIddictMongoDbOptions.cs b/src/OpenIddict.MongoDb/OpenIddictMongoDbOptions.cs index 326eaa09..3ae3c5aa 100644 --- a/src/OpenIddict.MongoDb/OpenIddictMongoDbOptions.cs +++ b/src/OpenIddict.MongoDb/OpenIddictMongoDbOptions.cs @@ -30,6 +30,11 @@ namespace OpenIddict.MongoDb /// public IMongoDatabase Database { get; set; } + /// + /// Gets or sets a boolean indicating whether automatic initialization should be disabled. + /// + public bool DisableInitialization { get; set; } + /// /// Gets or sets the maximal duration given to the MongoDB client to initialize /// the database and register the indexes used by the OpenIddict entities. diff --git a/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbBuilderTests.cs b/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbBuilderTests.cs index 8e536f4d..14bd3e93 100644 --- a/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbBuilderTests.cs +++ b/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbBuilderTests.cs @@ -29,6 +29,23 @@ namespace OpenIddict.MongoDb.Tests Assert.Equal("services", exception.ParamName); } + [Fact] + public void DisableInitialization_InitializationIsCorrectlyDisabled() + { + // Arrange + var services = CreateServices(); + var builder = CreateBuilder(services); + + // Act + builder.DisableInitialization(); + + // Assert + var provider = services.BuildServiceProvider(); + var options = provider.GetRequiredService>().CurrentValue; + + Assert.True(options.DisableInitialization); + } + [Fact] public void ReplaceDefaultApplicationEntity_EntityIsCorrectlySet() { diff --git a/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbContextTests.cs b/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbContextTests.cs index 75ba7a31..88ecfcd8 100644 --- a/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbContextTests.cs +++ b/test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbContextTests.cs @@ -165,6 +165,32 @@ namespace OpenIddict.MongoDb.Tests Assert.Same(database.Object, await context.GetDatabaseAsync(CancellationToken.None)); } + [Fact] + public async Task GetDatabaseAsync_SkipsInitializationWhenDisabled() + { + // Arrange + var services = new ServiceCollection(); + var provider = services.BuildServiceProvider(); + + var database = GetDatabase(); + var options = Mock.Of>( + mock => mock.CurrentValue == new OpenIddictMongoDbOptions + { + Database = database.Object, + DisableInitialization = true + }); + + var context = new OpenIddictMongoDbContext(options, provider); + + // Act + await context.GetDatabaseAsync(CancellationToken.None); + + // Assert + database.Verify(mock => mock.GetCollection(It.IsAny(), It.IsAny()), Times.Never()); + database.Verify(mock => mock.GetCollection(It.IsAny(), It.IsAny()), Times.Never()); + database.Verify(mock => mock.GetCollection(It.IsAny(), It.IsAny()), Times.Never()); + } + [Fact] public async Task GetDatabaseAsync_ReturnsCachedDatabase() {