From cfe620210eb5e069a9384f45e0bddfc637a86b13 Mon Sep 17 00:00:00 2001 From: Stefan Schultz <28778796+itsmestefanjay@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:40:19 +0100 Subject: [PATCH] add more tests --- .../secrets/common/ProviderAppConfig.java | 10 +- .../kv/GenericKeyValueVaultSecretService.java | 3 +- .../VersionedKeyValueVaultSecretService.java | 10 +- .../provider/VaultSecretProviderTest.java | 12 ++- ...GenericKeyValueVaultSecretServiceTest.java | 93 +++++++++++++++++++ ...rsionedKeyValueVaultSecretServiceTest.java | 91 ++++++++++++++++++ 6 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 src/test/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretServiceTest.java create mode 100644 src/test/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretServiceTest.java diff --git a/src/main/java/com/consid/bpm/camunda/secrets/common/ProviderAppConfig.java b/src/main/java/com/consid/bpm/camunda/secrets/common/ProviderAppConfig.java index 2e3b8bc..2804bb8 100644 --- a/src/main/java/com/consid/bpm/camunda/secrets/common/ProviderAppConfig.java +++ b/src/main/java/com/consid/bpm/camunda/secrets/common/ProviderAppConfig.java @@ -5,15 +5,18 @@ import com.consid.bpm.camunda.secrets.provider.kv.GenericKeyValueVaultSecretService; import com.consid.bpm.camunda.secrets.provider.kv.VersionedKeyValueVaultSecretService; import com.consid.bpm.camunda.secrets.worker.CustomJobWorker; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.vault.authentication.TokenAuthentication; import org.springframework.vault.client.VaultEndpoint; import org.springframework.vault.core.VaultTemplate; +import org.springframework.vault.core.VaultVersionedKeyValueTemplate; import java.net.URI; +@Slf4j @Configuration public class ProviderAppConfig { @@ -29,7 +32,7 @@ public VaultSecretProvider secretProvider(VaultSecretService vaultSecretService) @Bean public VaultTemplate vaultTemplate(VaultConfigurationProperties properties) { - URI endpoint = URI.create(String.format("%s:%d", properties.getHost(), properties.getPort())); + var endpoint = URI.create(String.format("%s:%d", properties.getHost(), properties.getPort())); return new VaultTemplate(VaultEndpoint.from(endpoint), new TokenAuthentication(properties.getToken())); } @@ -39,6 +42,7 @@ VaultSecretService genericKeyValueVaultService( VaultTemplate vaultTemplate, VaultConfigurationProperties properties ) { + log.info("Initializing generic key value backend '{}' for vault", properties.getBackend()); return new GenericKeyValueVaultSecretService(vaultTemplate, properties.getPath(), properties.getBackend()); } @@ -48,7 +52,9 @@ VaultSecretService versionedKeyValueVaultService( VaultTemplate vaultTemplate, VaultConfigurationProperties properties ) { - return new VersionedKeyValueVaultSecretService(vaultTemplate, properties.getPath(), properties.getBackend(), properties.getSecretVersion()); + log.info("Initializing versioned key value backend '{}' for vault", properties.getBackend()); + var versionedTemplate = new VaultVersionedKeyValueTemplate(vaultTemplate, properties.getBackend()); + return new VersionedKeyValueVaultSecretService(versionedTemplate, properties.getPath(), properties.getSecretVersion()); } } diff --git a/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretService.java b/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretService.java index 3c7cdc0..8096046 100644 --- a/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretService.java +++ b/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretService.java @@ -22,7 +22,6 @@ public GenericKeyValueVaultSecretService(VaultTemplate vaultTemplate, String pat this.vaultTemplate = vaultTemplate; this.path = path; this.backend = backend; - log.info("Initializing generic key value backend '{}' for vault", backend); } @Override @@ -39,7 +38,7 @@ public Optional getSecretByKey(String key) { private Map readSecretsFromPath() { try { // secrets are read from v1 api from backend/path (no data segment) - VaultResponse response = vaultTemplate.read(backend + "/" + path); + var response = vaultTemplate.read(backend + "/" + path); if (response != null) { return response.getRequiredData(); } diff --git a/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretService.java b/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretService.java index dc94dcd..13022e8 100644 --- a/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretService.java +++ b/src/main/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretService.java @@ -3,7 +3,6 @@ import com.consid.bpm.camunda.secrets.provider.VaultSecretService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.springframework.vault.core.VaultTemplate; import org.springframework.vault.core.VaultVersionedKeyValueTemplate; import org.springframework.vault.support.Versioned; @@ -18,11 +17,10 @@ public class VersionedKeyValueVaultSecretService implements VaultSecretService { private final String path; private final int version; - public VersionedKeyValueVaultSecretService(VaultTemplate vaultVTemplate, String path, String backend, int version) { + public VersionedKeyValueVaultSecretService(VaultVersionedKeyValueTemplate vaultTemplate, String path, int version) { this.path = path; this.version = version; - this.vaultTemplate = new VaultVersionedKeyValueTemplate(vaultVTemplate, backend); - log.info("Initializing versioned key value backend '{}' for vault", backend); + this.vaultTemplate = vaultTemplate; } @@ -33,14 +31,14 @@ public Map getSecretsFromVault() { @Override public Optional getSecretByKey(String key) { - Map secrets = readSecretsFromVault(); + var secrets = readSecretsFromVault(); return Optional.ofNullable(secrets.get(key)); } private Map readSecretsFromVault() { try { // secrets are read from v2 api from backend/data/path - Versioned> secrets = vaultTemplate.get(path, Versioned.Version.from(version)); + var secrets = vaultTemplate.get(path, Versioned.Version.from(version)); if (secrets != null) { return secrets.getRequiredData(); } diff --git a/src/test/java/com/consid/bpm/camunda/secrets/provider/VaultSecretProviderTest.java b/src/test/java/com/consid/bpm/camunda/secrets/provider/VaultSecretProviderTest.java index 4f4750f..313c551 100644 --- a/src/test/java/com/consid/bpm/camunda/secrets/provider/VaultSecretProviderTest.java +++ b/src/test/java/com/consid/bpm/camunda/secrets/provider/VaultSecretProviderTest.java @@ -1,5 +1,6 @@ package com.consid.bpm.camunda.secrets.provider; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -17,13 +18,18 @@ class VaultSecretProviderTest { @Mock - VaultSecretService secretService; + private VaultSecretService secretService; + private VaultSecretProvider provider; + + @BeforeEach + public void setUp() { + provider = new VaultSecretProvider(secretService); + } @Test public void test_secrets_retrieved_as_expected() { // given Mockito.when(secretService.getSecretsFromVault()).thenReturn(Map.of("apiKey", "1234-5678-9012-3456")); - VaultSecretProvider provider = new VaultSecretProvider(secretService); // when String apiKey = provider.getSecret("apiKey"); @@ -36,7 +42,6 @@ public void test_secrets_retrieved_as_expected() { public void test_secrets_cached_as_expected() { // given Mockito.when(secretService.getSecretsFromVault()).thenReturn(Map.of("apiKey", "1234-5678-9012-3456")); - VaultSecretProvider provider = new VaultSecretProvider(secretService); // when String apiKey = provider.getSecret("apiKey"); @@ -52,7 +57,6 @@ public void test_secrets_cached_as_expected() { public void test_unknown_secrets_return_null_as_expected() { // given Mockito.when(secretService.getSecretsFromVault()).thenReturn(Collections.emptyMap()); - VaultSecretProvider provider = new VaultSecretProvider(secretService); // when String apiKey = provider.getSecret("unknown"); diff --git a/src/test/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretServiceTest.java b/src/test/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretServiceTest.java new file mode 100644 index 0000000..354f56c --- /dev/null +++ b/src/test/java/com/consid/bpm/camunda/secrets/provider/kv/GenericKeyValueVaultSecretServiceTest.java @@ -0,0 +1,93 @@ +package com.consid.bpm.camunda.secrets.provider.kv; + +import com.consid.bpm.camunda.secrets.provider.VaultSecretService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.vault.core.VaultTemplate; +import org.springframework.vault.support.VaultResponse; + +import java.util.Map; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class GenericKeyValueVaultSecretServiceTest { + + @Mock + private VaultTemplate vaultTemplate; + private VaultSecretService secretService; + + @BeforeEach + public void setUp() { + secretService = new GenericKeyValueVaultSecretService(vaultTemplate, "path", "backend"); + } + + @Test + public void test_secrets_are_loaded_as_expected() { + // given + Map expectedSecrets = Map.of("apiKey", "0000-0000-0000-0000"); + VaultResponse response = new VaultResponse(); + response.setData(expectedSecrets); + Mockito.when(vaultTemplate.read(anyString())).thenReturn(response); + + // when + Map secrets = secretService.getSecretsFromVault(); + + // then + assertThat(secrets).isEqualTo(expectedSecrets); + verify(vaultTemplate).read(eq("backend/path")); + } + + @Test + public void test_existing_secret_by_key_is_returned_as_expected() { + // given + Map expectedSecrets = Map.of("apiKey", "0000-0000-0000-0000"); + VaultResponse response = new VaultResponse(); + response.setData(expectedSecrets); + Mockito.when(vaultTemplate.read(anyString())).thenReturn(response); + + // when + Optional secret = secretService.getSecretByKey("apiKey"); + + // then + assertThat(secret.isPresent()).isTrue(); + assertThat(secret.get()).isEqualTo("0000-0000-0000-0000"); + } + + @Test + public void test_non_existing_secret_by_key_is_returned_empty_as_expected() { + // given + Map expectedSecrets = Map.of("apiKey", "0000-0000-0000-0000"); + VaultResponse response = new VaultResponse(); + response.setData(expectedSecrets); + Mockito.when(vaultTemplate.read(anyString())).thenReturn(response); + + // when + Optional secret = secretService.getSecretByKey("unknown"); + + // then + assertThat(secret.isPresent()).isFalse(); + } + + @Test + public void test_empty_secrets_return_empty_map_as_expected() { + // given + VaultResponse response = new VaultResponse(); + Mockito.when(vaultTemplate.read(anyString())).thenReturn(response); + + // when + Map secrets = secretService.getSecretsFromVault(); + + // then + assertThat(secrets).isEmpty(); + } + +} \ No newline at end of file diff --git a/src/test/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretServiceTest.java b/src/test/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretServiceTest.java new file mode 100644 index 0000000..db39da2 --- /dev/null +++ b/src/test/java/com/consid/bpm/camunda/secrets/provider/kv/VersionedKeyValueVaultSecretServiceTest.java @@ -0,0 +1,91 @@ +package com.consid.bpm.camunda.secrets.provider.kv; + +import com.consid.bpm.camunda.secrets.provider.VaultSecretService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.vault.core.VaultVersionedKeyValueTemplate; +import org.springframework.vault.support.Versioned; + +import java.util.Map; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class VersionedKeyValueVaultSecretServiceTest { + + @Mock + private VaultVersionedKeyValueTemplate vaultTemplate; + private VaultSecretService secretService; + + @BeforeEach + public void setUp() { + secretService = new VersionedKeyValueVaultSecretService(vaultTemplate, "path", 1); + } + + @Test + public void test_secrets_are_loaded_as_expected() { + // given + Map expectedSecrets = Map.of("apiKey", "0000-0000-0000-0000"); + Versioned.Version expectedVersion = Versioned.Version.from(1); + Versioned> versionedSecrets = Versioned.create(expectedSecrets, expectedVersion); + Mockito.when(vaultTemplate.get(anyString(), any(Versioned.Version.class))).thenReturn(versionedSecrets); + + // when + Map secrets = secretService.getSecretsFromVault(); + + // then + assertThat(secrets).isEqualTo(expectedSecrets); + verify(vaultTemplate).get(eq("path"), eq(expectedVersion)); + } + + @Test + public void test_existing_secret_by_key_is_returned_as_expected() { + // given + Map expectedSecrets = Map.of("apiKey", "0000-0000-0000-0000"); + Versioned.Version expectedVersion = Versioned.Version.from(1); + Versioned> versionedSecrets = Versioned.create(expectedSecrets, expectedVersion); + Mockito.when(vaultTemplate.get(anyString(), any(Versioned.Version.class))).thenReturn(versionedSecrets); + + // when + Optional secret = secretService.getSecretByKey("apiKey"); + + // then + assertThat(secret.isPresent()).isTrue(); + assertThat(secret.get()).isEqualTo("0000-0000-0000-0000"); + } + + @Test + public void test_non_existing_secret_by_key_is_returned_empty_as_expected() { + // given + Versioned> versionedSecrets = Versioned.create(Map.of()); + Mockito.when(vaultTemplate.get(anyString(), any(Versioned.Version.class))).thenReturn(versionedSecrets); + + // when + Optional secret = secretService.getSecretByKey("unknown"); + + // then + assertThat(secret.isPresent()).isFalse(); + } + + @Test + public void test_empty_secrets_return_empty_map_as_expected() { + // given + Versioned.Version expectedVersion = Versioned.Version.from(1); + Versioned> versionedSecrets = Versioned.create(null, expectedVersion); + Mockito.when(vaultTemplate.get(anyString(), any(Versioned.Version.class))).thenReturn(versionedSecrets); + + // when + Map secrets = secretService.getSecretsFromVault(); + + // then + assertThat(secrets).isEmpty(); + } + +} \ No newline at end of file