Commit 5d25588d authored by Christian Dupuis's avatar Christian Dupuis

Make properties to sanitize configurable in EnvironmentEndpoint.

Add "key" to default keys that will be sanitized. fixes #1027
parent 1a32a6a0
...@@ -66,7 +66,7 @@ public class ConfigurationPropertiesReportEndpoint extends ...@@ -66,7 +66,7 @@ public class ConfigurationPropertiesReportEndpoint extends
private static final String CGLIB_FILTER_ID = "cglibFilter"; private static final String CGLIB_FILTER_ID = "cglibFilter";
private String[] keysToSanitize = new String[] { "password", "secret" }; private String[] keysToSanitize = new String[] { "password", "secret", "key" };
private ApplicationContext context; private ApplicationContext context;
...@@ -76,10 +76,6 @@ public class ConfigurationPropertiesReportEndpoint extends ...@@ -76,10 +76,6 @@ public class ConfigurationPropertiesReportEndpoint extends
super("configprops"); super("configprops");
} }
public String[] getKeysToSanitize() {
return this.keysToSanitize;
}
@Override @Override
public void setApplicationContext(ApplicationContext context) throws BeansException { public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context; this.context = context;
......
...@@ -26,12 +26,14 @@ import org.springframework.core.env.EnumerablePropertySource; ...@@ -26,12 +26,14 @@ import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource; import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment; import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.Assert;
/** /**
* {@link Endpoint} to expose {@link ConfigurableEnvironment environment} information. * {@link Endpoint} to expose {@link ConfigurableEnvironment environment} information.
* *
* @author Dave Syer * @author Dave Syer
* @author Phillip Webb * @author Phillip Webb
* @author Christian Dupuis
*/ */
@ConfigurationProperties(prefix = "endpoints.env", ignoreUnknownFields = false) @ConfigurationProperties(prefix = "endpoints.env", ignoreUnknownFields = false)
public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> implements public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> implements
...@@ -39,6 +41,8 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i ...@@ -39,6 +41,8 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i
private Environment environment; private Environment environment;
private String[] keysToSanitize = new String[] { "password", "secret", "key" };
/** /**
* Create a new {@link EnvironmentEndpoint} instance. * Create a new {@link EnvironmentEndpoint} instance.
*/ */
...@@ -46,6 +50,11 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i ...@@ -46,6 +50,11 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i
super("env"); super("env");
} }
public void setKeysToSanitize(String... keysToSanitize) {
Assert.notNull(keysToSanitize, "KeysToSanitize must not be null");
this.keysToSanitize = keysToSanitize;
}
@Override @Override
public Map<String, Object> invoke() { public Map<String, Object> invoke() {
Map<String, Object> result = new LinkedHashMap<String, Object>(); Map<String, Object> result = new LinkedHashMap<String, Object>();
...@@ -71,10 +80,11 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i ...@@ -71,10 +80,11 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i
return new StandardEnvironment().getPropertySources(); return new StandardEnvironment().getPropertySources();
} }
public static Object sanitize(String name, Object object) { public Object sanitize(String name, Object object) {
if (name.toLowerCase().endsWith("password") for (String keyToSanitize : this.keysToSanitize) {
|| name.toLowerCase().endsWith("secret")) { if (name.toLowerCase().endsWith(keyToSanitize)) {
return object == null ? null : "******"; return (object == null ? null : "******");
}
} }
return object; return object;
} }
......
...@@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; ...@@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
* Adapter to expose {@link EnvironmentEndpoint} as an {@link MvcEndpoint}. * Adapter to expose {@link EnvironmentEndpoint} as an {@link MvcEndpoint}.
* *
* @author Dave Syer * @author Dave Syer
* @author Christian Dupuis
*/ */
public class EnvironmentMvcEndpoint extends EndpointMvcAdapter implements public class EnvironmentMvcEndpoint extends EndpointMvcAdapter implements
EnvironmentAware { EnvironmentAware {
...@@ -47,7 +48,7 @@ public class EnvironmentMvcEndpoint extends EndpointMvcAdapter implements ...@@ -47,7 +48,7 @@ public class EnvironmentMvcEndpoint extends EndpointMvcAdapter implements
if (result == null) { if (result == null) {
throw new NoSuchPropertyException("No such property: " + name); throw new NoSuchPropertyException("No such property: " + name);
} }
return EnvironmentEndpoint.sanitize(name, result); return ((EnvironmentEndpoint) getDelegate()).sanitize(name, result);
} }
@Override @Override
......
/* /*
* Copyright 2012-2013 the original author or authors. * Copyright 2012-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,18 +16,22 @@ ...@@ -16,18 +16,22 @@
package org.springframework.boot.actuate.endpoint; package org.springframework.boot.actuate.endpoint;
import java.util.Map;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
/** /**
* Tests for {@link EnvironmentEndpoint}. * Tests for {@link EnvironmentEndpoint}.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Christian Dupuis
*/ */
public class EnvironmentEndpointTests extends AbstractEndpointTests<EnvironmentEndpoint> { public class EnvironmentEndpointTests extends AbstractEndpointTests<EnvironmentEndpoint> {
...@@ -40,6 +44,19 @@ public class EnvironmentEndpointTests extends AbstractEndpointTests<EnvironmentE ...@@ -40,6 +44,19 @@ public class EnvironmentEndpointTests extends AbstractEndpointTests<EnvironmentE
assertThat(getEndpointBean().invoke().size(), greaterThan(0)); assertThat(getEndpointBean().invoke().size(), greaterThan(0));
} }
@SuppressWarnings("unchecked")
@Test
public void testKeySanitization() throws Exception {
System.setProperty("dbPassword", "123456");
System.setProperty("apiKey", "123456");
EnvironmentEndpoint report = getEndpointBean();
Map<String, Object> env = report.invoke();
assertEquals("******",
((Map<String, Object>) env.get("systemProperties")).get("dbPassword"));
assertEquals("******",
((Map<String, Object>) env.get("systemProperties")).get("apiKey"));
}
@Configuration @Configuration
@EnableConfigurationProperties @EnableConfigurationProperties
public static class Config { public static class Config {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment