Commit feaaf03d authored by Tim Olshansky's avatar Tim Olshansky

Merge pull request #89 from wikiwi/header-auth-method

Implement Authentication via an HTTP Header 
parents b6ba137f ca41b316
package org.gitlab.api;
public enum AuthMethod {
HEADER, URL_PARAMETER
}
...@@ -32,27 +32,33 @@ public class GitlabAPI { ...@@ -32,27 +32,33 @@ public class GitlabAPI {
private final String apiToken; private final String apiToken;
private final TokenType tokenType; private final TokenType tokenType;
private AuthMethod authMethod;
private boolean ignoreCertificateErrors = false; private boolean ignoreCertificateErrors = false;
private GitlabAPI(String hostUrl, String apiToken, TokenType tokenType) { private GitlabAPI(String hostUrl, String apiToken, TokenType tokenType, AuthMethod method) {
this.hostUrl = hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl; this.hostUrl = hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl;
this.apiToken = apiToken; this.apiToken = apiToken;
this.tokenType = tokenType; this.tokenType = tokenType;
this.authMethod = method;
} }
public static GitlabSession connect(String hostUrl, String username, String password) throws IOException { public static GitlabSession connect(String hostUrl, String username, String password) throws IOException {
String tailUrl = GitlabSession.URL; String tailUrl = GitlabSession.URL;
GitlabAPI api = connect(hostUrl, null, (TokenType) null); GitlabAPI api = connect(hostUrl, null, null, null);
return api.dispatch().with("login", username).with("password", password) return api.dispatch().with("login", username).with("password", password)
.to(tailUrl, GitlabSession.class); .to(tailUrl, GitlabSession.class);
} }
public static GitlabAPI connect(String hostUrl, String apiToken) { public static GitlabAPI connect(String hostUrl, String apiToken) {
return new GitlabAPI(hostUrl, apiToken, TokenType.PRIVATE_TOKEN); return new GitlabAPI(hostUrl, apiToken, TokenType.PRIVATE_TOKEN, AuthMethod.HEADER);
} }
public static GitlabAPI connect(String hostUrl, String apiToken, TokenType tokenType) { public static GitlabAPI connect(String hostUrl, String apiToken, TokenType tokenType) {
return new GitlabAPI(hostUrl, apiToken, tokenType); return new GitlabAPI(hostUrl, apiToken, tokenType, AuthMethod.HEADER);
}
public static GitlabAPI connect(String hostUrl, String apiToken, TokenType tokenType, AuthMethod method) {
return new GitlabAPI(hostUrl, apiToken, tokenType, method);
} }
public GitlabAPI ignoreCertificateErrors(boolean ignoreCertificateErrors) { public GitlabAPI ignoreCertificateErrors(boolean ignoreCertificateErrors) {
...@@ -61,11 +67,11 @@ public class GitlabAPI { ...@@ -61,11 +67,11 @@ public class GitlabAPI {
} }
public GitlabHTTPRequestor retrieve() { public GitlabHTTPRequestor retrieve() {
return new GitlabHTTPRequestor(this); return new GitlabHTTPRequestor(this).authenticate(apiToken, tokenType, authMethod);
} }
public GitlabHTTPRequestor dispatch() { public GitlabHTTPRequestor dispatch() {
return new GitlabHTTPRequestor(this).method("POST"); return new GitlabHTTPRequestor(this).authenticate(apiToken, tokenType, authMethod).method("POST");
} }
public boolean isIgnoreCertificateErrors() { public boolean isIgnoreCertificateErrors() {
...@@ -73,10 +79,6 @@ public class GitlabAPI { ...@@ -73,10 +79,6 @@ public class GitlabAPI {
} }
public URL getAPIUrl(String tailAPIUrl) throws IOException { public URL getAPIUrl(String tailAPIUrl) throws IOException {
if (apiToken != null) {
tailAPIUrl = tailAPIUrl + (tailAPIUrl.indexOf('?') > 0 ? '&' : '?') + tokenType.getTokenParamName() + "=" + apiToken;
}
if (!tailAPIUrl.startsWith("/")) { if (!tailAPIUrl.startsWith("/")) {
tailAPIUrl = "/" + tailAPIUrl; tailAPIUrl = "/" + tailAPIUrl;
} }
......
package org.gitlab.api; package org.gitlab.api;
public enum TokenType { public enum TokenType {
PRIVATE_TOKEN("private_token") PRIVATE_TOKEN("private_token", "PRIVATE-TOKEN", "%s"),
, ACCESS_TOKEN("access_token"), ACCESS_TOKEN("access_token", "Authorization", "Bearer %s");
;
private final String tokenParamName; private final String tokenParamName;
private final String tokenHeaderName;
private final String tokenHeaderFormat;
TokenType(String tokenParamName) { /**
* Constructor
*
* @param tokenParamName The url parameter name when using AuthMethod.URL_PARAMETER
* @param tokenHeaderName The header name when using AuthMethod.HEADER
* @param tokenHeaderFormat The header format for String.format when using AuthMethod.HEADER
*/
TokenType(String tokenParamName, String tokenHeaderName, String tokenHeaderFormat) {
this.tokenParamName = tokenParamName; this.tokenParamName = tokenParamName;
this.tokenHeaderName = tokenHeaderName;
this.tokenHeaderFormat = tokenHeaderFormat;
} }
public String getTokenParamName() { public String getTokenParamName() {
return tokenParamName; return tokenParamName;
} }
public String getTokenHeaderName() {
return tokenHeaderName;
}
public String getTokenHeaderFormat() {
return tokenHeaderFormat;
}
} }
package org.gitlab.api.http; package org.gitlab.api.http;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.gitlab.api.AuthMethod;
import org.gitlab.api.GitlabAPI; import org.gitlab.api.GitlabAPI;
import org.gitlab.api.TokenType;
import org.gitlab.api.models.GitlabCommit; import org.gitlab.api.models.GitlabCommit;
import javax.net.ssl.*; import javax.net.ssl.*;
...@@ -34,6 +36,10 @@ public class GitlabHTTPRequestor { ...@@ -34,6 +36,10 @@ public class GitlabHTTPRequestor {
private String method = "GET"; // Default to GET requests private String method = "GET"; // Default to GET requests
private Map<String, Object> data = new HashMap<String, Object>(); private Map<String, Object> data = new HashMap<String, Object>();
private String apiToken;
private TokenType tokenType;
private AuthMethod authMethod;
private enum METHOD { private enum METHOD {
GET, PUT, POST, PATCH, DELETE, HEAD, OPTIONS, TRACE; GET, PUT, POST, PATCH, DELETE, HEAD, OPTIONS, TRACE;
...@@ -56,6 +62,22 @@ public class GitlabHTTPRequestor { ...@@ -56,6 +62,22 @@ public class GitlabHTTPRequestor {
this.root = root; this.root = root;
} }
/**
* Sets authentication data for the request.
* Has a fluent api for method chaining.
*
* @param token The token value
* @param type The type of the token
* @param method The authentication method
* @return this
*/
public GitlabHTTPRequestor authenticate(String token, TokenType type, AuthMethod method) {
this.apiToken = token;
this.tokenType = type;
this.authMethod = method;
return this;
}
/** /**
* Sets the HTTP Request method for the request. * Sets the HTTP Request method for the request.
* Has a fluent api for method chaining. * Has a fluent api for method chaining.
...@@ -236,11 +258,11 @@ public class GitlabHTTPRequestor { ...@@ -236,11 +258,11 @@ public class GitlabHTTPRequestor {
// there is a bug in the Gitlab CE API // there is a bug in the Gitlab CE API
// (https://gitlab.com/gitlab-org/gitlab-ce/issues/759) // (https://gitlab.com/gitlab-org/gitlab-ce/issues/759)
// that starts pagination with page=0 for commits // that starts pagination with page=0 for commits
this.url = new URL(url + "&page=1"); this.url = new URL(url + (url.indexOf('?') > 0 ? '&' : '?') + "page=1");
} else { } else {
// Since the page query was not present, its safe to assume that we just // Since the page query was not present, its safe to assume that we just
// currently used the first page, so we can default to page 2 // currently used the first page, so we can default to page 2
this.url = new URL(url + "&page=2"); this.url = new URL(url + (url.indexOf('?') > 0 ? '&' : '?') + "&page=2");
} }
} }
} }
...@@ -262,7 +284,16 @@ public class GitlabHTTPRequestor { ...@@ -262,7 +284,16 @@ public class GitlabHTTPRequestor {
ignoreCertificateErrors(); ignoreCertificateErrors();
} }
if (apiToken != null && authMethod == AuthMethod.URL_PARAMETER) {
String urlWithAuth = url.toString();
urlWithAuth = urlWithAuth + (urlWithAuth.indexOf('?') > 0 ? '&' : '?') + tokenType.getTokenParamName() + "=" + apiToken;
url = new URL(urlWithAuth);
}
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (apiToken != null && authMethod == AuthMethod.HEADER) {
connection.setRequestProperty(tokenType.getTokenHeaderName(), String.format(tokenType.getTokenHeaderFormat(), apiToken));
}
try { try {
connection.setRequestMethod(method); connection.setRequestMethod(method);
......
...@@ -40,6 +40,11 @@ public class GitlabAPITest { ...@@ -40,6 +40,11 @@ public class GitlabAPITest {
} }
} }
@Test
public void testAllProjects() throws IOException {
api.getAllProjects();
}
@Test @Test
public void testConnect() throws IOException { public void testConnect() throws IOException {
assertEquals(GitlabAPI.class, api.getClass()); assertEquals(GitlabAPI.class, api.getClass());
...@@ -47,7 +52,7 @@ public class GitlabAPITest { ...@@ -47,7 +52,7 @@ public class GitlabAPITest {
@Test @Test
public void testGetAPIUrl() throws IOException { public void testGetAPIUrl() throws IOException {
URL expected = new URL(TEST_URL + "/api/v3/?private_token=" + TEST_TOKEN); URL expected = new URL(TEST_URL + "/api/v3/");
assertEquals(expected, api.getAPIUrl("")); assertEquals(expected, api.getAPIUrl(""));
} }
......
Markdown is supported
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