Add missing flags to SealResponse (closes #20)

This commit is contained in:
Stefan Kalscheuer 2018-10-05 20:17:43 +02:00
parent 8287be48b9
commit 44858edb76
4 changed files with 182 additions and 2 deletions

View File

@ -2,6 +2,7 @@
* **[breaking]** Removed support for `HTTPVaultConnectorFactory#withSslContext()` in favor of `#withTrustedCA()` due to * **[breaking]** Removed support for `HTTPVaultConnectorFactory#withSslContext()` in favor of `#withTrustedCA()` due to
refactoring of the internal SSL handling (#17) refactoring of the internal SSL handling (#17)
* [improvement] `VaultConnector` extends `java.io.Serializable` (#19) * [improvement] `VaultConnector` extends `java.io.Serializable` (#19)
* [improvement] Added missing flags to `SealResponse` (#20)
* [improvement] Build environment and tests now compatible with Java 10 * [improvement] Build environment and tests now compatible with Java 10
* [dependencies] Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489) * [dependencies] Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489)
* [deprecation] `VaultConnectorFactory` is deprecated in favor of `VaultConnectorBuilder` with identical API (#18) * [deprecation] `VaultConnectorFactory` is deprecated in favor of `VaultConnectorBuilder` with identical API (#18)

View File

@ -22,14 +22,20 @@ import com.fasterxml.jackson.annotation.JsonProperty;
/** /**
* Vault response for seal status or unseal request. * Vault response for seal status or unseal request.
* *
* @author Stefan Kalscheuer * @author Stefan Kalscheuer
* @since 0.1 * @since 0.1
*/ */
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public final class SealResponse implements VaultResponse { public final class SealResponse implements VaultResponse {
@JsonProperty("type")
private String type;
@JsonProperty("sealed") @JsonProperty("sealed")
private boolean sealed; private boolean sealed;
@JsonProperty("initialized")
private boolean initialized;
@JsonProperty("t") @JsonProperty("t")
private Integer threshold; private Integer threshold;
@ -39,6 +45,26 @@ public final class SealResponse implements VaultResponse {
@JsonProperty("progress") @JsonProperty("progress")
private Integer progress; private Integer progress;
@JsonProperty("version")
private String version;
@JsonProperty("nonce")
private String nonce;
@JsonProperty("cluster_name")
private String clusterName;
@JsonProperty("cluster_id")
private String clusterId;
/**
* @return Seal type.
* @since 0.8
*/
public String getType() {
return type;
}
/** /**
* @return Seal status * @return Seal status
*/ */
@ -46,6 +72,14 @@ public final class SealResponse implements VaultResponse {
return sealed; return sealed;
} }
/**
* @return Vault initialization status (since Vault 0.11.2).
* @since 0.8
*/
public boolean isInitialized() {
return initialized;
}
/** /**
* @return Required threshold of secret shares * @return Required threshold of secret shares
*/ */
@ -66,4 +100,36 @@ public final class SealResponse implements VaultResponse {
public Integer getProgress() { public Integer getProgress() {
return progress; return progress;
} }
/**
* @return Vault version.
* @since 0.8
*/
public String getVersion() {
return version;
}
/**
* @return A random nonce.
* @since 0.8
*/
public String getNonce() {
return nonce;
}
/**
* @return Vault cluster name (only if unsealed).
* @since 0.8
*/
public String getClusterName() {
return clusterName;
}
/**
* @return Vault cluster ID (only if unsealed).
* @since 0.8
*/
public String getClusterId() {
return clusterId;
}
} }

View File

@ -111,6 +111,7 @@ public class HTTPVaultConnectorTest {
SealResponse sealStatus = connector.unseal(KEY); SealResponse sealStatus = connector.unseal(KEY);
assumeTrue(sealStatus != null); assumeTrue(sealStatus != null);
assumeFalse(sealStatus.isSealed()); assumeFalse(sealStatus.isSealed());
assumeTrue(sealStatus.isInitialized()); // Initialized flag of Vault 0.11.2 (#20).
} }
@AfterEach @AfterEach

View File

@ -0,0 +1,112 @@
/*
* 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.*;
import static org.junit.jupiter.api.Assertions.fail;
/**
* JUnit Test for {@link SealResponse} model.
*
* @author Stefan Kalscheuer
* @since 0.8
*/
public class SealResponseTest {
private static final String TYPE = "shamir";
private static final Integer THRESHOLD = 3;
private static final Integer SHARES = 5;
private static final Integer PROGRESS_SEALED = 2;
private static final Integer PROGRESS_UNSEALED = 0;
private static final String VERSION = "0.11.2";
private static final String CLUSTER_NAME = "vault-cluster-d6ec3c7f";
private static final String CLUSTER_ID = "3e8b3fec-3749-e056-ba41-b62a63b997e8";
private static final String NONCE = "ef05d55d-4d2c-c594-a5e8-55bc88604c24";
private static final String RES_SEALED = "{\n" +
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": true,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_SEALED + ",\n" +
" \"nonce\": \"\",\n" +
" \"version\": \"" + VERSION + "\"\n" +
"}";
private static final String RES_UNSEALED = "{\n" +
" \"type\": \"" + TYPE + "\",\n" +
" \"sealed\": false,\n" +
" \"initialized\": true,\n" +
" \"t\": " + THRESHOLD + ",\n" +
" \"n\": " + SHARES + ",\n" +
" \"progress\": " + PROGRESS_UNSEALED + ",\n" +
" \"version\": \"" + VERSION + "\",\n" +
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
" \"nonce\": \"" + NONCE + "\"\n" +
"}";
/**
* Test creation from JSON value as returned by Vault when sealed (JSON example close to Vault documentation).
*/
@Test
public void jsonRoundtripSealed() {
// First test sealed Vault's response.
try {
SealResponse res = new ObjectMapper().readValue(RES_SEALED, SealResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(true));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED));
assertThat("Nonce not empty", res.getNonce(), is(""));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
// And the fields, that should not be filled.
assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue()));
assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue()));
} catch (IOException e) {
fail("TokenResponse deserialization failed: " + e.getMessage());
}
// Not test unsealed Vault's response.
try {
SealResponse res = new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(false));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED));
assertThat("Incorrect nonce", res.getNonce(), is(NONCE));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID));
} catch (IOException e) {
fail("TokenResponse deserialization failed: " + e.getMessage());
}
}
}