From 25d60e05cc15f19940d6cb98345c0501a51cff7d Mon Sep 17 00:00:00 2001 From: Michael O'Cleirigh Date: Mon, 29 Sep 2014 11:41:14 -0400 Subject: [PATCH] Modify GitHubBuilder to resolve user credentials from the system environment Using the Jenkins EnvInject or Credentials Binding Plugins its possible to pass credentials as Environment Variables. Its useful for Github.connect() to be able to directly read the values of the login, password and oauth properties from the environment. This commit modifies the base Github.connect() method to resolve credentials in two steps: 1. ~/.github credentials file if it exists. 2. login, password or oauth variables from the environment A further fromEnvironment() method is provided to support loading from non-standard variable names. The old Github.connect() method would throw an IOException if the ~/.github file did not exist. Now it will fail silently instead dropping back to the anonymous users access level. --- src/main/java/org/kohsuke/github/GitHub.java | 4 +- .../org/kohsuke/github/GitHubBuilder.java | 78 ++++++++++++++++++- .../java/org/kohsuke/github/GitHubTest.java | 48 ++++++++++++ 3 files changed, 125 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 9037572c7c..66b6ffe1df 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -128,10 +128,10 @@ public class GitHub { } /** - * Obtains the credential from "~/.github" + * Obtains the credential from "~/.github" or from the System Environment Properties. */ public static GitHub connect() throws IOException { - return GitHubBuilder.fromPropertyFile().build(); + return GitHubBuilder.fromCredentials().build(); } /** diff --git a/src/main/java/org/kohsuke/github/GitHubBuilder.java b/src/main/java/org/kohsuke/github/GitHubBuilder.java index baf26a6415..053c7884bd 100644 --- a/src/main/java/org/kohsuke/github/GitHubBuilder.java +++ b/src/main/java/org/kohsuke/github/GitHubBuilder.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; @@ -12,19 +13,85 @@ */ public class GitHubBuilder { private String endpoint = GitHub.GITHUB_URL; - private String user; - private String password; - private String oauthToken; + + // default scoped so unit tests can read them. + /* private */ String user; + /* private */ String password; + /* private */ String oauthToken; + private HttpConnector connector; public GitHubBuilder() { } + /** + * First check if the credentials are configured using the ~/.github properties file. + * + * If no user is specified it means there is no configuration present so check the environment instead. + * + * the system properties for the login, password or oauth environment variables. + * + * @return the configured Builder from credentials defined on the system or in the environment. + * + * @throws IOException + */ + public static GitHubBuilder fromCredentials() throws IOException { + + GitHubBuilder builder; + try { + builder = fromPropertyFile(); + + if (builder.user != null) + return builder; + else + return fromEnvironment(); + + } catch (FileNotFoundException e) { + return fromEnvironment(); + } + + } + + public static GitHubBuilder fromEnvironment(String loginVariableName, String passwordVariableName, String oauthVariableName) throws IOException { + + Properties systemProps = System.getProperties(); + + Properties env = new Properties(); + + Object loginValue = systemProps.get(loginVariableName); + + if (loginValue != null) + env.put("login", loginValue); + + Object passwordValue = systemProps.get(passwordVariableName); + + if (passwordValue != null) + env.put("password", passwordValue); + + Object oauthValue = systemProps.get(oauthVariableName); + + if (oauthValue != null) + env.put("oauth", oauthValue); + + return fromProperties(env); + + } + + public static GitHubBuilder fromEnvironment() throws IOException { + + /* + * Expects there to be some combination of the following fields: + * login, oauth, password + */ + return fromProperties(System.getProperties()); + } + public static GitHubBuilder fromPropertyFile() throws IOException { File homeDir = new File(System.getProperty("user.home")); File propertyFile = new File(homeDir, ".github"); return fromPropertyFile(propertyFile.getPath()); } + public static GitHubBuilder fromPropertyFile(String propertyFileName) throws IOException { Properties props = new Properties(); FileInputStream in = null; @@ -34,6 +101,11 @@ public static GitHubBuilder fromPropertyFile(String propertyFileName) throws IOE } finally { IOUtils.closeQuietly(in); } + + return fromProperties(props); + } + + public static GitHubBuilder fromProperties(Properties props) { GitHubBuilder self = new GitHubBuilder(); self.withOAuthToken(props.getProperty("oauth"), props.getProperty("login")); self.withPassword(props.getProperty("login"), props.getProperty("password")); diff --git a/src/test/java/org/kohsuke/github/GitHubTest.java b/src/test/java/org/kohsuke/github/GitHubTest.java index 6ff39feec9..697d99767a 100644 --- a/src/test/java/org/kohsuke/github/GitHubTest.java +++ b/src/test/java/org/kohsuke/github/GitHubTest.java @@ -1,5 +1,8 @@ package org.kohsuke.github; +import java.io.IOException; +import java.util.Properties; + import junit.framework.TestCase; /** @@ -21,4 +24,49 @@ public void testGitHubServerWithoutServer() throws Exception { GitHub hub = GitHub.connectUsingPassword("kohsuke", "bogus"); assertEquals("https://api.github.com/test", hub.getApiURL("/test").toString()); } + + public void testGitHubFromEnvironment() throws IOException { + + Properties props = System.getProperties(); + + props.put("login", "bogus"); + + GitHub hub = GitHub.connect(); + + assertEquals("bogus", hub.login); + + } + + public void testGitHubBuilderFromEnvironment() throws IOException { + + Properties props = System.getProperties(); + + props.put("login", "bogus"); + props.put("oauth", "bogus"); + props.put("password", "bogus"); + + GitHubBuilder builder = GitHubBuilder.fromEnvironment(); + + assertEquals("bogus", builder.user); + assertEquals("bogus", builder.oauthToken); + assertEquals("bogus", builder.password); + + } + + public void testGitHubBuilderFromCustomEnvironment() throws IOException { + + Properties props = System.getProperties(); + + props.put("customLogin", "bogusLogin"); + props.put("customOauth", "bogusOauth"); + props.put("customPassword", "bogusPassword"); + + GitHubBuilder builder = GitHubBuilder.fromEnvironment("customLogin", "customPassword", "customOauth"); + + assertEquals("bogusLogin", builder.user); + assertEquals("bogusOauth", builder.oauthToken); + assertEquals("bogusPassword", builder.password); + + } + }