From f42bd967c586dd5b5d459b610ac8bc46da123f0d Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 16 Oct 2023 15:58:52 +0200 Subject: [PATCH] Polishing. Add since and author tags. Reorder fields. Introduce empty VaultTokenRequest and refactor interface methods to default methods for delegation on the interface level. See gh-690 Original pull request: gh-803 --- .../vault/core/VaultTokenOperations.java | 17 +++- .../vault/core/VaultTokenTemplate.java | 21 +---- .../vault/support/VaultTokenRequest.java | 90 ++++++++++--------- .../VaultTokenTemplateIntegrationTests.java | 4 +- 4 files changed, 67 insertions(+), 65 deletions(-) diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenOperations.java index f8363436..1b752742 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenOperations.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenOperations.java @@ -24,6 +24,7 @@ import org.springframework.vault.support.VaultTokenResponse; * Interface that specifies token-related operations. * * @author Mark Paluch + * @author Nanne Baars * @see Auth Backend: Token */ public interface VaultTokenOperations { @@ -34,7 +35,9 @@ public interface VaultTokenOperations { * @see POST * /auth/token/create */ - VaultTokenResponse create() throws VaultException; + default VaultTokenResponse create() throws VaultException { + return create(VaultTokenRequest.empty()); + } /** * Create a new token for the given {@link VaultTokenRequest}. @@ -51,16 +54,20 @@ public interface VaultTokenOperations { * @return a {@link VaultTokenResponse} * @see POST * /auth/token/create/:role + * @since 3.1 */ - VaultTokenResponse create(String role) throws VaultException; + default VaultTokenResponse create(String role) throws VaultException { + return create(role, VaultTokenRequest.empty()); + } /** * Create a new token for the given {@code role} and {@link VaultTokenRequest}. - * @param role must not be {@literal null}. + * @param role must not be {@literal null} or empty. * @param request must not be {@literal null}. * @return a {@link VaultTokenResponse} * @see POST * /auth/token/create/:role + * @since 3.1 */ VaultTokenResponse create(String role, VaultTokenRequest request) throws VaultException; @@ -70,7 +77,9 @@ public interface VaultTokenOperations { * @see POST * /auth/token/create-orphan */ - VaultTokenResponse createOrphan(); + default VaultTokenResponse createOrphan() { + return createOrphan(VaultTokenRequest.empty()); + } /** * Create a new orphan token for the given {@link VaultTokenRequest}. diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java index 5b306a78..b97902c9 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java @@ -34,6 +34,7 @@ import org.springframework.web.client.HttpStatusCodeException; * Default implementation of {@link VaultTokenOperations}. * * @author Mark Paluch + * @author Nanne Baars */ public class VaultTokenTemplate implements VaultTokenOperations { @@ -50,11 +51,6 @@ public class VaultTokenTemplate implements VaultTokenOperations { this.vaultOperations = vaultOperations; } - @Override - public VaultTokenResponse create() { - return create(VaultTokenRequest.builder().build()); - } - @Override public VaultTokenResponse create(VaultTokenRequest request) { @@ -63,24 +59,13 @@ public class VaultTokenTemplate implements VaultTokenOperations { return writeAndReturn("auth/token/create", request, VaultTokenResponse.class); } - @Override - public VaultTokenResponse create(String role) throws VaultException { - - return create(role, VaultTokenRequest.builder().build()); - } - @Override public VaultTokenResponse create(String role, VaultTokenRequest request) throws VaultException { - Assert.notNull(role, "role must not be null"); + Assert.hasText(role, "Role must not be null or empty"); Assert.notNull(request, "VaultTokenRequest must not be null"); - return writeAndReturn("auth/token/create/%s".formatted(role), request, VaultTokenResponse.class); - } - - @Override - public VaultTokenResponse createOrphan() { - return createOrphan(VaultTokenRequest.builder().build()); + return writeAndReturn(String.format("auth/token/create/%s", role), request, VaultTokenResponse.class); } @Override diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java index 79fa5922..28697b2c 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java @@ -22,10 +22,10 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.stream.StreamSupport; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.stream.StreamSupport; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -33,9 +33,12 @@ import org.springframework.util.Assert; * Value object to bind Vault HTTP Token API requests. * * @author Mark Paluch + * @author Nanne Baars */ public class VaultTokenRequest { + private static final VaultTokenRequest EMPTY = VaultTokenRequest.builder().build(); + @Nullable private final String id; @@ -61,15 +64,15 @@ public class VaultTokenRequest { @JsonProperty("display_name") private final String displayName; - @JsonProperty("num_uses") - private final int numUses; - @JsonProperty("entity_alias") private final String entityAlias; + @JsonProperty("num_uses") + private final int numUses; + VaultTokenRequest(@Nullable String id, List policies, Map meta, boolean noParent, boolean noDefaultPolicy, boolean renewable, @Nullable String ttl, @Nullable String explicitMaxTtl, - String displayName, int numUses, String entityAlias) { + String displayName, String entityAlias, int numUses) { this.id = id; this.policies = policies; @@ -91,6 +94,14 @@ public class VaultTokenRequest { return new VaultTokenRequestBuilder(); } + /** + * @return an empty token request. + * @since 3.1 + */ + public static VaultTokenRequest empty() { + return EMPTY; + } + /** * @return Id of the client token. */ @@ -158,6 +169,15 @@ public class VaultTokenRequest { return this.displayName; } + /** + * @return then name of the entity alias to associate with during token creation. Only + * works in combination with role name. + * @since 3.1 + */ + public String getEntityAlias() { + return this.entityAlias; + } + /** * @return the number of allowed token uses. */ @@ -165,15 +185,6 @@ public class VaultTokenRequest { return this.numUses; } - /** - * @return then name of the entity alias to associate with during token creation. Only - * works in combination with role_name argument and used entity alias must be listed - * in allowed_entity_aliases - */ - public String getEntityAlias() { - return this.entityAlias; - } - /** * Builder to build a {@link VaultTokenRequest}. */ @@ -200,17 +211,18 @@ public class VaultTokenRequest { private String displayName = ""; - private int numUses; - + @Nullable private String entityAlias; + private int numUses; + VaultTokenRequestBuilder() { } /** - * Configure a the Id of the client token. Can only be specified by a root token. - * Otherwise, the token Id is a randomly generated UUID. - * @param id the token Id. + * Configure the token identifier. Can only be specified by a root token. + * Otherwise, the token identifier is a randomly generated UUID. + * @param id the token identifier. * @return {@code this} {@link VaultTokenRequestBuilder}. */ public VaultTokenRequestBuilder id(String id) { @@ -386,21 +398,6 @@ public class VaultTokenRequest { return this; } - /** - * Configure the maximum uses for the token. This can be used to create a - * one-time-token or limited use token. Defaults to {@literal 0}, which has no - * limit to the number of uses. - * @param numUses number of uses, must not be negative. - * @return {@code this} {@link VaultTokenRequestBuilder}. - */ - public VaultTokenRequestBuilder numUses(int numUses) { - - Assert.isTrue(numUses >= 0, "Number of uses must not be negative"); - - this.numUses = numUses; - return this; - } - /** * Configure a display name for the token, defaults to "token". * @param displayName must not be empty or {@literal null}. @@ -418,6 +415,7 @@ public class VaultTokenRequest { * Configure the entity alias for the token. * @param entityAlias must not be empty or {@literal null}. * @return {@code this} {@link VaultTokenRequestBuilder}. + * @since 3.1 */ public VaultTokenRequestBuilder entityAlias(String entityAlias) { @@ -428,9 +426,20 @@ public class VaultTokenRequest { } /** - * Build a new {@link VaultTokenRequest} instance. - * @return a new {@link VaultCertificateRequest}. + * Configure the maximum uses for the token. This can be used to create a + * one-time-token or limited use token. Defaults to {@literal 0}, which has no + * limit to the number of uses. + * @param numUses number of uses, must not be negative. + * @return {@code this} {@link VaultTokenRequestBuilder}. */ + public VaultTokenRequestBuilder numUses(int numUses) { + + Assert.isTrue(numUses >= 0, "Number of uses must not be negative"); + + this.numUses = numUses; + return this; + } + /** * Build a new {@link VaultTokenRequest} instance. * @return a new {@link VaultCertificateRequest}. @@ -442,13 +451,12 @@ public class VaultTokenRequest { case 1 -> List.of(this.policies.get(0)); default -> List.copyOf(this.policies); }; - Map meta = switch (this.meta.size()) { - case 0 -> Map.of(); - default -> Collections.unmodifiableMap(new LinkedHashMap<>(this.meta)); - }; + + Map meta = this.meta.isEmpty() ? Map.of() + : Collections.unmodifiableMap(new LinkedHashMap<>(this.meta)); return new VaultTokenRequest(this.id, policies, meta, this.noParent, this.noDefaultPolicy, this.renewable, - this.ttl, this.explicitMaxTtl, this.displayName, this.numUses, this.entityAlias); + this.ttl, this.explicitMaxTtl, this.displayName, this.entityAlias, this.numUses); } private static List toList(Iterable iter) { diff --git a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTokenTemplateIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTokenTemplateIntegrationTests.java index 4fbabf02..78bd6d61 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTokenTemplateIntegrationTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultTokenTemplateIntegrationTests.java @@ -47,6 +47,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; * Integration tests for {@link VaultTokenTemplate} through {@link VaultTokenOperations}. * * @author Mark Paluch + * @author Nanne Baars */ @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = VaultIntegrationTestConfiguration.class) @@ -100,8 +101,7 @@ class VaultTokenTemplateIntegrationTests extends IntegrationTestSupport { @Test void noTokenWhenRoleDoesNotExists() { - - assertThatThrownBy(() -> this.tokenOperations.create("unknown-role")).isInstanceOf(VaultException.class); + assertThatExceptionOfType(VaultException.class).isThrownBy(() -> this.tokenOperations.create("unknown-role")); } @Test