Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions src/main/java/io/github/jopenlibs/vault/api/Logical.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,51 @@ public LogicalResponse read(final String path, Boolean shouldRetry, final Intege
public LogicalResponse write(final String path, final Map<String, Object> nameValuePairs)
throws VaultException {
if (engineVersionForSecretPath(path).equals(2)) {
return write(path, nameValuePairs, logicalOperations.writeV2);
return write(path, nameValuePairs, logicalOperations.writeV2, null);
} else {
return write(path, nameValuePairs, logicalOperations.writeV1);
return write(path, nameValuePairs, logicalOperations.writeV1, null);
}
}

/**
* <p>Basic operation to store secrets. Multiple name value pairs can be stored under the same
* secret key. E.g.:</p>
*
* <blockquote>
* <pre>{@code
* final Map<String, String> nameValuePairs = new HashMap<String, Object>();
* nameValuePairs.put("value", "foo");
* nameValuePairs.put("other_value", "bar");
*
* final LogicalResponse response = vault.logical().write("secret/hello", nameValuePairs);
* }</pre>
* </blockquote>
*
* <p>The values in these name-value pairs may be booleans, numerics, strings, or nested JSON
* objects. However, be aware that this method does not recursively parse any nested
* structures. If you wish to write arbitrary JSON objects to Vault... then you should parse
* them to JSON outside of this method, and pass them here as JSON strings.</p>
*
* @param path The Vault key value to which to write (e.g. <code>secret/hello</code>)
* @param nameValuePairs Secret name and value pairs to store under this Vault key (can be
* @param wrapTTL Time (in seconds) which secret is wrapped
* <code>null</code> for writing to keys that do not need or expect any fields to be specified)
* @return The response information received from Vault
* @throws VaultException If any errors occurs with the REST request, and the maximum number of
* retries is exceeded.
*/
public LogicalResponse write(final String path, final Map<String, Object> nameValuePairs,
final Integer wrapTTL)
throws VaultException {
if (engineVersionForSecretPath(path).equals(2)) {
return write(path, nameValuePairs, logicalOperations.writeV2, wrapTTL);
} else {
return write(path, nameValuePairs, logicalOperations.writeV1, wrapTTL);
}
}

private LogicalResponse write(final String path, final Map<String, Object> nameValuePairs,
final logicalOperations operation) throws VaultException {
final logicalOperations operation, final Integer wrapTTL) throws VaultException {

return retry(attempt -> {
JsonObject requestJson = Json.object();
Expand Down Expand Up @@ -246,6 +283,7 @@ private LogicalResponse write(final String path, final Map<String, Object> nameV
.header("X-Vault-Token", config.getToken())
.header("X-Vault-Namespace", this.nameSpace)
.header("X-Vault-Request", "true")
.header("X-Vault-Wrap-TTL", wrapTTL != null ? wrapTTL.toString() : null)
.connectTimeoutSeconds(config.getOpenTimeout())
.readTimeoutSeconds(config.getReadTimeout())
.sslVerification(config.getSslConfig().isVerify())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class LogicalResponse extends VaultResponse {
private List<String> listData = new ArrayList<>();
private JsonObject dataObject = null;
private String leaseId;
private WrapResponse wrapResponse;
private Boolean renewable;
private Long leaseDuration;

Expand Down Expand Up @@ -61,6 +62,10 @@ public Long getLeaseDuration() {
return leaseDuration;
}

public WrapResponse getWrapResponse() {
return wrapResponse;
}

private void parseMetadataFields() {
try {
final String jsonString = new String(getRestResponse().getBody(),
Expand All @@ -70,6 +75,8 @@ private void parseMetadataFields() {
this.leaseId = jsonObject.get("lease_id").asString();
this.renewable = jsonObject.get("renewable").asBoolean();
this.leaseDuration = jsonObject.get("lease_duration").asLong();

this.wrapResponse = new WrapResponse(getRestResponse(), getRetries());
} catch (Exception ignored) {
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.github.jopenlibs.vault.VaultException;
import io.github.jopenlibs.vault.response.AuthResponse;
import io.github.jopenlibs.vault.response.LogicalResponse;
import io.github.jopenlibs.vault.response.WrapResponse;
import io.github.jopenlibs.vault.util.VaultContainer;
import java.io.IOException;
import java.util.HashMap;
Expand All @@ -21,6 +22,8 @@

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNotSame;
import static junit.framework.TestCase.assertTrue;

/**
Expand Down Expand Up @@ -66,6 +69,34 @@ public void testWriteAndRead() throws VaultException {
assertEquals(value, valueRead);
}

/**
* Write a wrapped secret and verify that it can be read, using KV Secrets engine version 2.
*
* @throws VaultException On error.
*/
@Test
public void testWriteAndReadWrapped() throws VaultException {
final String pathToWrite = "secret/hellowrapped";
final String pathToRead = "secret/hellowrapped";
final int wrapTTL = 60;

final String value = "world";
final Vault vault = container.getRootVault();

final Map<String, Object> testMap = new HashMap<>();
testMap.put("value", value);

LogicalResponse response = vault.logical().write(pathToWrite, testMap, wrapTTL);

final String valueRead = vault.logical().read(pathToRead).getData().get("value");
WrapResponse wrapResponse = response.getWrapResponse();
assertNotNull(response.getWrapResponse());

assertNotSame("", wrapResponse.getToken());
assertEquals(wrapTTL, wrapResponse.getTtl());
assertEquals(value, valueRead);
}

/**
* Write a secret and verify that it can be read, using KV Secrets engine version 1.
*
Expand Down