Commit 507a7e77 authored by Greg Messner's avatar Greg Messner
Browse files

Mods to support OAuth2 login (#111).

parent fe2552ef
package org.gitlab4j.api; package org.gitlab4j.api;
import java.util.Map;
import javax.ws.rs.core.Response;
import org.gitlab4j.api.Constants.TokenType; import org.gitlab4j.api.Constants.TokenType;
import org.gitlab4j.api.models.OauthTokenResponse;
import org.gitlab4j.api.models.Session; import org.gitlab4j.api.models.Session;
import org.gitlab4j.api.models.User; import org.gitlab4j.api.models.User;
import org.gitlab4j.api.models.Version; import org.gitlab4j.api.models.Version;
import javax.ws.rs.core.Response;
import java.util.Map;
/** /**
* This class is provides a simplified interface to a GitLab API server, and divides the API up into * This class is provides a simplified interface to a GitLab API server, and divides the API up into
* a separate API class for each concern. * a separate API class for each concern.
...@@ -19,7 +21,7 @@ public class GitLabApi { ...@@ -19,7 +21,7 @@ public class GitLabApi {
/** Specifies the version of the GitLab API to communicate with. */ /** Specifies the version of the GitLab API to communicate with. */
public enum ApiVersion { public enum ApiVersion {
V3, V4; V3, V4, OAUTH2_CLIENT;
public String getApiNamespace() { public String getApiNamespace() {
return ("/api/" + name().toLowerCase()); return ("/api/" + name().toLowerCase());
...@@ -51,6 +53,102 @@ public class GitLabApi { ...@@ -51,6 +53,102 @@ public class GitLabApi {
private Session session; private Session session;
/**
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
* and creates a new {@code GitLabApi} instance using returned access token.</p>
*
* @param url GitLab URL
* @param username user name for which private token should be obtained
* @param password password for a given {@code username}
* @return new {@code GitLabApi} instance configured for a user-specific token
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/
public static GitLabApi oauth2Login(String url, String username, String password) throws GitLabApiException {
return (GitLabApi.oauth2Login(ApiVersion.V4, url, username, password, null, null, false));
}
/**
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
* and creates a new {@code GitLabApi} instance using returned access token.</p>
*
* @param url GitLab URL
* @param username user name for which private token should be obtained
* @param password password for a given {@code username}
* @param ignoreCertificateErrors if true will set up the Jersey system ignore SSL certificate errors
* @return new {@code GitLabApi} instance configured for a user-specific token
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/
public static GitLabApi oauth2Login(String url, String username, String password, boolean ignoreCertificateErrors) throws GitLabApiException {
return (GitLabApi.oauth2Login(ApiVersion.V4, url, username, password, null, null, ignoreCertificateErrors));
}
/**
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
* and creates a new {@code GitLabApi} instance using returned access token.</p>
*
* @param url GitLab URL
* @param username user name for which private token should be obtained
* @param password password for a given {@code username}
* @param secretToken use this token to validate received payloads
* @param clientConfigProperties Map instance with additional properties for the Jersey client connection
* @param ignoreCertificateErrors if true will set up the Jersey system ignore SSL certificate errors
* @return new {@code GitLabApi} instance configured for a user-specific token
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/
public static GitLabApi oauth2Login(String url, String username, String password,
String secretToken, Map<String, Object> clientConfigProperties, boolean ignoreCertificateErrors)
throws GitLabApiException {
return (GitLabApi.oauth2Login(ApiVersion.V4, url, username, password, secretToken, clientConfigProperties, ignoreCertificateErrors));
}
/**
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
* and creates a new {@code GitLabApi} instance using returned access token.</p>
*
* @param url GitLab URL
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param username user name for which private token should be obtained
* @param password password for a given {@code username}
* @param secretToken use this token to validate received payloads
* @param clientConfigProperties Map instance with additional properties for the Jersey client connection
* @param ignoreCertificateErrors if true will set up the Jersey system ignore SSL certificate errors
* @return new {@code GitLabApi} instance configured for a user-specific token
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/
public static GitLabApi oauth2Login(ApiVersion apiVersion, String url, String username, String password,
String secretToken, Map<String, Object> clientConfigProperties, boolean ignoreCertificateErrors)
throws GitLabApiException {
if (username == null || username.trim().length() == 0) {
throw new IllegalArgumentException("both username and email cannot be empty or null");
}
GitLabApi gitLabApi = new GitLabApi(ApiVersion.OAUTH2_CLIENT, url, (String)null);
if (ignoreCertificateErrors) {
gitLabApi.setIgnoreCertificateErrors(true);
}
class Oauth2Api extends AbstractApi {
Oauth2Api(GitLabApi gitlabApi) {
super(gitlabApi);
}
}
GitLabApiForm formData = new GitLabApiForm()
.withParam("grant_type", "password", true)
.withParam("username", username, true)
.withParam("password", password, true);
Response response = new Oauth2Api(gitLabApi).post(Response.Status.OK, formData, "oauth", "token");
OauthTokenResponse oauthToken = response.readEntity(OauthTokenResponse.class);
gitLabApi = new GitLabApi(apiVersion, url, TokenType.ACCESS, oauthToken.getAccessToken(), secretToken, clientConfigProperties);
if (ignoreCertificateErrors) {
gitLabApi.setIgnoreCertificateErrors(true);
}
return (gitLabApi);
}
/** /**
* <p>Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance * <p>Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance
* using returned private token and the specified GitLab API version.</p> * using returned private token and the specified GitLab API version.</p>
...@@ -65,7 +163,7 @@ public class GitLabApi { ...@@ -65,7 +163,7 @@ public class GitLabApi {
* @throws GitLabApiException GitLabApiException if any exception occurs during execution * @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/ */
public static GitLabApi login(ApiVersion apiVersion, String url, String username, String password) throws GitLabApiException { public static GitLabApi login(ApiVersion apiVersion, String url, String username, String password) throws GitLabApiException {
return (login(apiVersion, url, username, password, false)); return (GitLabApi.login(apiVersion, url, username, password, false));
} }
/** /**
...@@ -81,7 +179,7 @@ public class GitLabApi { ...@@ -81,7 +179,7 @@ public class GitLabApi {
* @throws GitLabApiException GitLabApiException if any exception occurs during execution * @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/ */
public static GitLabApi login(String url, String username, String password) throws GitLabApiException { public static GitLabApi login(String url, String username, String password) throws GitLabApiException {
return (login(ApiVersion.V4, url, username, password, false)); return (GitLabApi.login(ApiVersion.V4, url, username, password, false));
} }
/** /**
...@@ -105,12 +203,22 @@ public class GitLabApi { ...@@ -105,12 +203,22 @@ public class GitLabApi {
gitLabApi.setIgnoreCertificateErrors(true); gitLabApi.setIgnoreCertificateErrors(true);
} }
SessionApi sessionApi = gitLabApi.getSessionApi(); try {
Session session = sessionApi.login(username, null, password);
gitLabApi = new GitLabApi(apiVersion, url, session);
if (ignoreCertificateErrors) { SessionApi sessionApi = gitLabApi.getSessionApi();
gitLabApi.setIgnoreCertificateErrors(true); Session session = sessionApi.login(username, null, password);
gitLabApi = new GitLabApi(apiVersion, url, session);
if (ignoreCertificateErrors) {
gitLabApi.setIgnoreCertificateErrors(true);
}
} catch (GitLabApiException gle) {
if (gle.getHttpStatus() != Response.Status.NOT_FOUND.getStatusCode()) {
throw (gle);
} else {
gitLabApi = GitLabApi.oauth2Login(apiVersion, url, username, password, null, null, ignoreCertificateErrors);
}
} }
return (gitLabApi); return (gitLabApi);
...@@ -130,7 +238,7 @@ public class GitLabApi { ...@@ -130,7 +238,7 @@ public class GitLabApi {
* @throws GitLabApiException GitLabApiException if any exception occurs during execution * @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/ */
public static GitLabApi login(String url, String username, String password, boolean ignoreCertificateErrors) throws GitLabApiException { public static GitLabApi login(String url, String username, String password, boolean ignoreCertificateErrors) throws GitLabApiException {
return (login(ApiVersion.V4, url, username, password, ignoreCertificateErrors)); return (GitLabApi.login(ApiVersion.V4, url, username, password, ignoreCertificateErrors));
} }
/** /**
...@@ -148,7 +256,7 @@ public class GitLabApi { ...@@ -148,7 +256,7 @@ public class GitLabApi {
*/ */
@Deprecated @Deprecated
public static GitLabApi create(String url, String username, String password) throws GitLabApiException { public static GitLabApi create(String url, String username, String password) throws GitLabApiException {
return (login(url, username, password)); return (GitLabApi.login(url, username, password));
} }
/** /**
......
...@@ -194,7 +194,11 @@ public class GitLabApiClient { ...@@ -194,7 +194,11 @@ public class GitLabApiClient {
public GitLabApiClient(ApiVersion apiVersion, String hostUrl, TokenType tokenType, String authToken, String secretToken, Map<String, Object> clientConfigProperties) { public GitLabApiClient(ApiVersion apiVersion, String hostUrl, TokenType tokenType, String authToken, String secretToken, Map<String, Object> clientConfigProperties) {
// Remove the trailing "/" from the hostUrl if present // Remove the trailing "/" from the hostUrl if present
this.hostUrl = (hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl) + apiVersion.getApiNamespace(); this.hostUrl = (hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl);
if (ApiVersion.OAUTH2_CLIENT != apiVersion) {
this.hostUrl += apiVersion.getApiNamespace();
}
this.tokenType = tokenType; this.tokenType = tokenType;
this.authToken = authToken; this.authToken = authToken;
......
...@@ -2,6 +2,7 @@ package org.gitlab4j.api; ...@@ -2,6 +2,7 @@ package org.gitlab4j.api;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue;
import org.gitlab4j.api.GitLabApi.ApiVersion; import org.gitlab4j.api.GitLabApi.ApiVersion;
...@@ -20,7 +21,7 @@ import org.junit.Test; ...@@ -20,7 +21,7 @@ import org.junit.Test;
* *
* If any of the above are NULL, all tests in this class will be skipped. * If any of the above are NULL, all tests in this class will be skipped.
*/ */
public class TestGitLabSession { public class TestGitLabLogin {
// The following needs to be set to your test repository // The following needs to be set to your test repository
private static final String TEST_USERNAME; private static final String TEST_USERNAME;
...@@ -35,8 +36,9 @@ public class TestGitLabSession { ...@@ -35,8 +36,9 @@ public class TestGitLabSession {
} }
private static String problems = ""; private static String problems = "";
private static boolean hasSession;
public TestGitLabSession() { public TestGitLabLogin() {
super(); super();
} }
...@@ -62,24 +64,18 @@ public class TestGitLabSession { ...@@ -62,24 +64,18 @@ public class TestGitLabSession {
} }
if (problems.isEmpty()) { if (problems.isEmpty()) {
String savedVersion = null;
try { try {
GitLabApi gitLabApi = new GitLabApi(ApiVersion.V4, TEST_HOST_URL, TEST_PRIVATE_TOKEN); GitLabApi gitLabApi = new GitLabApi(ApiVersion.V4, TEST_HOST_URL, TEST_PRIVATE_TOKEN);
Version version = gitLabApi.getVersion(); Version version = gitLabApi.getVersion();
savedVersion = version.getVersion();
String[] parts = version.getVersion().split(".", -1); String[] parts = version.getVersion().split(".", -1);
if (parts.length == 3) { if (parts.length == 3) {
if (Integer.parseInt(parts[0]) < 10 || if (Integer.parseInt(parts[0]) < 10 ||
(Integer.parseInt(parts[0]) == 10 && Integer.parseInt(parts[1]) < 2)) { (Integer.parseInt(parts[0]) == 10 && Integer.parseInt(parts[1]) < 2)) {
savedVersion = null; hasSession = true;
} }
} }
} catch (Exception e) { } catch (Exception e) {
} }
if (savedVersion != null) {
problems += "GitLab version " + savedVersion + " does not support sessions\n";
}
} }
if (!problems.isEmpty()) { if (!problems.isEmpty()) {
...@@ -95,6 +91,7 @@ public class TestGitLabSession { ...@@ -95,6 +91,7 @@ public class TestGitLabSession {
@Test @Test
public void testSession() throws GitLabApiException { public void testSession() throws GitLabApiException {
assumeTrue(hasSession);
GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V4, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD); GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V4, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD);
assertNotNull(gitLabApi); assertNotNull(gitLabApi);
assertNotNull(gitLabApi.getSession()); assertNotNull(gitLabApi.getSession());
...@@ -104,9 +101,29 @@ public class TestGitLabSession { ...@@ -104,9 +101,29 @@ public class TestGitLabSession {
@Test @Test
public void testSessionV3() throws GitLabApiException { public void testSessionV3() throws GitLabApiException {
assumeTrue(hasSession);
GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V3, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD); GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V3, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD);
assertNotNull(gitLabApi); assertNotNull(gitLabApi);
assertNotNull(gitLabApi.getSession()); assertNotNull(gitLabApi.getSession());
assertEquals(TEST_PRIVATE_TOKEN, gitLabApi.getSession().getPrivateToken()); assertEquals(TEST_PRIVATE_TOKEN, gitLabApi.getSession().getPrivateToken());
} }
@Test
public void testSessionFallover() throws GitLabApiException {
assumeFalse(hasSession);
GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V4, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD);
assertNotNull(gitLabApi);
Version version = gitLabApi.getVersion();
assertNotNull(version);
}
@Test
public void testOauth2Login() throws GitLabApiException {
GitLabApi gitLabApi = GitLabApi.oauth2Login(TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD, null, null, true);
assertNotNull(gitLabApi);
Version version = gitLabApi.getVersion();
assertNotNull(version);
}
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment