diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..485d23d
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,15 @@
+## 0.3.0 [2016-10-07]
+* [feature] Retrieval of JSON objects (#1)
+* [test] Tested against Vault 0.6.2
+
+## 0.2.0 [2016-09-01]
+* Dependecies updated and CommonsIO removed
+* [fix] Fixed auth backend detection for Vault 0.6.1
+* [test] Tested against Vault 0.6.1
+
+## 0.1.1 [2016-06-20]
+* [fix] Check for "permission denied" without status code 400 instead of 403
+* [test] Tested against Vault 0.6.0
+
+## 0.1.0 [2016-03-29]
+* First release
\ No newline at end of file
diff --git a/README.md b/README.md
index f0265ce..3d9c9c7 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
* Write secrets
* List secrets
* Connector Factory with builder pattern
-* Tested against Vault 0.6.1
+* Tested against Vault 0.6.2
**Usage Example**
@@ -38,7 +38,7 @@ String secret = vault.readSecret("some/secret/key").getValue();
de.stklcode.jvault
connector
- 0.2.0
+ 0.3.0
```
diff --git a/pom.xml b/pom.xml
index 8bfd2d3..db2358e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,11 @@
de.stklcode.jvault
connector
- 0.2.0
+ 0.3.0
+
+
+ UTF-8
+
@@ -37,12 +41,12 @@
com.fasterxml.jackson.core
jackson-core
- 2.8.1
+ 2.8.3
com.fasterxml.jackson.core
jackson-databind
- 2.8.1
+ 2.8.3
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..984bf04 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,10 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
+import java.io.IOException;
import java.util.Map;
/**
@@ -27,4 +29,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"}