/* * Copyright 2012-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.boot.actuate.endpoint; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.junit.After; import org.junit.Test; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link EnvironmentEndpoint}. * * @author Phillip Webb * @author Christian Dupuis * @author Nicolas Lejeune * @author Stephane Nicoll * @author Madhura Bhave */ public class EnvironmentEndpointTests extends AbstractEndpointTests<EnvironmentEndpoint> { public EnvironmentEndpointTests() { super(Config.class, EnvironmentEndpoint.class, "env", true, "endpoints.env"); } @Override @After public void close() { System.clearProperty("VCAP_SERVICES"); } @Test public void invoke() throws Exception { assertThat(getEndpointBean().invoke()).isNotEmpty(); } @SuppressWarnings("unchecked") @Test public void testCompositeSource() throws Exception { EnvironmentEndpoint report = getEndpointBean(); CompositePropertySource source = new CompositePropertySource("composite"); source.addPropertySource(new MapPropertySource("one", Collections.singletonMap("foo", (Object) "bar"))); source.addPropertySource(new MapPropertySource("two", Collections.singletonMap("foo", (Object) "spam"))); this.context.getEnvironment().getPropertySources().addFirst(source); Map<String, Object> env = report.invoke(); assertThat(((Map<String, Object>) env.get("composite:one")).get("foo")) .isEqualTo("bar"); } @SuppressWarnings("unchecked") @Test public void testKeySanitization() throws Exception { System.setProperty("dbPassword", "123456"); System.setProperty("apiKey", "123456"); System.setProperty("mySecret", "123456"); System.setProperty("myCredentials", "123456"); System.setProperty("VCAP_SERVICES", "123456"); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> systemProperties = (Map<String, Object>) env .get("systemProperties"); assertThat(systemProperties.get("dbPassword")).isEqualTo("******"); assertThat(systemProperties.get("apiKey")).isEqualTo("******"); assertThat(systemProperties.get("mySecret")).isEqualTo("******"); assertThat(systemProperties.get("myCredentials")).isEqualTo("******"); assertThat(systemProperties.get("VCAP_SERVICES")).isEqualTo("******"); clearSystemProperties("dbPassword", "apiKey", "mySecret", "myCredentials"); } @SuppressWarnings("unchecked") @Test public void testKeySanitizationCredentialsPattern() throws Exception { System.setProperty("my.services.amqp-free.credentials.uri", "123456"); System.setProperty("credentials.http_api_uri", "123456"); System.setProperty("my.services.cleardb-free.credentials", "123456"); System.setProperty("foo.mycredentials.uri", "123456"); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> systemProperties = (Map<String, Object>) env .get("systemProperties"); assertThat(systemProperties.get("my.services.amqp-free.credentials.uri")) .isEqualTo("******"); assertThat(systemProperties.get("credentials.http_api_uri")).isEqualTo("******"); assertThat(systemProperties.get("my.services.cleardb-free.credentials")) .isEqualTo("******"); assertThat(systemProperties.get("foo.mycredentials.uri")).isEqualTo("******"); clearSystemProperties("my.services.amqp-free.credentials.uri", "credentials.http_api_uri", "my.services.cleardb-free.credentials", "foo.mycredentials.uri"); } @SuppressWarnings("unchecked") @Test public void testKeySanitizationWithCustomKeys() throws Exception { System.setProperty("dbPassword", "123456"); System.setProperty("apiKey", "123456"); EnvironmentEndpoint report = getEndpointBean(); report.setKeysToSanitize("key"); Map<String, Object> env = report.invoke(); Map<String, Object> systemProperties = (Map<String, Object>) env .get("systemProperties"); assertThat(systemProperties.get("dbPassword")).isEqualTo("123456"); assertThat(systemProperties.get("apiKey")).isEqualTo("******"); clearSystemProperties("dbPassword", "apiKey"); } @SuppressWarnings("unchecked") @Test public void testKeySanitizationWithCustomPattern() throws Exception { System.setProperty("dbPassword", "123456"); System.setProperty("apiKey", "123456"); EnvironmentEndpoint report = getEndpointBean(); report.setKeysToSanitize(".*pass.*"); Map<String, Object> env = report.invoke(); Map<String, Object> systemProperties = (Map<String, Object>) env .get("systemProperties"); assertThat(systemProperties.get("dbPassword")).isEqualTo("******"); assertThat(systemProperties.get("apiKey")).isEqualTo("123456"); clearSystemProperties("dbPassword", "apiKey"); } @SuppressWarnings("unchecked") @Test public void testKeySanitizationWithCustomKeysByEnvironment() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "endpoints.env.keys-to-sanitize: key"); this.context.register(Config.class); this.context.refresh(); System.setProperty("dbPassword", "123456"); System.setProperty("apiKey", "123456"); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> systemProperties = (Map<String, Object>) env .get("systemProperties"); assertThat(systemProperties.get("dbPassword")).isEqualTo("123456"); assertThat(systemProperties.get("apiKey")).isEqualTo("******"); clearSystemProperties("dbPassword", "apiKey"); } @SuppressWarnings("unchecked") @Test public void testKeySanitizationWithCustomPatternByEnvironment() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "endpoints.env.keys-to-sanitize: .*pass.*"); this.context.register(Config.class); this.context.refresh(); System.setProperty("dbPassword", "123456"); System.setProperty("apiKey", "123456"); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> systemProperties = (Map<String, Object>) env .get("systemProperties"); assertThat(systemProperties.get("dbPassword")).isEqualTo("******"); assertThat(systemProperties.get("apiKey")).isEqualTo("123456"); clearSystemProperties("dbPassword", "apiKey"); } @SuppressWarnings("unchecked") @Test public void testKeySanitizationWithCustomPatternAndKeyByEnvironment() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "endpoints.env.keys-to-sanitize: .*pass.*, key"); this.context.register(Config.class); this.context.refresh(); System.setProperty("dbPassword", "123456"); System.setProperty("apiKey", "123456"); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> systemProperties = (Map<String, Object>) env .get("systemProperties"); assertThat(systemProperties.get("dbPassword")).isEqualTo("******"); assertThat(systemProperties.get("apiKey")).isEqualTo("******"); clearSystemProperties("dbPassword", "apiKey"); } @SuppressWarnings("unchecked") @Test public void propertyWithPlaceholderResolved() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "my.foo: ${bar.blah}", "bar.blah: hello"); this.context.register(Config.class); this.context.refresh(); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> testProperties = (Map<String, Object>) env.get("test"); assertThat(testProperties.get("my.foo")).isEqualTo("hello"); } @SuppressWarnings("unchecked") @Test public void propertyWithPlaceholderNotResolved() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "my.foo: ${bar.blah}"); this.context.register(Config.class); this.context.refresh(); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> testProperties = (Map<String, Object>) env.get("test"); assertThat(testProperties.get("my.foo")).isEqualTo("${bar.blah}"); } @SuppressWarnings("unchecked") @Test public void propertyWithSensitivePlaceholderResolved() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "my.foo: http://${bar.password}://hello", "bar.password: hello"); this.context.register(Config.class); this.context.refresh(); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> testProperties = (Map<String, Object>) env.get("test"); assertThat(testProperties.get("my.foo")).isEqualTo("http://******://hello"); } @SuppressWarnings("unchecked") @Test public void propertyWithSensitivePlaceholderNotResolved() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "my.foo: http://${bar.password}://hello"); this.context.register(Config.class); this.context.refresh(); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> testProperties = (Map<String, Object>) env.get("test"); assertThat(testProperties.get("my.foo")) .isEqualTo("http://${bar.password}://hello"); } @Test @SuppressWarnings("unchecked") public void propertyWithTypeOtherThanStringShouldNotFail() throws Exception { this.context = new AnnotationConfigApplicationContext(); MutablePropertySources propertySources = this.context.getEnvironment() .getPropertySources(); Map<String, Object> source = new HashMap<String, Object>(); source.put("foo", Collections.singletonMap("bar", "baz")); propertySources.addFirst(new MapPropertySource("test", source)); this.context.register(Config.class); this.context.refresh(); EnvironmentEndpoint report = getEndpointBean(); Map<String, Object> env = report.invoke(); Map<String, Object> testProperties = (Map<String, Object>) env.get("test"); Map<String, String> foo = (Map<String, String>) testProperties.get("foo"); assertThat(foo.get("bar")).isEqualTo("baz"); } private void clearSystemProperties(String... properties) { for (String property : properties) { System.clearProperty(property); } } @Configuration @EnableConfigurationProperties public static class Config { @Bean public EnvironmentEndpoint endpoint() { return new EnvironmentEndpoint(); } } }