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:
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.mongo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mongodb.ConnectionString;
|
||||
|
||||
/**
|
||||
@@ -24,6 +27,7 @@ import com.mongodb.ConnectionString;
|
||||
* @author Moritz Halbritter
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @author Scott Frederick
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public class PropertiesMongoConnectionDetails implements MongoConnectionDetails {
|
||||
@@ -44,7 +48,9 @@ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails
|
||||
if (this.properties.getUsername() != null) {
|
||||
builder.append(this.properties.getUsername());
|
||||
builder.append(":");
|
||||
builder.append(this.properties.getPassword());
|
||||
if (this.properties.getPassword() != null) {
|
||||
builder.append(this.properties.getPassword());
|
||||
}
|
||||
builder.append("@");
|
||||
}
|
||||
builder.append((this.properties.getHost() != null) ? this.properties.getHost() : "localhost");
|
||||
@@ -55,20 +61,12 @@ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails
|
||||
if (this.properties.getAdditionalHosts() != null) {
|
||||
builder.append(String.join(",", this.properties.getAdditionalHosts()));
|
||||
}
|
||||
if (this.properties.getMongoClientDatabase() != null || this.properties.getReplicaSetName() != null
|
||||
|| this.properties.getAuthenticationDatabase() != null) {
|
||||
builder.append("/");
|
||||
if (this.properties.getMongoClientDatabase() != null) {
|
||||
builder.append(this.properties.getMongoClientDatabase());
|
||||
}
|
||||
else if (this.properties.getAuthenticationDatabase() != null) {
|
||||
builder.append(this.properties.getAuthenticationDatabase());
|
||||
}
|
||||
if (this.properties.getReplicaSetName() != null) {
|
||||
builder.append("?");
|
||||
builder.append("replicaSet=");
|
||||
builder.append(this.properties.getReplicaSetName());
|
||||
}
|
||||
builder.append("/");
|
||||
builder.append(this.properties.getMongoClientDatabase());
|
||||
List<String> options = getOptions();
|
||||
if (!options.isEmpty()) {
|
||||
builder.append("?");
|
||||
builder.append(String.join("&", options));
|
||||
}
|
||||
return new ConnectionString(builder.toString());
|
||||
}
|
||||
@@ -79,4 +77,15 @@ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails
|
||||
PropertiesMongoConnectionDetails.this.properties.getGridfs().getBucket());
|
||||
}
|
||||
|
||||
private List<String> getOptions() {
|
||||
List<String> options = new ArrayList<>();
|
||||
if (this.properties.getReplicaSetName() != null) {
|
||||
options.add("replicaSet=" + this.properties.getReplicaSetName());
|
||||
}
|
||||
if (this.properties.getUsername() != null && this.properties.getAuthenticationDatabase() != null) {
|
||||
options.add("authSource=" + this.properties.getAuthenticationDatabase());
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<>();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user