feat: add custom_metadata, cas_required and delete_version_after fields
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Stefan Kalscheuer 2024-06-22 14:32:07 +02:00
parent e0711e6108
commit 5f1f94f59c
Signed by: stefan
GPG Key ID: 3887EC2A53B55430
5 changed files with 83 additions and 6 deletions

View File

@ -10,6 +10,7 @@
* Add missing `num_uses` field to `AuthData`
* Add `mount_type` attribute to common response model
* Add `auth` attribute to common response model
* Add `custom_metadata`, `cas_required` and `delete_version_after` fields for KVv2 metadata
### Fix
* Rename `enable_local_secret_id` to `local_secret_ids` in `AppRole` model

View File

@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@ -34,7 +35,7 @@ import java.util.Objects;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class SecretMetadata implements Serializable {
private static final long serialVersionUID = -4967896264361344676L;
private static final long serialVersionUID = -905059942871916214L;
private static final DateTimeFormatter TIME_FORMAT =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX");
@ -57,6 +58,15 @@ public final class SecretMetadata implements Serializable {
@JsonProperty("versions")
private Map<Integer, VersionMetadata> versions;
@JsonProperty("cas_required")
private Boolean casRequired;
@JsonProperty("custom_metadata")
private HashMap<String, String> customMetadata;
@JsonProperty("delete_version_after")
private String deleteVersionAfter;
/**
* @return Time of secret creation as raw string representation.
* @deprecated Method left for backwards compatibility only. Use {@link #getCreatedTime()} instead.
@ -125,6 +135,30 @@ public final class SecretMetadata implements Serializable {
return versions;
}
/**
* @return CAS required?
* @since 1.3
*/
public Boolean isCasRequired() {
return casRequired;
}
/**
* @return Custom metadata.
* @since 1.3
*/
public Map<String, String> getCustomMetadata() {
return customMetadata;
}
/**
* @return time duration to delete version
* @since 1.3
*/
public String getDeleteVersionAfter() {
return deleteVersionAfter;
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -138,11 +172,15 @@ public final class SecretMetadata implements Serializable {
Objects.equals(maxVersions, that.maxVersions) &&
Objects.equals(oldestVersion, that.oldestVersion) &&
Objects.equals(updatedTime, that.updatedTime) &&
Objects.equals(versions, that.versions);
Objects.equals(versions, that.versions) &&
Objects.equals(casRequired, that.casRequired) &&
Objects.equals(customMetadata, that.customMetadata) &&
Objects.equals(deleteVersionAfter, that.deleteVersionAfter);
}
@Override
public int hashCode() {
return Objects.hash(createdTime, currentVersion, maxVersions, oldestVersion, updatedTime, versions);
return Objects.hash(createdTime, currentVersion, maxVersions, oldestVersion, updatedTime, versions, casRequired,
customMetadata, deleteVersionAfter);
}
}

View File

@ -22,6 +22,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
@ -33,7 +35,7 @@ import java.util.Objects;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class VersionMetadata implements Serializable {
private static final long serialVersionUID = -6815731513868586713L;
private static final long serialVersionUID = 8495687554714216478L;
private static final DateTimeFormatter TIME_FORMAT =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX");
@ -50,6 +52,9 @@ public final class VersionMetadata implements Serializable {
@JsonProperty("version")
private Integer version;
@JsonProperty("custom_metadata")
private HashMap<String, String> customMetadata;
/**
* @return Time of secret creation as raw string representation.
* @deprecated Method left for backwards compatibility only. Use {@link #getCreatedTime()} instead.
@ -104,6 +109,14 @@ public final class VersionMetadata implements Serializable {
return version;
}
/**
* @return Custom metadata.
* @since 1.3
*/
public Map<String, String> getCustomMetadata() {
return customMetadata;
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -115,11 +128,12 @@ public final class VersionMetadata implements Serializable {
return destroyed == that.destroyed &&
Objects.equals(createdTime, that.createdTime) &&
Objects.equals(deletionTime, that.deletionTime) &&
Objects.equals(version, that.version);
Objects.equals(version, that.version) &&
Objects.equals(customMetadata, that.customMetadata);
}
@Override
public int hashCode() {
return Objects.hash(createdTime, deletionTime, destroyed, version);
return Objects.hash(createdTime, deletionTime, destroyed, version, customMetadata);
}
}

View File

@ -21,6 +21,7 @@ import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
@ -42,6 +43,9 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
private static final String SECRET_META_CREATED = "2018-03-22T02:24:06.945319214Z";
private static final String SECRET_META_DELETED = "2018-03-23T03:25:07.056420325Z";
private static final List<String> SECRET_WARNINGS = null;
private static final String CUSTOM_META_KEY = "foo";
private static final String CUSTOM_META_VAL = "bar";
private static final String SECRET_JSON_V2 = "{\n" +
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
@ -54,6 +58,7 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
" },\n" +
" \"metadata\": {\n" +
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
" \"custom_metadata\": null,\n" +
" \"deletion_time\": \"\",\n" +
" \"destroyed\": false,\n" +
" \"version\": 1\n" +
@ -73,6 +78,9 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
" },\n" +
" \"metadata\": {\n" +
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
" \"custom_metadata\": {" +
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
" },\n" +
" \"deletion_time\": \"" + SECRET_META_DELETED + "\",\n" +
" \"destroyed\": true,\n" +
" \"version\": 2\n" +
@ -113,6 +121,7 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
assertNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date");
assertFalse(res.getMetadata().isDestroyed(), "Secret destroyed when not expected");
assertEquals(1, res.getMetadata().getVersion(), "Incorrect secret version");
assertNull(res.getMetadata().getCustomMetadata(), "Incorrect custom metadata");
// Deleted KV v2 secret.
res = assertDoesNotThrow(
@ -127,6 +136,7 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
assertNotNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date");
assertTrue(res.getMetadata().isDestroyed(), "Secret destroyed when not expected");
assertEquals(2, res.getMetadata().getVersion(), "Incorrect secret version");
assertEquals(Map.of(CUSTOM_META_KEY, CUSTOM_META_VAL), res.getMetadata().getCustomMetadata(), "Incorrect custom metadata");
}
private void assertSecretData(SecretResponse res) {

View File

@ -20,6 +20,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import de.stklcode.jvault.connector.model.AbstractModelTest;
import org.junit.jupiter.api.Test;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
/**
@ -35,11 +37,20 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
private static final Integer CURRENT_VERSION = 3;
private static final Integer MAX_VERSIONS = 0;
private static final Integer OLDEST_VERSION = 1;
private static final Boolean CAS_REQUIRED = false;
private static final String CUSTOM_META_KEY = "test";
private static final String CUSTOM_META_VAL = "123";
private static final String DELETE_VERSION_AFTER = "0s";
private static final String META_JSON = "{\n" +
" \"data\": {\n" +
" \"cas_required\": " + CAS_REQUIRED + ",\n" +
" \"created_time\": \"" + V1_TIME + "\",\n" +
" \"current_version\": " + CURRENT_VERSION + ",\n" +
" \"custom_metadata\": {" +
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
" },\n" +
" \"delete_version_after\": \"" + DELETE_VERSION_AFTER + "\"," +
" \"max_versions\": " + MAX_VERSIONS + ",\n" +
" \"oldest_version\": " + OLDEST_VERSION + ",\n" +
" \"updated_time\": \"" + V3_TIME + "\",\n" +
@ -88,11 +99,14 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
);
assertNotNull(res, "Parsed response is NULL");
assertNotNull(res.getMetadata(), "Parsed metadata is NULL");
assertEquals(CAS_REQUIRED, res.getMetadata().isCasRequired(), "Incorrect CAS required flag");
assertEquals(V1_TIME, res.getMetadata().getCreatedTimeString(), "Incorrect created time");
assertNotNull(res.getMetadata().getCreatedTime(), "Parting created time failed");
assertEquals(CURRENT_VERSION, res.getMetadata().getCurrentVersion(), "Incorrect current version");
assertEquals(MAX_VERSIONS, res.getMetadata().getMaxVersions(), "Incorrect max versions");
assertEquals(OLDEST_VERSION, res.getMetadata().getOldestVersion(), "Incorrect oldest version");
assertEquals(Map.of(CUSTOM_META_KEY, CUSTOM_META_VAL), res.getMetadata().getCustomMetadata(), "Incorrect custom metadata");
assertEquals(DELETE_VERSION_AFTER, res.getMetadata().getDeleteVersionAfter(), "Incorrect delete version after");
assertEquals(V3_TIME, res.getMetadata().getUpdatedTimeString(), "Incorrect updated time");
assertNotNull(res.getMetadata().getUpdatedTime(), "Parting updated time failed");
assertEquals(3, res.getMetadata().getVersions().size(), "Incorrect number of versions");