From cecc1c8817611a084b81cabe5215938110a57f5f Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 31 Oct 2016 20:55:05 -0700 Subject: [PATCH] Disable DevTools property defaults in production Update `DevToolsPropertyDefaultsPostProcessor` so that property defaults are only added at development time. Properties are now added only when `Restarter` is initialize or remote devtools is enabled. Fixes gh-7014 --- ...DevToolsPropertyDefaultsPostProcessor.java | 25 +++++++- .../DevToolPropertiesIntegrationTests.java | 57 ++++++++++++++++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java index c3814a03fe..4fbf54f9b5 100755 --- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java +++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java @@ -21,10 +21,13 @@ import java.util.HashMap; import java.util.Map; import org.springframework.boot.SpringApplication; +import org.springframework.boot.bind.RelaxedPropertyResolver; +import org.springframework.boot.devtools.restart.Restarter; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; @@ -59,7 +62,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - if (isLocalApplication(environment)) { + if (isLocalApplication(environment) && canAddProperties(environment)) { PropertySource propertySource = new MapPropertySource("refresh", PROPERTIES); environment.getPropertySources().addLast(propertySource); @@ -70,4 +73,24 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro return environment.getPropertySources().get("remoteUrl") == null; } + private boolean canAddProperties(Environment environment) { + return isRestarterInitialized() || isRemoteRestartEnabled(environment); + } + + private boolean isRestarterInitialized() { + try { + Restarter restarter = Restarter.getInstance(); + return (restarter != null && restarter.getInitialUrls() != null); + } + catch (Exception ex) { + return false; + } + } + + private boolean isRemoteRestartEnabled(Environment environment) { + RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, + "spring.devtools.remote."); + return resolver.containsProperty("secret"); + } + } diff --git a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolPropertiesIntegrationTests.java b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolPropertiesIntegrationTests.java index 2caae8c0e9..7fa890e272 100644 --- a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolPropertiesIntegrationTests.java +++ b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolPropertiesIntegrationTests.java @@ -16,11 +16,20 @@ package org.springframework.boot.devtools.env; -import org.junit.After; -import org.junit.Test; +import java.net.URL; +import java.util.Collections; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.devtools.restart.RestartInitializer; +import org.springframework.boot.devtools.restart.Restarter; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -32,13 +41,22 @@ import org.springframework.context.annotation.Configuration; */ public class DevToolPropertiesIntegrationTests { + @Rule + public ExpectedException thrown = ExpectedException.none(); + private ConfigurableApplicationContext context; + @Before + public void setup() { + Restarter.initialize(new String[] {}, false, new MockInitializer(), false); + } + @After public void cleanup() { if (this.context != null) { this.context.close(); } + Restarter.clearInstance(); } @Test @@ -59,6 +77,33 @@ public class DevToolPropertiesIntegrationTests { this.context.getBean(MyBean.class); } + @Test + public void postProcessWhenRestarterDisabledAndRemoteSecretNotSetShouldNotAddPropertySource() + throws Exception { + Restarter.clearInstance(); + Restarter.disable(); + SpringApplication application = new SpringApplication( + BeanConditionConfiguration.class); + application.setWebEnvironment(false); + this.context = application.run(); + this.thrown.expect(NoSuchBeanDefinitionException.class); + this.context.getBean(MyBean.class); + } + + @Test + public void postProcessWhenRestarterDisabledAndRemoteSecretSetShouldAddPropertySource() + throws Exception { + Restarter.clearInstance(); + Restarter.disable(); + SpringApplication application = new SpringApplication( + BeanConditionConfiguration.class); + application.setWebEnvironment(false); + application.setDefaultProperties(Collections.singletonMap( + "spring.devtools.remote.secret", "donttell")); + this.context = application.run(); + this.context.getBean(MyBean.class); + } + @Configuration @ConditionalOnProperty("spring.h2.console.enabled") static class ClassConditionConfiguration { @@ -79,4 +124,12 @@ public class DevToolPropertiesIntegrationTests { } + static class MockInitializer implements RestartInitializer { + + @Override + public URL[] getInitialUrls(Thread thread) { + return new URL[] {}; + } + + } }