GitCredentialsProviderFactory.java
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.config.server.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.springframework.util.ClassUtils;
import static org.springframework.util.StringUtils.hasText;
/**
* A CredentialsProvider factory for Git repositories. Can handle AWS CodeCommit
* repositories and other repositories with username/password.
*
* @author Don Laidlaw
* @author Gareth Clay
*
*/
public class GitCredentialsProviderFactory {
protected Log logger = LogFactory.getLog(getClass());
/**
* Enable the AWS Code Commit credentials provider for Git URI's that match the AWS
* Code Commit pattern of
* https://git-codecommit.${AWS_REGION}.amazonaws.com/${repoPath}. Enabled by default.
*/
protected boolean awsCodeCommitEnabled = true;
/**
* Search for a credential provider that will handle the specified URI. If not found,
* and the username or passphrase has text, then create a default using the provided
* username and password or passphrase. Otherwise null.
* @param uri the URI of the repository (cannot be null)
* @param username the username provided for the repository (may be null)
* @param password the password provided for the repository (may be null)
* @param passphrase the passphrase to unlock the ssh private key (may be null)
* @return the first matched credentials provider or the default or null.
* @deprecated in favour of
* {@link #createFor(String, String, String, String, boolean)}
*/
@Deprecated
public CredentialsProvider createFor(String uri, String username, String password, String passphrase) {
return createFor(uri, username, password, passphrase, false);
}
/**
* Search for a credential provider that will handle the specified URI. If not found,
* and the username or passphrase has text, then create a default using the provided
* username and password or passphrase.
*
* If skipSslValidation is true and the URI has an https scheme, the default
* credential provider's behaviour is modified to suppress any SSL validation errors
* that occur when communicating via the URI.
*
* Otherwise null.
* @param uri the URI of the repository (cannot be null)
* @param username the username provided for the repository (may be null)
* @param password the password provided for the repository (may be null)
* @param passphrase the passphrase to unlock the ssh private key (may be null)
* @param skipSslValidation whether to skip SSL validation when connecting via HTTPS
* @return the first matched credentials provider or the default or null.
*/
public CredentialsProvider createFor(String uri, String username, String password, String passphrase,
boolean skipSslValidation) {
CredentialsProvider provider = null;
if (awsAvailable() && AwsCodeCommitCredentialProvider.canHandle(uri)) {
this.logger.debug("Constructing AwsCodeCommitCredentialProvider for URI " + uri);
AwsCodeCommitCredentialProvider aws = new AwsCodeCommitCredentialProvider();
aws.setUsername(username);
aws.setPassword(password);
provider = aws;
}
else if (hasText(username)) {
this.logger.debug("Constructing UsernamePasswordCredentialsProvider for URI " + uri);
provider = new UsernamePasswordCredentialsProvider(username, password.toCharArray());
}
else if (hasText(username) && !hasText(passphrase)) {
// useful for token based login gh-1602
// see
// https://stackoverflow.com/questions/28073266/how-to-use-jgit-to-push-changes-to-remote-with-oauth-access-token
this.logger.debug("Constructing UsernamePasswordCredentialsProvider for URI " + uri);
provider = new UsernamePasswordCredentialsProvider(username, (String) null);
}
else if (hasText(passphrase)) {
this.logger.debug("Constructing PassphraseCredentialsProvider for URI " + uri);
provider = new PassphraseCredentialsProvider(passphrase);
}
if (skipSslValidation && GitSkipSslValidationCredentialsProvider.canHandle(uri)) {
this.logger.debug("Constructing GitSkipSslValidationCredentialsProvider for URI " + uri);
provider = new GitSkipSslValidationCredentialsProvider(provider);
}
if (provider == null) {
this.logger.debug("No credentials provider required for URI " + uri);
}
return provider;
}
/**
* Check to see if the AWS Authentication API is available.
* @return true if the com.amazonaws.auth.DefaultAWSCredentialsProviderChain is
* present, false otherwise.
*/
private boolean awsAvailable() {
return this.awsCodeCommitEnabled
&& ClassUtils.isPresent("software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain", null);
}
/**
* @return the awsCodeCommitEnabled
*/
public boolean isAwsCodeCommitEnabled() {
return this.awsCodeCommitEnabled;
}
/**
* @param awsCodeCommitEnabled the awsCodeCommitEnabled to set
*/
public void setAwsCodeCommitEnabled(boolean awsCodeCommitEnabled) {
this.awsCodeCommitEnabled = awsCodeCommitEnabled;
}
}