From bb91fb432fd88fcede78133199cf6664337ca3e6 Mon Sep 17 00:00:00 2001 From: Robin Harrison Date: Tue, 29 Mar 2022 12:36:25 +0100 Subject: [PATCH] Allow config to be supplied at runtime not compile time - Add CORE_STUB_KEYSTORE_FILE property - Add property for keystore_file - Add conditional logic to handle missing both of keystore_file and keystore_base64 properties - Add compose file for docker-compose startup - Delete bash script for startup --- .gitignore | 3 ++ di-ipv-core-stub/.env.sample | 1 + di-ipv-core-stub/Dockerfile | 1 - di-ipv-core-stub/README.MD | 29 ++++++++++--------- di-ipv-core-stub/compose.yaml | 17 +++++++++++ di-ipv-core-stub/di-ipv-config.yaml | 7 +++++ .../uk/gov/di/ipv/stub/core/CoreStub.java | 24 ++++++++++++--- .../ipv/stub/core/config/CoreStubConfig.java | 13 ++++++--- di-ipv-core-stub/startup.sh | 18 ------------ 9 files changed, 72 insertions(+), 41 deletions(-) create mode 100644 di-ipv-core-stub/.env.sample create mode 100644 di-ipv-core-stub/compose.yaml create mode 100644 di-ipv-core-stub/di-ipv-config.yaml delete mode 100755 di-ipv-core-stub/startup.sh diff --git a/.gitignore b/.gitignore index 42fcb4372..8780b7561 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ hs_err_pid* *.iml .DS_Store build + + +**/.env diff --git a/di-ipv-core-stub/.env.sample b/di-ipv-core-stub/.env.sample new file mode 100644 index 000000000..4e320cd0b --- /dev/null +++ b/di-ipv-core-stub/.env.sample @@ -0,0 +1 @@ +CONFIG_DIRECTORY=/path/to/config/data/files \ No newline at end of file diff --git a/di-ipv-core-stub/Dockerfile b/di-ipv-core-stub/Dockerfile index 9ad14bf3c..1b066eaf5 100644 --- a/di-ipv-core-stub/Dockerfile +++ b/di-ipv-core-stub/Dockerfile @@ -21,7 +21,6 @@ COPY --from=build \ /app/ WORKDIR /app -ADD config config RUN tar -xvf src.tar \ && rm src.tar diff --git a/di-ipv-core-stub/README.MD b/di-ipv-core-stub/README.MD index 904c364fe..a1c5d324e 100644 --- a/di-ipv-core-stub/README.MD +++ b/di-ipv-core-stub/README.MD @@ -17,29 +17,30 @@ This stub allows us to: ## Config Core Stub config from the `di-ipv-config` repository directory `/stubs/di-ipv-core-stub` will be available at: -* Docker image: `/app/config/` +* Docker image: `/app/` * PaaS: `config/` ## Environment -Variable | Description | Example Value ---- | --- | --- | -CORE_STUB_PORT | The port number the IPV Core Stub should run on | `8085` | -CORE_STUB_CLIENT_ID | The id of the IPV Core Stub client | `ipv-core-stub` | -CORE_STUB_REDIRECT_URL | The OAuth callback url | `http://localhost:8085/callback` | -CORE_STUB_MAX_SEARCH_RESULTS | Max search by name results | `200` | -CORE_STUB_USER_DATA_PATH | File path to Experian user data zip file | `/app/config/experian-uat-users-large.zip` | -CORE_STUB_CONFIG_FILE | File path to the credential issuer config | `/app/config/cris-dev.yaml` for Docker, `config/cris-dev.yaml` for PaaS| -CORE_STUB_KEYSTORE_BASE64 | Base64 of p12 signing keystore || -CORE_STUB_KEYSTORE_PASSWORD | password for the p12 signing keystore | `puppet` | -CORE_STUB_KEYSTORE_ALIAS | alias for key in the p12 signing keystore | `ipv-core-stub` | +| Variable | Description | Example Value | +|------------------------------|------------------------------------------------|-------------------------------------------------------------------------| +| CORE_STUB_PORT | The port number the IPV Core Stub should run on | `8085` | +| CORE_STUB_CLIENT_ID | The id of the IPV Core Stub client | `ipv-core-stub` | +| CORE_STUB_REDIRECT_URL | The OAuth callback url | `http://localhost:8085/callback` | +| CORE_STUB_MAX_SEARCH_RESULTS | Max search by name results | `200` | +| CORE_STUB_USER_DATA_PATH | File path to Experian user data zip file | `/app/config/experian-uat-users-large.zip` | +| CORE_STUB_CONFIG_FILE | File path to the credential issuer config | `/app/config/cris-dev.yaml` for Docker, `config/cris-dev.yaml` for PaaS | +| CORE_STUB_KEYSTORE_BASE64 | Base64 of p12 signing keystore | | +| CORE_STUB_KEYSTORE_FILE | File path to p12 signing keystore | | +| CORE_STUB_KEYSTORE_PASSWORD | password for the p12 signing keystore | `puppet` | +| CORE_STUB_KEYSTORE_ALIAS | alias for key in the p12 signing keystore | `ipv-core-stub` | ## Running locally -To run locally in a docker container, you can run the startup script. +To run locally in a docker container, you can run the `docker-compose` command. Remember to set the directory for the config files, as given in the [sample .env file](./env.sample) ```shell -./startup.sh +docker-compose up ``` This will build the project with gradle in docker and run it. diff --git a/di-ipv-core-stub/compose.yaml b/di-ipv-core-stub/compose.yaml new file mode 100644 index 000000000..0546228a4 --- /dev/null +++ b/di-ipv-core-stub/compose.yaml @@ -0,0 +1,17 @@ +version: "3.9" +services: + core-stub: + build: ./ + environment: + CORE_STUB_CONFIG_FILE: "/app/di-ipv-cri-config.yaml" + CORE_STUB_KEYSTORE_ALIAS: ipv-core-stub + CORE_STUB_KEYSTORE_PASSWORD: "puppet" + CORE_STUB_KEYSTORE_FILE: "/app/keystore.jks" + CORE_STUB_USER_DATA_PATH: "/app/experian-uat-users-large.zip" + + volumes: + - "./di-ipv-config.yaml:/app/di-ipv-cri-config.yaml" + - "${CONFIG_DIRECTORY}/keystore.jks:/app/keystore.jks" + - "${CONFIG_DIRECTORY}/experian-uat-users-large.zip:/app/experian-uat-users-large.zip" + ports: + - "8085:8085" \ No newline at end of file diff --git a/di-ipv-core-stub/di-ipv-config.yaml b/di-ipv-core-stub/di-ipv-config.yaml new file mode 100644 index 000000000..fcc2e9d0a --- /dev/null +++ b/di-ipv-core-stub/di-ipv-config.yaml @@ -0,0 +1,7 @@ +credentialIssuerConfigs: + - id: exampleCRI + name: Example CRI + authorizeUrl: http://localhost:1234/oauth2/authorize + tokenUrl: http://localhost:5678/oauth2/token + credentialUrl: http://localhost:5678/oauth2/credential + sendIdentityClaims: true \ No newline at end of file diff --git a/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/CoreStub.java b/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/CoreStub.java index 8f87b787a..784a26d1e 100644 --- a/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/CoreStub.java +++ b/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/CoreStub.java @@ -12,6 +12,8 @@ import uk.gov.di.ipv.stub.core.utils.ViewHelper; import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.security.KeyFactory; import java.security.KeyStore; import java.text.ParseException; import java.util.Base64; @@ -53,11 +55,25 @@ private ExceptionHandler exceptionHandler() { private RSAKey getSigningKeystore() throws Exception { KeyStore keystore = KeyStore.getInstance("pkcs12"); final char[] keyStorePassword = CoreStubConfig.CORE_STUB_KEYSTORE_PASSWORD.toCharArray(); - try (ByteArrayInputStream inputStream = - new ByteArrayInputStream( - Base64.getDecoder().decode(CoreStubConfig.CORE_STUB_KEYSTORE_BASE64))) { - keystore.load(inputStream, keyStorePassword); + + if (CoreStubConfig.CORE_STUB_KEYSTORE_FILE != null) { + try (FileInputStream inputStream = + new FileInputStream(CoreStubConfig.CORE_STUB_KEYSTORE_FILE)) { + keystore.load( + inputStream, keyStorePassword); + } + } else if (CoreStubConfig.CORE_STUB_KEYSTORE_BASE64 != null) { + try (ByteArrayInputStream inputStream = + new ByteArrayInputStream( + Base64.getDecoder().decode(CoreStubConfig.CORE_STUB_KEYSTORE_BASE64))) { + keystore.load( + inputStream, keyStorePassword); + } + } else { + throw new Exception( + "CORE_STUB_KEYSTORE_FILE or CORE_STUB_KEYSTORE_BASE64 must be provided"); } + return Objects.requireNonNull( RSAKey.load(keystore, CoreStubConfig.CORE_STUB_KEYSTORE_ALIAS, keyStorePassword)); } diff --git a/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/config/CoreStubConfig.java b/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/config/CoreStubConfig.java index 403fb3ae6..3025e11ca 100644 --- a/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/config/CoreStubConfig.java +++ b/di-ipv-core-stub/src/main/java/uk/gov/di/ipv/stub/core/config/CoreStubConfig.java @@ -41,9 +41,10 @@ public class CoreStubConfig { getConfigValue("CORE_STUB_USER_DATA_PATH", "config/experian-uat-users-large.zip"); public static final String CORE_STUB_CONFIG_FILE = getConfigValue("CORE_STUB_CONFIG_FILE", "/app/config/cris-dev.yaml"); - public static final byte[] CORE_STUB_KEYSTORE_BASE64 = - getConfigValue("CORE_STUB_KEYSTORE_BASE64", null).getBytes(); - + public static final String CORE_STUB_KEYSTORE_BASE64 = + getConfigValue("CORE_STUB_KEYSTORE_BASE64", null, true); + public static final String CORE_STUB_KEYSTORE_FILE = + getConfigValue("CORE_STUB_KEYSTORE_FILE", null, true); public static final String CORE_STUB_SIGNING_PRIVATE_KEY_JWK_BASE64 = getConfigValue("CORE_STUB_SIGNING_PRIVATE_KEY_JWK_BASE64", null); public static final String CORE_STUB_KEYSTORE_PASSWORD = @@ -57,8 +58,12 @@ public class CoreStubConfig { public static final List credentialIssuers = new ArrayList<>(); private static String getConfigValue(String key, String defaultValue) { + return getConfigValue(key, defaultValue, false); + } + + private static String getConfigValue(String key, String defaultValue, Boolean allowNullValue) { String envValue = Optional.ofNullable(System.getenv(key)).orElse(defaultValue); - if (StringUtils.isBlank(envValue)) { + if (!allowNullValue && StringUtils.isBlank(envValue)) { throw new IllegalStateException( "env var '%s' is not set and there is no default value".formatted(key)); } diff --git a/di-ipv-core-stub/startup.sh b/di-ipv-core-stub/startup.sh deleted file mode 100755 index 5946818b2..000000000 --- a/di-ipv-core-stub/startup.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -set -eu - -CONFIG_DIR="../../di-ipv-config/stubs/di-ipv-core-stub" - -clean_up () { - rm -r config -} -trap clean_up EXIT - -if [ ! -d "$CONFIG_DIR" ]; then - { echo "🛑 config dir '$CONFIG_DIR' does not exist in expected location"; exit 1; } -fi - -cp -r $CONFIG_DIR config - -docker build -t ipv-core-stub . -docker run -p 8085:8085 --env-file ${CONFIG_DIR}/.env ipv-core-stub