diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index fa2d96b66a4f..9c4f670c8db0 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -35,6 +35,7 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Scott Frederick + * @author He Zean */ class PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests { @@ -60,6 +61,16 @@ void runWithBitnamiImageCreatesConnectionDetails(JdbcConnectionDetails connectio checkDatabaseAccess(connectionDetails); } + @DockerComposeTest(composeFile = "postgres-bitnami-empty-password-compose.yaml", + image = TestImage.BITNAMI_POSTGRESQL) + void runWithBitnamiImageCreatesConnectionDetailsWithAllowEmptyPassword(JdbcConnectionDetails connectionDetails) + throws ClassNotFoundException { + assertThat(connectionDetails.getUsername()).isEqualTo("myuser"); + assertThat(connectionDetails.getPassword()).isEmpty(); + assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:postgresql://").endsWith("/mydatabase"); + checkDatabaseAccess(connectionDetails); + } + @DockerComposeTest(composeFile = "postgres-application-name-compose.yaml", image = TestImage.POSTGRESQL) void runCreatesConnectionDetailsApplicationName(JdbcConnectionDetails connectionDetails) throws ClassNotFoundException { diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index b6e0e2e604e2..f11c4652240a 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -37,6 +37,7 @@ * @author Andy Wilkinson * @author Phillip Webb * @author Scott Frederick + * @author He Zean */ class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests { @@ -63,6 +64,17 @@ void runWithBitnamiImageCreatesConnectionDetails(R2dbcConnectionDetails connecti checkDatabaseAccess(connectionDetails); } + @DockerComposeTest(composeFile = "postgres-bitnami-empty-password-compose.yaml", + image = TestImage.BITNAMI_POSTGRESQL) + void runWithBitnamiImageCreatesConnectionDetailsWithAllowEmptyPassword(R2dbcConnectionDetails connectionDetails) { + ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions(); + assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.USER)).isEqualTo("myuser"); + assertThat(connectionFactoryOptions.getValue(ConnectionFactoryOptions.PASSWORD)).isNull(); + assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.DATABASE)) + .isEqualTo("mydatabase"); + checkDatabaseAccess(connectionDetails); + } + @DockerComposeTest(composeFile = "postgres-application-name-compose.yaml", image = TestImage.POSTGRESQL) void runCreatesConnectionDetailsApplicationName(R2dbcConnectionDetails connectionDetails) { assertConnectionDetails(connectionDetails); diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-bitnami-empty-password-compose.yaml b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-bitnami-empty-password-compose.yaml new file mode 100644 index 000000000000..967796341602 --- /dev/null +++ b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-bitnami-empty-password-compose.yaml @@ -0,0 +1,9 @@ +services: + database: + image: '{imageName}' + ports: + - '5432' + environment: + - 'POSTGRESQL_USERNAME=myuser' + - 'POSTGRESQL_DATABASE=mydatabase' + - 'ALLOW_EMPTY_PASSWORD=yes' diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java index 220dbbf3e55b..07c1ce583bc9 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java +++ b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java @@ -17,6 +17,7 @@ package org.springframework.boot.docker.compose.service.connection.postgres; import java.util.Map; +import java.util.Objects; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -67,8 +68,9 @@ private String extractPassword(Map env) { return null; } String password = env.getOrDefault("POSTGRES_PASSWORD", env.get("POSTGRESQL_PASSWORD")); - Assert.state(StringUtils.hasLength(password), "PostgreSQL password must be provided"); - return password; + boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD"); + Assert.state(allowEmpty || StringUtils.hasLength(password), "PostgreSQL password must be provided"); + return Objects.requireNonNullElse(password, ""); } private boolean isUsingTrustHostAuthMethod(Map env) { diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java index 24ce50bc11df..519d217b99d2 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java +++ b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java @@ -93,6 +93,12 @@ void getPasswordWhenHasTrustHostAuthMethod() { assertThat(environment.getPassword()).isNull(); } + @Test + void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() { + PostgresEnvironment environment = new PostgresEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes")); + assertThat(environment.getPassword()).isEmpty(); + } + @Test void getDatabaseWhenNoPostgresDbOrPostgresUser() { PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));