diff --git a/pom.xml b/pom.xml index 790eaddc7..94cf80a60 100644 --- a/pom.xml +++ b/pom.xml @@ -206,7 +206,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.2.0 + 3.3.0 8 true @@ -436,7 +436,7 @@ com.infradna.tool bridge-method-annotation - 1.18 + 1.21 true @@ -525,7 +525,7 @@ org.mockito mockito-core - 3.9.0 + 3.10.0 test @@ -537,7 +537,7 @@ com.github.tomakehurst wiremock-jre8-standalone - 2.27.2 + 2.28.0 test diff --git a/src/main/java/org/kohsuke/github/GitHubBuilder.java b/src/main/java/org/kohsuke/github/GitHubBuilder.java index 94ba46a0e..80960b979 100644 --- a/src/main/java/org/kohsuke/github/GitHubBuilder.java +++ b/src/main/java/org/kohsuke/github/GitHubBuilder.java @@ -24,6 +24,9 @@ import javax.annotation.Nonnull; */ public class GitHubBuilder implements Cloneable { + // for testing + static File HOME_DIRECTORY = null; + // default scoped so unit tests can read them. /* private */ String endpoint = GitHubClient.GITHUB_URL; @@ -60,13 +63,13 @@ public class GitHubBuilder implements Cloneable { builder = fromEnvironment(); - if (builder.authorizationProvider != null) + if (builder.authorizationProvider != AuthorizationProvider.ANONYMOUS) return builder; try { builder = fromPropertyFile(); - if (builder.authorizationProvider != null) + if (builder.authorizationProvider != AuthorizationProvider.ANONYMOUS) return builder; } catch (FileNotFoundException e) { // fall through @@ -178,7 +181,7 @@ public class GitHubBuilder implements Cloneable { * the io exception */ public static GitHubBuilder fromPropertyFile() throws IOException { - File homeDir = new File(System.getProperty("user.home")); + File homeDir = HOME_DIRECTORY != null ? HOME_DIRECTORY : new File(System.getProperty("user.home")); File propertyFile = new File(homeDir, ".github"); return fromPropertyFile(propertyFile.getPath()); } diff --git a/src/test/java/org/kohsuke/github/GitHubConnectionTest.java b/src/test/java/org/kohsuke/github/GitHubConnectionTest.java index 852b64e39..5e96cc280 100644 --- a/src/test/java/org/kohsuke/github/GitHubConnectionTest.java +++ b/src/test/java/org/kohsuke/github/GitHubConnectionTest.java @@ -1,14 +1,19 @@ package org.kohsuke.github; +import org.apache.commons.lang3.SystemUtils; import org.junit.Assume; import org.junit.Test; +import org.kohsuke.github.authorization.AuthorizationProvider; import org.kohsuke.github.authorization.UserAuthorizationProvider; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Properties; import static org.hamcrest.Matchers.*; @@ -137,6 +142,147 @@ public class GitHubConnectionTest extends AbstractGitHubWireMockTest { assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); } + @Test + public void testGitHubBuilderFromCredentialsWithEnvironment() throws IOException { + // we disable this test for JDK 16+ as the current hacks in setupEnvironment() don't work with JDK 16+ + Assume.assumeThat(Double.valueOf(System.getProperty("java.specification.version")), lessThan(16.0)); + Assume.assumeFalse(SystemUtils.IS_OS_WINDOWS); + + Map props = new HashMap(); + + props.put("endpoint", "bogus endpoint url"); + props.put("oauth", "bogus oauth token string"); + setupEnvironment(props); + GitHubBuilder builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.endpoint, equalTo("bogus endpoint url")); + + assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); + assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), nullValue()); + + props.put("login", "bogus login"); + setupEnvironment(props); + builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); + assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); + + props.put("jwt", "bogus jwt token string"); + setupEnvironment(props); + builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.authorizationProvider, not(instanceOf(UserAuthorizationProvider.class))); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("Bearer bogus jwt token string")); + + props.put("password", "bogus weak password"); + setupEnvironment(props); + builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), + equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA==")); + assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); + } + + @Test + public void testGitHubBuilderFromCredentialsWithPropertyFile() throws IOException { + // we disable this test for JDK 16+ as the current hacks in setupEnvironment() don't work with JDK 16+ + Assume.assumeThat(Double.valueOf(System.getProperty("java.specification.version")), lessThan(16.0)); + Assume.assumeFalse(SystemUtils.IS_OS_WINDOWS); + + Map props = new HashMap(); + + // Clear the environment + setupEnvironment(props); + try { + GitHubBuilder.HOME_DIRECTORY = new File(getTestDirectory()); + try { + GitHubBuilder builder = GitHubBuilder.fromCredentials(); + fail(); + } catch (Exception e) { + assertThat(e, instanceOf(IOException.class)); + assertThat(e.getMessage(), equalTo("Failed to resolve credentials from ~/.github or the environment.")); + } + + props = new HashMap(); + + props.put("endpoint", "bogus endpoint url"); + props.put("oauth", "bogus oauth token string"); + + setupPropertyFile(props); + + GitHubBuilder builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.endpoint, equalTo("bogus endpoint url")); + + assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), + equalTo("token bogus oauth token string")); + assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), nullValue()); + + props.put("login", "bogus login"); + setupPropertyFile(props); + builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), + equalTo("token bogus oauth token string")); + assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); + + props.put("jwt", "bogus jwt token string"); + setupPropertyFile(props); + builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.authorizationProvider, not(instanceOf(UserAuthorizationProvider.class))); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), + equalTo("Bearer bogus jwt token string")); + + props.put("password", "bogus weak password"); + setupPropertyFile(props); + builder = GitHubBuilder.fromCredentials(); + + assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + assertThat(builder.authorizationProvider.getEncodedAuthorization(), + equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA==")); + assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); + } finally { + GitHubBuilder.HOME_DIRECTORY = null; + File propertyFile = new File(getTestDirectory(), ".github"); + propertyFile.delete(); + } + } + + private void setupPropertyFile(Map props) throws IOException { + File propertyFile = new File(getTestDirectory(), ".github"); + Properties properties = new Properties(); + properties.putAll(props); + properties.store(new FileOutputStream(propertyFile), ""); + } + + private String getTestDirectory() { + return new File("target").getAbsolutePath(); + } + + @Test + public void testAnonymous() throws IOException { + // we disable this test for JDK 16+ as the current hacks in setupEnvironment() don't work with JDK 16+ + Assume.assumeThat(Double.valueOf(System.getProperty("java.specification.version")), lessThan(16.0)); + + Map props = new HashMap(); + + props.put("endpoint", mockGitHub.apiServer().baseUrl()); + setupEnvironment(props); + + // No values present except endpoint + GitHubBuilder builder = GitHubBuilder + .fromEnvironment("customLogin", "customPassword", "customOauth", "endpoint"); + + assertThat(builder.endpoint, equalTo(mockGitHub.apiServer().baseUrl())); + assertThat(builder.authorizationProvider, sameInstance(AuthorizationProvider.ANONYMOUS)); + } + @Test public void testGithubBuilderWithAppInstallationToken() throws Exception {