From 81094fca7f777baae9fd16bad19ee7ec8f54f570 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 7 Sep 2020 15:28:43 +0200 Subject: [PATCH] Polishing Add author tags. Return generated tweak from encode and batch encode methods. Switch simple encode/decode methods to default interface methods. Introduce VaultTransformContext.isEmpty() method to check if the context is empty. Align equals/hashCode methods with Spring style. Reformat code. Resolves gh-570. --- .../vault/core/VaultOperations.java | 1 + .../vault/core/VaultTransformOperations.java | 29 ++- .../vault/core/VaultTransformTemplate.java | 107 +++++------ .../vault/support/TransformCiphertext.java | 7 +- .../vault/support/TransformPlaintext.java | 23 ++- .../vault/support/VaultTransformContext.java | 19 +- .../support/VaultTransformDecodeResult.java | 4 +- .../support/VaultTransformEncodeResult.java | 1 + ...aultTemplateTransformIntegrationTests.java | 28 ++- ...aultTransformTemplateIntegrationTests.java | 173 +++++++++--------- src/main/asciidoc/new-features.adoc | 1 + 11 files changed, 195 insertions(+), 198 deletions(-) diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java index eebe7440..227c7413 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java @@ -34,6 +34,7 @@ import org.springframework.web.client.RestClientException; * the {@link #doWithVault(RestOperationsCallback) without a session}. * * @author Mark Paluch + * @author Lauren Voswinkel * @see #doWithSession(RestOperationsCallback) * @see #doWithVault(RestOperationsCallback) * @see org.springframework.web.client.RestOperations diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformOperations.java index 79f240af..37b665c5 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformOperations.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformOperations.java @@ -15,21 +15,29 @@ */ package org.springframework.vault.core; -import org.springframework.vault.support.*; - import java.util.List; +import org.springframework.vault.support.Ciphertext; +import org.springframework.vault.support.Plaintext; +import org.springframework.vault.support.TransformCiphertext; +import org.springframework.vault.support.TransformPlaintext; +import org.springframework.vault.support.VaultTransformContext; +import org.springframework.vault.support.VaultTransformDecodeResult; +import org.springframework.vault.support.VaultTransformEncodeResult; + /** * Interface that specifies operations using the {@code transform} backend. * * @author Lauren Voswinkel + * @author Mark Paluch + * @since 2.3 * @see Transform * Secrets Engine - * @since 2.3 */ public interface VaultTransformOperations { + /** - * Encodes the provided plaintext using the named role. + * Encode the provided plaintext using the named role. * @param roleName must not be empty or {@literal null}. * @param plaintext must not be empty or {@literal null}. * @return cipher text. @@ -37,7 +45,7 @@ public interface VaultTransformOperations { String encode(String roleName, String plaintext); /** - * Encodes the provided plaintext using the named role. + * Encode the provided plaintext using the named role. * @param roleName must not be empty or {@literal null}. * @param plaintext must not be {@literal null}. * @return cipher text. @@ -45,14 +53,16 @@ public interface VaultTransformOperations { TransformCiphertext encode(String roleName, TransformPlaintext plaintext); /** - * Encodes the provided plaintext using the named role. + * Encode the provided plaintext using the named role. * @param roleName must not be empty or {@literal null}. * @param plaintext must not be empty or {@literal null}. * @param transformRequest must not be {@literal null}. Use * {@link VaultTransformContext#empty()} if no request options provided. * @return cipher text. */ - String encode(String roleName, byte[] plaintext, VaultTransformContext transformRequest); + default TransformCiphertext encode(String roleName, byte[] plaintext, VaultTransformContext transformRequest) { + return encode(roleName, TransformPlaintext.of(plaintext).with(transformRequest)); + } /** * Encode the provided batch of plaintext using the role given and transformation in @@ -71,7 +81,9 @@ public interface VaultTransformOperations { * @param ciphertext must not be empty or {@literal null}. * @return plain text. */ - String decode(String roleName, String ciphertext); + default String decode(String roleName, String ciphertext) { + return decode(roleName, TransformCiphertext.of(ciphertext)).asString(); + } /** * Decode the provided ciphertext using the named role. @@ -101,4 +113,5 @@ public interface VaultTransformOperations { * @return the decrypted result in the order of {@code batchRequest} ciphertexts. */ List decode(String roleName, List batchRequest); + } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformTemplate.java index feab723c..406a8ed9 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransformTemplate.java @@ -15,20 +15,29 @@ */ package org.springframework.vault.core; -import org.springframework.lang.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + import org.springframework.util.Assert; import org.springframework.util.Base64Utils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.vault.VaultException; -import org.springframework.vault.support.*; - -import java.util.*; +import org.springframework.vault.support.TransformCiphertext; +import org.springframework.vault.support.TransformPlaintext; +import org.springframework.vault.support.VaultResponse; +import org.springframework.vault.support.VaultTransformContext; +import org.springframework.vault.support.VaultTransformDecodeResult; +import org.springframework.vault.support.VaultTransformEncodeResult; /** * Default implementation of {@link VaultTransformOperations}. * * @author Lauren Voswinkel + * @author Mark Paluch * @since 2.3 */ public class VaultTransformTemplate implements VaultTransformOperations { @@ -72,27 +81,16 @@ public class VaultTransformTemplate implements VaultTransformOperations { Assert.hasText(roleName, "Role name must not be empty"); Assert.notNull(plaintext, "Plaintext must not be null"); - String ciphertext = encode(roleName, plaintext.getPlaintext(), plaintext.getContext()); - - return toCiphertext(ciphertext, plaintext.getContext()); - } - - @Override - public String encode(String roleName, byte[] plaintext, VaultTransformContext transformContext) { - - Assert.hasText(roleName, "Role name must not be empty"); - Assert.notNull(plaintext, "Plaintext must not be null"); - Assert.notNull(transformContext, "VaultTransformContext must not be null"); - Map request = new LinkedHashMap<>(); - String value = new String(plaintext); - request.put("value", value); + request.put("value", plaintext.asString()); - applyTransformOptions(transformContext, request); + applyTransformOptions(plaintext.getContext(), request); - return (String) this.vaultOperations.write(String.format("%s/encode/%s", this.path, roleName), request) - .getRequiredData().get("encoded_value"); + Map data = this.vaultOperations + .write(String.format("%s/encode/%s", this.path, roleName), request).getRequiredData(); + + return toCiphertext(data, plaintext.getContext()); } @Override @@ -109,9 +107,7 @@ public class VaultTransformTemplate implements VaultTransformOperations { vaultRequest.put("value", request.asString()); - if (request.getContext() != null) { - applyTransformOptions(request.getContext(), vaultRequest); - } + applyTransformOptions(request.getContext(), vaultRequest); batch.add(vaultRequest); } @@ -122,22 +118,6 @@ public class VaultTransformTemplate implements VaultTransformOperations { return toEncodedResults(vaultResponse, batchRequest); } - @Override - public String decode(String roleName, String ciphertext) { - - Assert.hasText(roleName, "Key name must not be empty"); - Assert.hasText(ciphertext, "Ciphertext must not be empty"); - - Map request = new LinkedHashMap<>(); - - request.put("value", ciphertext); - - String plaintext = (String) this.vaultOperations - .write(String.format("%s/decode/%s", this.path, roleName), request).getRequiredData().get("decoded_value"); - - return new String(plaintext); - } - @Override public TransformPlaintext decode(String roleName, TransformCiphertext ciphertext) { @@ -162,10 +142,8 @@ public class VaultTransformTemplate implements VaultTransformOperations { applyTransformOptions(transformContext, request); - String plaintext = (String) this.vaultOperations - .write(String.format("%s/decode/%s", this.path, roleName), request).getRequiredData().get("decoded_value"); - - return plaintext; + return (String) this.vaultOperations.write(String.format("%s/decode/%s", this.path, roleName), request) + .getRequiredData().get("decoded_value"); } @Override @@ -181,10 +159,7 @@ public class VaultTransformTemplate implements VaultTransformOperations { Map vaultRequest = new LinkedHashMap<>(2); vaultRequest.put("value", request.getCiphertext()); - - if (request.getContext() != null) { - applyTransformOptions(request.getContext(), vaultRequest); - } + applyTransformOptions(request.getContext(), vaultRequest); batch.add(vaultRequest); } @@ -207,7 +182,7 @@ public class VaultTransformTemplate implements VaultTransformOperations { } private static List toEncodedResults(VaultResponse vaultResponse, - List batchRequest) { + List batchRequest) { List result = new ArrayList<>(batchRequest.size()); List> batchData = getBatchData(vaultResponse); @@ -223,7 +198,7 @@ public class VaultTransformTemplate implements VaultTransformOperations { encoded = new VaultTransformEncodeResult(new VaultException(data.get("error"))); } else { - encoded = new VaultTransformEncodeResult(toCiphertext(data.get("encoded_value"), plaintext.getContext())); + encoded = new VaultTransformEncodeResult(toCiphertext(data, plaintext.getContext())); } } else { @@ -260,7 +235,8 @@ public class VaultTransformTemplate implements VaultTransformOperations { return result; } - private static VaultTransformDecodeResult getDecryptionResult(Map data, TransformCiphertext ciphertext) { + private static VaultTransformDecodeResult getDecryptionResult(Map data, + TransformCiphertext ciphertext) { if (StringUtils.hasText(data.get("error"))) { return new VaultTransformDecodeResult(new VaultException(data.get("error"))); @@ -268,15 +244,26 @@ public class VaultTransformTemplate implements VaultTransformOperations { if (StringUtils.hasText(data.get("decoded_value"))) { - byte[] plaintext = data.get("decoded_value").getBytes(); - return new VaultTransformDecodeResult(TransformPlaintext.of(plaintext).with(ciphertext.getContext())); + return new VaultTransformDecodeResult( + TransformPlaintext.of(data.get("decoded_value")).with(ciphertext.getContext())); } return new VaultTransformDecodeResult(TransformPlaintext.empty().with(ciphertext.getContext())); } - private static TransformCiphertext toCiphertext(String ciphertext, @Nullable VaultTransformContext context) { - return context != null ? TransformCiphertext.of(ciphertext).with(context) : TransformCiphertext.of(ciphertext); + private static TransformCiphertext toCiphertext(Map data, VaultTransformContext context) { + + String ciphertext = (String) data.get("encoded_value"); + + VaultTransformContext contextToUse = context; + if (data.containsKey("tweak")) { + byte[] tweak = Base64Utils.decodeFromString((String) data.get("tweak")); + contextToUse = VaultTransformContext.builder().transformation(context.getTransformation()).tweak(tweak) + .build(); + } + + return contextToUse.isEmpty() ? TransformCiphertext.of(ciphertext) + : TransformCiphertext.of(ciphertext).with(contextToUse); } @SuppressWarnings("unchecked") @@ -284,14 +271,4 @@ public class VaultTransformTemplate implements VaultTransformOperations { return (List>) vaultResponse.getRequiredData().get("batch_results"); } - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getSimpleName()); - sb.append(" [vaultOperations=").append(this.vaultOperations); - sb.append(", path='").append(this.path).append('\''); - sb.append(']'); - return sb.toString(); - } - } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/TransformCiphertext.java b/spring-vault-core/src/main/java/org/springframework/vault/support/TransformCiphertext.java index bfeeb261..a0685392 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/TransformCiphertext.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/TransformCiphertext.java @@ -38,7 +38,8 @@ public class TransformCiphertext { } /** - * Factory method to create {@link TransformCiphertext} from the given {@code ciphertext}. + * Factory method to create {@link TransformCiphertext} from the given + * {@code ciphertext}. * @param ciphertext the ciphertext to decrypt, must not be {@literal null} or empty. * @return the {@link TransformCiphertext} for {@code ciphertext}. */ @@ -58,8 +59,8 @@ public class TransformCiphertext { } /** - * Create a new {@link TransformCiphertext} object from this ciphertext associated with the - * given {@link VaultTransformContext}. + * Create a new {@link TransformCiphertext} object from this ciphertext associated + * with the given {@link VaultTransformContext}. * @param context transit context, must not be {@literal null}. * @return the new {@link TransformCiphertext} object. */ diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/TransformPlaintext.java b/spring-vault-core/src/main/java/org/springframework/vault/support/TransformPlaintext.java index 4796c37d..ae6cc363 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/TransformPlaintext.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/TransformPlaintext.java @@ -16,9 +16,7 @@ package org.springframework.vault.support; import org.springframework.util.Assert; - -import java.util.Arrays; -import java.util.Objects; +import org.springframework.util.ObjectUtils; /** * Value object representing plaintext with an optional {@link VaultTransformContext}. @@ -44,7 +42,6 @@ public class TransformPlaintext { /** * Factory method to create an empty {@link TransformPlaintext}. * @return the empty {@link TransformPlaintext} object. - * @since 1.1.2 */ public static TransformPlaintext empty() { return EMPTY; @@ -93,12 +90,15 @@ public class TransformPlaintext { } /** - * Create a new {@link TransformPlaintext} object from this plaintext associated with the given - * {@link VaultTransformContext}. + * Create a new {@link TransformPlaintext} object from this plaintext associated with + * the given {@link VaultTransformContext}. * @param context transform context. * @return the new {@link TransformPlaintext} object. */ public TransformPlaintext with(VaultTransformContext context) { + + Assert.notNull(context, "VaultTransformContext must not be null"); + return new TransformPlaintext(getPlaintext(), context); } @@ -116,14 +116,17 @@ public class TransformPlaintext { return true; if (!(o instanceof TransformPlaintext)) return false; - TransformPlaintext plaintext1 = (TransformPlaintext) o; - return Arrays.equals(this.plaintext, plaintext1.plaintext) && this.context.equals(plaintext1.context); + TransformPlaintext that = (TransformPlaintext) o; + if (!ObjectUtils.nullSafeEquals(this.plaintext, that.plaintext)) { + return false; + } + return ObjectUtils.nullSafeEquals(this.context, that.context); } @Override public int hashCode() { - int result = Objects.hash(this.context); - result = 31 * result + Arrays.hashCode(this.plaintext); + int result = ObjectUtils.nullSafeHashCode(this.plaintext); + result = 31 * result + ObjectUtils.nullSafeHashCode(this.context); return result; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformContext.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformContext.java index ca9264e9..fb0aa657 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformContext.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformContext.java @@ -15,10 +15,12 @@ */ package org.springframework.vault.support; -import org.springframework.util.Assert; - import java.util.Arrays; +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + /** * Transform backend encode/decode context object. * @@ -37,7 +39,7 @@ public class VaultTransformContext { private final byte[] tweak; - VaultTransformContext(String transformation, byte[] tweak) { + private VaultTransformContext(String transformation, byte[] tweak) { this.transformation = transformation; this.tweak = tweak; } @@ -74,6 +76,15 @@ public class VaultTransformContext { return builder().tweak(tweak).build(); } + /** + * Return whether this object is an empty one. That is, transformation and tweak are + * both empty. + * @return {@code true} if this object is empty. + */ + public boolean isEmpty() { + return StringUtils.isEmpty(this.transformation) && ObjectUtils.isEmpty(this.tweak); + } + /** * @return the transformation name. */ @@ -114,7 +125,7 @@ public class VaultTransformContext { private byte[] tweak = new byte[0]; - VaultTransformRequestBuilder() { + private VaultTransformRequestBuilder() { } /** diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformDecodeResult.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformDecodeResult.java index 7d60eb8d..ea56c728 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformDecodeResult.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransformDecodeResult.java @@ -30,8 +30,8 @@ public class VaultTransformDecodeResult extends AbstractResult { + assertThatExceptionOfType(VaultException.class).isThrownBy(() -> { this.transformOperations.encode("myrole", "123-45-6789".getBytes(), transformRequest); - }); - - String expectedMessage = "incorrect tweak size provided"; - String actualMessage = exception.getMessage(); - - assertThat(actualMessage).contains(expectedMessage); + }).withMessageContaining("incorrect tweak size provided"); } @Test @@ -125,45 +131,64 @@ class VaultTransformTemplateIntegrationTests extends IntegrationTestSupport { VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("internalssn").build(); - String response = this.transformOperations.encode("myrole", "123-45-6789".getBytes(), transformRequest); - assertThat(response).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}"); + TransformCiphertext ciphertext = this.transformOperations.encode("myrole", "123-45-6789".getBytes(), + transformRequest); + assertThat(ciphertext.getCiphertext()).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}"); } @Test void encodeAndDecodeYieldsStartingResultWithSameTweakValueProvided() { - VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("myssn").tweak("somenum".getBytes()).build(); + + VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("myssn") + .tweak("somenum".getBytes()).build(); String targetValue = "123-45-6789"; - String response = this.transformOperations.encode("myrole", targetValue.getBytes(), transformRequest); - assertThat(response).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}"); - assertThat(response).isNotEqualTo(targetValue); + TransformCiphertext ciphertext = this.transformOperations.encode("myrole", targetValue.getBytes(), + transformRequest); + assertThat(ciphertext.getCiphertext()).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}").isNotEqualTo(targetValue); - String decodeResponse = this.transformOperations.decode("myrole", response, transformRequest); + String decodeResponse = this.transformOperations.decode("myrole", ciphertext.getCiphertext(), transformRequest); assertThat(decodeResponse).isEqualTo(targetValue); } @Test void encodeAndDecodeDoesNotYieldStartingResultWithDifferentTweakValueProvided() { - VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("myssn").tweak("somenum".getBytes()).build(); + + VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("myssn") + .tweak("somenum".getBytes()).build(); String targetValue = "123-45-6789"; - String response = this.transformOperations.encode("myrole", targetValue.getBytes(), transformRequest); - assertThat(response).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}"); - assertThat(response).isNotEqualTo(targetValue); + TransformCiphertext ciphertext = this.transformOperations.encode("myrole", targetValue.getBytes(), + transformRequest); + assertThat(ciphertext.getCiphertext()).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}").isNotEqualTo(targetValue); - VaultTransformContext decodeRequest = VaultTransformContext.builder().transformation("myssn").tweak("numsome".getBytes()).build(); + VaultTransformContext otherDecodeRequest = VaultTransformContext.builder().transformation("myssn") + .tweak("numsome".getBytes()).build(); - String decodeResponse = this.transformOperations.decode("myrole", response, decodeRequest); + String decodeResponse = this.transformOperations.decode("myrole", ciphertext.getCiphertext(), + otherDecodeRequest); assertThat(decodeResponse).isNotEqualTo(targetValue); } + @Test + void encodeAndDecodeWithoutContextWorksForGeneratedTweakSource() { + + VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("generatedssn").build(); + + TransformCiphertext ciphertext = this.transformOperations.encode("generatedrole", "123-45-6789".getBytes(), + transformRequest); + + TransformPlaintext plaintext = this.transformOperations.decode("generatedrole", ciphertext); + assertThat(plaintext.asString()).isEqualTo("123-45-6789"); + } + @Test void encodeAndDecodeWithoutContextWorksForInternalTweakSource() { + String targetValue = "123-45-6789"; String response = this.transformOperations.encode("internalrole", targetValue); - assertThat(response).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}"); - assertThat(response).isNotEqualTo(targetValue); + assertThat(response).matches("[0-9]{3}-[0-9]{2}-[0-9]{4}").isNotEqualTo(targetValue); String decodeResponse = this.transformOperations.decode("internalrole", response); assertThat(decodeResponse).isEqualTo(targetValue); @@ -171,35 +196,19 @@ class VaultTransformTemplateIntegrationTests extends IntegrationTestSupport { @Test void batchEncodeAndDecodeYieldsStartingResults() { - VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("myssn").tweak("somenum".getBytes()).build(); - List ssns = Arrays.asList( - "123-01-4567", - "123-02-4567", - "123-03-4567", - "123-04-4567", - "123-05-4567" - ); + VaultTransformContext transformRequest = VaultTransformContext.builder().transformation("myssn") + .tweak("somenum".getBytes()).build(); + + List ssns = Arrays.asList("123-01-4567", "123-02-4567", "123-03-4567", "123-04-4567", "123-05-4567"); List encoded = this.transformOperations.encode("myrole", - Arrays.asList( - TransformPlaintext.of(ssns.get(0)).with(transformRequest), - TransformPlaintext.of(ssns.get(1)).with(transformRequest), - TransformPlaintext.of(ssns.get(2)).with(transformRequest), - TransformPlaintext.of(ssns.get(3)).with(transformRequest), - TransformPlaintext.of(ssns.get(4)).with(transformRequest) - ) - ); + ssns.stream().map(TransformPlaintext::of).map(plaintext -> plaintext.with(transformRequest)) + .collect(Collectors.toList())); List decoded = this.transformOperations.decode("myrole", - Arrays.asList( - TransformCiphertext.of(encoded.get(0).getAsString()).with(transformRequest), - TransformCiphertext.of(encoded.get(1).getAsString()).with(transformRequest), - TransformCiphertext.of(encoded.get(2).getAsString()).with(transformRequest), - TransformCiphertext.of(encoded.get(3).getAsString()).with(transformRequest), - TransformCiphertext.of(encoded.get(4).getAsString()).with(transformRequest) - ) - ); + encoded.stream().map(VaultTransformEncodeResult::getAsString).map(TransformCiphertext::of) + .map(ciphertext -> ciphertext.with(transformRequest)).collect(Collectors.toList())); for (int i = 0; i < decoded.size(); i++) { assertThat(decoded.get(i).getAsString()).isEqualTo(ssns.get(i)); @@ -209,36 +218,18 @@ class VaultTransformTemplateIntegrationTests extends IntegrationTestSupport { @Test void batchEncodeAndDecodeYieldsStartingResultsForInternalWithNoContext() { - List ssns = Arrays.asList( - "123-01-4567", - "123-02-4567", - "123-03-4567", - "123-04-4567", - "123-05-4567" - ); + List ssns = Arrays.asList("123-01-4567", "123-02-4567", "123-03-4567", "123-04-4567", "123-05-4567"); List encoded = this.transformOperations.encode("internalrole", - Arrays.asList( - TransformPlaintext.of(ssns.get(0)), - TransformPlaintext.of(ssns.get(1)), - TransformPlaintext.of(ssns.get(2)), - TransformPlaintext.of(ssns.get(3)), - TransformPlaintext.of(ssns.get(4)) - ) - ); + ssns.stream().map(TransformPlaintext::of).collect(Collectors.toList())); List decoded = this.transformOperations.decode("internalrole", - Arrays.asList( - TransformCiphertext.of(encoded.get(0).getAsString()), - TransformCiphertext.of(encoded.get(1).getAsString()), - TransformCiphertext.of(encoded.get(2).getAsString()), - TransformCiphertext.of(encoded.get(3).getAsString()), - TransformCiphertext.of(encoded.get(4).getAsString()) - ) - ); + encoded.stream().map(VaultTransformEncodeResult::getAsString).map(TransformCiphertext::of) + .collect(Collectors.toList())); for (int i = 0; i < decoded.size(); i++) { assertThat(decoded.get(i).getAsString()).isEqualTo(ssns.get(i)); } } + } diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc index 3f23391b..afc8f1e6 100644 --- a/src/main/asciidoc/new-features.adoc +++ b/src/main/asciidoc/new-features.adoc @@ -7,6 +7,7 @@ * Support for PEM-encoded certificates for keystore and truststore usage. * `ReactiveVaultEndpointProvider` for non-blocking lookup of `VaultEndpoint`. * `VaultKeyValueMetadataOperations` for Key-Value metadata interaction. +* Support for `transform` backend (Enterprise Feature). [[new-features.2-2-0]] === What's new in Spring Vault 2.2