Implement writing of KV v2 secret data (#16)

This commit is contained in:
2019-03-22 14:27:30 +01:00
parent e4cf8a1dde
commit ab33325b8e
5 changed files with 257 additions and 14 deletions

View File

@ -32,9 +32,7 @@ import java.io.*;
import java.lang.reflect.Field;
import java.net.ServerSocket;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import static org.apache.commons.io.FileUtils.copyDirectory;
@ -82,6 +80,8 @@ public class HTTPVaultConnectorTest {
private static final String SECRET2_KEY = "foo2";
private static final String SECRET2_VALUE1 = "bar2";
private static final String SECRET2_VALUE2 = "bar3";
private static final String SECRET2_VALUE3 = "bar4";
private static final String SECRET2_VALUE4 = "bar4";
private Process vaultProcess;
private VaultConnector connector;
@ -766,6 +766,62 @@ public class HTTPVaultConnectorTest {
}
}
/**
* Test writing of secrets to KV v2 store.
*/
@Test
public void writeSecretV2Test() {
authUser();
assumeTrue(connector.isAuthorized());
// First get the current version of the secret.
int currentVersion = -1;
try {
MetadataResponse res = connector.readSecretMetadata(MOUNT_KV2, SECRET2_KEY);
currentVersion = res.getMetadata().getCurrentVersion();
} catch (VaultConnectorException e) {
fail("Reading secret metadata failed: " + e.getMessage());
}
// Now write (update) the data and verify the version.
try {
Map<String, Object> data = new HashMap<>();
data.put("value", SECRET2_VALUE3);
SecretVersionResponse res = connector.writeSecretData(MOUNT_KV2, SECRET2_KEY, data);
assertThat("Version not updated after writing secret", res.getMetadata().getVersion(), is(currentVersion + 1));
currentVersion = res.getMetadata().getVersion();
} catch (VaultConnectorException e) {
fail("Writing secret to KV v2 store failed: " + e.getMessage());
}
// Verify the content.
try {
SecretResponse res = connector.readSecretData(MOUNT_KV2, SECRET2_KEY);
assertThat("Data not updated correctly", res.getValue(), is(SECRET2_VALUE3));
} catch (VaultConnectorException e) {
fail("Reading secret from KV v2 store failed: " + e.getMessage());
}
// Now try with explicit CAS value (invalid).
try {
Map<String, Object> data = new HashMap<>();
data.put("value", SECRET2_VALUE4);
SecretVersionResponse res = connector.writeSecretData(MOUNT_KV2, SECRET2_KEY, data, currentVersion - 1);
fail("Writing secret to KV v2 with invalid CAS value succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception", e, is(instanceOf(InvalidResponseException.class)));
}
// And finally with a correct CAS value.
try {
Map<String, Object> data = new HashMap<>();
data.put("value", SECRET2_VALUE4);
SecretVersionResponse res = connector.writeSecretData(MOUNT_KV2, SECRET2_KEY, data, currentVersion);
} catch (VaultConnectorException e) {
fail("Writing secret to KV v2 with correct CAS value failed: " + e.getMessage());
}
}
/**
* Test reading of secret metadata from KV v2 store.
*/

View File

@ -0,0 +1,66 @@
/*
* Copyright 2016-2018 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.fail;
/**
* JUnit Test for {@link SecretVersionResponse} model.
*
* @author Stefan Kalscheuer
* @since 0.8
*/
public class SecretVersionResponseTest {
private static final String CREATION_TIME = "2018-03-22T02:24:06.945319214Z";
private static final String DELETION_TIME = "2018-03-22T02:36:43.986212308Z";
private static final Integer VERSION = 42;
private static final String META_JSON = "{\n" +
" \"data\": {\n" +
" \"created_time\": \"" + CREATION_TIME + "\",\n" +
" \"deletion_time\": \"" + DELETION_TIME + "\",\n" +
" \"destroyed\": false,\n" +
" \"version\": " + VERSION + "\n" +
" }\n" +
"}";
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
SecretVersionResponse res = new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Parsed metadatra is NULL", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(CREATION_TIME));
assertThat("Incorrect deletion time", res.getMetadata().getDeletionTimeString(), is(DELETION_TIME));
assertThat("Incorrect destroyed state", res.getMetadata().isDestroyed(), is(false));
assertThat("Incorrect version", res.getMetadata().getVersion(), is(VERSION));
} catch (IOException e) {
fail("SecretVersionResponse deserialization failed: " + e.getMessage());
}
}
}