From 9caeac4cba6c7bb0afa55c46042d7dfa535e1774 Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Mon, 19 Nov 2018 15:21:10 +0100 Subject: [PATCH] Support secret_id_bound_cidrs replacing bound_cidr_list for AppRole (#24) The latter parameter is deprecated in Vault. The connector now supports both while the former one is deprecated and will be removed when it is removed from Vault. --- CHANGELOG.md | 1 + .../jvault/connector/model/AppRole.java | 93 ++++++++++++++++--- .../connector/model/AppRoleBuilder.java | 24 ++++- .../connector/model/AppRoleBuilderTest.java | 17 +++- 4 files changed, 118 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ff3a3d..909f987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ refactoring of the internal SSL handling (#17) * [improvement] Build environment and tests now compatible with Java 10 * [dependencies] Updated dependencies to fix vulnerabilities (i.e. CVE-2018-7489) * [deprecation] `VaultConnectorFactory` is deprecated in favor of `VaultConnectorBuilder` with identical API (#18) +* [deprecation] `AppRoleBuilder#withBoundCidrList(List)` is deprecated in favor of `AppRoleBuilder#withSecretIdBoundCidrs(List)` (#24) ## 0.7.1 [2018-03-17] * [improvement] Added automatic module name for JPMS compatibility diff --git a/src/main/java/de/stklcode/jvault/connector/model/AppRole.java b/src/main/java/de/stklcode/jvault/connector/model/AppRole.java index 8675698..1a7b783 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/AppRole.java +++ b/src/main/java/de/stklcode/jvault/connector/model/AppRole.java @@ -41,6 +41,8 @@ public final class AppRole { private List boundCidrList; + private List secretIdBoundCidrs; + private List policies; @JsonProperty("secret_id_num_uses") @@ -73,24 +75,57 @@ public final class AppRole { /** * Construct complete {@link AppRole} object. * - * @param name Role name (required) - * @param id Role ID (optional) - * @param bindSecretId Bind secret ID (optional) - * @param boundCidrList Whitelist of subnets in CIDR notation (optional) - * @param policies List of policies (optional) - * @param secretIdNumUses Maximum number of uses per secret (optional) - * @param secretIdTtl Maximum TTL in seconds for secrets (optional) - * @param tokenTtl Token TTL in seconds (optional) - * @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional) - * @param period Duration in seconds, if set the token is a periodic token (optional) + * @param name Role name (required) + * @param id Role ID (optional) + * @param bindSecretId Bind secret ID (optional) + * @param secretIdBoundCidrs Whitelist of subnets in CIDR notation (optional) + * @param policies List of policies (optional) + * @param secretIdNumUses Maximum number of uses per secret (optional) + * @param secretIdTtl Maximum TTL in seconds for secrets (optional) + * @param tokenTtl Token TTL in seconds (optional) + * @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional) + * @param period Duration in seconds, if set the token is a periodic token (optional) */ - public AppRole(final String name, final String id, final Boolean bindSecretId, final List boundCidrList, + public AppRole(final String name, final String id, final Boolean bindSecretId, final List secretIdBoundCidrs, final List policies, final Integer secretIdNumUses, final Integer secretIdTtl, final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) { this.name = name; this.id = id; this.bindSecretId = bindSecretId; + this.secretIdBoundCidrs = secretIdBoundCidrs; + this.policies = policies; + this.secretIdNumUses = secretIdNumUses; + this.secretIdTtl = secretIdTtl; + this.tokenTtl = tokenTtl; + this.tokenMaxTtl = tokenMaxTtl; + this.period = period; + } + + /** + * Construct complete {@link AppRole} object. + * + * This constructor is used for transition from {@code bound_cidr_list} to {@code secret_id_bound_cidrs} only. + * + * @param name Role name (required) + * @param id Role ID (optional) + * @param bindSecretId Bind secret ID (optional) + * @param boundCidrList Whitelist of subnets in CIDR notation (optional) + * @param secretIdBoundCidrs Whitelist of subnets in CIDR notation (optional) + * @param policies List of policies (optional) + * @param secretIdNumUses Maximum number of uses per secret (optional) + * @param secretIdTtl Maximum TTL in seconds for secrets (optional) + * @param tokenTtl Token TTL in seconds (optional) + * @param tokenMaxTtl Maximum token TTL in seconds, including renewals (optional) + * @param period Duration in seconds, if set the token is a periodic token (optional) + */ + AppRole(final String name, final String id, final Boolean bindSecretId, final List boundCidrList, + final List secretIdBoundCidrs, final List policies, final Integer secretIdNumUses, + final Integer secretIdTtl, final Integer tokenTtl, final Integer tokenMaxTtl, final Integer period) { + this.name = name; + this.id = id; + this.bindSecretId = bindSecretId; this.boundCidrList = boundCidrList; + this.secretIdBoundCidrs = secretIdBoundCidrs; this.policies = policies; this.secretIdNumUses = secretIdNumUses; this.secretIdTtl = secretIdTtl; @@ -122,14 +157,18 @@ public final class AppRole { /** * @return list of bound CIDR subnets + * @deprecated Use {@link #getSecretIdBoundCidrs()} instead, as this parameter is deprecated in Vault. */ + @Deprecated public List getBoundCidrList() { return boundCidrList; } /** * @param boundCidrList list of subnets in CIDR notation to bind role to + * @deprecated Use {@link #setSecretIdBoundCidrs(List)} instead, as this parameter is deprecated in Vault. */ + @Deprecated @JsonSetter("bound_cidr_list") public void setBoundCidrList(final List boundCidrList) { this.boundCidrList = boundCidrList; @@ -137,7 +176,9 @@ public final class AppRole { /** * @return list of subnets in CIDR notation as comma-separated {@link String} + * @deprecated Use {@link #getSecretIdBoundCidrsString()} instead, as this parameter is deprecated in Vault. */ + @Deprecated @JsonGetter("bound_cidr_list") @JsonInclude(JsonInclude.Include.NON_EMPTY) public String getBoundCidrListString() { @@ -146,6 +187,36 @@ public final class AppRole { return String.join(",", boundCidrList); } + /** + * @return list of bound CIDR subnets + * @since 0.8 replaces {@link #getBoundCidrList()} + */ + public List getSecretIdBoundCidrs() { + return secretIdBoundCidrs; + } + + /** + * @param secretIdBoundCidrs List of subnets in CIDR notation to bind secrets of this role to. + * @since 0.8 replaces {@link #setBoundCidrList(List)} + */ + @JsonSetter("secret_id_bound_cidrs") + public void setSecretIdBoundCidrs(final List secretIdBoundCidrs) { + this.secretIdBoundCidrs = secretIdBoundCidrs; + } + + /** + * @return List of subnets in CIDR notation as comma-separated {@link String} + * @since 0.8 replaces {@link #getBoundCidrListString()} ()} + */ + @JsonGetter("secret_id_bound_cidrs") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public String getSecretIdBoundCidrsString() { + if (secretIdBoundCidrs == null || secretIdBoundCidrs.isEmpty()) { + return ""; + } + return String.join(",", secretIdBoundCidrs); + } + /** * @return list of policies */ diff --git a/src/main/java/de/stklcode/jvault/connector/model/AppRoleBuilder.java b/src/main/java/de/stklcode/jvault/connector/model/AppRoleBuilder.java index bbc4d87..a059e1b 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/AppRoleBuilder.java +++ b/src/main/java/de/stklcode/jvault/connector/model/AppRoleBuilder.java @@ -30,6 +30,7 @@ public final class AppRoleBuilder { private String id; private Boolean bindSecretId; private List boundCidrList; + private List secretIdBoundCidrs; private List policies; private Integer secretIdNumUses; private Integer secretIdTtl; @@ -93,12 +94,26 @@ public final class AppRoleBuilder { * * @param boundCidrList List of CIDR blocks which can perform login * @return self + * @deprecated Use {@link #withSecretIdBoundCidrs(List)} instead, as this parameter is deprecated in Vault. */ + @Deprecated public AppRoleBuilder withBoundCidrList(final List boundCidrList) { this.boundCidrList = boundCidrList; return this; } + /** + * Set bound CIDR blocks. + * + * @param secretIdBoundCidrs List of CIDR blocks which can perform login + * @return self + * @since 0.8 replaces {@link #withBoundCidrList(List)} + */ + public AppRoleBuilder withSecretIdBoundCidrs(final List secretIdBoundCidrs) { + this.secretIdBoundCidrs = secretIdBoundCidrs; + return this; + } + /** * Add a CIDR block to list of bound blocks. * @@ -106,9 +121,15 @@ public final class AppRoleBuilder { * @return self */ public AppRoleBuilder withCidrBlock(final String cidrBlock) { - if (boundCidrList == null) + if (boundCidrList == null) { boundCidrList = new ArrayList<>(); + } boundCidrList.add(cidrBlock); + + if (secretIdBoundCidrs == null) { + secretIdBoundCidrs = new ArrayList<>(); + } + secretIdBoundCidrs.add(cidrBlock); return this; } @@ -204,6 +225,7 @@ public final class AppRoleBuilder { id, bindSecretId, boundCidrList, + secretIdBoundCidrs, policies, secretIdNumUses, secretIdTtl, diff --git a/src/test/java/de/stklcode/jvault/connector/model/AppRoleBuilderTest.java b/src/test/java/de/stklcode/jvault/connector/model/AppRoleBuilderTest.java index f194e95..0a2a9e8 100644 --- a/src/test/java/de/stklcode/jvault/connector/model/AppRoleBuilderTest.java +++ b/src/test/java/de/stklcode/jvault/connector/model/AppRoleBuilderTest.java @@ -51,8 +51,8 @@ public class AppRoleBuilderTest { private static final Integer TOKEN_MAX_TTL = 9600; private static final Integer PERIOD = 1234; private static final String JSON_MIN = "{\"role_name\":\"" + NAME + "\"}"; - private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"bound_cidr_list\":\"%s\",\"policies\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"token_ttl\":%d,\"token_max_ttl\":%d,\"period\":%d}", - NAME, ID, BIND_SECRET_ID, CIDR_1, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD); + private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"bound_cidr_list\":\"%s\",\"secret_id_bound_cidrs\":\"%s\",\"policies\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"token_ttl\":%d,\"token_max_ttl\":%d,\"period\":%d}", + NAME, ID, BIND_SECRET_ID, CIDR_1, CIDR_1, POLICY, SECRET_ID_NUM_USES, SECRET_ID_TTL, TOKEN_TTL, TOKEN_MAX_TTL, PERIOD); @BeforeAll public static void init() { @@ -69,6 +69,7 @@ public class AppRoleBuilderTest { assertThat(role.getId(), is(nullValue())); assertThat(role.getBindSecretId(), is(nullValue())); assertThat(role.getBoundCidrList(), is(nullValue())); + assertThat(role.getSecretIdBoundCidrs(), is(nullValue())); assertThat(role.getPolicies(), is(nullValue())); assertThat(role.getSecretIdNumUses(), is(nullValue())); assertThat(role.getSecretIdTtl(), is(nullValue())); @@ -89,6 +90,7 @@ public class AppRoleBuilderTest { .withId(ID) .withBindSecretID(BIND_SECRET_ID) .withBoundCidrList(BOUND_CIDR_LIST) + .withSecretIdBoundCidrs(BOUND_CIDR_LIST) .withPolicies(POLICIES) .withSecretIdNumUses(SECRET_ID_NUM_USES) .withSecretIdTtl(SECRET_ID_TTL) @@ -100,6 +102,7 @@ public class AppRoleBuilderTest { assertThat(role.getId(), is(ID)); assertThat(role.getBindSecretId(), is(BIND_SECRET_ID)); assertThat(role.getBoundCidrList(), is(BOUND_CIDR_LIST)); + assertThat(role.getSecretIdBoundCidrs(), is(BOUND_CIDR_LIST)); assertThat(role.getPolicies(), is(POLICIES)); assertThat(role.getSecretIdNumUses(), is(SECRET_ID_NUM_USES)); assertThat(role.getSecretIdTtl(), is(SECRET_ID_TTL)); @@ -128,12 +131,16 @@ public class AppRoleBuilderTest { role = new AppRoleBuilder(NAME).withCidrBlock(CIDR_2).build(); assertThat(role.getBoundCidrList(), hasSize(1)); assertThat(role.getBoundCidrList(), contains(CIDR_2)); + assertThat(role.getSecretIdBoundCidrs(), hasSize(1)); + assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_2)); role = new AppRoleBuilder(NAME) - .withBoundCidrList(BOUND_CIDR_LIST) + .withSecretIdBoundCidrs(BOUND_CIDR_LIST) .withCidrBlock(CIDR_2) .build(); - assertThat(role.getBoundCidrList(), hasSize(2)); - assertThat(role.getBoundCidrList(), contains(CIDR_1, CIDR_2)); + assertThat(role.getBoundCidrList(), hasSize(1)); + assertThat(role.getBoundCidrList(), contains(CIDR_2)); + assertThat(role.getSecretIdBoundCidrs(), hasSize(2)); + assertThat(role.getSecretIdBoundCidrs(), contains(CIDR_1, CIDR_2)); /* Add single policy */ role = new AppRoleBuilder(NAME).withPolicy(POLICY_2).build();