diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigLocation.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigLocation.java index 05fc41fe..522e6435 100644 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigLocation.java +++ b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigLocation.java @@ -44,7 +44,8 @@ public class VaultConfigLocation extends ConfigDataResource { super(optional); - Assert.hasText(contextPath, "Context path must not be empty"); + Assert.hasText(contextPath, "Location must not be empty"); + validatePath(contextPath); this.secretBackendMetadata = KeyValueSecretBackendMetadata.create(contextPath); this.optional = optional; @@ -54,6 +55,7 @@ public class VaultConfigLocation extends ConfigDataResource { Assert.notNull(secretBackendMetadata, "SecretBackendMetadata must not be null"); + validatePath(secretBackendMetadata.getPath()); this.secretBackendMetadata = secretBackendMetadata; this.optional = optional; } @@ -101,4 +103,9 @@ public class VaultConfigLocation extends ConfigDataResource { return sb.toString(); } + private static void validatePath(String contextPath) { + Assert.isTrue(!contextPath.endsWith("/"), + () -> String.format("Location 'vault://%s' must not end with a trailing slash", contextPath)); + } + } diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderIntegrationTests.java index 600e0eec..75f2596e 100644 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderIntegrationTests.java +++ b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderIntegrationTests.java @@ -30,6 +30,7 @@ import org.springframework.cloud.vault.util.Settings; import org.springframework.context.ConfigurableApplicationContext; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; /** * Integration tests for {@link VaultConfigDataLoader}. @@ -62,6 +63,25 @@ public class VaultConfigDataLoaderIntegrationTests extends IntegrationTestSuppor } } + @Test + public void vaultLocationEndingWithSlashShouldFail() { + + SpringApplication application = new SpringApplication(Config.class); + application.setWebApplicationType(WebApplicationType.NONE); + application.setAdditionalProfiles("cloud"); + + try (ConfigurableApplicationContext context = application.run("--spring.application.name=my-config-loader", + "--spring.config.import=vault://secret/my-config-loader/cloud/", + "--spring.cloud.vault.token=" + Settings.token().getToken())) { + + fail("expected exception"); + } + catch (IllegalArgumentException e) { + assertThat(e).hasMessageContaining( + "Location 'vault://secret/my-config-loader/cloud/' must not end with a trailing slash"); + } + } + @Test public void shouldConsiderDisabledVault() { diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java index c02b44fc..ee9751a3 100644 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java +++ b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java @@ -29,6 +29,7 @@ import org.springframework.boot.context.config.Profiles; import org.springframework.boot.context.properties.bind.Binder; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -67,6 +68,17 @@ public class VaultConfigDataLocationResolverUnitTests { .hasSize(3); } + @Test + public void shouldRejectLocationWithTrailingSlash() { + + VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver(); + + assertThatIllegalArgumentException() + .isThrownBy(() -> resolver.resolveProfileSpecific(this.contextMock, + ConfigDataLocation.of("vault://foo/"), this.profilesMock)) + .withMessage("Location 'vault://foo/' must not end with a trailing slash"); + } + @Test public void shouldDiscoverContextualLocations() {