Fix building of MongoDB connection string with authentication db

This commit restores the previous behavior of MongoDB auto-
configuration, where the value of the
`spring.data.mongodb.authentication-database` is set in the
credentials when provided.

Fixes gh-35567
This commit is contained in:
Scott Frederick
2023-05-19 16:22:15 -05:00
parent 593fa1dc42
commit a02eb48528
4 changed files with 269 additions and 15 deletions

View File

@@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.internal.MongoClientImpl;
@@ -107,6 +108,95 @@ class MongoAutoConfigurationTests {
});
}
@Test
void doesNotConfigureCredentialsWithoutUsername() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.password=secret",
"spring.data.mongodb.authentication-database=authdb")
.run((context) -> assertThat(getSettings(context).getCredential()).isNull());
}
@Test
void configuresCredentialsFromPropertiesWithDefaultDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.username=user", "spring.data.mongodb.password=secret")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("test");
});
}
@Test
void configuresCredentialsFromPropertiesWithDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.username=user", "spring.data.mongodb.password=secret",
"spring.data.mongodb.database=mydb")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("mydb");
});
}
@Test
void configuresCredentialsFromPropertiesWithAuthDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.username=user", "spring.data.mongodb.password=secret",
"spring.data.mongodb.database=mydb", "spring.data.mongodb.authentication-database=authdb")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("authdb");
});
}
@Test
void doesNotConfigureCredentialsWithoutUsernameInUri() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://localhost/mydb?authSource=authdb")
.run((context) -> assertThat(getSettings(context).getCredential()).isNull());
}
@Test
void configuresCredentialsFromUriPropertyWithDefaultDatabase() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://user:secret@localhost/")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("admin");
});
}
@Test
void configuresCredentialsFromUriPropertyWithDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://user:secret@localhost/mydb",
"spring.data.mongodb.database=notused", "spring.data.mongodb.authentication-database=notused")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("mydb");
});
}
@Test
void configuresCredentialsFromUriPropertyWithAuthDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://user:secret@localhost/mydb?authSource=authdb",
"spring.data.mongodb.database=notused", "spring.data.mongodb.authentication-database=notused")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("authdb");
});
}
@Test
void configuresSingleClient() {
this.contextRunner.withUserConfiguration(FallbackMongoClientConfig.class)

View File

@@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicReference;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ReadPreference;
import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory;
import com.mongodb.connection.SslSettings;
@@ -121,6 +122,95 @@ class MongoReactiveAutoConfigurationTests {
});
}
@Test
void doesNotConfigureCredentialsWithoutUsername() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.password=secret",
"spring.data.mongodb.authentication-database=authdb")
.run((context) -> assertThat(getSettings(context).getCredential()).isNull());
}
@Test
void configuresCredentialsFromPropertiesWithDefaultDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.username=user", "spring.data.mongodb.password=secret")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("test");
});
}
@Test
void configuresCredentialsFromPropertiesWithDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.username=user", "spring.data.mongodb.password=secret",
"spring.data.mongodb.database=mydb")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("mydb");
});
}
@Test
void configuresCredentialsFromPropertiesWithAuthDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.username=user", "spring.data.mongodb.password=secret",
"spring.data.mongodb.database=mydb", "spring.data.mongodb.authentication-database=authdb")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("authdb");
});
}
@Test
void doesNotConfigureCredentialsWithoutUsernameInUri() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://localhost/mydb?authSource=authdb")
.run((context) -> assertThat(getSettings(context).getCredential()).isNull());
}
@Test
void configuresCredentialsFromUriPropertyWithDefaultDatabase() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://user:secret@localhost/")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("admin");
});
}
@Test
void configuresCredentialsFromUriPropertyWithDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://user:secret@localhost/mydb",
"spring.data.mongodb.database=notused", "spring.data.mongodb.authentication-database=notused")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("mydb");
});
}
@Test
void configuresCredentialsFromUriPropertyWithAuthDatabase() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://user:secret@localhost/mydb?authSource=authdb",
"spring.data.mongodb.database=notused", "spring.data.mongodb.authentication-database=notused")
.run((context) -> {
MongoCredential credential = getSettings(context).getCredential();
assertThat(credential.getUserName()).isEqualTo("user");
assertThat(credential.getPassword()).isEqualTo("secret".toCharArray());
assertThat(credential.getSource()).isEqualTo("authdb");
});
}
@Test
void nettyStreamFactoryFactoryIsConfiguredAutomatically() {
AtomicReference<EventLoopGroup> eventLoopGroupReference = new AtomicReference<>();

View File

@@ -25,11 +25,66 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link PropertiesMongoConnectionDetails}.
*
* @author Christoph Dreis
* @author Scott Frederick
*/
class PropertiesMongoConnectionDetailsTests {
private final MongoProperties properties = new MongoProperties();
@Test
void credentialsCanBeConfiguredWithUsername() {
this.properties.setUsername("user");
ConnectionString connectionString = getConnectionString();
assertThat(connectionString.getUsername()).isEqualTo("user");
assertThat(connectionString.getPassword()).isEmpty();
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
assertThat(connectionString.getCredential().getPassword()).isEmpty();
assertThat(connectionString.getCredential().getSource()).isEqualTo("test");
}
@Test
void credentialsCanBeConfiguredWithUsernameAndPassword() {
this.properties.setUsername("user");
this.properties.setPassword("secret".toCharArray());
ConnectionString connectionString = getConnectionString();
assertThat(connectionString.getUsername()).isEqualTo("user");
assertThat(connectionString.getPassword()).isEqualTo("secret".toCharArray());
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
assertThat(connectionString.getCredential().getPassword()).isEqualTo("secret".toCharArray());
assertThat(connectionString.getCredential().getSource()).isEqualTo("test");
}
@Test
void databaseCanBeConfigured() {
this.properties.setDatabase("db");
ConnectionString connectionString = getConnectionString();
assertThat(connectionString.getDatabase()).isEqualTo("db");
}
@Test
void databaseHasDefaultWhenNotConfigured() {
ConnectionString connectionString = getConnectionString();
assertThat(connectionString.getDatabase()).isEqualTo("test");
}
@Test
void authenticationDatabaseCanBeConfigured() {
this.properties.setUsername("user");
this.properties.setDatabase("db");
this.properties.setAuthenticationDatabase("authdb");
ConnectionString connectionString = getConnectionString();
assertThat(connectionString.getDatabase()).isEqualTo("db");
assertThat(connectionString.getCredential().getSource()).isEqualTo("authdb");
assertThat(connectionString.getCredential().getUserName()).isEqualTo("user");
}
@Test
void authenticationDatabaseIsNotConfiguredWhenUsernameIsNotConfigured() {
this.properties.setAuthenticationDatabase("authdb");
ConnectionString connectionString = getConnectionString();
assertThat(connectionString.getCredential()).isNull();
}
@Test
void replicaSetCanBeConfigured() {
this.properties.setReplicaSetName("test");
@@ -37,6 +92,16 @@ class PropertiesMongoConnectionDetailsTests {
assertThat(connectionString.getRequiredReplicaSetName()).isEqualTo("test");
}
@Test
void replicaSetCanBeConfiguredWithDatabase() {
this.properties.setUsername("user");
this.properties.setDatabase("db");
this.properties.setReplicaSetName("test");
ConnectionString connectionString = getConnectionString();
assertThat(connectionString.getDatabase()).isEqualTo("db");
assertThat(connectionString.getRequiredReplicaSetName()).isEqualTo("test");
}
private PropertiesMongoConnectionDetails createConnectionDetails() {
return new PropertiesMongoConnectionDetails(this.properties);
}