Consider prefixes when sanitizing /configprops

Update ConfigurationPropertiesReportEndpoint so that property prefixes
are also considered when sanitizing values.

Fixes gh-4415
This commit is contained in:
Phillip Webb 2015-11-09 11:17:38 -08:00
parent 4aefe9f856
commit bd20b5419e
2 changed files with 71 additions and 5 deletions

View File

@ -111,7 +111,7 @@ public class ConfigurationPropertiesReportEndpoint
Map<String, Object> root = new HashMap<String, Object>();
String prefix = extractPrefix(context, beanFactoryMetaData, beanName, bean);
root.put("prefix", prefix);
root.put("properties", sanitize(safeSerialize(mapper, bean, prefix)));
root.put("properties", sanitize(prefix, safeSerialize(mapper, bean, prefix)));
result.put(beanName, root);
}
if (context.getParent() != null) {
@ -231,15 +231,18 @@ public class ConfigurationPropertiesReportEndpoint
* @return the sanitized map
*/
@SuppressWarnings("unchecked")
private Map<String, Object> sanitize(Map<String, Object> map) {
private Map<String, Object> sanitize(String prefix, Map<String, Object> map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
String qualifiedKey = (prefix.length() == 0 ? prefix : prefix + ".") + key;
Object value = entry.getValue();
if (value instanceof Map) {
map.put(key, sanitize((Map<String, Object>) value));
map.put(key, sanitize(qualifiedKey, (Map<String, Object>) value));
}
else {
map.put(key, this.sanitizer.sanitize(key, value));
value = this.sanitizer.sanitize(key, value);
value = this.sanitizer.sanitize(qualifiedKey, value);
map.put(key, value);
}
}
return map;

View File

@ -16,6 +16,7 @@
package org.springframework.boot.actuate.endpoint;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
@ -135,8 +136,8 @@ public class ConfigurationPropertiesReportEndpointTests
assertEquals("654321", nestedProperties.get("myTestProperty"));
}
@SuppressWarnings("unchecked")
@Test
@SuppressWarnings("unchecked")
public void testKeySanitizationWithCustomPatternAndKeyByEnvironment()
throws Exception {
this.context = new AnnotationConfigApplicationContext();
@ -153,6 +154,29 @@ public class ConfigurationPropertiesReportEndpointTests
assertEquals("******", nestedProperties.get("myTestProperty"));
}
@Test
@SuppressWarnings("unchecked")
public void testKeySanitizationWithCustomPatternUsingCompositeKeys()
throws Exception {
// gh-4415
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"endpoints.configprops.keys-to-sanitize: .*\\.secrets\\..*, .*\\.hidden\\..*");
this.context.register(Config.class);
this.context.refresh();
ConfigurationPropertiesReportEndpoint report = getEndpointBean();
Map<String, Object> properties = report.invoke();
Map<String, Object> nestedProperties = (Map<String, Object>) ((Map<String, Object>) properties
.get("testProperties")).get("properties");
assertNotNull(nestedProperties);
Map<String, Object> secrets = (Map<String, Object>) nestedProperties
.get("secrets");
Map<String, Object> hidden = (Map<String, Object>) nestedProperties.get("hidden");
assertEquals("******", secrets.get("mine"));
assertEquals("******", secrets.get("yours"));
assertEquals("******", hidden.get("mine"));
}
@Test
@SuppressWarnings("unchecked")
public void mixedBoolean() throws Exception {
@ -197,6 +221,15 @@ public class ConfigurationPropertiesReportEndpointTests
private Boolean mixedBoolean = true;
private Map<String, Object> secrets = new HashMap<String, Object>();
private Hidden hidden = new Hidden();
public TestProperties() {
this.secrets.put("mine", "myPrivateThing");
this.secrets.put("yours", "yourPrivateThing");
}
public String getDbPassword() {
return this.dbPassword;
}
@ -221,5 +254,35 @@ public class ConfigurationPropertiesReportEndpointTests
this.mixedBoolean = mixedBoolean;
}
public Map<String, Object> getSecrets() {
return this.secrets;
}
public void setSecrets(Map<String, Object> secrets) {
this.secrets = secrets;
}
public Hidden getHidden() {
return this.hidden;
}
public void setHidden(Hidden hidden) {
this.hidden = hidden;
}
public static class Hidden {
private String mine = "mySecret";
public String getMine() {
return this.mine;
}
public void setMine(String mine) {
this.mine = mine;
}
}
}
}