diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java index 388144c0..f80631af 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2013-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. @@ -21,7 +21,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.config.client.ConfigClientProperties; import org.springframework.cloud.config.server.config.ConfigServerProperties; import org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration; -import org.springframework.cloud.config.server.config.TransportConfiguration; import org.springframework.cloud.config.server.environment.EnvironmentRepository; import org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator; import org.springframework.context.annotation.Bean; @@ -45,7 +44,7 @@ import org.springframework.util.StringUtils; public class ConfigServerBootstrapConfiguration { @EnableConfigurationProperties(ConfigServerProperties.class) - @Import({ EnvironmentRepositoryConfiguration.class, TransportConfiguration.class }) + @Import({ EnvironmentRepositoryConfiguration.class }) protected static class LocalPropertySourceLocatorConfiguration { @Autowired diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java index 8a7a4140..0d36c9e6 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-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. @@ -29,7 +29,7 @@ import org.springframework.context.annotation.Import; @ConditionalOnBean(ConfigServerConfiguration.Marker.class) @EnableConfigurationProperties(ConfigServerProperties.class) @Import({ EnvironmentRepositoryConfiguration.class, CompositeConfiguration.class, ResourceRepositoryConfiguration.class, - ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class, TransportConfiguration.class }) + ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class }) public class ConfigServerAutoConfiguration { } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java index f5132f2a..9acd3b39 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java @@ -17,7 +17,6 @@ package org.springframework.cloud.config.server.config; import java.util.List; import java.util.Optional; - import javax.servlet.http.HttpServletRequest; import org.eclipse.jgit.api.TransportConfigCallback; @@ -114,14 +113,14 @@ class DefaultRepositoryConfiguration { private ConfigServerProperties server; @Autowired(required = false) - private TransportConfigCallback transportConfigCallback; + private TransportConfigCallback customTransportConfigCallback; @Bean public MultipleJGitEnvironmentRepository defaultEnvironmentRepository( MultipleJGitEnvironmentProperties environmentProperties) { MultipleJGitEnvironmentRepositoryFactory gitEnvironmentRepositoryFactory = new MultipleJGitEnvironmentRepositoryFactory(environment, server, - Optional.ofNullable(transportConfigCallback)); + Optional.ofNullable(customTransportConfigCallback)); return gitEnvironmentRepositoryFactory.build(environmentProperties); } } @@ -199,8 +198,8 @@ class CompositeRepositoryConfiguration { @Bean public MultipleJGitEnvironmentRepositoryFactory gitEnvironmentRepositoryFactory( ConfigurableEnvironment environment, ConfigServerProperties server, - Optional transportConfigCallback) { - return new MultipleJGitEnvironmentRepositoryFactory(environment, server, transportConfigCallback); + Optional customTransportConfigCallback) { + return new MultipleJGitEnvironmentRepositoryFactory(environment, server, customTransportConfigCallback); } } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/TransportConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/TransportConfiguration.java deleted file mode 100644 index aa6aaccb..00000000 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/TransportConfiguration.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2015-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.cloud.config.server.config; - -import com.jcraft.jsch.JSch; -import com.jcraft.jsch.Session; -import org.eclipse.jgit.api.TransportConfigCallback; -import org.eclipse.jgit.transport.*; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.config.server.ssh.PropertyBasedSshSessionFactory; -import org.springframework.cloud.config.server.ssh.SshUriProperties; -import org.springframework.cloud.config.server.ssh.SshUriPropertyProcessor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Configure a callback to set up a property based SSH settings before running a transport command (such as clone or fetch) - * - * @author Ollie Hughes - */ -@Configuration -@ConditionalOnClass(TransportConfigCallback.class) -@EnableConfigurationProperties(SshUriProperties.class) -public class TransportConfiguration { - - @ConditionalOnMissingBean(TransportConfigCallback.class) - @Bean - public TransportConfigCallback propertiesBasedSshTransportCallback(final SshUriProperties sshUriProperties) { - if(sshUriProperties.isIgnoreLocalSshSettings()) { - return new PropertiesBasedSshTransportConfigCallback(sshUriProperties); - } - else return new FileBasedSshTransportConfigCallback(sshUriProperties); - } - - /** - * Configure JGit transport command to use a SSH session factory that is configured using properties defined - * in {@link SshUriProperties} - */ - public static class PropertiesBasedSshTransportConfigCallback implements TransportConfigCallback { - - private SshUriProperties sshUriProperties; - - public PropertiesBasedSshTransportConfigCallback(SshUriProperties sshUriProperties) { - this.sshUriProperties = sshUriProperties; - } - - public SshUriProperties getSshUriProperties() { - return sshUriProperties; - } - - @Override - public void configure(Transport transport) { - if (transport instanceof SshTransport) { - SshTransport sshTransport = (SshTransport) transport; - sshTransport.setSshSessionFactory( - new PropertyBasedSshSessionFactory( - new SshUriPropertyProcessor(sshUriProperties).getSshKeysByHostname(), new JSch())); - } - } - } - - /** - * Configure JGit transport command to use a default SSH session factory based on local machines SSH config. - * Allow strict host key checking to be set. - */ - public static class FileBasedSshTransportConfigCallback implements TransportConfigCallback { - - private SshUriProperties sshUriProperties; - - public FileBasedSshTransportConfigCallback(SshUriProperties sshUriProperties) { - this.sshUriProperties = sshUriProperties; - } - - public SshUriProperties getSshUriProperties() { - return sshUriProperties; - } - - @Override - public void configure(Transport transport) { - SshSessionFactory.setInstance(new JschConfigSessionFactory() { - @Override - protected void configure(OpenSshConfig.Host hc, Session session) { - session.setConfig("StrictHostKeyChecking", - sshUriProperties.isStrictHostKeyChecking() ? "yes" : "no"); - } - }); - } - } -} diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java index fcf816a0..3c3a43ba 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java @@ -15,6 +15,8 @@ */ package org.springframework.cloud.config.server.environment; +import javax.validation.constraints.Pattern; + import org.springframework.cloud.config.server.support.AbstractScmAccessorProperties; /** @@ -40,6 +42,42 @@ public class JGitEnvironmentProperties extends AbstractScmAccessorProperties { */ private int refreshRate = 0; + /** + * Valid SSH private key. Must be set if ignoreLocalSshSettings is true and Git URI is SSH format. + */ + private String privateKey; + + /** + * One of ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, or ecdsa-sha2-nistp521. Must be set if hostKey is also set. + */ + private String hostKeyAlgorithm; + + /** + * Valid SSH host key. Must be set if hostKeyAlgorithm is also set. + */ + private String hostKey; + + /** + * Location of custom .known_hosts file. + */ + private String knownHostsFile; + + /** + * Override server authentication method order. This should allow for evading login prompts if server has keyboard-interactive authentication before the publickey method. + */ + @Pattern(regexp = "([\\w -]+,)*([\\w -]+)") + private String preferredAuthentications; + + /** + * If true, use property-based instead of file-based SSH config. + */ + private boolean ignoreLocalSshSettings; + + /** + * If false, ignore errors with host key + */ + private boolean strictHostKeyChecking = true; + public JGitEnvironmentProperties() { super(); setDefaultLabel(DEFAULT_LABEL); @@ -84,4 +122,62 @@ public class JGitEnvironmentProperties extends AbstractScmAccessorProperties { public void setRefreshRate(int refreshRate) { this.refreshRate = refreshRate; } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public String getHostKeyAlgorithm() { + return hostKeyAlgorithm; + } + + public void setHostKeyAlgorithm(String hostKeyAlgorithm) { + this.hostKeyAlgorithm = hostKeyAlgorithm; + } + + public String getHostKey() { + return hostKey; + } + + public void setHostKey(String hostKey) { + this.hostKey = hostKey; + } + + public String getKnownHostsFile() { + return knownHostsFile; + } + + public void setKnownHostsFile(String knownHostsFile) { + this.knownHostsFile = knownHostsFile; + } + + public String getPreferredAuthentications() { + return preferredAuthentications; + } + + public void setPreferredAuthentications(String preferredAuthentications) { + this.preferredAuthentications = preferredAuthentications; + } + + public boolean isIgnoreLocalSshSettings() { + return ignoreLocalSshSettings; + } + + public void setIgnoreLocalSshSettings(boolean ignoreLocalSshSettings) { + this.ignoreLocalSshSettings = ignoreLocalSshSettings; + } + + @Override + public boolean isStrictHostKeyChecking() { + return strictHostKeyChecking; + } + + @Override + public void setStrictHostKeyChecking(boolean strictHostKeyChecking) { + this.strictHostKeyChecking = strictHostKeyChecking; + } } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java index 026b0f9d..3a1353a5 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java @@ -19,11 +19,21 @@ import java.util.LinkedHashMap; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.config.server.ssh.HostKeyAlgoSupported; +import org.springframework.cloud.config.server.ssh.HostKeyAndAlgoBothExist; +import org.springframework.cloud.config.server.ssh.KnownHostsFileIsValid; +import org.springframework.cloud.config.server.ssh.PrivateKeyIsValid; +import org.springframework.validation.annotation.Validated; /** * @author Dylan Roberts */ @ConfigurationProperties("spring.cloud.config.server.git") +@Validated +@PrivateKeyIsValid +@HostKeyAndAlgoBothExist +@HostKeyAlgoSupported +@KnownHostsFileIsValid public class MultipleJGitEnvironmentProperties extends JGitEnvironmentProperties { /** * Map of repository identifier to location and other properties. diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java index 73e02e14..a01aaa9b 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java @@ -20,6 +20,8 @@ import java.util.Optional; import org.eclipse.jgit.api.TransportConfigCallback; import org.springframework.cloud.config.server.config.ConfigServerProperties; +import org.springframework.cloud.config.server.ssh.FileBasedSshTransportConfigCallback; +import org.springframework.cloud.config.server.ssh.PropertiesBasedSshTransportConfigCallback; import org.springframework.core.env.ConfigurableEnvironment; /** @@ -29,23 +31,31 @@ public class MultipleJGitEnvironmentRepositoryFactory implements EnvironmentRepo MultipleJGitEnvironmentProperties> { private ConfigurableEnvironment environment; private ConfigServerProperties server; - private Optional transportConfigCallback; + private Optional customTransportConfigCallback; public MultipleJGitEnvironmentRepositoryFactory(ConfigurableEnvironment environment, ConfigServerProperties server, - Optional transportConfigCallback) { + Optional customTransportConfigCallback) { this.environment = environment; this.server = server; - this.transportConfigCallback = transportConfigCallback; + this.customTransportConfigCallback = customTransportConfigCallback; } @Override public MultipleJGitEnvironmentRepository build(MultipleJGitEnvironmentProperties environmentProperties) { MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(environment, environmentProperties); - repository.setTransportConfigCallback(transportConfigCallback.orElse(null)); + repository.setTransportConfigCallback(customTransportConfigCallback + .orElse(buildTransportConfigCallback(environmentProperties))); if (server.getDefaultLabel() != null) { repository.setDefaultLabel(server.getDefaultLabel()); } return repository; } + + private TransportConfigCallback buildTransportConfigCallback(final MultipleJGitEnvironmentProperties gitEnvironmentProperties) { + if (gitEnvironmentProperties.isIgnoreLocalSshSettings()) { + return new PropertiesBasedSshTransportConfigCallback(gitEnvironmentProperties); + } + return new FileBasedSshTransportConfigCallback(gitEnvironmentProperties); + } } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/FileBasedSshTransportConfigCallback.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/FileBasedSshTransportConfigCallback.java new file mode 100644 index 00000000..b4541ac7 --- /dev/null +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/FileBasedSshTransportConfigCallback.java @@ -0,0 +1,53 @@ +/* + * 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.cloud.config.server.ssh; + +import com.jcraft.jsch.Session; +import org.eclipse.jgit.api.TransportConfigCallback; +import org.eclipse.jgit.transport.JschConfigSessionFactory; +import org.eclipse.jgit.transport.OpenSshConfig; +import org.eclipse.jgit.transport.SshSessionFactory; +import org.eclipse.jgit.transport.Transport; + +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties; + +/** + * Configure JGit transport command to use a default SSH session factory based on local machines SSH config. + * Allow strict host key checking to be set. + */ +public class FileBasedSshTransportConfigCallback implements TransportConfigCallback { + + private MultipleJGitEnvironmentProperties sshUriProperties; + + public FileBasedSshTransportConfigCallback(MultipleJGitEnvironmentProperties sshUriProperties) { + this.sshUriProperties = sshUriProperties; + } + + public MultipleJGitEnvironmentProperties getSshUriProperties() { + return sshUriProperties; + } + + @Override + public void configure(Transport transport) { + SshSessionFactory.setInstance(new JschConfigSessionFactory() { + @Override + protected void configure(OpenSshConfig.Host hc, Session session) { + session.setConfig("StrictHostKeyChecking", + sshUriProperties.isStrictHostKeyChecking() ? "yes" : "no"); + } + }); + } +} diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java index d75d2e48..e3652592 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java @@ -23,6 +23,8 @@ import java.util.Set; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; +import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties; +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties; import org.springframework.validation.annotation.Validated; import static java.lang.String.format; @@ -30,14 +32,14 @@ import static org.springframework.cloud.config.server.ssh.SshPropertyValidator.i import static org.springframework.util.StringUtils.hasText; /** - * JSR-303 Cross Field validator that ensures that a {@link SshUriProperties} bean for the constraints: + * JSR-303 Cross Field validator that ensures that a {@link MultipleJGitEnvironmentProperties} bean for the constraints: * - If host key algo is supported * * Beans annotated with {@link HostKeyAlgoSupported} and {@link Validated} will have the constraints applied. * * @author Ollie Hughes */ -public class HostKeyAlgoSupportedValidator implements ConstraintValidator { +public class HostKeyAlgoSupportedValidator implements ConstraintValidator { private static final String GIT_PROPERTY_PREFIX = "spring.cloud.config.server.git."; private final SshPropertyValidator sshPropertyValidator = new SshPropertyValidator(); private static final Set VALID_HOST_KEY_ALGORITHMS = new LinkedHashSet<>(Arrays.asList( @@ -49,12 +51,12 @@ public class HostKeyAlgoSupportedValidator implements ConstraintValidator validationResults = new HashSet<>(); - List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties); + List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties); - for (SshUri extractedProperty : extractedProperties) { + for (JGitEnvironmentProperties extractedProperty : extractedProperties) { if (sshUriProperties.isIgnoreLocalSshSettings() && isSshUri(extractedProperty.getUri())) { validationResults.add(isHostKeySpecifiedWhenAlgorithmSet(extractedProperty, context)); } @@ -62,7 +64,7 @@ public class HostKeyAlgoSupportedValidator implements ConstraintValidator { +public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator { private static final String GIT_PROPERTY_PREFIX = "spring.cloud.config.server.git."; private final SshPropertyValidator sshPropertyValidator = new SshPropertyValidator(); @@ -46,11 +48,11 @@ public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator validationResults = new HashSet<>(); - List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties); + List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties); - for (SshUri extractedProperty : extractedProperties) { + for (JGitEnvironmentProperties extractedProperty : extractedProperties) { if (sshUriProperties.isIgnoreLocalSshSettings() && isSshUri(extractedProperty.getUri())) { validationResults.add( isAlgorithmSpecifiedWhenHostKeySet(extractedProperty, context) @@ -60,7 +62,7 @@ public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator * Beans annotated with {@link KnownHostsFileIsValid} and {@link Validated} will have the constraints applied. * * @author Edgars Jasmans */ -public class KnownHostsFileValidator implements ConstraintValidator { +public class KnownHostsFileValidator implements ConstraintValidator { @Override public void initialize(KnownHostsFileIsValid knownHostsFileIsValid) { @@ -40,7 +41,7 @@ public class KnownHostsFileValidator implements ConstraintValidator { +public class PrivateKeyValidator implements ConstraintValidator { private static final String GIT_PROPERTY_PREFIX = "spring.cloud.config.server.git."; private final SshPropertyValidator sshPropertyValidator = new SshPropertyValidator(); @@ -49,12 +51,12 @@ public class PrivateKeyValidator implements ConstraintValidator validationResults = new HashSet<>(); - List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties); + List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties); - for (SshUri extractedProperty : extractedProperties) { + for (JGitEnvironmentProperties extractedProperty : extractedProperties) { if (extractedProperty.isIgnoreLocalSshSettings() && isSshUri(extractedProperty.getUri())) { validationResults.add( isPrivateKeyPresent(extractedProperty, context) @@ -65,7 +67,7 @@ public class PrivateKeyValidator implements ConstraintValidator sshKeysByHostname; + private final Map sshKeysByHostname; private final JSch jSch; - public PropertyBasedSshSessionFactory(Map sshKeysByHostname, JSch jSch) { + public PropertyBasedSshSessionFactory(Map sshKeysByHostname, JSch jSch) { this.sshKeysByHostname = sshKeysByHostname; this.jSch = jSch; } @Override protected void configure(Host hc, Session session) { - SshUri sshProperties = sshKeysByHostname.get(hc.getHostName()); + JGitEnvironmentProperties sshProperties = sshKeysByHostname.get(hc.getHostName()); String hostKeyAlgorithm = sshProperties.getHostKeyAlgorithm(); if (hostKeyAlgorithm != null) { session.setConfig(SERVER_HOST_KEY, hostKeyAlgorithm); @@ -69,7 +71,7 @@ public class PropertyBasedSshSessionFactory extends JschConfigSessionFactory { @Override protected Session createSession(Host hc, String user, String host, int port, FS fs) throws JSchException { if (sshKeysByHostname.containsKey(host)) { - SshUri sshUriProperties = sshKeysByHostname.get(host); + JGitEnvironmentProperties sshUriProperties = sshKeysByHostname.get(host); jSch.addIdentity(host, sshUriProperties.getPrivateKey().getBytes(), null, null); if (sshUriProperties.getKnownHostsFile() != null) { jSch.setKnownHosts(sshUriProperties.getKnownHostsFile()); diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java index 6b1b1475..75b1fc4a 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java @@ -24,6 +24,8 @@ import java.util.Map; import org.eclipse.jgit.transport.URIish; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties; +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties; import org.springframework.stereotype.Component; import static org.springframework.util.StringUtils.hasText; @@ -34,7 +36,7 @@ import static org.springframework.util.StringUtils.hasText; * @author Ollie Hughes */ @Component -@EnableConfigurationProperties(SshUriProperties.class) +@EnableConfigurationProperties(MultipleJGitEnvironmentProperties.class) public class SshPropertyValidator { protected static boolean isSshUri(Object uri) { @@ -55,10 +57,10 @@ public class SshPropertyValidator { return false; } - protected List extractRepoProperties(SshUriProperties sshUriProperties) { - List allRepoProperties = new ArrayList<>(); + protected List extractRepoProperties(MultipleJGitEnvironmentProperties sshUriProperties) { + List allRepoProperties = new ArrayList<>(); allRepoProperties.add(sshUriProperties); - Map repos = sshUriProperties.getRepos(); + Map repos = sshUriProperties.getRepos(); if (repos != null) { allRepoProperties.addAll(repos.values()); } diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUri.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUri.java deleted file mode 100644 index a7211160..00000000 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUri.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 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.cloud.config.server.ssh; - -import org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriNestedRepoProperties; - -import javax.validation.constraints.Pattern; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Base class that contains configuration properties for Git SSH properties - * - * @author Ollie Hughes - */ -public abstract class SshUri { - private String privateKey; - private String uri; - private String hostKeyAlgorithm; - private String hostKey; - private String knownHostsFile; - @Pattern(regexp = "([\\w -]+,)*([\\w -]+)") - private String preferredAuthentications; - private boolean ignoreLocalSshSettings; - private boolean strictHostKeyChecking = true; - - public static SshUriPropertiesBuilder builder() { - return new SshUriPropertiesBuilder(); - } - - public String getUri() { - return this.uri; - } - - public String getHostKeyAlgorithm() { - return this.hostKeyAlgorithm; - } - - public String getHostKey() { - return this.hostKey; - } - - public String getKnownHostsFile() { - return this.knownHostsFile; - } - - public String getPreferredAuthentications() { - return this.preferredAuthentications; - } - - public String getPrivateKey() { - return this.privateKey; - } - - public boolean isIgnoreLocalSshSettings() { - return this.ignoreLocalSshSettings; - } - - public boolean isStrictHostKeyChecking() { - return this.strictHostKeyChecking; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public void setHostKeyAlgorithm(String hostKeyAlgorithm) { - this.hostKeyAlgorithm = hostKeyAlgorithm; - } - - public void setHostKey(String hostKey) { - this.hostKey = hostKey; - } - - public void setKnownHostsFile(String knownHostsFile) { - this.knownHostsFile = knownHostsFile; - } - - public void setPreferredAuthentications(String preferredAuthentications) { - this.preferredAuthentications = preferredAuthentications; - } - - public void setPrivateKey(String privateKey) { - this.privateKey = privateKey; - } - - public void setIgnoreLocalSshSettings(boolean ignoreLocalSshSettings) { - this.ignoreLocalSshSettings = ignoreLocalSshSettings; - } - - public void setStrictHostKeyChecking(boolean strictHostKeyChecking) { - this.strictHostKeyChecking = strictHostKeyChecking; - } - - public String toString() { - return "org.springframework.cloud.config.server.ssh.SshUriProperties(uri=" + this.getUri() - + " hostKeyAlgorithm=" + this.getHostKeyAlgorithm() - + ", hostKey=" + this.getHostKey() - + ", privateKey=" + this.getPrivateKey() - + ", ignoreLocalSshSettings=" + this.isIgnoreLocalSshSettings() - + ", knownHostsFile=" + this.getKnownHostsFile() - + ", preferredAuthentications=" + this.getPreferredAuthentications() - + ", strictHostKeyChecking=" + this.isStrictHostKeyChecking() + ",)"; - } - - public static class SshUriPropertiesBuilder { - private String uri; - private String hostKeyAlgorithm; - private String hostKey; - private String privateKey; - private String knownHostsFile; - private String preferredAuthentications; - private boolean ignoreLocalSshSettings; - private boolean strictHostKeyChecking = true; - private Map repos = new LinkedHashMap<>(); - - SshUriPropertiesBuilder() { - } - - public SshUri.SshUriPropertiesBuilder uri(String uri) { - this.uri = uri; - return this; - } - - public SshUri.SshUriPropertiesBuilder hostKeyAlgorithm(String hostKeyAlgorithm) { - this.hostKeyAlgorithm = hostKeyAlgorithm; - return this; - } - - public SshUri.SshUriPropertiesBuilder hostKey(String hostKey) { - this.hostKey = hostKey; - return this; - } - - public SshUri.SshUriPropertiesBuilder privateKey(String privateKey) { - this.privateKey = privateKey; - return this; - } - - public SshUri.SshUriPropertiesBuilder knownHostsFile(String knownHostsFile) { - this.knownHostsFile = knownHostsFile; - return this; - } - - public SshUri.SshUriPropertiesBuilder preferredAuthentications(String preferredAuthentications) { - this.preferredAuthentications = preferredAuthentications; - return this; - } - - public SshUri.SshUriPropertiesBuilder ignoreLocalSshSettings(boolean ignoreLocalSshSettings) { - this.ignoreLocalSshSettings = ignoreLocalSshSettings; - return this; - } - - public SshUri.SshUriPropertiesBuilder strictHostKeyChecking(boolean strictHostKeyChecking) { - this.strictHostKeyChecking = strictHostKeyChecking; - return this; - } - - public SshUri.SshUriPropertiesBuilder repos(Map repos) { - this.repos = repos; - return this; - } - - public SshUriProperties build() { - SshUriProperties sshUriProperties = new SshUriProperties(); - sshUriProperties.setRepos(repos); - build(sshUriProperties); - return sshUriProperties; - } - - public SshUriNestedRepoProperties buildAsNestedRepo() { - SshUriNestedRepoProperties sshUriNestedRepoProperties = new SshUriNestedRepoProperties(); - build(sshUriNestedRepoProperties); - return sshUriNestedRepoProperties; - } - - private void build(SshUri sshUriNestedRepoProperties) { - sshUriNestedRepoProperties.setUri(uri); - sshUriNestedRepoProperties.setHostKeyAlgorithm(hostKeyAlgorithm); - sshUriNestedRepoProperties.setHostKey(hostKey); - sshUriNestedRepoProperties.setPrivateKey(privateKey); - sshUriNestedRepoProperties.setKnownHostsFile(knownHostsFile); - sshUriNestedRepoProperties.setPreferredAuthentications(preferredAuthentications); - sshUriNestedRepoProperties.setIgnoreLocalSshSettings(ignoreLocalSshSettings); - sshUriNestedRepoProperties.setStrictHostKeyChecking(strictHostKeyChecking); - } - - public String toString() { - return "org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriPropertiesBuilder(uri=" + this.uri - + "hostKeyAlgorithm=" + this.hostKeyAlgorithm - + ", hostKey=" + this.hostKey - + ", privateKey=" + this.privateKey - + ", knownHostsFile=" + this.knownHostsFile - + ", preferredAuthentications=" + this.preferredAuthentications - + ", ignoreLocalSshSettings=" + this.ignoreLocalSshSettings - + ", strictHostKeyChecking=" + this.strictHostKeyChecking - + ", repos=" + this.repos + ")"; - } - } -} diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriProperties.java deleted file mode 100644 index 7aa9879d..00000000 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriProperties.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2015 - 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.cloud.config.server.ssh; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -/** - * Data container for property based SSH config - * - * @author Ollie Hughes - */ -@ConfigurationProperties("spring.cloud.config.server.git") -@Validated -@PrivateKeyIsValid -@HostKeyAndAlgoBothExist -@HostKeyAlgoSupported -@KnownHostsFileIsValid -public class SshUriProperties extends SshUri { - - private Map repos = new LinkedHashMap<>(); - - public Map getRepos() { - return this.repos; - } - - public void setRepos(Map repos) { - this.repos = repos; - } - - public void addRepo(String repoName, SshUriProperties.SshUriNestedRepoProperties properties) { - this.repos.put(repoName, properties); - } - - @Override - public String toString() { - return super.toString() + "{repos=" + repos + "}"; - } - - /** - * Differentiate between sets of properties that are defined in nested Git repos. - * This is to prevent boot from guarding against a potential infinite deserialization of nested properties. - * This sub class differentiates from {@link SshUriProperties} as it does not contain the self mao - */ - public static class SshUriNestedRepoProperties extends SshUri { - - } -} diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java index 36cbf85a..c5465fb1 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. @@ -21,7 +21,9 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.jgit.transport.URIish; -import org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriNestedRepoProperties; + +import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties; +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties; import static org.springframework.cloud.config.server.ssh.SshPropertyValidator.isSshUri; @@ -32,25 +34,25 @@ import static org.springframework.cloud.config.server.ssh.SshPropertyValidator.i */ public class SshUriPropertyProcessor { - private final SshUriProperties sshUriProperties; + private final MultipleJGitEnvironmentProperties sshUriProperties; - public SshUriPropertyProcessor(SshUriProperties sshUriProperties) { + public SshUriPropertyProcessor(MultipleJGitEnvironmentProperties sshUriProperties) { this.sshUriProperties = sshUriProperties; } - public Map getSshKeysByHostname() { + public Map getSshKeysByHostname() { return extractNestedProperties(sshUriProperties); } - private Map extractNestedProperties(SshUriProperties uriProperties) { - Map sshUriPropertyMap = new HashMap<>(); + private Map extractNestedProperties(MultipleJGitEnvironmentProperties uriProperties) { + Map sshUriPropertyMap = new HashMap<>(); String parentUri = uriProperties.getUri(); if (isSshUri(parentUri) && getHostname(parentUri) != null) { sshUriPropertyMap.put(getHostname(parentUri), uriProperties); } - Map repos = uriProperties.getRepos(); + Map repos = uriProperties.getRepos(); if(repos != null) { - for (SshUriNestedRepoProperties repoProperties : repos.values()) { + for (MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties repoProperties : repos.values()) { String repoUri = repoProperties.getUri(); if (isSshUri(repoUri) && getHostname(repoUri) != null) { sshUriPropertyMap.put(getHostname(repoUri), repoProperties); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java index 98a06fd9..3ca53211 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2017 the original author or authors. + * Copyright 2013-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. @@ -24,7 +24,6 @@ import org.junit.runners.Suite.SuiteClasses; import org.springframework.cloud.config.server.config.ConfigServerHealthIndicatorTests; import org.springframework.cloud.config.server.config.CustomCompositeEnvironmentRepositoryTests; import org.springframework.cloud.config.server.config.CustomEnvironmentRepositoryTests; -import org.springframework.cloud.config.server.config.TransportConfigurationTest; import org.springframework.cloud.config.server.credentials.AwsCodeCommitCredentialsProviderTests; import org.springframework.cloud.config.server.credentials.GitCredentialsProviderFactoryTests; import org.springframework.cloud.config.server.encryption.CipherEnvironmentEncryptorTests; @@ -108,7 +107,6 @@ import org.springframework.cloud.config.server.ssh.SshUriPropertyProcessorTest; ConfigServerHealthIndicatorTests.class, CustomCompositeEnvironmentRepositoryTests.class, CustomEnvironmentRepositoryTests.class, - TransportConfigurationTest.class, BootstrapConfigServerIntegrationTests.class, }) @Ignore diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java index b22b3166..3d755412 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-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. @@ -16,6 +16,9 @@ package org.springframework.cloud.config.server; +import java.io.File; +import java.lang.reflect.Method; + import com.jcraft.jsch.Session; import org.eclipse.jgit.api.TransportConfigCallback; import org.eclipse.jgit.transport.JschConfigSessionFactory; @@ -25,20 +28,22 @@ import org.eclipse.jgit.util.FS; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.config.server.config.TransportConfiguration; +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties; import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository; +import org.springframework.cloud.config.server.ssh.FileBasedSshTransportConfigCallback; +import org.springframework.cloud.config.server.ssh.PropertiesBasedSshTransportConfigCallback; import org.springframework.cloud.config.server.ssh.SshPropertyValidator; -import org.springframework.cloud.config.server.ssh.SshUriProperties; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; -import java.io.File; -import java.lang.reflect.Method; - import static junit.framework.TestCase.assertTrue; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -49,124 +54,251 @@ import static org.mockito.Mockito.verify; */ public class TransportConfigurationIntegrationTests { - @RunWith(SpringRunner.class) - @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "spring.config.name:ssh/ssh-private-key-block",}) - @ActiveProfiles({"test", "git"}) public static class PropertyBasedCallbackTest { - @Autowired - private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = {"spring.config.name:ssh/ssh-private-key-block"}) + @ActiveProfiles({"test", "git"}) + public static class StaticTest { - @Test - public void propertyBasedTransportCallbackIsConfigured() throws Exception { - TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); - assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class))); - } - } + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; - @RunWith(SpringRunner.class) - @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "spring.config.name:ssh/ssh-private-key-newline" - }) - @ActiveProfiles({"test", "git"}) - public static class PrivateKeyPropertyWithLineBreaks { - - @Autowired - private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; - - @Test - public void privateKeyPropertyWithLineBreaks() throws Exception { - TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); - assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class))); - - TransportConfiguration.PropertiesBasedSshTransportConfigCallback configCallback = - (TransportConfiguration.PropertiesBasedSshTransportConfigCallback) transportConfigCallback; - assertThat(configCallback.getSshUriProperties().getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1))); - } - } - - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "spring.config.name:ssh/ssh-nested-settings" - }) - @ActiveProfiles({"test", "git"}) - public static class SshPropertiesWithinNestedRepo { - - @Autowired - private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; - - @Test - public void sshPropertiesWithinNestedRepo() throws Exception { - TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); - assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class))); - - TransportConfiguration.PropertiesBasedSshTransportConfigCallback configCallback = - (TransportConfiguration.PropertiesBasedSshTransportConfigCallback) transportConfigCallback; - SshUriProperties sshUriProperties = configCallback.getSshUriProperties(); - assertThat(sshUriProperties.getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1))); - - assertThat(sshUriProperties.getRepos().get("repo1"), is(notNullValue())); - assertThat(sshUriProperties.getRepos().get("repo1").getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_2))); - } - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "spring.cloud.config.server.git.uri=git@gitserver.com:team/repo.git", - "spring.cloud.config.server.git.ignoreLocalSshSettings=false",}) - @ActiveProfiles({"test", "git"}) - public static class FileBasedCallbackTest { - - @Autowired - private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; - - @Test - public void fileBasedTransportCallbackIsConfigured() throws Exception { - TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); - assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.FileBasedSshTransportConfigCallback.class))); - } - - - @Test - public void strictHostKeyCheckShouldCheck() throws Exception { - String uri = "git+ssh://git@somegitserver/somegitrepo"; - SshSessionFactory.setInstance(null); - jGitEnvironmentRepository.setUri(uri); - jGitEnvironmentRepository.setBasedir(new File("./mybasedir")); - assertTrue(jGitEnvironmentRepository.isStrictHostKeyChecking()); - jGitEnvironmentRepository.setCloneOnStart(true); - try { - // this will throw but we don't care about connecting. - jGitEnvironmentRepository.afterPropertiesSet(); - } catch (Exception e) { - final OpenSshConfig.Host hc = OpenSshConfig.get(FS.detect()).lookup("github.com"); - JschConfigSessionFactory factory = (JschConfigSessionFactory) SshSessionFactory.getInstance(); - // There's no public method that can be used to inspect the ssh - // configuration, so we'll reflect - // the configure method to allow us to check that the config - // property is set as expected. - Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class, - Session.class); - configure.setAccessible(true); - Session session = mock(Session.class); - ArgumentCaptor keyCaptor = ArgumentCaptor.forClass(String.class); - ArgumentCaptor valueCaptor = ArgumentCaptor.forClass(String.class); - configure.invoke(factory, hc, session); - verify(session).setConfig(keyCaptor.capture(), valueCaptor.capture()); - configure.setAccessible(false); - assertTrue("yes".equals(valueCaptor.getValue())); + @Test + public void propertyBasedTransportCallbackIsConfigured() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class))); } } + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = {"spring.config.name:ssh/ssh-private-key-block-list"}) + @ActiveProfiles({"test", "composite"}) + public static class ListTest { + + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + + @Test + public void propertyBasedTransportCallbackIsConfigured() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class))); + } + } + + } + + public static class PrivateKeyPropertyWithLineBreaks { + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.config.name:ssh/ssh-private-key-newline" + }) + @ActiveProfiles({"test", "git"}) + public static class StaticTest { + + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + + @Test + public void privateKeyPropertyWithLineBreaks() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class))); + + PropertiesBasedSshTransportConfigCallback configCallback = + (PropertiesBasedSshTransportConfigCallback) transportConfigCallback; + assertThat(configCallback.getSshUriProperties().getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1))); + } + } + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.config.name:ssh/ssh-private-key-newline-list" + }) + @ActiveProfiles({"test", "composite"}) + public static class ListTest { + + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + + @Test + public void privateKeyPropertyWithLineBreaks() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class))); + + PropertiesBasedSshTransportConfigCallback configCallback = + (PropertiesBasedSshTransportConfigCallback) transportConfigCallback; + assertThat(configCallback.getSshUriProperties().getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1))); + } + } + + } + + public static class SshPropertiesWithinNestedRepo { + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.config.name:ssh/ssh-nested-settings" + }) + @ActiveProfiles({"test", "git"}) + public static class StaticTest { + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + + @Test + public void sshPropertiesWithinNestedRepo() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class))); + + PropertiesBasedSshTransportConfigCallback configCallback = + (PropertiesBasedSshTransportConfigCallback) transportConfigCallback; + MultipleJGitEnvironmentProperties sshUriProperties = configCallback.getSshUriProperties(); + assertThat(sshUriProperties.getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1))); + + assertThat(sshUriProperties.getRepos().get("repo1"), is(notNullValue())); + assertThat(sshUriProperties.getRepos().get("repo1").getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_2))); + } + } + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.config.name:ssh/ssh-nested-settings-list" + }) + @ActiveProfiles({"test", "composite"}) + public static class ListTest { + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + + @Test + public void sshPropertiesWithinNestedRepo() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class))); + + PropertiesBasedSshTransportConfigCallback configCallback = + (PropertiesBasedSshTransportConfigCallback) transportConfigCallback; + MultipleJGitEnvironmentProperties sshUriProperties = configCallback.getSshUriProperties(); + assertThat(sshUriProperties.getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1))); + + assertThat(sshUriProperties.getRepos().get("repo1"), is(notNullValue())); + assertThat(sshUriProperties.getRepos().get("repo1").getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_2))); + } + } + + } + + public static class FileBasedCallbackTest { + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.cloud.config.server.git.uri=git@gitserver.com:team/repo.git", + "spring.cloud.config.server.git.ignoreLocalSshSettings=false",}) + @ActiveProfiles({"test", "git"}) + public static class StaticTest { + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + + @Test + public void fileBasedTransportCallbackIsConfigured() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(FileBasedSshTransportConfigCallback.class))); + } + + @Test + public void strictHostKeyCheckShouldCheck() throws Exception { + String uri = "git+ssh://git@somegitserver/somegitrepo"; + SshSessionFactory.setInstance(null); + jGitEnvironmentRepository.setUri(uri); + jGitEnvironmentRepository.setBasedir(new File("./mybasedir")); + assertTrue(jGitEnvironmentRepository.isStrictHostKeyChecking()); + jGitEnvironmentRepository.setCloneOnStart(true); + try { + // this will throw but we don't care about connecting. + jGitEnvironmentRepository.afterPropertiesSet(); + } catch (Exception e) { + final OpenSshConfig.Host hc = OpenSshConfig.get(FS.detect()).lookup("github.com"); + JschConfigSessionFactory factory = (JschConfigSessionFactory) SshSessionFactory.getInstance(); + // There's no public method that can be used to inspect the ssh + // configuration, so we'll reflect + // the configure method to allow us to check that the config + // property is set as expected. + Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class, + Session.class); + configure.setAccessible(true); + Session session = mock(Session.class); + ArgumentCaptor keyCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor valueCaptor = ArgumentCaptor.forClass(String.class); + configure.invoke(factory, hc, session); + verify(session).setConfig(keyCaptor.capture(), valueCaptor.capture()); + configure.setAccessible(false); + assertTrue("yes".equals(valueCaptor.getValue())); + } + } + } + + @RunWith(SpringRunner.class) + @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.cloud.config.server.composite[0].type=git", + "spring.cloud.config.server.composite[0].uri=git@gitserver.com:team/repo.git", + "spring.cloud.config.server.composite[0].ignoreLocalSshSettings=false",}) + @ActiveProfiles({"test", "composite"}) + public static class ListTest { + @Autowired + private MultipleJGitEnvironmentRepository jGitEnvironmentRepository; + + @Test + public void fileBasedTransportCallbackIsConfigured() throws Exception { + TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback(); + assertThat(transportConfigCallback, is(instanceOf(FileBasedSshTransportConfigCallback.class))); + } + + @Test + public void strictHostKeyCheckShouldCheck() throws Exception { + String uri = "git+ssh://git@somegitserver/somegitrepo"; + SshSessionFactory.setInstance(null); + jGitEnvironmentRepository.setUri(uri); + jGitEnvironmentRepository.setBasedir(new File("./mybasedir")); + assertTrue(jGitEnvironmentRepository.isStrictHostKeyChecking()); + jGitEnvironmentRepository.setCloneOnStart(true); + try { + // this will throw but we don't care about connecting. + jGitEnvironmentRepository.afterPropertiesSet(); + } catch (Exception e) { + final OpenSshConfig.Host hc = OpenSshConfig.get(FS.detect()).lookup("github.com"); + JschConfigSessionFactory factory = (JschConfigSessionFactory) SshSessionFactory.getInstance(); + // There's no public method that can be used to inspect the ssh + // configuration, so we'll reflect + // the configure method to allow us to check that the config + // property is set as expected. + Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class, + Session.class); + configure.setAccessible(true); + Session session = mock(Session.class); + ArgumentCaptor keyCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor valueCaptor = ArgumentCaptor.forClass(String.class); + configure.invoke(factory, hc, session); + verify(session).setConfig(keyCaptor.capture(), valueCaptor.capture()); + configure.setAccessible(false); + assertTrue("yes".equals(valueCaptor.getValue())); + } + } + } + } private static class TestProperties { diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/TransportConfigurationTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/TransportConfigurationTest.java deleted file mode 100644 index 40296eef..00000000 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/TransportConfigurationTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2015 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.cloud.config.server.config; - -import org.eclipse.jgit.api.TransportConfigCallback; -import org.junit.Test; -import org.springframework.cloud.config.server.ssh.SshUri; -import org.springframework.cloud.config.server.ssh.SshUriProperties; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.instanceOf; -/** -* @author Ollie Hughes -*/ -public class TransportConfigurationTest { - @Test - public void propertiesBasedSshTransportCallbackCreated() throws Exception { - SshUriProperties ignoreLocalSettings = SshUri.builder() - .uri("user@gitrepo.com:proj/repo") - .ignoreLocalSshSettings(true) - .build(); - TransportConfiguration transportConfiguration = new TransportConfiguration(); - TransportConfigCallback transportConfigCallback = transportConfiguration.propertiesBasedSshTransportCallback(ignoreLocalSettings); - assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class))); - } - - @Test - public void fileBasedSshTransportCallbackCreated() throws Exception { - SshUriProperties dontIgnoreLocalSettings = SshUri.builder() - .uri("user@gitrepo.com:proj/repo") - .ignoreLocalSshSettings(false) - .build(); - - TransportConfiguration transportConfiguration = new TransportConfiguration(); - TransportConfigCallback transportConfigCallback = transportConfiguration.propertiesBasedSshTransportCallback(dontIgnoreLocalSettings); - assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.FileBasedSshTransportConfigCallback.class))); - - } - -} \ No newline at end of file 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 a8eeeb43..0a00e1d5 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 @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 the original author or authors. + * Copyright 2015 - 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. @@ -22,6 +22,10 @@ import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; +import com.jcraft.jsch.HostKey; +import com.jcraft.jsch.HostKeyRepository; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; import org.eclipse.jgit.transport.OpenSshConfig.Host; import org.junit.Assert; import org.junit.Test; @@ -29,19 +33,11 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; -import com.jcraft.jsch.HostKey; -import com.jcraft.jsch.HostKeyRepository; -import com.jcraft.jsch.JSch; -import com.jcraft.jsch.Session; - -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -70,10 +66,9 @@ public class PropertyBasedSshSessionFactoryTest { @Test public void strictHostKeyCheckingIsOptional() { - SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder() - .uri("ssh://gitlab.example.local:3322/somerepo.git") - .privateKey(PRIVATE_KEY) - .build(); + JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties(); + sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git"); + sshKey.setPrivateKey(PRIVATE_KEY); setupSessionFactory(sshKey); factory.configure(hc, session); @@ -84,11 +79,10 @@ public class PropertyBasedSshSessionFactoryTest { @Test public void strictHostKeyCheckingIsUsed() { - SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder() - .uri("ssh://gitlab.example.local:3322/somerepo.git") - .hostKey(HOST_KEY) - .privateKey(PRIVATE_KEY) - .build(); + JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties(); + sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git"); + sshKey.setHostKey(HOST_KEY); + sshKey.setPrivateKey(PRIVATE_KEY); setupSessionFactory(sshKey); factory.configure(hc, session); @@ -99,12 +93,11 @@ public class PropertyBasedSshSessionFactoryTest { @Test public void hostKeyAlgorithmIsSpecified() { - SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder() - .uri("ssh://gitlab.example.local:3322/somerepo.git") - .hostKeyAlgorithm(HOST_KEY_ALGORITHM) - .hostKey(HOST_KEY) - .privateKey(PRIVATE_KEY) - .build(); + JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties(); + sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git"); + sshKey.setHostKeyAlgorithm(HOST_KEY_ALGORITHM); + sshKey.setHostKey(HOST_KEY); + sshKey.setPrivateKey(PRIVATE_KEY); setupSessionFactory(sshKey); factory.configure(hc, session); @@ -115,10 +108,9 @@ public class PropertyBasedSshSessionFactoryTest { @Test public void privateKeyIsUsed() throws Exception { - SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder() - .uri("git@gitlab.example.local:someorg/somerepo.git") - .privateKey(PRIVATE_KEY) - .build(); + JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties(); + sshKey.setUri("git@gitlab.example.local:someorg/somerepo.git"); + sshKey.setPrivateKey(PRIVATE_KEY); setupSessionFactory(sshKey); factory.createSession(hc, null, SshUriPropertyProcessor.getHostname(sshKey.getUri()), 22, null); @@ -127,11 +119,10 @@ public class PropertyBasedSshSessionFactoryTest { @Test public void hostKeyIsUsed() throws Exception { - SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder() - .uri("git@gitlab.example.local:someorg/somerepo.git") - .hostKey(HOST_KEY) - .privateKey(PRIVATE_KEY) - .build(); + JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties(); + sshKey.setUri("git@gitlab.example.local:someorg/somerepo.git"); + sshKey.setHostKey(HOST_KEY); + sshKey.setPrivateKey(PRIVATE_KEY); setupSessionFactory(sshKey); factory.createSession(hc, null, SshUriPropertyProcessor.getHostname(sshKey.getUri()), 22, null); @@ -144,11 +135,10 @@ public class PropertyBasedSshSessionFactoryTest { @Test public void preferredAuthenticationsIsSpecified() { - SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder() - .uri("ssh://gitlab.example.local:3322/somerepo.git") - .privateKey(PRIVATE_KEY) - .preferredAuthentications("password,keyboard-interactive") - .build(); + JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties(); + sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git"); + sshKey.setPrivateKey(PRIVATE_KEY); + sshKey.setPreferredAuthentications("password,keyboard-interactive"); setupSessionFactory(sshKey); factory.configure(hc, session); @@ -159,11 +149,10 @@ public class PropertyBasedSshSessionFactoryTest { @Test public void customKnownHostsFileIsUsed() throws Exception { - SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder() - .uri("git@gitlab.example.local:someorg/somerepo.git") - .privateKey(PRIVATE_KEY) - .knownHostsFile("/ssh/known_hosts") - .build(); + JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties(); + sshKey.setUri("git@gitlab.example.local:someorg/somerepo.git"); + sshKey.setPrivateKey(PRIVATE_KEY); + sshKey.setKnownHostsFile("/ssh/known_hosts"); setupSessionFactory(sshKey); factory.createSession(hc, null, SshUriPropertyProcessor.getHostname(sshKey.getUri()), 22, null); @@ -173,8 +162,8 @@ public class PropertyBasedSshSessionFactoryTest { Assert.assertEquals("/ssh/known_hosts", captor.getValue()); } - private void setupSessionFactory(SshUri sshKey) { - Map sshKeysByHostname = new HashMap<>(); + private void setupSessionFactory(JGitEnvironmentProperties sshKey) { + Map sshKeysByHostname = new HashMap<>(); sshKeysByHostname.put(SshUriPropertyProcessor.getHostname(sshKey.getUri()), sshKey); factory = new PropertyBasedSshSessionFactory(sshKeysByHostname, jSch) ; when(hc.getHostName()).thenReturn(SshUriPropertyProcessor.getHostname(sshKey.getUri())); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java index 942f96ec..921067aa 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java @@ -16,14 +16,16 @@ package org.springframework.cloud.config.server.ssh; -import org.junit.BeforeClass; -import org.junit.Test; - +import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; -import java.util.Set; + +import org.junit.BeforeClass; +import org.junit.Test; + +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; @@ -76,119 +78,102 @@ public class SshPropertyValidatorTest { @Test public void supportedParametersSuccesful() throws Exception { - SshUriProperties validSettings = SshUri.builder() - .uri(SSH_URI) - .ignoreLocalSshSettings(true) - .privateKey(VALID_PRIVATE_KEY) - .hostKey(VALID_HOST_KEY) - .hostKeyAlgorithm("ssh-rsa") - .build(); + MultipleJGitEnvironmentProperties validSettings = new MultipleJGitEnvironmentProperties(); + validSettings.setUri(SSH_URI); + validSettings.setIgnoreLocalSshSettings(true); + validSettings.setPrivateKey(VALID_PRIVATE_KEY); + validSettings.setHostKey(VALID_HOST_KEY); + validSettings.setHostKeyAlgorithm("ssh-rsa"); - Set> constraintViolations = validator.validate(validSettings); + Set> constraintViolations = validator.validate(validSettings); assertThat(constraintViolations, hasSize(0)); - } @Test public void invalidPrivateKeyFails() throws Exception { + MultipleJGitEnvironmentProperties invalidKey = new MultipleJGitEnvironmentProperties(); + invalidKey.setUri(SSH_URI); + invalidKey.setIgnoreLocalSshSettings(true); + invalidKey.setPrivateKey("invalid_key"); - SshUriProperties invalidKey = SshUri.builder() - .uri(SSH_URI) - .ignoreLocalSshSettings(true) - .privateKey("invalid_key") - .build(); - - Set> constraintViolations = validator.validate(invalidKey); + Set> constraintViolations = validator.validate(invalidKey); assertThat(constraintViolations, hasSize(1)); - } @Test public void missingPrivateKeyFails() throws Exception { + MultipleJGitEnvironmentProperties missingKey = new MultipleJGitEnvironmentProperties(); + missingKey.setUri(SSH_URI); + missingKey.setIgnoreLocalSshSettings(true); - SshUriProperties missingKey = SshUri.builder() - .uri(SSH_URI) - .ignoreLocalSshSettings(true) - .build(); - - Set> constraintViolations = validator.validate(missingKey); + Set> constraintViolations = validator.validate(missingKey); assertThat(constraintViolations, hasSize(1)); } @Test public void hostKeyWithMissingAlgoFails() throws Exception { + MultipleJGitEnvironmentProperties missingAlgo = new MultipleJGitEnvironmentProperties(); + missingAlgo.setUri(SSH_URI); + missingAlgo.setIgnoreLocalSshSettings(true); + missingAlgo.setPrivateKey(VALID_PRIVATE_KEY); + missingAlgo.setHostKey("some_host"); - SshUriProperties missingAlgo = SshUri.builder() - .uri(SSH_URI) - .ignoreLocalSshSettings(true) - .privateKey(VALID_PRIVATE_KEY) - .hostKey("some_host") - .build(); - - Set> constraintViolations = validator.validate(missingAlgo); + Set> constraintViolations = validator.validate(missingAlgo); assertThat(constraintViolations, hasSize(1)); } @Test public void algoWithMissingHostKeyFails() throws Exception { + MultipleJGitEnvironmentProperties missingHostKey = new MultipleJGitEnvironmentProperties(); + missingHostKey.setUri(SSH_URI); + missingHostKey.setIgnoreLocalSshSettings(true); + missingHostKey.setPrivateKey(VALID_PRIVATE_KEY); + missingHostKey.setHostKeyAlgorithm("ssh-rsa"); - SshUriProperties missingHostKey = SshUri.builder() - .uri(SSH_URI) - .ignoreLocalSshSettings(true) - .privateKey(VALID_PRIVATE_KEY) - .hostKeyAlgorithm("ssh-rsa") - .build(); - - Set> constraintViolations = validator.validate(missingHostKey); + Set> constraintViolations = validator.validate(missingHostKey); assertThat(constraintViolations, hasSize(1)); } @Test public void unsupportedAlgoFails() throws Exception { + MultipleJGitEnvironmentProperties unsupportedAlgo = new MultipleJGitEnvironmentProperties(); + unsupportedAlgo.setUri(SSH_URI); + unsupportedAlgo.setIgnoreLocalSshSettings(true); + unsupportedAlgo.setPrivateKey(VALID_PRIVATE_KEY); + unsupportedAlgo.setHostKey("some_host_key"); + unsupportedAlgo.setHostKeyAlgorithm("unsupported"); - SshUriProperties unsupportedAlgo = SshUri.builder() - .uri(SSH_URI) - .ignoreLocalSshSettings(true) - .privateKey(VALID_PRIVATE_KEY) - .hostKey("some_host_key") - .hostKeyAlgorithm("unsupported") - .build(); - - Set> constraintViolations = validator.validate(unsupportedAlgo); + Set> constraintViolations = validator.validate(unsupportedAlgo); assertThat(constraintViolations, hasSize(1)); } @Test public void validatorNotRunIfIgnoreLocalSettingsFalse() throws Exception { + MultipleJGitEnvironmentProperties useLocal = new MultipleJGitEnvironmentProperties(); + useLocal.setUri(SSH_URI); + useLocal.setIgnoreLocalSshSettings(false); + useLocal.setPrivateKey("invalid_key"); - SshUriProperties useLocal = (SshUri.builder() - .uri(SSH_URI) - .ignoreLocalSshSettings(false) - .privateKey("invalid_key") - .build()); - - Set> constraintViolations = validator.validate(useLocal); + Set> constraintViolations = validator.validate(useLocal); assertThat(constraintViolations, hasSize(0)); } @Test public void validatorNotRunIfHttpsUri() throws Exception { + MultipleJGitEnvironmentProperties httpsUri = new MultipleJGitEnvironmentProperties(); + httpsUri.setUri("https://somerepo.com/team/project.git"); + httpsUri.setIgnoreLocalSshSettings(true); + httpsUri.setPrivateKey("invalid_key"); - SshUriProperties httpsUri = (SshUri.builder() - .uri("https://somerepo.com/team/project.git") - .ignoreLocalSshSettings(true) - .privateKey("invalid_key") - .build()); - - Set> constraintViolations = validator.validate(httpsUri); + Set> constraintViolations = validator.validate(httpsUri); assertThat(constraintViolations, hasSize(0)); } @Test public void preferredAuthenticationsIsValidated() throws Exception { - SshUriProperties sshUriProperties = new SshUriProperties(); + MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties(); assertThat(validator.validate(sshUriProperties), hasSize(0)); sshUriProperties.setPreferredAuthentications("keyboard-interactive, public-key ,kerberos"); @@ -200,7 +185,7 @@ public class SshPropertyValidatorTest { @Test public void knowHostsFileIsValidated() throws Exception { - SshUriProperties sshUriProperties = new SshUriProperties(); + MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties(); assertThat(validator.validate(sshUriProperties), hasSize(0)); sshUriProperties.setKnownHostsFile("non-existing.file"); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java index 8f7fd49a..c1cb8e22 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015 - 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. @@ -18,13 +18,19 @@ package org.springframework.cloud.config.server.ssh; import java.util.Map; + import org.eclipse.jgit.transport.SshSessionFactory; import org.junit.After; import org.junit.Test; -import org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriNestedRepoProperties; +import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties; +import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; /** @@ -54,43 +60,45 @@ public class SshUriPropertyProcessorTest { @Test public void testSingleSshUriProperties() { SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(mainRepoPropertiesFixture()); - Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); + Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); assertThat(sshKeysByHostname.values(), hasSize(1)); - SshUri sshKey = sshKeysByHostname.get(HOST1); + JGitEnvironmentProperties sshKey = sshKeysByHostname.get(HOST1); assertMainRepo(sshKey); } @Test public void testMultipleSshUriPropertiess() { - SshUriProperties sshUriProperties = mainRepoPropertiesFixture(); - addRepoProperties(sshUriProperties, SshUri.builder() - .uri(URI2) - .privateKey(PRIVATE_KEY2) - .buildAsNestedRepo(), "repo2"); - addRepoProperties(sshUriProperties, SshUri.builder() - .uri(URI3) - .privateKey(PRIVATE_KEY3) - .buildAsNestedRepo(), "repo3"); + MultipleJGitEnvironmentProperties sshUriProperties = mainRepoPropertiesFixture(); + MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties nestedSshUriProperties1 = + new MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties(); + nestedSshUriProperties1.setUri(URI2); + nestedSshUriProperties1.setPrivateKey(PRIVATE_KEY2); + MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties nestedSshUriProperties2 = + new MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties(); + nestedSshUriProperties2.setUri(URI3); + nestedSshUriProperties2.setPrivateKey(PRIVATE_KEY3); + addRepoProperties(sshUriProperties, nestedSshUriProperties1, "repo2"); + addRepoProperties(sshUriProperties, nestedSshUriProperties2, "repo3"); SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties); - Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); + Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); assertThat(sshKeysByHostname.values(), hasSize(3)); - SshUri sshKey1 = sshKeysByHostname.get(HOST1); + JGitEnvironmentProperties sshKey1 = sshKeysByHostname.get(HOST1); assertMainRepo(sshKey1); - SshUri sshKey2 = sshKeysByHostname.get(HOST2); + JGitEnvironmentProperties sshKey2 = sshKeysByHostname.get(HOST2); assertThat(SshUriPropertyProcessor.getHostname(sshKey2.getUri()), is(equalTo(HOST2))); assertThat(sshKey2.getHostKeyAlgorithm(), is(nullValue())); assertThat(sshKey2.getHostKey(), is(nullValue())); assertThat(sshKey2.getPrivateKey(), is(equalTo(PRIVATE_KEY2))); - SshUri sshKey3 = sshKeysByHostname.get(HOST3); + JGitEnvironmentProperties sshKey3 = sshKeysByHostname.get(HOST3); assertThat(SshUriPropertyProcessor.getHostname(sshKey3.getUri()), is(equalTo(HOST3))); assertThat(sshKey3.getHostKeyAlgorithm(), is(nullValue())); @@ -100,58 +108,62 @@ public class SshUriPropertyProcessorTest { @Test public void testSameHostnameDifferentKeysFirstOneWins() { - SshUriProperties sshUriProperties = mainRepoPropertiesFixture(); - addRepoProperties(sshUriProperties, SshUri.builder().uri(URI1) - .privateKey(PRIVATE_KEY1) - .hostKey(HOST_KEY1) - .hostKeyAlgorithm(ALGO1) - .buildAsNestedRepo(), "repo2"); + MultipleJGitEnvironmentProperties sshUriProperties = mainRepoPropertiesFixture(); + MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties nestedSshUriProperties = new MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties(); + nestedSshUriProperties.setUri(URI1); + nestedSshUriProperties.setPrivateKey(PRIVATE_KEY1); + nestedSshUriProperties.setHostKey(HOST_KEY1); + nestedSshUriProperties.setHostKeyAlgorithm(ALGO1); + addRepoProperties(sshUriProperties, nestedSshUriProperties, "repo2"); SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties); - Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); + Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); assertThat(sshKeysByHostname.values(), hasSize(1)); - SshUri sshKey = sshKeysByHostname.get(HOST1); + JGitEnvironmentProperties sshKey = sshKeysByHostname.get(HOST1); assertMainRepo(sshKey); } @Test public void testNoSshUriProperties() { - SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(new SshUriProperties()); - Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); + SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(new MultipleJGitEnvironmentProperties()); + Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); assertThat(sshKeysByHostname.values(), hasSize(0)); } @Test public void testInvalidUriDoesNotAddEntry() { - SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(SshUri.builder().uri("invalid_uri").build()); - Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); + MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties(); + sshUriProperties.setUri("invalid_uri"); + SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties); + Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); assertThat(sshKeysByHostname.values(), hasSize(0)); } @Test public void testHttpsUriDoesNotAddEntry() { - SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(SshUri.builder().uri("https://user@github.com/proj/repo.git").build()); - Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); + MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties(); + sshUriProperties.setUri("https://user@github.com/proj/repo.git"); + SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties); + Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname(); assertThat(sshKeysByHostname.values(), hasSize(0)); } - private SshUriProperties mainRepoPropertiesFixture() { - - return SshUri.builder() - .uri(URI1) - .hostKeyAlgorithm(ALGO1) - .hostKey(HOST_KEY1) - .privateKey(PRIVATE_KEY1) - .build(); + private MultipleJGitEnvironmentProperties mainRepoPropertiesFixture() { + MultipleJGitEnvironmentProperties result = new MultipleJGitEnvironmentProperties(); + result.setUri(URI1); + result.setHostKeyAlgorithm(ALGO1); + result.setHostKey(HOST_KEY1); + result.setPrivateKey(PRIVATE_KEY1); + return result; } - private void addRepoProperties(SshUriProperties mainRepoProperties, SshUriNestedRepoProperties repoProperties, String repoName) { - mainRepoProperties.addRepo(repoName, repoProperties); + private void addRepoProperties(MultipleJGitEnvironmentProperties mainRepoProperties, MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties repoProperties, String repoName) { + mainRepoProperties.getRepos().put(repoName, repoProperties); } - private void assertMainRepo(SshUri sshKey) { + private void assertMainRepo(JGitEnvironmentProperties sshKey) { assertThat(sshKey, is(notNullValue())); assertThat(SshUriPropertyProcessor.getHostname(sshKey.getUri()), is(equalTo(HOST1))); assertThat(sshKey.getHostKeyAlgorithm(), is(equalTo(ALGO1))); diff --git a/spring-cloud-config-server/src/test/resources/ssh/ssh-nested-settings-list.yml b/spring-cloud-config-server/src/test/resources/ssh/ssh-nested-settings-list.yml new file mode 100644 index 00000000..c265f489 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/ssh/ssh-nested-settings-list.yml @@ -0,0 +1,42 @@ +spring: + cloud: + config: + server: + composite: + - type: git + uri: git@gitserver.com:team/repo1.git + ignoreLocalSshSettings: true + privateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAoqyz6YaYMTr7L8GLPSQpAQXaM04gRx4CCsGK2kfLQdw4BlqI\nyyxp38YcuZG9cUDBAxby+K2TKmwHaC1R61QTwbPuCRdIPrDwRz+FLoegm3iDLCmn\nuP6rjZDneYsqfU1KSdrOwIbCnONfDdvYL/vnZC/o8DDMlk5Orw2SfHkT3pq0o8km\nayBwN4Sf3bpyWTY0oZcmNeSCCoIdE59k8Pa7/t9bwY9caLj05C3DEsjucc7Ei/Eq\nTOyGyobtXwaya5CqKLUHes74Poz1aEP/yVFdUud91uezd8ZK1P1t5/ZKA3R6aHir\n+diDJ2/GQ2tD511FW46yw+EtBUJTO6ADVv4UnQIDAQABAoIBAF+5qwEfX82QfKFk\njfADqFFexUDtl1biFKeJrpC2MKhn01wByH9uejrhFKQqW8UaKroLthyZ34DWIyGt\nlDnHGv0gSVF2LuAdNLdobJGt49e4+c9yD61vxzm97Eh8mRs08SM2q/VlF35E2fmI\nxdWusUImYzd8L9e+6tRd8zZl9UhG5vR5XIstKqxC6S0g79aAt0hasE4Gw1FKOf2V\n4mlL15atjQSKCPdOicuyc4zpjAtU1A9AfF51iG8oOUuJebPW8tCftfOQxaeGFgMG\n7M9aai1KzXR6M5IBAKEv31yBvz/SHTneP7oZXNLeC1GIR420PKybmeZdNK8BbEAu\n3reKgm0CgYEA03Sx8JoF5UBsIvFPpP1fjSlTgKryM5EJR6KQtj5e4YfyxccJepN8\nq4MrqDfNKleG/a1acEtDMhBNovU7Usp2QIP7zpAeioHBOhmE5WSieZGc3icOGWWq\nmRkdulSONruqWKv76ZoluxftekE03bDhZDNlcCgmrslEKB/ufHd2oc8CgYEAxPFa\nlKOdSeiYFV5CtvO8Ro8em6rGpSsVz4qkPxbeBqUDCb9KXHhq6YrhRxOIfQJKfT7M\nZFCn8ArJXKgOGu+KsvwIErFHF9g2jJMG4DOUTpkQgi2yveihFxcmz/AltyVXgrnv\nZWQbAerH77pdKKhNivLGgEv72GYawdYjYNjemdMCgYA2kEMmMahZyrDcp2YEzfit\nBT/t0K6kzcUWPgWXcSqsiZcEn+J7RbmCzFskkhmX1nQX23adyV3yejB+X0dKisHO\nzf/ZAmlPFkJVCqa3RquCMSfIT02dEhXeYZPBM/Zqeyxuqxpa4hLgX0FBLbhFiFHw\nuC5xrXql2XuD2xF//peXEwKBgQC+pa28Cg7vRxxCQzduB9CQtWc55j3aEjVQ7bNF\n54sS/5ZLT0Ra8677WZfuyDfuW9NkHvCZg4Ku2qJG8eCFrrGjxlrCTZ62tHVJ6+JS\nE1xUIdRbUIWhVZrr0VufG6hG/P0T7Y6Tpi6G0pKtvMkF3LcD9TS3adboix8H2ZXx\n4L7MRQKBgQC0OO3qqNXOjIVYWOoqXLybOY/Wqu9lxCAgGyCYaMcstnBI7W0MZTBr\n/syluvGsaFc1sE7MMGOOzKi1tF4YvDmSnzA/R1nmaPguuD9fOA+w7Pwkv5vLvuJq\n2U7EeNwxq1I1L3Ag6E7wH4BHLHd4TKaZR6agFkn8oomz71yZPGjuZQ==\n-----END RSA PRIVATE KEY-----" + repos: + repo1: + uri: git@gitserver.com:team/repo2.git + hostKey: someHostKey + hostKeyAlgorithm: ssh-rsa + privateKey: | + -----BEGIN RSA PRIVATE KEY----- + MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX + IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF + ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud + 1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i + oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W + DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd + fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b + BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG + EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj + 5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8 + +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe + pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG + ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ + xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW + dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi + PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX + VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z + FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R + gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4 + VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV + cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee + KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N + CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs + q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J + 69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT + -----END RSA PRIVATE KEY----- diff --git a/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-block-list.yml b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-block-list.yml new file mode 100644 index 00000000..90bb2009 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-block-list.yml @@ -0,0 +1,36 @@ +spring: + cloud: + config: + server: + composite: + - type: git + uri: git@gitserver.com:team/repo.git + ignoreLocalSshSettings: true + privateKey: | + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAoqyz6YaYMTr7L8GLPSQpAQXaM04gRx4CCsGK2kfLQdw4BlqI + yyxp38YcuZG9cUDBAxby+K2TKmwHaC1Wf1QTwbPuCRdIPrDwRz+FLoegm3iDLCmn + uP6rjZDneYsqfU1sSdrOwIbCnONfDdvYL/vnZC/o8DDMlk5Orw2SfHkT3pq0o8km + ayBwN4Sf3bpyWTY0oZcmNeSCCoIdE59k8Pa7/t9bwY9caLj05C3DEsjucc7Ei/Eq + TOyGyobtXwaya5CqKLUHes74Poz1aEP/yVFdUud91uezd8ZK1P1t5/ZKA3R6aHir + +diDJ2/GQ2tD511FW46yw+EtBUJTO6ADVv4UnQIDAQABAoIBAF+5qwEfX82QfKFk + jfADqFFexUDtl1biFKeJrpC2MKhn01wByH9uejrhFKQqW8UaKroLthyZ34DWIyGt + lDnHGv0gSVF2LuAdNLdobJGt49e4+c9yD61vxzm97Eh8mRs08SM2q/VlF35E2fmI + xdWusUImYzd8L9e+6tRd8zZl9UhG5vR5XIstKqxC6S0g79aAt0hasE4Gw1FKOf2V + 4mlL15atjQSKCPdOicuyc4zpjAtU1A9AfF51iG8oOUuJebPW8tCftfOQxaeGFgMG + 7M9aai1KzXR6M5IBAKEv31yBvz/SHTneP7oZXNLeC1GIR420PKybmeZdNK8BbEAu + 3reKgm0CgYEA03Sx8JgF5UBsIvFPpP1fjSlTgKryM5EJR6KQtj5e4YfyxccJepN8 + q4MrqDfNKleG/a1acEtDMhBNovU7Usp2QIP7zpAeioHBOhmE5WSieZGc3icOGWWq + mRkdulSONruqWKv76ZoluxftekE03bDhZDNlcCgmrslEKB/ufHd2oc8CgYEAxPFa + lKOdSeiYFV5CtvO8Ro8em6rGpSsVz4qkPxbeBqUDCb9KXHhq6YrhRxOIfQJKfT7M + ZFCn8ArJXKgOGu+KsvwIErFHF9g2jJMG4DOUTpkQgi2yveihFxcmz/AltyVXgrnv + ZWQbAerH77pdKKhNivLGgEv72GYawdYjYNjemdMCgYA2kEMmMahZyrDcp2YEzfit + BT/t0K6kzcUWPgWXcSqsiZcEn+J7RbmCzFskkhmX1nQX23adyV3yejB+X0dKisHO + zf/ZAmlPFkJVCqa3RquCMSfIT02dEhXeYZPBM/Zqeyxuqxpa4hLgX0FBLbhFiFHw + uC5xrXql2XuD2xF//peXEwKBgQC+pa28Cg7vRxxCQzduB9CQtWc55j3aEjVQ7bNF + 54sS/5ZLT0Ra8677WZfuyDfuW9NkHvCZg4Ku2qJG8eCFrrGjxlrCTZ62tHVJ6+JS + E1xUIdRbUIWhVZrr0VufG6hG/P0T7Y6Tpi6G0pKtvMkF3LcD9TS3adboix8H2ZXx + 4L7MRQKBgQC0OO3qqNXOjIVYWOoqXLybOY/Wqu9lxCAgGyCYaMcstnBI7W0MZTBr + /syluvGsaFc1sE7MMGOOzKi1tF4YvDmSnzA/R1nmaPguuD9fOA+w7Pwkv5vLvuJq + 2U7EeNwxq1I1L3Ag6E7wH4BHLHd4TKaZR6agFkn8oomz71yZPGjuZQ== + -----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-newline-list.yml b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-newline-list.yml new file mode 100644 index 00000000..2fe26da9 --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-newline-list.yml @@ -0,0 +1,11 @@ +spring: + cloud: + config: + server: + composite: + - type: git + uri: git@gitserver.com:team/repo.git + ignoreLocalSshSettings: true + privateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAoqyz6YaYMTr7L8GLPSQpAQXaM04gRx4CCsGK2kfLQdw4BlqI\nyyxp38YcuZG9cUDBAxby+K2TKmwHaC1R61QTwbPuCRdIPrDwRz+FLoegm3iDLCmn\nuP6rjZDneYsqfU1KSdrOwIbCnONfDdvYL/vnZC/o8DDMlk5Orw2SfHkT3pq0o8km\nayBwN4Sf3bpyWTY0oZcmNeSCCoIdE59k8Pa7/t9bwY9caLj05C3DEsjucc7Ei/Eq\nTOyGyobtXwaya5CqKLUHes74Poz1aEP/yVFdUud91uezd8ZK1P1t5/ZKA3R6aHir\n+diDJ2/GQ2tD511FW46yw+EtBUJTO6ADVv4UnQIDAQABAoIBAF+5qwEfX82QfKFk\njfADqFFexUDtl1biFKeJrpC2MKhn01wByH9uejrhFKQqW8UaKroLthyZ34DWIyGt\nlDnHGv0gSVF2LuAdNLdobJGt49e4+c9yD61vxzm97Eh8mRs08SM2q/VlF35E2fmI\nxdWusUImYzd8L9e+6tRd8zZl9UhG5vR5XIstKqxC6S0g79aAt0hasE4Gw1FKOf2V\n4mlL15atjQSKCPdOicuyc4zpjAtU1A9AfF51iG8oOUuJebPW8tCftfOQxaeGFgMG\n7M9aai1KzXR6M5IBAKEv31yBvz/SHTneP7oZXNLeC1GIR420PKybmeZdNK8BbEAu\n3reKgm0CgYEA03Sx8JoF5UBsIvFPpP1fjSlTgKryM5EJR6KQtj5e4YfyxccJepN8\nq4MrqDfNKleG/a1acEtDMhBNovU7Usp2QIP7zpAeioHBOhmE5WSieZGc3icOGWWq\nmRkdulSONruqWKv76ZoluxftekE03bDhZDNlcCgmrslEKB/ufHd2oc8CgYEAxPFa\nlKOdSeiYFV5CtvO8Ro8em6rGpSsVz4qkPxbeBqUDCb9KXHhq6YrhRxOIfQJKfT7M\nZFCn8ArJXKgOGu+KsvwIErFHF9g2jJMG4DOUTpkQgi2yveihFxcmz/AltyVXgrnv\nZWQbAerH77pdKKhNivLGgEv72GYawdYjYNjemdMCgYA2kEMmMahZyrDcp2YEzfit\nBT/t0K6kzcUWPgWXcSqsiZcEn+J7RbmCzFskkhmX1nQX23adyV3yejB+X0dKisHO\nzf/ZAmlPFkJVCqa3RquCMSfIT02dEhXeYZPBM/Zqeyxuqxpa4hLgX0FBLbhFiFHw\nuC5xrXql2XuD2xF//peXEwKBgQC+pa28Cg7vRxxCQzduB9CQtWc55j3aEjVQ7bNF\n54sS/5ZLT0Ra8677WZfuyDfuW9NkHvCZg4Ku2qJG8eCFrrGjxlrCTZ62tHVJ6+JS\nE1xUIdRbUIWhVZrr0VufG6hG/P0T7Y6Tpi6G0pKtvMkF3LcD9TS3adboix8H2ZXx\n4L7MRQKBgQC0OO3qqNXOjIVYWOoqXLybOY/Wqu9lxCAgGyCYaMcstnBI7W0MZTBr\n/syluvGsaFc1sE7MMGOOzKi1tF4YvDmSnzA/R1nmaPguuD9fOA+w7Pwkv5vLvuJq\n2U7EeNwxq1I1L3Ag6E7wH4BHLHd4TKaZR6agFkn8oomz71yZPGjuZQ==\n-----END RSA PRIVATE KEY-----" + hostKey: somekey + hostKeyAlgorithm: ssh-rsa