Proxy support for pull, push and mirror commands (#1773)

Apply proxy support for jGit by extracting the required functionality from the DefaultAdvancedHttpClient into its own class HttpURLConnectionFactory. This new class is now used by the DefaultAdvancedHttpClient and jGit.
The HttpURLConnection also fixes proxy server authentication, which was non functional in DefaultAdvancedHttpClient.
The proxy support for SVNKit is implemented by using the provided method of the BasicAuthenticationManager.
For mercurial the support is configured by writing the required settings to a temporary hgrc file.
This commit is contained in:
Sebastian Sdorra
2021-08-19 11:27:51 +02:00
committed by GitHub
parent a7bb67f36b
commit 7f9f4e566c
54 changed files with 2996 additions and 1098 deletions

View File

@@ -32,10 +32,15 @@ import org.mockito.junit.MockitoJUnitRunner;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.auth.SVNAuthentication;
import org.tmatesoft.svn.core.auth.SVNPasswordAuthentication;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import org.tmatesoft.svn.core.wc.admin.SVNAdminClient;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.net.GlobalProxyConfiguration;
import sonia.scm.net.ProxyConfiguration;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.repository.api.MirrorCommandResult;
import sonia.scm.repository.api.SimpleUsernamePasswordCredential;
@@ -45,8 +50,11 @@ import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static sonia.scm.repository.api.MirrorCommandResult.ResultType.OK;
@RunWith(MockitoJUnitRunner.class)
@@ -57,6 +65,8 @@ public class SvnMirrorCommandTest extends AbstractSvnCommandTestBase {
private SvnContext emptyContext;
private final ScmConfiguration configuration = new ScmConfiguration();
@Before
public void bendContextToNewRepository() throws IOException, SVNException {
emptyContext = createEmptyContext();
@@ -91,10 +101,119 @@ public class SvnMirrorCommandTest extends AbstractSvnCommandTestBase {
}
@Test
public void shouldUseCredentials() {
MirrorCommandResult result = callMirror(emptyContext, repositoryDirectory, createCredential("svnadmin", "secret"));
public void shouldUseCredentials() throws SVNException {
SVNURL url = SVNURL.parseURIEncoded("https://svn.hitchhiker.com");
assertThat(result.getResult()).isEqualTo(OK);
MirrorCommandRequest request = new MirrorCommandRequest();
request.setCredentials(
singletonList(new SimpleUsernamePasswordCredential("trillian", "secret".toCharArray()))
);
SvnMirrorCommand mirrorCommand = createMirrorCommand(emptyContext);
BasicAuthenticationManager authenticationManager = mirrorCommand.createAuthenticationManager(url, request);
SVNAuthentication authentication = authenticationManager.getFirstAuthentication(
ISVNAuthenticationManager.PASSWORD, "Hitchhiker Auth Gate", url
);
assertThat(authentication).isInstanceOfSatisfying(SVNPasswordAuthentication.class, passwordAuth -> {
assertThat(passwordAuth.getUserName()).isEqualTo("trillian");
assertThat(passwordAuth.getPasswordValue()).isEqualTo("secret".toCharArray());
});
}
@Test
public void shouldUseTrustManager() throws SVNException {
SVNURL url = SVNURL.parseURIEncoded("https://svn.hitchhiker.com");
SvnMirrorCommand mirrorCommand = createMirrorCommand(emptyContext);
BasicAuthenticationManager authenticationManager = mirrorCommand.createAuthenticationManager(url, new MirrorCommandRequest());
assertThat(authenticationManager.getTrustManager(url)).isSameAs(trustManager);
}
@Test
public void shouldApplySimpleProxySettings() throws SVNException {
configuration.setEnableProxy(true);
configuration.setProxyServer("proxy.hitchhiker.com");
configuration.setProxyPort(3128);
BasicAuthenticationManager authenticationManager = createAuthenticationManager();
assertThat(authenticationManager.getProxyHost()).isEqualTo("proxy.hitchhiker.com");
assertThat(authenticationManager.getProxyPort()).isEqualTo(3128);
assertThat(authenticationManager.getProxyUserName()).isNull();
assertThat(authenticationManager.getProxyPasswordValue()).isNull();
}
@Test
public void shouldApplyProxySettingsWithCredentials() throws SVNException {
configuration.setEnableProxy(true);
configuration.setProxyServer("proxy.hitchhiker.com");
configuration.setProxyPort(3128);
configuration.setProxyUser("trillian");
configuration.setProxyPassword("secret");
BasicAuthenticationManager authenticationManager = createAuthenticationManager();
assertThat(authenticationManager.getProxyHost()).isEqualTo("proxy.hitchhiker.com");
assertThat(authenticationManager.getProxyPort()).isEqualTo(3128);
assertThat(authenticationManager.getProxyUserName()).isEqualTo("trillian");
assertThat(authenticationManager.getProxyPasswordValue()).isEqualTo("secret".toCharArray());
}
@Test
public void shouldSkipProxySettingsIfDisabled() throws SVNException {
configuration.setEnableProxy(false);
configuration.setProxyServer("proxy.hitchhiker.com");
configuration.setProxyPort(3128);
BasicAuthenticationManager authenticationManager = createAuthenticationManager();
assertThat(authenticationManager.getProxyHost()).isNull();
}
@Test
public void shouldSkipProxySettingsIfHostIsOnExcludeList() throws SVNException {
configuration.setEnableProxy(true);
configuration.setProxyServer("proxy.hitchhiker.com");
configuration.setProxyPort(3128);
configuration.setProxyExcludes(singleton("svn.hitchhiker.com"));
BasicAuthenticationManager authenticationManager = createAuthenticationManager();
assertThat(authenticationManager.getProxyHost()).isNull();
}
@Test
public void shouldApplyLocalProxySettings() throws SVNException {
MirrorCommandRequest request = new MirrorCommandRequest();
request.setProxyConfiguration(createProxyConfiguration());
BasicAuthenticationManager authenticationManager = createAuthenticationManager(request);
assertThat(authenticationManager.getProxyHost()).isEqualTo("proxy.hitchhiker.com");
assertThat(authenticationManager.getProxyPort()).isEqualTo(3128);
assertThat(authenticationManager.getProxyUserName()).isNull();
assertThat(authenticationManager.getProxyPasswordValue()).isNull();
}
private ProxyConfiguration createProxyConfiguration() {
ProxyConfiguration configuration = mock(ProxyConfiguration.class);
when(configuration.isEnabled()).thenReturn(true);
when(configuration.getHost()).thenReturn("proxy.hitchhiker.com");
when(configuration.getPort()).thenReturn(3128);
return configuration;
}
private BasicAuthenticationManager createAuthenticationManager() throws SVNException {
return createAuthenticationManager(new MirrorCommandRequest());
}
private BasicAuthenticationManager createAuthenticationManager(MirrorCommandRequest request) throws SVNException {
SVNURL url = SVNURL.parseURIEncoded("https://svn.hitchhiker.com");
SvnMirrorCommand mirrorCommand = createMirrorCommand(emptyContext);
return mirrorCommand.createAuthenticationManager(url, request);
}
private MirrorCommandResult callMirrorUpdate(SvnContext context, File source) {
@@ -115,11 +234,7 @@ public class SvnMirrorCommandTest extends AbstractSvnCommandTestBase {
}
private SvnMirrorCommand createMirrorCommand(SvnContext context) {
return new SvnMirrorCommand(context, trustManager);
}
private Consumer<MirrorCommandRequest> createCredential(String username, String password) {
return request -> request.setCredentials(singletonList(new SimpleUsernamePasswordCredential(username, password.toCharArray())));
return new SvnMirrorCommand(context, trustManager, new GlobalProxyConfiguration(configuration));
}
private SvnContext createEmptyContext() throws SVNException, IOException {