diff --git a/src/main/java/de/stklcode/jvault/connector/VaultConnector.java b/src/main/java/de/stklcode/jvault/connector/VaultConnector.java index d09ec03..ca58663 100644 --- a/src/main/java/de/stklcode/jvault/connector/VaultConnector.java +++ b/src/main/java/de/stklcode/jvault/connector/VaultConnector.java @@ -2,10 +2,7 @@ package de.stklcode.jvault.connector; import de.stklcode.jvault.connector.exception.VaultConnectorException; import de.stklcode.jvault.connector.model.AuthBackend; -import de.stklcode.jvault.connector.model.response.SealResponse; -import de.stklcode.jvault.connector.model.response.SecretResponse; -import de.stklcode.jvault.connector.model.response.TokenResponse; -import de.stklcode.jvault.connector.model.response.AuthResponse; +import de.stklcode.jvault.connector.model.response.*; import java.util.List; diff --git a/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java b/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java index e05b023..c55786b 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java +++ b/src/main/java/de/stklcode/jvault/connector/model/response/SecretResponse.java @@ -1,8 +1,12 @@ package de.stklcode.jvault.connector.model.response; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; import de.stklcode.jvault.connector.exception.InvalidResponseException; +import java.io.IOException; import java.util.Map; /** @@ -27,4 +31,20 @@ public class SecretResponse extends VaultDataResponse { public String getValue() { return value; } + + /** + * Get response parsed as JSON + * @param type Class to parse response + * @param Class to parse response + * @return Parsed object + * @throws InvalidResponseException on parsing error + * @since 0.3 + */ + public T getValue(Class type) throws InvalidResponseException { + try { + return new ObjectMapper().readValue(getValue(), type); + } catch (IOException e) { + throw new InvalidResponseException("Unable to parse response payload: " + e.getMessage()); + } + } } \ No newline at end of file diff --git a/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java b/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java index 9662b43..3b5a6f0 100644 --- a/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java +++ b/src/test/java/de/stklcode/jvault/connector/HTTPVaultConnectorTest.java @@ -1,15 +1,14 @@ package de.stklcode.jvault.connector; +import de.stklcode.jvault.connector.exception.InvalidResponseException; +import de.stklcode.jvault.connector.model.response.*; +import de.stklcode.jvault.connector.test.Credentials; import de.stklcode.jvault.connector.test.VaultConfiguration; import de.stklcode.jvault.connector.exception.InvalidRequestException; import de.stklcode.jvault.connector.exception.PermissionDeniedException; import de.stklcode.jvault.connector.exception.VaultConnectorException; import de.stklcode.jvault.connector.factory.VaultConnectorFactory; import de.stklcode.jvault.connector.model.AuthBackend; -import de.stklcode.jvault.connector.model.response.AuthResponse; -import de.stklcode.jvault.connector.model.response.SealResponse; -import de.stklcode.jvault.connector.model.response.SecretResponse; -import de.stklcode.jvault.connector.model.response.TokenResponse; import org.junit.*; import org.junit.rules.TemporaryFolder; @@ -20,9 +19,7 @@ import java.io.IOException; import java.net.ServerSocket; import java.util.List; -import static org.hamcrest.CoreMatchers.hasItem; -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.core.Is.is; import static org.junit.Assert.*; @@ -45,6 +42,7 @@ public class HTTPVaultConnectorTest { private static String USER_ID = "5ADF8218-D7FB-4089-9E38-287465DBF37E"; private static String SECRET_PATH = "userstore"; private static String SECRET_KEY = "foo"; + private static String SECRET_KEY_JSON = "json"; private static String SECRET_VALUE = "bar"; private Process vaultProcess; @@ -112,9 +110,9 @@ public class HTTPVaultConnectorTest { */ @Test public void authTokenTest() { - TokenResponse res = null; + TokenResponse res; try { - res = connector.authToken("52135869df23a5e64c5d33a9785af5edb456b8a4a235d1fe135e6fba1c35edf6"); + connector.authToken("52135869df23a5e64c5d33a9785af5edb456b8a4a235d1fe135e6fba1c35edf6"); fail("Logged in with invalid token"); } catch (VaultConnectorException ignored) { } @@ -211,6 +209,21 @@ public class HTTPVaultConnectorTest { } catch (VaultConnectorException e) { fail("Valid secret path could not be read: " + e.getMessage()); } + /* Try to read accessible path with JSON value */ + try { + res = connector.readSecret(SECRET_PATH + "/" + SECRET_KEY_JSON); + assertThat("Known secret returned null value.", res.getValue(), notNullValue()); + } catch (VaultConnectorException e) { + fail("Valid secret path could not be read: " + e.getMessage()); + } + try { + Credentials parsedRes = res.getValue(Credentials.class); + assertThat("JSON response was null", parsedRes, notNullValue()); + assertThat("JSON response incorrect", parsedRes.getUsername(), is("user")); + assertThat("JSON response incorrect", parsedRes.getPassword(), is("password")); + } catch (InvalidResponseException e) { + fail("JSON response could not be parsed: " + e.getMessage()); + } } /** @@ -277,7 +290,7 @@ public class HTTPVaultConnectorTest { /** * Initialize Vault with resource datastore and generated configuration. * @return Vault Configuration - * @throws IllegalStateException + * @throws IllegalStateException on error */ private VaultConfiguration initializeVault() throws IllegalStateException { String dataResource = getClass().getResource("/data_dir").getPath(); @@ -291,10 +304,10 @@ public class HTTPVaultConnectorTest { /* Write configuration file */ BufferedWriter bw = null; - File configFIle = null; + File configFile = null; try { - configFIle = tmpDir.newFile("vault.conf"); - bw = new BufferedWriter(new FileWriter(configFIle)); + configFile = tmpDir.newFile("vault.conf"); + bw = new BufferedWriter(new FileWriter(configFile)); bw.write(config.toString()); } catch (IOException e) { @@ -313,7 +326,7 @@ public class HTTPVaultConnectorTest { /* Start vault process */ try { - vaultProcess = Runtime.getRuntime().exec("vault server -config " + configFIle.toString()); + vaultProcess = Runtime.getRuntime().exec("vault server -config " + configFile.toString()); } catch (IOException e) { e.printStackTrace(); throw new IllegalStateException("Unable to start vault. Make sure vault binary is in your executable path."); diff --git a/src/test/java/de/stklcode/jvault/connector/test/Credentials.java b/src/test/java/de/stklcode/jvault/connector/test/Credentials.java new file mode 100644 index 0000000..b84b48d --- /dev/null +++ b/src/test/java/de/stklcode/jvault/connector/test/Credentials.java @@ -0,0 +1,26 @@ +package de.stklcode.jvault.connector.test; + + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Simple credentials class for JSON testing. + * + * @author Stefan Kalscheuer + * @since 0.1 + */ +public class Credentials { + @JsonProperty("username") + private String username; + + @JsonProperty("password") + private String password; + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } +} diff --git a/src/test/resources/data_dir/core/_audit b/src/test/resources/data_dir/core/_audit index 9850d12..dc9ab5f 100644 --- a/src/test/resources/data_dir/core/_audit +++ b/src/test/resources/data_dir/core/_audit @@ -1 +1 @@ -{"Key":"core/audit","Value":"AAAAAQJ+0lfxYOKIXzquksd3Il4zfW4ja6BdScu7mCAijGDph63S5yWH92olwI2SQA=="} +{"Key":"core/audit","Value":"AAAAAQI4CkDWnI49wp9iDaEMhEgTyBBtXOuIcrn7m4qifUOwQ6reTf3BKc5IQXuhxN5h51KVeinMklz3Ld0Qgw=="} diff --git a/src/test/resources/data_dir/core/_auth b/src/test/resources/data_dir/core/_auth index c45fcdc..bf42fd1 100644 --- a/src/test/resources/data_dir/core/_auth +++ b/src/test/resources/data_dir/core/_auth @@ -1 +1 @@ -{"Key":"core/auth","Value":"AAAAAQJeg+aK83bfYUPm5KV/+Y1Cf8fVX8Oq7cFiYE3PN4Tcl2j9YD7c+fijkopFzPLxh/EBRVzGTjBBkWBDTLC4EKn2lU8A+NJK6frGOu5Vjc4+WipBUcsGGcfosvxrZk8ZrTt09PRo7CnAFzmH4CgIVuEFv3NZyjXX08EMakxmH6R4S8Ti3cmit5Kr1TKSGnHeMfO6lBnAobAfNlfgNDM90yAxaQUT9gR27TabSKsVvkIY/0oxIcVFQ1RuF7xcdAOJ82wlWkcfT+rMhSS6roGt9Njx9t0PQNjv2eomh/leuhTUzfu4oAbtJJO3IPuC/KkJZpKinjJaGlA5Kx5m7W09DHieyI0GXmjJXH9oCj0z9w6eKDNZmjC1xeFylBvkvnkAKA6QmUmZjoq+m81/UC/C/ShJYxDFxaHwCPgF92qSrT1VTrz5lYAyyjJmrnbyuUXfgG6d4dbDxT/DVddHtIzHbBBT0xxjNM/+WxOSdRYZXKsfm8ovGaFWJr9AyFfEnyS0E9FJvkEXp68eNdacgdM3Ow5Zchm2/I9F4wN577ZwK9oGO2kjkDv4pwKQJ6uDYXeJDZxeMO2rXk/9sY8rAV20loOnqryfO3IE876H97KyE1LEzrky7mVw3YL/CDlZCO5Sf2IHTmwKylTRlsnUO1I5bviFD3a3EdeIGeDuNbWIqiju2fpMQX4l2gUuY4pysBM28AwbTe3zp348PePFpTcGE0/YwsW/aJit3VOc6xNX9WU="} +{"Key":"core/auth","Value":"AAAAAQKA3+V0TsgRYXO8NxjN1y6nBjUL9B2eOJe4Cfi56B3qmzGx1mhyn1SRkyWBbRIjIOp/a8d52P5ukK3AU3FpOC8w8W/aYLZVZONhMn4tnzvN9+FDYp5Kx8FqNBunDgOwygkMsgd0fnrAgxefUU1z4iY5hlXl/45qwWE6HXbrCJ5uBciHZajmKbCZPe9oc/i0Lw0hZXW598kJV6OmzGesWqYmkbyohv5d1vTB1nuDNG5MvxtWoNIcF5u5+x487zg0FQ6womZOyR7xQKxXyIYescIjAmSjJ6Xlr0rj41NSCzMIhP6fkDHI+YiPAcXDHynjMRV4rky9PG5PSJQgp1jYUUjo/3crc1ssBMSPTEecdc9xOyS903o2/fvc9aFm0CBOtlrlbLzzEztIrHPwJAkCoyqgpk/LcJgV6DRM8xmy+MDTNBFnLhzTeKyK2z7c932JYHTNO8YiIzmc8xAOY46YMEofGu0dVi6QTtfxIs3934NoO5p+EM0RcBnLme8FVWr+QsyL64SFJ3sF7t9WuwRccLTpJaQm5r7YsUFSOZSczrMkWAPIyJFprCA678HVgpVUUOeA1vC96am7+IybvOD8n7Hwu8PCKoXUStsJya+WR1gZ3zjd6zN9byibve6MXxMvYpFp4zv4l2whavvPzO5sCM6xookFvhUVZPvcTrQIhxSoTLabJClss4VJKZoV6HK4m4JZcgKXAVuHBf4WHDV+vFPnc5IITneMR1I2GYJPaOlhDlB2MO0WbCBWDc+EhuelmuiUdZFT3u4zshaODpPzvVzWwbWwIQyFfL7dM3ZCiIGS9Bo6pAj6b8zsjg=="} diff --git a/src/test/resources/data_dir/core/_mounts b/src/test/resources/data_dir/core/_mounts index 9895ebe..f499870 100644 --- a/src/test/resources/data_dir/core/_mounts +++ b/src/test/resources/data_dir/core/_mounts @@ -1 +1 @@ -{"Key":"core/mounts","Value":"AAAAAQLyZ1sJsIcAqhtCBFotH08os+J6UEjDnte1gzUp8md8RNH2LFTBe+8iwqSjgpJCyQPYXxDb7l5S4YG8ypUAk5yZA/CaC5y2idWXBrvzihCdDgOv+xLB17mGRuIJdPSdG2TlPY/HJBkadAPOzzD+qFHJKOeH+YOVwBQQP8GA9uLm3DZNHOSej59Y8wN7R9hJX1aXBnkqFhpLdARXqrlSI8SiWz3TNA2vmm4cCzxGcmKEUF3m6peBr47TTnZtcciGI0vd7yIbMeblF93HcrNMcQnKB4ItR8a+yO4WZHg/Y1iWn0JQB0y0FSYg+OFFolsMQpQDDd+YTUpj8zJ2pmlRZ9n19WBHD2VbkzkCyR214+NzCpOfCUsguYdGR34trwU6/4W5ApxtY/+T35vQ+esztU2HgQqJES6s8708Nn589Kvzg/+etbvhfq/DmWOcwZOtb2X/EQHaDmHWzsWqQ26Ux32WiAjedVwoba6vT23MIgUBjdHIKuTlrV6JqNVeuevfmfpBW8y/EhcAm6e2s8jTkdoaSPvq2NaBT9HF6FWJNXhVxAXQlOp7ibx5nk7l312umi2hbZ0+2Ad2wTGCVsECa26ZqXzBbU3uNni4sNdqbTq0i7unpqEQnyfTGcHkxe1uIbT2sK/AydtaOV8IDN4Z0HUBX9tj2UpQr8LX+JW9wX3MIXxQVfogyi/AmQRiDYuPeJyvvTTininGOHLSQyl/jRO/A3SdrTmppcwyNmTS1tzpwDawCP9yLWcw0/QVYgd8wMgmVjKsGuxJqWtEibnEnP9oU8Epi1Zy0OPXLUAT/06R9xtIMRReS2+VhBrFGmkD6eVL6EX0OOZ3yA6CxIft7cHQNishwIGL"} +{"Key":"core/mounts","Value":"AAAAAQKEEYCeXSTFocHW81rN1uI6MofozgPy2HnyOaonbuLKzaYM90H7UWfCymZ8sJ/3buSfv8/HNGkrjMHXnwyNbwTZrMt1+3LzSySfrNuq8naoLCbZK0Pn3vJElDnJAej44SBoKrmC04RAj7ROjxB5Eiqe4VJmj2KzjX8pnwKo2cFvetgNiW1a1W9zqqDZX4HRxTCfiS4RwLdkWrUjYvwjX4tQB+GYuixUEWWCsUXSAoIhHx/H7AkmJaJVyrHILjHAcSD8fgxCHwFwf7xaMgQhWqj+ofBYwilgtXkPc/vcmT1pZqw8RgHrfMKTl1gGmuXiiL9/tkWeMs4u9H9+nhLFYy6V2EDFDKPc+zvHg/c4lRUvN0AnX1A050ZJKucYDLq8IxRuBQL4ZZ0syyIVxoA2iJYgIy8dZXHg232LQg5Gicc+sqHKMAJxknkEwl2QBPhcAyGobent4UaAx9b+7LGXhg=="} diff --git a/src/test/resources/data_dir/logical/b85d867d-74d1-7d84-7a97-4597d813a5fb/userstore/_json b/src/test/resources/data_dir/logical/b85d867d-74d1-7d84-7a97-4597d813a5fb/userstore/_json new file mode 100644 index 0000000..c19f8a0 --- /dev/null +++ b/src/test/resources/data_dir/logical/b85d867d-74d1-7d84-7a97-4597d813a5fb/userstore/_json @@ -0,0 +1 @@ +{"Key":"logical/b85d867d-74d1-7d84-7a97-4597d813a5fb/userstore/json","Value":"AAAAAQIow6Rc/bPZhf5PDQ3jK/diX99iQZM01NA62tkT0BaKE4UfmSYuYDVUCIrWUOKsVyvD48phL3hEHfgNrJzVsVIk296Br/y7/es9z5zOxe9VATSSJy3CI54AtA=="} diff --git a/src/test/resources/data_dir/sys/policy/_response-wrapping b/src/test/resources/data_dir/sys/policy/_response-wrapping new file mode 100644 index 0000000..c489342 --- /dev/null +++ b/src/test/resources/data_dir/sys/policy/_response-wrapping @@ -0,0 +1 @@ +{"Key":"sys/policy/response-wrapping","Value":"AAAAAQLDl3zy1uKv9o2NhIyl43YAtoxGChOUc4aMa7beod+3e8FkdOsZt9BIirHsqjJ+VoxQyz+HroBaNfKPsyos3WLWvz5IUZ1UHr/jLG2SjrJfCKvco85RsFytkzp3T+Z5JB2vVfm22PpBIbjq2+XpHLKIqARqTWYl7Wnql572JZOvPY0w"}