Polish "Encode credentials in Docker Compose MongoDB connection string"

See gh-51939
This commit is contained in:
Stéphane Nicoll
2026-10-07 15:31:19 +02:00
parent 64b6c98beb
commit eb0887085e
4 changed files with 24 additions and 46 deletions
@@ -18,8 +18,6 @@ package org.springframework.boot.mongodb.docker.compose;
import com.mongodb.ConnectionString;
import com.mongodb.MongoCredential;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails;
@@ -52,18 +50,6 @@ class MongoDockerComposeConnectionDetailsFactoryIntegrationTests {
assertThat(sslBundle).isNotNull();
}
@DockerComposeTest(composeFile = "mongo-with-reserved-characters-in-credentials-compose.yaml",
image = TestImage.MONGODB)
void runWithReservedCharactersInCredentialsCreatesConnectionDetails(MongoConnectionDetails connectionDetails) {
ConnectionString connectionString = connectionDetails.getConnectionString();
MongoCredential credential = connectionString.getCredential();
assertThat(credential).isNotNull();
assertThat(credential.getPassword()).isEqualTo("p@ss:w/rd".toCharArray());
try (MongoClient client = MongoClients.create(connectionString)) {
assertThat(client.listDatabaseNames()).contains("admin");
}
}
private void assertConnectionDetailsWithDatabase(MongoConnectionDetails connectionDetails, String database) {
ConnectionString connectionString = connectionDetails.getConnectionString();
MongoCredential credential = connectionString.getCredential();
@@ -1,9 +0,0 @@
services:
mongo:
image: '{imageName}'
ports:
- '27017'
environment:
MONGO_INITDB_ROOT_USERNAME: 'root'
MONGO_INITDB_ROOT_PASSWORD: 'p@ss:w/rd'
MONGO_INITDB_DATABASE: 'mydatabase'
@@ -88,7 +88,7 @@ class MongoDockerComposeConnectionDetailsFactory extends DockerComposeConnection
return new ConnectionString(builder.toString());
}
private String encode(String input) {
private static String encode(String input) {
return URLEncoder.encode(input, StandardCharsets.UTF_8).replace("+", "%20");
}
@@ -32,28 +32,19 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for
* {@link MongoDockerComposeConnectionDetailsFactory.MongoDockerComposeConnectionDetails}.
* Tests for {@link MongoDockerComposeConnectionDetailsFactory}.
*
* @author Iram Tazim Hoque
*/
class MongoDockerComposeConnectionDetailsFactoryConnectionDetailsTests {
private final RunningService service = mock(RunningService.class);
MongoDockerComposeConnectionDetailsFactoryConnectionDetailsTests() {
given(this.service.labels()).willReturn(Collections.emptyMap());
ConnectionPorts connectionPorts = mock(ConnectionPorts.class);
given(this.service.ports()).willReturn(connectionPorts);
given(this.service.host()).willReturn("localhost");
given(connectionPorts.get(27017)).willReturn(30001);
}
class MongoDockerComposeConnectionDetailsFactoryTests {
@Test
void createConnectionDetails() {
given(this.service.env()).willReturn(Map.of("MONGO_INITDB_ROOT_USERNAME", "root", "MONGO_INITDB_ROOT_PASSWORD",
"secret", "MONGO_INITDB_DATABASE", "mydatabase"));
ConnectionString connectionString = getConnectionString();
RunningService runningService = mockRunningService();
given(runningService.env()).willReturn(Map.of("MONGO_INITDB_ROOT_USERNAME", "root",
"MONGO_INITDB_ROOT_PASSWORD", "secret", "MONGO_INITDB_DATABASE", "mydatabase"));
ConnectionString connectionString = new MongoDockerComposeConnectionDetails(runningService)
.getConnectionString();
assertThat(connectionString.getHosts()).containsExactly("localhost:30001");
assertThat(connectionString.getDatabase()).isEqualTo("mydatabase");
MongoCredential credential = connectionString.getCredential();
@@ -65,9 +56,11 @@ class MongoDockerComposeConnectionDetailsFactoryConnectionDetailsTests {
@Test
void createConnectionDetailsWhenCredentialsContainReservedCharacters() {
given(this.service.env()).willReturn(Map.of("MONGO_INITDB_ROOT_USERNAME", "us@r:name",
RunningService runningService = mockRunningService();
given(runningService.env()).willReturn(Map.of("MONGO_INITDB_ROOT_USERNAME", "us@r:name",
"MONGO_INITDB_ROOT_PASSWORD", "p@ss:w/rd%?#[] +", "MONGO_INITDB_DATABASE", "mydatabase"));
ConnectionString connectionString = getConnectionString();
ConnectionString connectionString = new MongoDockerComposeConnectionDetails(runningService)
.getConnectionString();
assertThat(connectionString.getHosts()).containsExactly("localhost:30001");
assertThat(connectionString.getDatabase()).isEqualTo("mydatabase");
MongoCredential credential = connectionString.getCredential();
@@ -79,15 +72,23 @@ class MongoDockerComposeConnectionDetailsFactoryConnectionDetailsTests {
@Test
void createConnectionDetailsWithoutCredentials() {
given(this.service.env()).willReturn(Collections.emptyMap());
ConnectionString connectionString = getConnectionString();
RunningService runningService = mockRunningService();
given(runningService.env()).willReturn(Collections.emptyMap());
ConnectionString connectionString = new MongoDockerComposeConnectionDetails(runningService)
.getConnectionString();
assertThat(connectionString.getHosts()).containsExactly("localhost:30001");
assertThat(connectionString.getDatabase()).isEqualTo("test");
assertThat(connectionString.getCredential()).isNull();
}
private ConnectionString getConnectionString() {
return new MongoDockerComposeConnectionDetails(this.service).getConnectionString();
private static RunningService mockRunningService() {
RunningService service = mock(RunningService.class);
given(service.labels()).willReturn(Collections.emptyMap());
ConnectionPorts connectionPorts = mock(ConnectionPorts.class);
given(service.ports()).willReturn(connectionPorts);
given(service.host()).willReturn("localhost");
given(connectionPorts.get(27017)).willReturn(30001);
return service;
}
}