From c227cf7977ece340ffb2485f4b26086963d07cdd Mon Sep 17 00:00:00 2001 From: John Blum Date: Fri, 13 Jul 2018 20:31:47 -0700 Subject: [PATCH] Replace Boolean.getBoolean(..) property resolution for client/server SSL enablement to use Spring's Environment. Rename spring.boot.data.gemfire.security.ssl.environment.post-processor.disabled to spring.boot.data.gemfire.security.ssl.post-processor.enabled. Resolves GitHub Issue #9. --- .../autoconfigure/SslAutoConfiguration.java | 40 +++---- .../ssl/SslAutoConfigurationUnitTests.java | 102 ++++++++++++++++++ 2 files changed, 123 insertions(+), 19 deletions(-) create mode 100644 spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure/security/ssl/SslAutoConfigurationUnitTests.java diff --git a/spring-geode-autoconfigure/src/main/java/org/springframework/geode/boot/autoconfigure/SslAutoConfiguration.java b/spring-geode-autoconfigure/src/main/java/org/springframework/geode/boot/autoconfigure/SslAutoConfiguration.java index c2a73ca5..174fd673 100644 --- a/spring-geode-autoconfigure/src/main/java/org/springframework/geode/boot/autoconfigure/SslAutoConfiguration.java +++ b/spring-geode-autoconfigure/src/main/java/org/springframework/geode/boot/autoconfigure/SslAutoConfiguration.java @@ -43,6 +43,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.env.PropertySource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotatedTypeMetadata; @@ -85,8 +86,8 @@ import org.springframework.util.StringUtils; @SuppressWarnings("unused") public class SslAutoConfiguration { - public static final String SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_DISABLED_PROPERTY = - "spring.boot.data.gemfire.security.ssl.environment.post-processor.disabled"; + public static final String SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY = + "spring.boot.data.gemfire.security.ssl.environment.post-processor.enabled"; private static final String CURRENT_WORKING_DIRECTORY = System.getProperty("user.dir"); private static final String GEMFIRE_SSL_KEYSTORE_PROPERTY = "gemfire.ssl-keystore"; @@ -144,10 +145,8 @@ public class SslAutoConfiguration { private static Optional resolveKeyStoreFromClassPath(Environment environment) { - /* - System.err.printf("KEYSTORE LOCATION [%s]%n", ObjectUtils.doOperationSafely(() -> - new File(new ClassPathResource(keystoreName).getURL().toURI())).getAbsolutePath()); - */ + //System.err.printf("KEYSTORE LOCATION [%s]%n", ObjectUtils.doOperationSafely(() -> + // new File(new ClassPathResource(keystoreName).getURL().toURI())).getAbsolutePath()); return locateKeyStoreInClassPath(environment) .map(resource -> { @@ -283,7 +282,7 @@ public class SslAutoConfiguration { } - static class SslEnvironmentPostProcessor implements EnvironmentPostProcessor { + public static class SslEnvironmentPostProcessor implements EnvironmentPostProcessor { @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { @@ -293,24 +292,27 @@ public class SslAutoConfiguration { .filter(SslAutoConfiguration::isSslNotConfigured) .map(SslAutoConfiguration::resolveTrustedKeyStore) .filter(StringUtils::hasText) - .ifPresent(trustedKeyStore -> { + .ifPresent(trustedKeyStore -> configureSsl(environment, trustedKeyStore)); + } - Properties gemfireSslProperties = new Properties(); - - gemfireSslProperties.setProperty(SECURITY_SSL_KEYSTORE_PROPERTY, trustedKeyStore); - gemfireSslProperties.setProperty(SECURITY_SSL_TRUSTSTORE_PROPERTY, trustedKeyStore); - - environment.getPropertySources() - .addFirst(new PropertiesPropertySource(GEMFIRE_SSL_PROPERTY_SOURCE_NAME, gemfireSslProperties)); - }); + private PropertySource newPropertySource(String name, Properties properties) { + return new PropertiesPropertySource(name, properties); } private boolean isEnabled(Environment environment) { - return !isDisabled(environment); + return environment.getProperty(SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY, + Boolean.class, true); } - private boolean isDisabled(Environment environment) { - return Boolean.getBoolean(SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_DISABLED_PROPERTY); + private void configureSsl(ConfigurableEnvironment environment, String trustedKeyStore) { + + Properties gemfireSslProperties = new Properties(); + + gemfireSslProperties.setProperty(SECURITY_SSL_KEYSTORE_PROPERTY, trustedKeyStore); + gemfireSslProperties.setProperty(SECURITY_SSL_TRUSTSTORE_PROPERTY, trustedKeyStore); + + environment.getPropertySources() + .addFirst(newPropertySource(GEMFIRE_SSL_PROPERTY_SOURCE_NAME, gemfireSslProperties)); } } diff --git a/spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure/security/ssl/SslAutoConfigurationUnitTests.java b/spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure/security/ssl/SslAutoConfigurationUnitTests.java new file mode 100644 index 00000000..db73917e --- /dev/null +++ b/spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure/security/ssl/SslAutoConfigurationUnitTests.java @@ -0,0 +1,102 @@ +/* + * Copyright 2018 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.geode.boot.autoconfigure.security.ssl; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.geode.boot.autoconfigure.SslAutoConfiguration; +import org.springframework.geode.boot.autoconfigure.SslAutoConfiguration.SslEnvironmentPostProcessor; + +/** + * Unit Tests for {@link SslAutoConfiguration}. + * + * @author John Blum + * @see org.junit.Test + * @see org.mockito.Mockito + * @see org.springframework.core.env.ConfigurableEnvironment + * @see org.springframework.geode.boot.autoconfigure.SslAutoConfiguration + * @since 1.0.0 + */ +public class SslAutoConfigurationUnitTests { + + @Test + public void sslConfigurationIsDisabled() { + + SslEnvironmentPostProcessor environmentPostProcessor = new SslEnvironmentPostProcessor(); + + ConfigurableEnvironment mockEnvironment = mock(ConfigurableEnvironment.class); + + when(mockEnvironment.getProperty(eq(SslAutoConfiguration.SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY), + eq(Boolean.class), eq(true))) + .thenReturn(false); + + environmentPostProcessor.postProcessEnvironment(mockEnvironment, null); + + verify(mockEnvironment, times(1)) + .getProperty(eq(SslAutoConfiguration.SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY), + eq(Boolean.class), eq(true)); + + verify(mockEnvironment, never()).containsProperty(eq("spring.data.gemfire.security.ssl.keystore")); + } + + @Test + public void sslConfigurationIsEnabled() { + + SslEnvironmentPostProcessor environmentPostProcessor = new SslEnvironmentPostProcessor(); + + ConfigurableEnvironment mockEnvironment = mock(ConfigurableEnvironment.class); + + when(mockEnvironment.getProperty(eq(SslAutoConfiguration.SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY), + eq(Boolean.class), eq(true))) + .thenReturn(true); + + environmentPostProcessor.postProcessEnvironment(mockEnvironment, null); + + verify(mockEnvironment, times(1)) + .getProperty(eq(SslAutoConfiguration.SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY), + eq(Boolean.class), eq(true)); + + verify(mockEnvironment, times(1)) + .containsProperty(eq("spring.data.gemfire.security.ssl.keystore")); + } + + @Test + public void sslConfigurationIsEnabledWhenEnabledPropertyNotPresent() { + + SslEnvironmentPostProcessor environmentPostProcessor = new SslEnvironmentPostProcessor(); + + ConfigurableEnvironment mockEnvironment = spy(new StandardEnvironment()); + + environmentPostProcessor.postProcessEnvironment(mockEnvironment, null); + + verify(mockEnvironment, times(1)) + .getProperty(eq(SslAutoConfiguration.SECURITY_SSL_ENVIRONMENT_POST_PROCESSOR_ENABLED_PROPERTY), + eq(Boolean.class), eq(true)); + + verify(mockEnvironment, times(1)) + .containsProperty(eq("spring.data.gemfire.security.ssl.keystore")); + } +}