diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostCredentialsProvider.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostCredentialsProvider.java index 364e441b..4a9cbeab 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostCredentialsProvider.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostCredentialsProvider.java @@ -29,7 +29,7 @@ public class ProxyHostCredentialsProvider extends BasicCredentialsProvider { for (ProxyHostProperties proxy : proxyHostProperties) { - if (proxy != null && proxy.getUsername() != null && proxy.getPassword() != null) { + if (proxy != null && proxy.connectionInformationProvided() && proxy.authenticationProvided()) { AuthScope authscope = new AuthScope(proxy.getHost(), proxy.getPort()); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword()); diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostProperties.java index 84eec408..ed0afaae 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostProperties.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/ProxyHostProperties.java @@ -17,6 +17,7 @@ package org.springframework.cloud.config.server.proxy; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonValue; /** @@ -102,4 +103,14 @@ public class ProxyHostProperties { } + @JsonIgnore + public boolean connectionInformationProvided() { + return host != null && !host.isEmpty() && port > 0; + } + + @JsonIgnore + public boolean authenticationProvided() { + return username != null && password != null; + } + } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlanner.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlanner.java index 77fa0bc8..782d9845 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlanner.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlanner.java @@ -47,7 +47,7 @@ public class SchemeBasedRoutePlanner extends DefaultRoutePlanner { } private HttpHost buildProxy(ProxyHostProperties properties, String scheme) { - if (properties == null) { + if (properties == null || !properties.connectionInformationProvided()) { return null; } return new HttpHost(properties.getHost(), properties.getPort(), scheme); diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactory.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactory.java index 56cfc91d..97fa7ffa 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactory.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactory.java @@ -79,7 +79,7 @@ public class PropertyBasedSshSessionFactory extends JschConfigSessionFactory { } ProxyHostProperties proxyHostProperties = sshProperties.getProxy().get(ProxyHostProperties.ProxyForScheme.HTTP); - if (proxyHostProperties != null) { + if (proxyHostProperties != null && proxyHostProperties.connectionInformationProvided()) { ProxyHTTP proxy = createProxy(proxyHostProperties); proxy.setUserPasswd(proxyHostProperties.getUsername(), proxyHostProperties.getPassword()); session.setProxy(proxy); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java index a0a82a2e..73c5d065 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java @@ -45,7 +45,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; - /** * @author Dave Syer * @author Roy Clarkson @@ -92,25 +91,25 @@ class EnvironmentControllerIntegrationTests { } @ParameterizedTest - @ValueSource(strings = {"yml", "yaml", "json", "properties"}) + @ValueSource(strings = { "yml", "yaml", "json", "properties" }) public void profileContainingExtensionKeyword(String extensionKeyword) throws Exception { String profiles = "dev-" + extensionKeyword; Environment dashEnvironment = new Environment("foo", profiles); dashEnvironment.add(new PropertySource("foo", new HashMap<>())); when(this.repository.findOne("foo", profiles, null, false)).thenReturn(dashEnvironment); this.mvc.perform(MockMvcRequestBuilders.get("/foo/" + profiles)) - .andExpect(MockMvcResultMatchers.status().isOk()); + .andExpect(MockMvcResultMatchers.status().isOk()); verify(this.repository).findOne("foo", profiles, null, false); } @ParameterizedTest - @ValueSource(strings = {"yml", "yaml", "json", "properties"}) + @ValueSource(strings = { "yml", "yaml", "json", "properties" }) public void profileHavingAnExtension(String extensionKeyword) throws Exception { String profiles = "dev." + extensionKeyword; Environment dashEnvironment = new Environment("foo", profiles); dashEnvironment.add(new PropertySource("foo", new HashMap<>())); this.mvc.perform(MockMvcRequestBuilders.get("/foo/" + profiles)) - .andExpect(MockMvcResultMatchers.status().isNotFound()); + .andExpect(MockMvcResultMatchers.status().isNotFound()); verifyNoInteractions(this.repository); } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/ProxyHostCredentialsProviderTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/ProxyHostCredentialsProviderTest.java new file mode 100644 index 00000000..fa5d4cad --- /dev/null +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/ProxyHostCredentialsProviderTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2018-2019 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 + * + * https://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.cloud.config.server.proxy; + +import java.util.Map; + +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.junit.jupiter.api.Test; + +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +class ProxyHostCredentialsProviderTest { + + @Test + void should_take_only_proxy_with_connection_and_credentials_information_provided() { + ProxyHostProperties withoutConnection = proxyHost(null, 0, "user", "password"); + ProxyHostProperties withoutCredentials = proxyHost("bad.proxy", 666, null, null); + ProxyHostProperties goodProxy = proxyHost("good.proxy", 888, "user", "P@s$W0rd!"); + + ProxyHostCredentialsProvider provider = new ProxyHostCredentialsProvider(withoutConnection, withoutCredentials, goodProxy); + + Map credentials = (Map) ReflectionTestUtils.getField(provider, "credMap"); + assertThat(credentials).hasSize(1); + Map.Entry entry = credentials.entrySet().iterator().next(); + assertThat(entry.getKey().getHost()).isEqualTo("good.proxy"); + assertThat(entry.getKey().getPort()).isEqualTo(888); + assertThat(entry.getValue().getUserPrincipal().getName()).isEqualTo("user"); + assertThat(entry.getValue().getPassword()).isEqualTo("P@s$W0rd!"); + } + + private ProxyHostProperties proxyHost(String host, int port, String username, String password) { + ProxyHostProperties result = new ProxyHostProperties(); + result.setHost(host); + result.setPort(port); + result.setUsername(username); + result.setPassword(password); + return result; + } + +} diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/ProxyHostPropertiesTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/ProxyHostPropertiesTest.java new file mode 100644 index 00000000..5d366fe2 --- /dev/null +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/ProxyHostPropertiesTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2018-2019 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 + * + * https://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.cloud.config.server.proxy; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ProxyHostPropertiesTest { + + @Test + void connectionInformationProvided_should_return_false_when_host_is_null() { + ProxyHostProperties properties = proxyHost(null, 8080); + + final boolean result = properties.connectionInformationProvided(); + + assertThat(result).isFalse(); + } + + @Test + void connectionInformationProvided_should_return_false_when_host_is_empty() { + ProxyHostProperties properties = proxyHost("", 8080); + + final boolean result = properties.connectionInformationProvided(); + + assertThat(result).isFalse(); + } + + @Test + void connectionInformationProvided_should_return_false_when_port_is_null() { + ProxyHostProperties properties = proxyHost("host.address", 0); + + final boolean result = properties.connectionInformationProvided(); + + assertThat(result).isFalse(); + } + + @Test + void connectionInformationProvided_should_return_true_when_port_is_filled_and_port_positive() { + ProxyHostProperties properties = proxyHost("host.address", 8080); + + final boolean result = properties.connectionInformationProvided(); + + assertThat(result).isTrue(); + } + + @Test + void authenticationProvided_should_return_false_if_username_is_null() { + ProxyHostProperties properties = proxyHostWithCredentials(null, "P@s$W0rD!"); + + final boolean result = properties.authenticationProvided(); + + assertThat(result).isFalse(); + } + + @Test + void authenticationProvided_should_return_false_if_password_is_null() { + ProxyHostProperties properties = proxyHostWithCredentials("username", null); + + final boolean result = properties.authenticationProvided(); + + assertThat(result).isFalse(); + } + + @Test + void authenticationProvided_should_return_true_if_username_and_password_are_provided() { + ProxyHostProperties properties = proxyHostWithCredentials("username", "P@s$W0rD!"); + + final boolean result = properties.authenticationProvided(); + + assertThat(result).isTrue(); + } + + private ProxyHostProperties proxyHost(String host, int port) { + ProxyHostProperties properties = new ProxyHostProperties(); + properties.setHost(host); + properties.setPort(port); + return properties; + } + + private ProxyHostProperties proxyHostWithCredentials(String username, String password) { + ProxyHostProperties properties = new ProxyHostProperties(); + properties.setUsername(username); + properties.setPassword(password); + return properties; + } + +} diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlannerTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlannerTest.java index 12512709..44f2c5f5 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlannerTest.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/proxy/SchemeBasedRoutePlannerTest.java @@ -77,6 +77,15 @@ class SchemeBasedRoutePlannerTest { assertThat(result.getPort()).isEqualTo(UNSECURED_PROXY_PROPERTIES.getPort()); } + @Test + void determineProxy_should_return_null_when_provided_proxies_are_incomplete() { + SchemeBasedRoutePlanner planner = new SchemeBasedRoutePlanner(buildProxyProperties("", 777), buildProxyProperties("host", 0)); + + final HttpHost result = planner.determineProxy(target("https"), anyRequest(), anyContext()); + + assertThat(result).isNull(); + } + private HttpHost target(String scheme) { HttpHost host = mock(HttpHost.class); when(host.getSchemeName()).thenReturn(scheme); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java index ff53b77a..789c28c3 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java @@ -199,6 +199,8 @@ public class PropertyBasedSshSessionFactoryTest { sshProperties.setPrivateKey(PRIVATE_KEY); Map map = new HashMap<>(); ProxyHostProperties proxyHostProperties = new ProxyHostProperties(); + proxyHostProperties.setHost("host.domain"); + proxyHostProperties.setPort(8080); proxyHostProperties.setUsername("user"); proxyHostProperties.setPassword("password"); map.put(ProxyHostProperties.ProxyForScheme.HTTP, proxyHostProperties);