Merge remote-tracking branch 'origin/2.0.x'
This commit is contained in:
@@ -163,31 +163,34 @@ public class EnvironmentDecryptApplicationInitializer implements
|
||||
sources.add(0, source);
|
||||
}
|
||||
for (PropertySource<?> source : sources) {
|
||||
decrypt(source, overrides);
|
||||
collectEncryptedProperties(source, overrides);
|
||||
}
|
||||
|
||||
doDecrypt(overrides);
|
||||
return overrides;
|
||||
}
|
||||
|
||||
private Map<String, Object> decrypt(PropertySource<?> source) {
|
||||
Map<String, Object> overrides = new LinkedHashMap<>();
|
||||
decrypt(source, overrides);
|
||||
collectEncryptedProperties(source, overrides);
|
||||
doDecrypt(overrides);
|
||||
return overrides;
|
||||
}
|
||||
|
||||
private static final Pattern COLLECTION_PROPERTY = Pattern
|
||||
.compile("(\\S+)?\\[(\\d+)\\](\\.\\S+)?");
|
||||
|
||||
private void decrypt(PropertySource<?> source, Map<String, Object> overrides) {
|
||||
private void collectEncryptedProperties(PropertySource<?> source,
|
||||
Map<String, Object> overrides) {
|
||||
|
||||
if (source instanceof CompositePropertySource) {
|
||||
|
||||
for (PropertySource<?> nested : ((CompositePropertySource) source)
|
||||
.getPropertySources()) {
|
||||
decrypt(nested, overrides);
|
||||
collectEncryptedProperties(nested, overrides);
|
||||
}
|
||||
|
||||
}
|
||||
else if (source instanceof EnumerablePropertySource) {
|
||||
} else if (source instanceof EnumerablePropertySource) {
|
||||
Map<String, Object> otherCollectionProperties = new LinkedHashMap<>();
|
||||
boolean sourceHasDecryptedCollection = false;
|
||||
|
||||
@@ -197,37 +200,16 @@ public class EnvironmentDecryptApplicationInitializer implements
|
||||
if (property != null) {
|
||||
String value = property.toString();
|
||||
if (value.startsWith("{cipher}")) {
|
||||
value = value.substring("{cipher}".length());
|
||||
try {
|
||||
value = this.encryptor.decrypt(value);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Decrypted: key=" + key);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
String message = "Cannot decrypt: key=" + key;
|
||||
if (this.failOnError) {
|
||||
throw new IllegalStateException(message, e);
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn(message, e);
|
||||
}
|
||||
else {
|
||||
logger.warn(message);
|
||||
}
|
||||
// Set value to empty to avoid making a password out of the
|
||||
// cipher text
|
||||
value = "";
|
||||
}
|
||||
overrides.put(key, value);
|
||||
if (COLLECTION_PROPERTY.matcher(key).matches()) {
|
||||
sourceHasDecryptedCollection = true;
|
||||
}
|
||||
}
|
||||
else if (COLLECTION_PROPERTY.matcher(key).matches()) {
|
||||
// put non-ecrypted properties so merging of index properties
|
||||
} else if (COLLECTION_PROPERTY.matcher(key).matches()) {
|
||||
// put non-encrypted properties so merging of index properties
|
||||
// happens correctly
|
||||
otherCollectionProperties.put(key, value);
|
||||
} else {
|
||||
overrides.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,4 +221,35 @@ public class EnvironmentDecryptApplicationInitializer implements
|
||||
}
|
||||
}
|
||||
|
||||
private void doDecrypt(Map<String, Object> overrides) {
|
||||
for (String key : overrides.keySet()) {
|
||||
String value = overrides.get(key).toString();
|
||||
if (value.startsWith("{cipher}")) {
|
||||
value = value.substring("{cipher}".length());
|
||||
try {
|
||||
value = this.encryptor.decrypt(value);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Decrypted: key=" + key);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
String message = "Cannot decrypt: key=" + key;
|
||||
if (this.failOnError) {
|
||||
throw new IllegalStateException(message, e);
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn(message, e);
|
||||
}
|
||||
else {
|
||||
logger.warn(message);
|
||||
}
|
||||
// Set value to empty to avoid making a password out of the
|
||||
// cipher text
|
||||
value = "";
|
||||
}
|
||||
overrides.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.DECRYPTED_PROPERTY_SOURCE_NAME;
|
||||
|
||||
@@ -78,6 +80,17 @@ public class EnvironmentDecryptApplicationInitializerTests {
|
||||
assertEquals("spam", context.getEnvironment().getProperty("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertySourcesOrderedCorrectlyWithUnencryptedOverrides() {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("foo: {cipher}bar").applyTo(context);
|
||||
context.getEnvironment().getPropertySources()
|
||||
.addFirst(new MapPropertySource("test_override",
|
||||
Collections.<String, Object>singletonMap("foo", "spam")));
|
||||
this.listener.initialize(context);
|
||||
assertEquals("spam", context.getEnvironment().getProperty("foo"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void errorOnDecrypt() {
|
||||
this.listener = new EnvironmentDecryptApplicationInitializer(
|
||||
@@ -173,4 +186,22 @@ public class EnvironmentDecryptApplicationInitializerTests {
|
||||
initializer.initialize(ctx);
|
||||
assertEquals(expected, ctx.getEnvironment().getProperty("key"));
|
||||
}
|
||||
|
||||
@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.<String, Object>singletonMap("foo", "spam")));
|
||||
initializer.initialize(context);
|
||||
assertEquals("spam", context.getEnvironment().getProperty("foo"));
|
||||
assertEquals("bar2", context.getEnvironment().getProperty("foo2"));
|
||||
verify(encryptor).decrypt("bar2");
|
||||
verifyNoMoreInteractions(encryptor);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user