diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java index 8811ceab7f..c4dead466d 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java @@ -239,6 +239,9 @@ public class ConfigurationPropertiesReportEndpoint if (value instanceof Map) { map.put(key, sanitize(qualifiedKey, (Map) value)); } + else if (value instanceof List) { + map.put(key, sanitize(qualifiedKey, (List) value)); + } else { value = this.sanitizer.sanitize(key, value); value = this.sanitizer.sanitize(qualifiedKey, value); @@ -248,6 +251,24 @@ public class ConfigurationPropertiesReportEndpoint return map; } + @SuppressWarnings("unchecked") + private List sanitize(String prefix, List list) { + List sanitized = new ArrayList(); + for (Object item : list) { + if (item instanceof Map) { + sanitized.add(sanitize(prefix, (Map) item)); + } + else if (item instanceof List) { + sanitize(prefix, (List) item); + } + else { + item = this.sanitizer.sanitize(prefix, item); + sanitized.add(this.sanitizer.sanitize(prefix, item)); + } + } + return sanitized; + } + /** * Extension to {@link JacksonAnnotationIntrospector} to suppress CGLIB generated bean * properties. diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java index b8ebfe91d9..d29c14167d 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -16,7 +16,9 @@ package org.springframework.boot.actuate.endpoint; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.junit.Test; @@ -85,6 +87,19 @@ public class ConfigurationPropertiesReportEndpointTests assertThat(nestedProperties.get("myTestProperty")).isEqualTo("******"); } + @Test + @SuppressWarnings("unchecked") + public void testKeySanitizationWithList() throws Exception { + ConfigurationPropertiesReportEndpoint report = getEndpointBean(); + report.setKeysToSanitize("property"); + Map properties = report.invoke(); + Map nestedProperties = (Map) ((Map) properties + .get("testProperties")).get("properties"); + assertThat(nestedProperties).isNotNull(); + assertThat(nestedProperties.get("dbPassword")).isEqualTo("123456"); + assertThat(nestedProperties.get("myTestProperty")).isEqualTo("******"); + } + @SuppressWarnings("unchecked") @Test public void testKeySanitizationWithCustomPattern() throws Exception { @@ -183,6 +198,20 @@ public class ConfigurationPropertiesReportEndpointTests assertThat(nestedProperties.get("mixedBoolean")).isEqualTo(true); } + @Test + @SuppressWarnings("unchecked") + public void listsAreSanitized() throws Exception { + ConfigurationPropertiesReportEndpoint report = getEndpointBean(); + Map properties = report.invoke(); + Map nestedProperties = (Map) ((Map) properties + .get("testProperties")).get("properties"); + assertThat(nestedProperties.get("listItems")).isInstanceOf(List.class); + List list = (List) nestedProperties.get("listItems"); + assertThat(list).hasSize(1); + Map item = (Map) list.get(0); + assertThat(item.get("somePassword")).isEqualTo("******"); + } + @Configuration @EnableConfigurationProperties public static class Parent { @@ -223,9 +252,12 @@ public class ConfigurationPropertiesReportEndpointTests private Hidden hidden = new Hidden(); + private List listItems = new ArrayList(); + public TestProperties() { this.secrets.put("mine", "myPrivateThing"); this.secrets.put("yours", "yourPrivateThing"); + this.listItems.add(new ListItem()); } public String getDbPassword() { @@ -268,6 +300,14 @@ public class ConfigurationPropertiesReportEndpointTests this.hidden = hidden; } + public List getListItems() { + return this.listItems; + } + + public void setListItems(List listItems) { + this.listItems = listItems; + } + public static class Hidden { private String mine = "mySecret"; @@ -282,6 +322,20 @@ public class ConfigurationPropertiesReportEndpointTests } + public static class ListItem { + + private String somePassword = "secret"; + + public String getSomePassword() { + return this.somePassword; + } + + public void setSomePassword(String somePassword) { + this.somePassword = somePassword; + } + + } + } }