Refactors and tests in java-spiffe-helper.

Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
Max Lambrecht 2020-07-15 14:41:28 -03:00
parent 0c542c198c
commit e81a936a96
10 changed files with 382 additions and 175 deletions

View File

@ -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 <arg>", 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;
}
}

View File

@ -4,23 +4,12 @@ import io.spiffe.exception.SocketEndpointAddressException;
import io.spiffe.helper.exception.KeyStoreHelperException; import io.spiffe.helper.exception.KeyStoreHelperException;
import io.spiffe.helper.exception.RunnerException; import io.spiffe.helper.exception.RunnerException;
import io.spiffe.helper.keystore.KeyStoreHelper; import io.spiffe.helper.keystore.KeyStoreHelper;
import io.spiffe.helper.keystore.KeyStoreType;
import lombok.extern.java.Log; import lombok.extern.java.Log;
import lombok.val; 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.nio.file.Paths;
import java.util.Properties; import java.security.InvalidParameterException;
import java.security.KeyStoreException;
/** /**
* Entry point of the CLI to run the KeyStoreHelper. * 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" * 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 * @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 { public static void main(final String ...args) throws RunnerException {
String configFilePath = null;
try { try {
configFilePath = getCliConfigOption(args); val configFilePath = Config.getCliConfigOption(args);
val parameters = parseConfigFile(Paths.get(configFilePath)); val properties = Config.parseConfigFileProperties(Paths.get(configFilePath));
val options = toKeyStoreOptions(parameters); val options = Config.createKeyStoreOptions(properties);
try (val keyStoreHelper = KeyStoreHelper.create(options)) { try (val keyStoreHelper = KeyStoreHelper.create(options)) {
keyStoreHelper.run(true); keyStoreHelper.run(true);
} }
} catch (SocketEndpointAddressException | KeyStoreHelperException | RunnerException | IllegalArgumentException e) { } catch (SocketEndpointAddressException | KeyStoreHelperException | RunnerException | InvalidParameterException | KeyStoreException e) {
log.severe(e.getMessage()); log.severe(e.getMessage());
throw new RunnerException(e); 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 <arg>", 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;
}
} }

View File

@ -11,4 +11,8 @@ public class RunnerException extends Exception {
public RunnerException(Throwable cause) { public RunnerException(Throwable cause) {
super(cause); super(cause);
} }
public RunnerException(String message, Throwable cause) {
super(message, cause);
}
} }

View File

@ -57,7 +57,7 @@ class KeyStore {
} }
return keyStore; return keyStore;
} catch (IOException | NoSuchAlgorithmException | CertificateException e) { } catch (IOException | NoSuchAlgorithmException | CertificateException e) {
throw new KeyStoreException(e); throw new KeyStoreException("KeyStore cannot be created", e);
} }
} }

View File

@ -66,8 +66,9 @@ public class KeyStoreHelper implements Closeable {
* @return an instance of a KeyStoreHelper * @return an instance of a KeyStoreHelper
* @throws SocketEndpointAddressException if the socket endpoint address is not valid * @throws SocketEndpointAddressException if the socket endpoint address is not valid
* @throws KeyStoreHelperException if the KeyStoreHelper cannot be created * @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)) { if (options.keyStorePath.equals(options.trustStorePath)) {
throw new KeyStoreHelperException("KeyStore and TrustStore should use different files"); throw new KeyStoreHelperException("KeyStore and TrustStore should use different files");
@ -142,16 +143,12 @@ public class KeyStoreHelper implements Closeable {
this.workloadApiClient = workloadApiClient; this.workloadApiClient = workloadApiClient;
} }
private static KeyStore createKeyStore(KeyStoreOptions options, Path keyStorePath, String keyStorePass) throws KeyStoreHelperException { private static KeyStore createKeyStore(KeyStoreOptions options, Path keyStorePath, String keyStorePass) throws KeyStoreException {
try { return KeyStore.builder()
return KeyStore.builder() .keyStoreFilePath(keyStorePath)
.keyStoreFilePath(keyStorePath) .keyStoreType(options.keyStoreType)
.keyStoreType(options.keyStoreType) .keyStorePassword(keyStorePass)
.keyStorePassword(keyStorePass) .build();
.build();
} catch (KeyStoreException e) {
throw new KeyStoreHelperException("Error creating KeyStore/TrustStore", e);
}
} }
private static WorkloadApiClient createNewClient(final String spiffeSocketPath) throws SocketEndpointAddressException { private static WorkloadApiClient createNewClient(final String spiffeSocketPath) throws SocketEndpointAddressException {

View File

@ -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 <arg>", 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 <arg>", 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);
}
}
}

View File

@ -1,14 +1,14 @@
package io.spiffe.helper.cli; package io.spiffe.helper.cli;
import io.spiffe.exception.SocketEndpointAddressException;
import io.spiffe.helper.exception.RunnerException; import io.spiffe.helper.exception.RunnerException;
import lombok.val;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.security.KeyStoreException;
import java.util.Properties;
import static io.spiffe.helper.utils.TestUtils.toUri; import static io.spiffe.helper.utils.TestUtils.toUri;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -17,104 +17,73 @@ import static org.junit.jupiter.api.Assertions.fail;
class RunnerTest { class RunnerTest {
@Test @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")); final Path path = Paths.get(toUri("testdata/cli/missing-keystorepath.conf"));
try { try {
Runner.main("-c", path.toString()); Runner.main("-c", path.toString());
fail("expected exception: property is missing"); fail("expected exception: property is missing");
} catch (RunnerException e) { } catch (RunnerException e) {
assertEquals("keyStorePath config is missing", e.getCause().getMessage()); assertEquals("Missing value for config property: keyStorePath", e.getCause().getMessage());
} }
} }
@Test @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")); final Path path = Paths.get(toUri("testdata/cli/missing-keystorepass.conf"));
try { try {
Runner.main("-c", path.toString()); Runner.main("-c", path.toString());
fail("expected exception: property is missing"); fail("expected exception: property is missing");
} catch (RunnerException e) { } catch (RunnerException e) {
assertEquals("keyStorePass config is missing", e.getCause().getMessage()); assertEquals("Missing value for config property: keyStorePass", e.getCause().getMessage());
} }
} }
@Test @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")); final Path path = Paths.get(toUri("testdata/cli/missing-keypass.conf"));
try { try {
Runner.main("-c", path.toString()); Runner.main("-c", path.toString());
fail("expected exception: property is missing"); fail("expected exception: property is missing");
} catch (RunnerException e) { } catch (RunnerException e) {
assertEquals("keyPass config is missing", e.getCause().getMessage()); assertEquals("Missing value for config property: keyPass", e.getCause().getMessage());
} }
} }
@Test @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")); final Path path = Paths.get(toUri("testdata/cli/missing-truststorepath.conf"));
try { try {
Runner.main("-c", path.toString()); Runner.main("-c", path.toString());
fail("expected exception: property is missing"); fail("expected exception: property is missing");
} catch (RunnerException e) { } catch (RunnerException e) {
assertEquals("trustStorePath config is missing", e.getCause().getMessage()); assertEquals("Missing value for config property: trustStorePath", e.getCause().getMessage());
} }
} }
@Test @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")); final Path path = Paths.get(toUri("testdata/cli/missing-truststorepass.conf"));
try { try {
Runner.main("-c", path.toString()); Runner.main("-c", path.toString());
fail("expected exception: property is missing"); fail("expected exception: property is missing");
} catch (RunnerException e) { } catch (RunnerException e) {
assertEquals("trustStorePass config is missing", e.getCause().getMessage()); assertEquals("Missing value for config property: trustStorePass", e.getCause().getMessage());
} }
} }
@Test @Test
void testGetCliConfigOption_abbreviated() { void test_Main_throwsExceptionIfTheKeystoreCannotBeCreated() throws URISyntaxException, IOException {
String option = null; val file = new File("keystore123.p12");
file.createNewFile();
val configPath = Paths.get(toUri("testdata/cli/correct.conf"));
try { try {
option = Runner.getCliConfigOption("-c", "example"); Runner.main("-c", configPath.toString());
} catch (RunnerException e) { } catch (RunnerException e) {
fail(e); assertEquals("KeyStore cannot be created", e.getCause().getMessage());
} } finally {
assertEquals("example", option); file.delete();
}
@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 <arg>", e.getMessage());
} }
} }
@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"));
}
} }

View File

@ -149,6 +149,8 @@ class KeyStoreHelperTest {
fail("expected exception: KeyStore and TrustStore should use different files"); fail("expected exception: KeyStore and TrustStore should use different files");
} catch (KeyStoreHelperException e) { } catch (KeyStoreHelperException e) {
assertEquals("KeyStore and TrustStore should use different files", e.getMessage()); assertEquals("KeyStore and TrustStore should use different files", e.getMessage());
} catch (KeyStoreException e) {
fail(e);
} }
} }
@ -181,6 +183,8 @@ class KeyStoreHelperTest {
} catch (KeyStoreHelperException e) { } catch (KeyStoreHelperException e) {
assertEquals("Error running KeyStoreHelper", e.getMessage()); assertEquals("Error running KeyStoreHelper", e.getMessage());
assertEquals("java.nio.file.NoSuchFileException: dummy:/invalid", e.getCause().getCause().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); KeyStoreHelper.create(null);
} catch (NullPointerException e) { } catch (NullPointerException e) {
assertEquals("options is marked non-null but is null", e.getMessage()); assertEquals("options is marked non-null but is null", e.getMessage());
} catch (SocketEndpointAddressException | KeyStoreHelperException e) { } catch (SocketEndpointAddressException | KeyStoreHelperException | KeyStoreException e) {
fail(); 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) { private KeyStoreHelper.KeyStoreOptions getKeyStoreValidOptions(WorkloadApiClient workloadApiClient) {
val keyStorefileName = RandomStringUtils.randomAlphabetic(10); val keyStorefileName = RandomStringUtils.randomAlphabetic(10);
keyStoreFilePath = Paths.get(keyStorefileName); keyStoreFilePath = Paths.get(keyStorefileName);

View File

@ -12,6 +12,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Files; import java.nio.file.Files;
@ -144,26 +145,33 @@ public class KeyStoreTest {
@Test @Test
void testNewKeyStore_nullKeyStorePath_throwsException() throws KeyStoreException { void testNewKeyStore_nullKeyStorePath_throwsException() throws KeyStoreException {
try { try {
KeyStore.builder() KeyStore.builder().build();
.keyStoreFilePath(null)
.keyStoreType(KeyStoreType.JKS)
.keyStorePassword("keyStorePassword")
.build();
fail("exception expected"); fail("exception expected");
} catch (NullPointerException e) { } catch (NullPointerException e) {
assertEquals("keyStoreFilePath is marked non-null but is null", e.getMessage()); 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 @Test
void testNewKeyStore_nullKeyStorePassword_throwsException() throws KeyStoreException { void testNewKeyStore_nullKeyStorePassword_throwsException() throws KeyStoreException {
try { try {
KeyStore.builder() KeyStore.builder()
.keyStoreFilePath(Paths.get("anypath")) .keyStoreFilePath(Paths.get("anypath"))
.keyStoreType(KeyStoreType.PKCS12) .keyStoreType(KeyStoreType.PKCS12)
.keyStorePassword(null)
.build(); .build();
fail("exception expected"); fail("exception expected: keyStorePassword cannot be blank");
} catch (NullPointerException e) { } catch (NullPointerException e) {
assertEquals("keyStorePassword is marked non-null but is null", e.getMessage()); 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 @AfterEach
void tearDown() { void tearDown() {
deleteFile(keyStoreFilePath); deleteFile(keyStoreFilePath);

View File

@ -5,4 +5,4 @@ trustStorePath = truststore123.p12
trustStorePass = otherpass123 trustStorePass = otherpass123
keyStoreType = jks keyStoreType = jks
keyAlias = other_alias keyAlias = other_alias
spiffeSocketPath = unix:/tmp/agent.sock spiffeSocketPath = unix:/tmp/test