Added optimizations to EnvironmentDecryptApplicationInitializer

This commit is contained in:
Tim Ysewyn
2019-07-26 12:13:51 +02:00
committed by Dave Syer
parent 28b9727250
commit c19575b978
2 changed files with 179 additions and 57 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.cloud.bootstrap.encrypt;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
@@ -36,9 +37,13 @@ import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import static org.assertj.core.api.BDDAssertions.then;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.springframework.cloud.bootstrap.BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME;
import static org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME;
import static org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.DECRYPTED_PROPERTY_SOURCE_NAME;
/**
@@ -71,9 +76,8 @@ public class EnvironmentDecryptApplicationInitializerTests {
public void propertySourcesOrderedCorrectly() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestPropertyValues.of("foo: {cipher}bar").applyTo(context);
context.getEnvironment().getPropertySources()
.addFirst(new MapPropertySource("test_override",
Collections.<String, Object>singletonMap("foo", "{cipher}spam")));
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
"test_override", Collections.singletonMap("foo", "{cipher}spam")));
this.listener.initialize(context);
then(context.getEnvironment().getProperty("foo")).isEqualTo("spam");
}
@@ -155,13 +159,9 @@ public class EnvironmentDecryptApplicationInitializerTests {
@Test
public void testDecryptCompositePropertySource() {
TextEncryptor textEncryptor = mock(TextEncryptor.class);
when(textEncryptor.decrypt(eq("value1"))).thenReturn("always1");
when(textEncryptor.decrypt(eq("value2"))).thenReturn("always2");
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext();
EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer(
textEncryptor);
Encryptors.noOpText());
MapPropertySource devProfile = new MapPropertySource("dev-profile",
Collections.singletonMap("key", "{cipher}value1"));
@@ -176,7 +176,83 @@ public class EnvironmentDecryptApplicationInitializerTests {
ctx.getEnvironment().getPropertySources().addLast(cps);
initializer.initialize(ctx);
then(ctx.getEnvironment().getProperty("key")).isEqualTo("always1");
then(ctx.getEnvironment().getProperty("key")).isEqualTo("value1");
}
@Test
public void propertySourcesOrderedCorrectlyWithUnencryptedOverrides() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TestPropertyValues.of("foo: {cipher}bar").applyTo(context);
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
"test_override", Collections.singletonMap("foo", "spam")));
this.listener.initialize(context);
then(context.getEnvironment().getProperty("foo")).isEqualTo("spam");
}
@Test
public void doNotDecryptBootstrapTwice() {
TextEncryptor encryptor = mock(TextEncryptor.class);
when(encryptor.decrypt("bar")).thenReturn("bar");
when(encryptor.decrypt("bar2")).thenReturn("bar2");
when(encryptor.decrypt("bar3")).thenReturn("bar3");
when(encryptor.decrypt("baz")).thenReturn("baz");
EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer(
encryptor);
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
CompositePropertySource bootstrap = new CompositePropertySource(
BOOTSTRAP_PROPERTY_SOURCE_NAME);
bootstrap.addPropertySource(new MapPropertySource("configService",
Collections.singletonMap("foo", "{cipher}bar")));
context.getEnvironment().getPropertySources().addFirst(bootstrap);
Map<String, Object> props = new HashMap<>();
props.put("foo2", "{cipher}bar2");
props.put("bar", "{cipher}baz");
context.getEnvironment().getPropertySources().addAfter(
BOOTSTRAP_PROPERTY_SOURCE_NAME, new MapPropertySource("remote", props));
initializer.initialize(context);
// Simulate retrieval of new properties via Spring Cloud Config
props.put("foo2", "{cipher}bar3");
context.getEnvironment().getPropertySources().replace("remote",
new MapPropertySource("remote", props));
initializer.initialize(context);
verify(encryptor).decrypt("bar");
verify(encryptor).decrypt("bar2");
verify(encryptor).decrypt("bar3");
verify(encryptor, times(2)).decrypt("baz");
// Check if all encrypted properties are still decrypted
PropertySource<?> decryptedBootstrap = context.getEnvironment()
.getPropertySources().get(DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME);
then(decryptedBootstrap.getProperty("foo")).isEqualTo("bar");
PropertySource<?> decrypted = context.getEnvironment().getPropertySources()
.get(DECRYPTED_PROPERTY_SOURCE_NAME);
then(decrypted.getProperty("foo2")).isEqualTo("bar3");
then(decrypted.getProperty("bar")).isEqualTo("baz");
}
@Test
public void testOnlyDecryptIfNotOverridden() {
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
TextEncryptor encryptor = mock(TextEncryptor.class);
when(encryptor.decrypt("bar2")).thenReturn("bar2");
EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer(
encryptor);
TestPropertyValues.of("foo: {cipher}bar", "foo2: {cipher}bar2").applyTo(context);
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
"test_override", Collections.singletonMap("foo", "spam")));
initializer.initialize(context);
then(context.getEnvironment().getProperty("foo")).isEqualTo("spam");
then(context.getEnvironment().getProperty("foo2")).isEqualTo("bar2");
verify(encryptor).decrypt("bar2");
verifyNoMoreInteractions(encryptor);
}
}