From e81a936a9660f3acc8d98f549b89d7990f2334b1 Mon Sep 17 00:00:00 2001 From: Max Lambrecht Date: Wed, 15 Jul 2020 14:41:28 -0300 Subject: [PATCH] Refactors and tests in java-spiffe-helper. Signed-off-by: Max Lambrecht --- .../java/io/spiffe/helper/cli/Config.java | 96 ++++++++++++ .../java/io/spiffe/helper/cli/Runner.java | 108 +------------ .../helper/exception/RunnerException.java | 4 + .../io/spiffe/helper/keystore/KeyStore.java | 2 +- .../helper/keystore/KeyStoreHelper.java | 19 +-- .../java/io/spiffe/helper/cli/ConfigTest.java | 142 ++++++++++++++++++ .../java/io/spiffe/helper/cli/RunnerTest.java | 75 +++------ .../helper/keystore/KeyStoreHelperTest.java | 70 ++++++++- .../spiffe/helper/keystore/KeyStoreTest.java | 39 ++++- .../test/resources/testdata/cli/correct.conf | 2 +- 10 files changed, 382 insertions(+), 175 deletions(-) create mode 100644 java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Config.java create mode 100644 java-spiffe-helper/src/test/java/io/spiffe/helper/cli/ConfigTest.java diff --git a/java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Config.java b/java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Config.java new file mode 100644 index 0000000..f3f54c9 --- /dev/null +++ b/java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Config.java @@ -0,0 +1,96 @@ +package io.spiffe.helper.cli; + +import io.spiffe.helper.exception.RunnerException; +import io.spiffe.helper.keystore.KeyStoreHelper.KeyStoreOptions; +import io.spiffe.helper.keystore.KeyStoreType; +import lombok.val; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.InvalidParameterException; +import java.util.Properties; + +class Config { + + static final Option CONFIG_FILE_OPTION = + Option.builder("c") + .longOpt("config") + .hasArg(true) + .required(true) + .build(); + + private Config() { + } + + static Properties parseConfigFileProperties(final Path configFilePath) throws RunnerException { + Properties properties = new Properties(); + try (InputStream in = Files.newInputStream(configFilePath)) { + properties.load(in); + } catch (IOException e) { + val error = String.format("Cannot open config file: %s", configFilePath); + throw new RunnerException(error, e); + } + return properties; + } + + static String getCliConfigOption(final String... args) throws RunnerException { + final Options cliOptions = new Options(); + cliOptions.addOption(CONFIG_FILE_OPTION); + CommandLineParser parser = new DefaultParser(); + try { + val cmd = parser.parse(cliOptions, args); + return cmd.getOptionValue("config"); + } catch (ParseException e) { + val error = String.format("%s. Use -c, --config ", e.getMessage()); + throw new RunnerException(error); + } + } + + static KeyStoreOptions createKeyStoreOptions(final Properties properties) { + val keyStorePath = getProperty(properties, "keyStorePath"); + val keyStorePass = getProperty(properties, "keyStorePass"); + val keyPass = getProperty(properties, "keyPass"); + val trustStorePath = getProperty(properties, "trustStorePath"); + val trustStorePass = getProperty(properties, "trustStorePass"); + + val keyAlias = properties.getProperty("keyAlias", null); + val spiffeSocketPath = properties.getProperty("spiffeSocketPath", null); + val keyStoreTypeProp = properties.getProperty("keyStoreType", null); + + KeyStoreType keyStoreType; + if (StringUtils.isNotBlank(keyStoreTypeProp)) { + keyStoreType = KeyStoreType.parse(keyStoreTypeProp); + } else { + keyStoreType = KeyStoreType.getDefaultType(); + } + + return KeyStoreOptions.builder() + .keyStorePath(Paths.get(keyStorePath)) + .keyStorePass(keyStorePass) + .keyPass(keyPass) + .trustStorePath(Paths.get(trustStorePath)) + .trustStorePass(trustStorePass) + .keyAlias(keyAlias) + .spiffeSocketPath(spiffeSocketPath) + .keyStoreType(keyStoreType) + .build(); + + } + + static String getProperty(final Properties properties, final String key) { + final String value = properties.getProperty(key); + if (StringUtils.isBlank(value)) { + throw new InvalidParameterException(String.format("Missing value for config property: %s", key)); + } + return value; + } +} diff --git a/java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Runner.java b/java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Runner.java index f6dfffb..edc2fa0 100644 --- a/java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Runner.java +++ b/java-spiffe-helper/src/main/java/io/spiffe/helper/cli/Runner.java @@ -4,23 +4,12 @@ import io.spiffe.exception.SocketEndpointAddressException; import io.spiffe.helper.exception.KeyStoreHelperException; import io.spiffe.helper.exception.RunnerException; import io.spiffe.helper.keystore.KeyStoreHelper; -import io.spiffe.helper.keystore.KeyStoreType; import lombok.extern.java.Log; import lombok.val; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.commons.lang3.StringUtils; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Properties; +import java.security.InvalidParameterException; +import java.security.KeyStoreException; /** * Entry point of the CLI to run the KeyStoreHelper. @@ -37,102 +26,19 @@ public class Runner { * In the args needs to be passed the config file option as: "-c" and "path_to_config_file" * * @param args contains the option with the config file path + * @throws RunnerException is there is an error configuring or creating the KeyStoreHelper. */ public static void main(final String ...args) throws RunnerException { - String configFilePath = null; try { - configFilePath = getCliConfigOption(args); - val parameters = parseConfigFile(Paths.get(configFilePath)); - val options = toKeyStoreOptions(parameters); + val configFilePath = Config.getCliConfigOption(args); + val properties = Config.parseConfigFileProperties(Paths.get(configFilePath)); + val options = Config.createKeyStoreOptions(properties); try (val keyStoreHelper = KeyStoreHelper.create(options)) { keyStoreHelper.run(true); } - } catch (SocketEndpointAddressException | KeyStoreHelperException | RunnerException | IllegalArgumentException e) { + } catch (SocketEndpointAddressException | KeyStoreHelperException | RunnerException | InvalidParameterException | KeyStoreException e) { log.severe(e.getMessage()); throw new RunnerException(e); } } - - static Properties parseConfigFile(final Path configFilePath) throws RunnerException { - Properties prop = new Properties(); - try (InputStream in = Files.newInputStream(configFilePath)) { - prop.load(in); - } catch (IOException e) { - val error = String.format("Cannot open config file: %s %n %s", configFilePath, e.getMessage()); - throw new RunnerException(error); - } - return prop; - } - - static String getCliConfigOption(final String ...args) throws RunnerException { - final Options cliOptions = new Options(); - final Option confOption = new Option("c", "config", true, "config file"); - confOption.setRequired(true); - cliOptions.addOption(confOption); - CommandLineParser parser = new DefaultParser(); - CommandLine cmd = null; - try { - cmd = parser.parse(cliOptions, args); - } catch (ParseException e) { - val error = String.format( "%s. Use -c, --config ", e.getMessage()); - throw new RunnerException(error); - } - return cmd.getOptionValue("config"); - } - - private static KeyStoreHelper.KeyStoreOptions toKeyStoreOptions(final Properties properties) { - - val keyStorePath = getString(properties, "keyStorePath"); - if (StringUtils.isBlank(keyStorePath)) { - throw new IllegalArgumentException("keyStorePath config is missing"); - } - - val keyStorePass = getString(properties, "keyStorePass"); - if (StringUtils.isBlank(keyStorePass)) { - throw new IllegalArgumentException("keyStorePass config is missing"); - } - - val keyPass = getString(properties, "keyPass"); - if (StringUtils.isBlank(keyPass)) { - throw new IllegalArgumentException("keyPass config is missing"); - } - - val trustStorePath = getString(properties, "trustStorePath"); - if (StringUtils.isBlank(trustStorePath)) { - throw new IllegalArgumentException("trustStorePath config is missing"); - } - - val trustStorePass = getString(properties, "trustStorePass"); - if (StringUtils.isBlank(trustStorePass)) { - throw new IllegalArgumentException("trustStorePass config is missing"); - } - - val keyAlias = getString(properties, "keyAlias"); - val spiffeSocketPath = getString(properties, "spiffeSocketPath"); - - KeyStoreType keyStoreType = null; - val keyStoreTypeProp = properties.get("keyStoreType"); - if (keyStoreTypeProp != null) { - keyStoreType = KeyStoreType.parse(keyStoreTypeProp); - } - - return KeyStoreHelper.KeyStoreOptions.builder() - .keyStorePath(Paths.get(keyStorePath)) - .keyStorePass(keyStorePass) - .keyPass(keyPass) - .trustStorePath(Paths.get(trustStorePath)) - .trustStorePass(trustStorePass) - .keyAlias(keyAlias) - .spiffeSocketPath(spiffeSocketPath) - .keyStoreType(keyStoreType) - .build(); - } - - private static String getString(final Properties properties, final String propName) { - val property = properties.getProperty(propName); - if (property == null) { - return ""; - } - return property; - } } diff --git a/java-spiffe-helper/src/main/java/io/spiffe/helper/exception/RunnerException.java b/java-spiffe-helper/src/main/java/io/spiffe/helper/exception/RunnerException.java index 4860f9c..3711029 100644 --- a/java-spiffe-helper/src/main/java/io/spiffe/helper/exception/RunnerException.java +++ b/java-spiffe-helper/src/main/java/io/spiffe/helper/exception/RunnerException.java @@ -11,4 +11,8 @@ public class RunnerException extends Exception { public RunnerException(Throwable cause) { super(cause); } + + public RunnerException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStore.java b/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStore.java index 361936d..0f49020 100644 --- a/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStore.java +++ b/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStore.java @@ -57,7 +57,7 @@ class KeyStore { } return keyStore; } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - throw new KeyStoreException(e); + throw new KeyStoreException("KeyStore cannot be created", e); } } diff --git a/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStoreHelper.java b/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStoreHelper.java index 1d6286f..cc9159e 100644 --- a/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStoreHelper.java +++ b/java-spiffe-helper/src/main/java/io/spiffe/helper/keystore/KeyStoreHelper.java @@ -66,8 +66,9 @@ public class KeyStoreHelper implements Closeable { * @return an instance of a KeyStoreHelper * @throws SocketEndpointAddressException if the socket endpoint address is not valid * @throws KeyStoreHelperException if the KeyStoreHelper cannot be created + * @throws KeyStoreException if the underlying java KeyStore and TrustStore cannot be created */ - public static KeyStoreHelper create(@NonNull final KeyStoreOptions options) throws SocketEndpointAddressException, KeyStoreHelperException { + public static KeyStoreHelper create(@NonNull final KeyStoreOptions options) throws SocketEndpointAddressException, KeyStoreHelperException, KeyStoreException { if (options.keyStorePath.equals(options.trustStorePath)) { throw new KeyStoreHelperException("KeyStore and TrustStore should use different files"); @@ -142,16 +143,12 @@ public class KeyStoreHelper implements Closeable { this.workloadApiClient = workloadApiClient; } - private static KeyStore createKeyStore(KeyStoreOptions options, Path keyStorePath, String keyStorePass) throws KeyStoreHelperException { - try { - return KeyStore.builder() - .keyStoreFilePath(keyStorePath) - .keyStoreType(options.keyStoreType) - .keyStorePassword(keyStorePass) - .build(); - } catch (KeyStoreException e) { - throw new KeyStoreHelperException("Error creating KeyStore/TrustStore", e); - } + private static KeyStore createKeyStore(KeyStoreOptions options, Path keyStorePath, String keyStorePass) throws KeyStoreException { + return KeyStore.builder() + .keyStoreFilePath(keyStorePath) + .keyStoreType(options.keyStoreType) + .keyStorePassword(keyStorePass) + .build(); } private static WorkloadApiClient createNewClient(final String spiffeSocketPath) throws SocketEndpointAddressException { diff --git a/java-spiffe-helper/src/test/java/io/spiffe/helper/cli/ConfigTest.java b/java-spiffe-helper/src/test/java/io/spiffe/helper/cli/ConfigTest.java new file mode 100644 index 0000000..3580d12 --- /dev/null +++ b/java-spiffe-helper/src/test/java/io/spiffe/helper/cli/ConfigTest.java @@ -0,0 +1,142 @@ +package io.spiffe.helper.cli; + +import io.spiffe.helper.exception.RunnerException; +import io.spiffe.helper.keystore.KeyStoreHelper; +import io.spiffe.helper.keystore.KeyStoreType; +import lombok.val; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.Test; + +import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.util.Properties; + +import static io.spiffe.helper.utils.TestUtils.toUri; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +class ConfigTest { + + @Test + void parseConfigFileProperties() throws URISyntaxException { + val path = Paths.get(toUri("testdata/cli/correct.conf")); + + Properties properties = null; + try { + properties = Config.parseConfigFileProperties(path); + } catch (RunnerException e) { + fail(e); + } + + assertEquals("keystore123.p12", properties.getProperty("keyStorePath")); + assertEquals("example123", properties.getProperty("keyStorePass")); + assertEquals("pass123", properties.getProperty("keyPass")); + assertEquals("truststore123.p12", properties.getProperty("trustStorePath")); + assertEquals("otherpass123", properties.getProperty("trustStorePass")); + assertEquals("jks", properties.getProperty("keyStoreType")); + assertEquals("other_alias", properties.getProperty("keyAlias")); + assertEquals("unix:/tmp/test", properties.getProperty("spiffeSocketPath")); + } + + @Test + void parseConfigFile_doesNotExist() { + val randomFileName = RandomStringUtils.randomAlphabetic(10); + val path = Paths.get(randomFileName); + try { + Config.parseConfigFileProperties(path); + fail(); + } catch (RunnerException e) { + assertEquals("Cannot open config file: " + randomFileName, e.getMessage()); + } + + } + + @Test + void getCliConfigOption_validOption() { + try { + String option = Config.getCliConfigOption("-c", "test"); + assertEquals("test", option); + } catch (RunnerException e) { + fail(); + } + } + + @Test + void getCliConfigOption_validLongOption() { + try { + String option = Config.getCliConfigOption("--config", "example"); + assertEquals("example", option); + } catch (RunnerException e) { + fail(); + } + } + + @Test + void getCliConfigOption_unknownOption() { + try { + String option = Config.getCliConfigOption("-a", "test"); + } catch (RunnerException e) { + assertEquals("Unrecognized option: -a. Use -c, --config ", e.getMessage()); + } + } + + @Test + void testGetCliConfigOption_unknownLongOption() { + try { + Config.getCliConfigOption("--unknown", "example"); + fail("expected parse exception"); + } catch (RunnerException e) { + assertEquals("Unrecognized option: --unknown. Use -c, --config ", e.getMessage()); + } + } + + @Test + void createKeyStoreOptions() throws URISyntaxException { + Properties configuration = getValidConfiguration(); + KeyStoreHelper.KeyStoreOptions keyStoreOptions = Config.createKeyStoreOptions(configuration); + + assertEquals("keystore123.p12", keyStoreOptions.getKeyStorePath().toString()); + assertEquals("example123", keyStoreOptions.getKeyStorePass()); + assertEquals("pass123", keyStoreOptions.getKeyPass()); + assertEquals("truststore123.p12", keyStoreOptions.getTrustStorePath().toString()); + assertEquals("otherpass123", keyStoreOptions.getTrustStorePass()); + assertEquals("jks", keyStoreOptions.getKeyStoreType().value()); + assertEquals("other_alias", keyStoreOptions.getKeyAlias()); + assertEquals("unix:/tmp/test", keyStoreOptions.getSpiffeSocketPath()); + } + + @Test + void createKeyStoreOptions_aRequiredProperty_is_missing() throws URISyntaxException { + Properties configuration = getValidConfiguration(); + + // remove a required config + configuration.setProperty("trustStorePass", ""); + + try { + Config.createKeyStoreOptions(configuration); + fail(); + } catch (Exception e) { + assertEquals("Missing value for config property: trustStorePass", e.getMessage()); + } + } + + @Test + void createKeyStoreOptions_keyStoreTypeMissing_useDefault() throws URISyntaxException { + Properties configuration = getValidConfiguration(); + + configuration.setProperty("keyStoreType", ""); + + KeyStoreHelper.KeyStoreOptions keyStoreOptions = Config.createKeyStoreOptions(configuration); + assertEquals(KeyStoreType.getDefaultType(), keyStoreOptions.getKeyStoreType()); + } + + Properties getValidConfiguration() throws URISyntaxException { + val path = Paths.get(toUri("testdata/cli/correct.conf")); + Properties properties = null; + try { + return Config.parseConfigFileProperties(path); + } catch (RunnerException e) { + throw new IllegalStateException(e); + } + } +} \ No newline at end of file diff --git a/java-spiffe-helper/src/test/java/io/spiffe/helper/cli/RunnerTest.java b/java-spiffe-helper/src/test/java/io/spiffe/helper/cli/RunnerTest.java index 7ad3b99..9be7ac3 100644 --- a/java-spiffe-helper/src/test/java/io/spiffe/helper/cli/RunnerTest.java +++ b/java-spiffe-helper/src/test/java/io/spiffe/helper/cli/RunnerTest.java @@ -1,14 +1,14 @@ package io.spiffe.helper.cli; -import io.spiffe.exception.SocketEndpointAddressException; import io.spiffe.helper.exception.RunnerException; +import lombok.val; import org.junit.jupiter.api.Test; +import java.io.File; +import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.KeyStoreException; -import java.util.Properties; import static io.spiffe.helper.utils.TestUtils.toUri; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -17,104 +17,73 @@ import static org.junit.jupiter.api.Assertions.fail; class RunnerTest { @Test - void test_Main_KeyStorePathIsMissing() throws KeyStoreException, SocketEndpointAddressException, URISyntaxException { + void test_Main_KeyStorePathIsMissing() throws URISyntaxException { final Path path = Paths.get(toUri("testdata/cli/missing-keystorepath.conf")); try { Runner.main("-c", path.toString()); fail("expected exception: property is missing"); } catch (RunnerException e) { - assertEquals("keyStorePath config is missing", e.getCause().getMessage()); + assertEquals("Missing value for config property: keyStorePath", e.getCause().getMessage()); } } @Test - void test_Main_KeyStorePassIsMissing() throws KeyStoreException, SocketEndpointAddressException, URISyntaxException { + void test_Main_KeyStorePassIsMissing() throws URISyntaxException { final Path path = Paths.get(toUri("testdata/cli/missing-keystorepass.conf")); try { Runner.main("-c", path.toString()); fail("expected exception: property is missing"); } catch (RunnerException e) { - assertEquals("keyStorePass config is missing", e.getCause().getMessage()); + assertEquals("Missing value for config property: keyStorePass", e.getCause().getMessage()); } } @Test - void test_Main_KeyPassIsMissing() throws KeyStoreException, SocketEndpointAddressException, URISyntaxException { + void test_Main_KeyPassIsMissing() throws URISyntaxException { final Path path = Paths.get(toUri("testdata/cli/missing-keypass.conf")); try { Runner.main("-c", path.toString()); fail("expected exception: property is missing"); } catch (RunnerException e) { - assertEquals("keyPass config is missing", e.getCause().getMessage()); + assertEquals("Missing value for config property: keyPass", e.getCause().getMessage()); } } @Test - void test_Main_TrustStorePathIsMissing() throws KeyStoreException, SocketEndpointAddressException, URISyntaxException { + void test_Main_TrustStorePathIsMissing() throws URISyntaxException { final Path path = Paths.get(toUri("testdata/cli/missing-truststorepath.conf")); try { Runner.main("-c", path.toString()); fail("expected exception: property is missing"); } catch (RunnerException e) { - assertEquals("trustStorePath config is missing", e.getCause().getMessage()); + assertEquals("Missing value for config property: trustStorePath", e.getCause().getMessage()); } } @Test - void test_Main_TrustStorePassIsMissing() throws KeyStoreException, SocketEndpointAddressException, URISyntaxException { + void test_Main_TrustStorePassIsMissing() throws URISyntaxException { final Path path = Paths.get(toUri("testdata/cli/missing-truststorepass.conf")); try { Runner.main("-c", path.toString()); fail("expected exception: property is missing"); } catch (RunnerException e) { - assertEquals("trustStorePass config is missing", e.getCause().getMessage()); + assertEquals("Missing value for config property: trustStorePass", e.getCause().getMessage()); } } @Test - void testGetCliConfigOption_abbreviated() { - String option = null; + void test_Main_throwsExceptionIfTheKeystoreCannotBeCreated() throws URISyntaxException, IOException { + val file = new File("keystore123.p12"); + file.createNewFile(); + + val configPath = Paths.get(toUri("testdata/cli/correct.conf")); try { - option = Runner.getCliConfigOption("-c", "example"); + Runner.main("-c", configPath.toString()); } catch (RunnerException e) { - fail(e); - } - assertEquals("example", option); - } - - @Test - void testGetCliConfigOption() { - String option = null; - try { - option = Runner.getCliConfigOption("--config", "example"); - } catch (RunnerException e) { - fail(e); - } - assertEquals("example", option); - } - - @Test - void testGetCliConfigOption_nonExistent() { - try { - Runner.getCliConfigOption("--unknown", "example"); - fail("expected parse exception"); - } catch (RunnerException e) { - assertEquals("Unrecognized option: --unknown. Use -c, --config ", e.getMessage()); + assertEquals("KeyStore cannot be created", e.getCause().getMessage()); + } finally { + file.delete(); } } - @Test - void test_ParseConfigFile() throws URISyntaxException, RunnerException { - final Path path = Paths.get(toUri("testdata/cli/correct.conf")); - final Properties properties = Runner.parseConfigFile(path); - - assertEquals("keystore123.p12", properties.getProperty("keyStorePath")); - assertEquals("example123", properties.getProperty("keyStorePass")); - assertEquals("pass123", properties.getProperty("keyPass")); - assertEquals("truststore123.p12", properties.getProperty("trustStorePath")); - assertEquals("otherpass123", properties.getProperty("trustStorePass")); - assertEquals("jks", properties.getProperty("keyStoreType")); - assertEquals("other_alias", properties.getProperty("keyAlias")); - assertEquals("unix:/tmp/agent.sock", properties.getProperty("spiffeSocketPath")); - } } \ No newline at end of file diff --git a/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreHelperTest.java b/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreHelperTest.java index c4f26b0..d85370a 100644 --- a/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreHelperTest.java +++ b/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreHelperTest.java @@ -149,6 +149,8 @@ class KeyStoreHelperTest { fail("expected exception: KeyStore and TrustStore should use different files"); } catch (KeyStoreHelperException e) { assertEquals("KeyStore and TrustStore should use different files", e.getMessage()); + } catch (KeyStoreException e) { + fail(e); } } @@ -181,6 +183,8 @@ class KeyStoreHelperTest { } catch (KeyStoreHelperException e) { assertEquals("Error running KeyStoreHelper", e.getMessage()); assertEquals("java.nio.file.NoSuchFileException: dummy:/invalid", e.getCause().getCause().getMessage()); + } catch (KeyStoreException e) { + fail(e); } } @@ -201,7 +205,7 @@ class KeyStoreHelperTest { KeyStoreHelper.create(null); } catch (NullPointerException e) { assertEquals("options is marked non-null but is null", e.getMessage()); - } catch (SocketEndpointAddressException | KeyStoreHelperException e) { + } catch (SocketEndpointAddressException | KeyStoreHelperException | KeyStoreException e) { fail(); } } @@ -232,6 +236,70 @@ class KeyStoreHelperTest { } } + @Test + void keyStoreHelperOptions_allNull() { + try { + KeyStoreHelper.KeyStoreOptions.builder().build(); + } catch (NullPointerException e) { + assertEquals("keyStorePath is marked non-null but is null", e.getMessage()); + } + } + + @Test + void keyStoreHelperOptions_trustStorePathNull() { + try { + KeyStoreHelper.KeyStoreOptions + .builder() + .keyStorePath(Paths.get("test")) + .build(); + } catch (NullPointerException e) { + assertEquals("trustStorePath is marked non-null but is null", e.getMessage()); + } + } + + @Test + void keyStoreHelperOptions_keyStorePassNull() { + try { + KeyStoreHelper.KeyStoreOptions + .builder() + .keyStorePath(Paths.get("test")) + .trustStorePath(Paths.get("example")) + .build(); + } catch (NullPointerException e) { + assertEquals("keyStorePass is marked non-null but is null", e.getMessage()); + } + } + + @Test + void keyStoreHelperOptions_trustStorePassNull() { + try { + KeyStoreHelper.KeyStoreOptions + .builder() + .keyStorePath(Paths.get("test")) + .trustStorePath(Paths.get("example")) + .keyStorePass("example1") + .build(); + } catch (NullPointerException e) { + assertEquals("trustStorePass is marked non-null but is null", e.getMessage()); + } + } + + @Test + void keyStoreHelperOptions_keyPassNull() { + try { + KeyStoreHelper.KeyStoreOptions + .builder() + .keyStorePath(Paths.get("test")) + .trustStorePath(Paths.get("example")) + .keyStorePass("example1") + .trustStorePass("example2") + .build(); + } catch (NullPointerException e) { + assertEquals("keyPass is marked non-null but is null", e.getMessage()); + } + } + + private KeyStoreHelper.KeyStoreOptions getKeyStoreValidOptions(WorkloadApiClient workloadApiClient) { val keyStorefileName = RandomStringUtils.randomAlphabetic(10); keyStoreFilePath = Paths.get(keyStorefileName); diff --git a/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreTest.java b/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreTest.java index 00422c0..84c5149 100644 --- a/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreTest.java +++ b/java-spiffe-helper/src/test/java/io/spiffe/helper/keystore/KeyStoreTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; @@ -144,26 +145,33 @@ public class KeyStoreTest { @Test void testNewKeyStore_nullKeyStorePath_throwsException() throws KeyStoreException { try { - KeyStore.builder() - .keyStoreFilePath(null) - .keyStoreType(KeyStoreType.JKS) - .keyStorePassword("keyStorePassword") - .build(); + KeyStore.builder().build(); fail("exception expected"); } catch (NullPointerException e) { assertEquals("keyStoreFilePath is marked non-null but is null", e.getMessage()); } } + @Test + void testNewKeyStore_nullKeyStoreType_throwsException() throws KeyStoreException { + try { + KeyStore.builder() + .keyStoreFilePath(Paths.get("anypath")) + .build(); + fail("exception expected"); + } catch (NullPointerException e) { + assertEquals("keyStoreType is marked non-null but is null", e.getMessage()); + } + } + @Test void testNewKeyStore_nullKeyStorePassword_throwsException() throws KeyStoreException { try { KeyStore.builder() .keyStoreFilePath(Paths.get("anypath")) .keyStoreType(KeyStoreType.PKCS12) - .keyStorePassword(null) .build(); - fail("exception expected"); + fail("exception expected: keyStorePassword cannot be blank"); } catch (NullPointerException e) { assertEquals("keyStorePassword is marked non-null but is null", e.getMessage()); } @@ -183,6 +191,23 @@ public class KeyStoreTest { } } + @Test + void testLoadKeyStore_invalidFile() throws IOException { + File file = new File("test.txt"); + file.createNewFile(); + try { + KeyStore.builder() + .keyStoreFilePath(file.toPath()) + .keyStoreType(KeyStoreType.PKCS12) + .keyStorePassword("example") + .build(); + } catch (KeyStoreException e) { + assertEquals("KeyStore cannot be created", e.getMessage()); + } finally { + file.delete(); + } + } + @AfterEach void tearDown() { deleteFile(keyStoreFilePath); diff --git a/java-spiffe-helper/src/test/resources/testdata/cli/correct.conf b/java-spiffe-helper/src/test/resources/testdata/cli/correct.conf index 949aef5..f58de23 100644 --- a/java-spiffe-helper/src/test/resources/testdata/cli/correct.conf +++ b/java-spiffe-helper/src/test/resources/testdata/cli/correct.conf @@ -5,4 +5,4 @@ trustStorePath = truststore123.p12 trustStorePass = otherpass123 keyStoreType = jks keyAlias = other_alias -spiffeSocketPath = unix:/tmp/agent.sock +spiffeSocketPath = unix:/tmp/test