Skip to content

Commit 507a7e7

Browse files
committed
Mods to support OAuth2 login (#111).
1 parent fe2552e commit 507a7e7

File tree

3 files changed

+152
-23
lines changed

3 files changed

+152
-23
lines changed

src/main/java/org/gitlab4j/api/GitLabApi.java

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package org.gitlab4j.api;
22

3+
import java.util.Map;
4+
5+
import javax.ws.rs.core.Response;
6+
37
import org.gitlab4j.api.Constants.TokenType;
8+
import org.gitlab4j.api.models.OauthTokenResponse;
49
import org.gitlab4j.api.models.Session;
510
import org.gitlab4j.api.models.User;
611
import org.gitlab4j.api.models.Version;
712

8-
import javax.ws.rs.core.Response;
9-
import java.util.Map;
10-
1113
/**
1214
* This class is provides a simplified interface to a GitLab API server, and divides the API up into
1315
* a separate API class for each concern.
@@ -19,7 +21,7 @@ public class GitLabApi {
1921

2022
/** Specifies the version of the GitLab API to communicate with. */
2123
public enum ApiVersion {
22-
V3, V4;
24+
V3, V4, OAUTH2_CLIENT;
2325

2426
public String getApiNamespace() {
2527
return ("/api/" + name().toLowerCase());
@@ -51,6 +53,102 @@ public String getApiNamespace() {
5153
private Session session;
5254

5355

56+
/**
57+
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
58+
* and creates a new {@code GitLabApi} instance using returned access token.</p>
59+
*
60+
* @param url GitLab URL
61+
* @param username user name for which private token should be obtained
62+
* @param password password for a given {@code username}
63+
* @return new {@code GitLabApi} instance configured for a user-specific token
64+
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
65+
*/
66+
public static GitLabApi oauth2Login(String url, String username, String password) throws GitLabApiException {
67+
return (GitLabApi.oauth2Login(ApiVersion.V4, url, username, password, null, null, false));
68+
}
69+
70+
/**
71+
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
72+
* and creates a new {@code GitLabApi} instance using returned access token.</p>
73+
*
74+
* @param url GitLab URL
75+
* @param username user name for which private token should be obtained
76+
* @param password password for a given {@code username}
77+
* @param ignoreCertificateErrors if true will set up the Jersey system ignore SSL certificate errors
78+
* @return new {@code GitLabApi} instance configured for a user-specific token
79+
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
80+
*/
81+
public static GitLabApi oauth2Login(String url, String username, String password, boolean ignoreCertificateErrors) throws GitLabApiException {
82+
return (GitLabApi.oauth2Login(ApiVersion.V4, url, username, password, null, null, ignoreCertificateErrors));
83+
}
84+
85+
/**
86+
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
87+
* and creates a new {@code GitLabApi} instance using returned access token.</p>
88+
*
89+
* @param url GitLab URL
90+
* @param username user name for which private token should be obtained
91+
* @param password password for a given {@code username}
92+
* @param secretToken use this token to validate received payloads
93+
* @param clientConfigProperties Map instance with additional properties for the Jersey client connection
94+
* @param ignoreCertificateErrors if true will set up the Jersey system ignore SSL certificate errors
95+
* @return new {@code GitLabApi} instance configured for a user-specific token
96+
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
97+
*/
98+
public static GitLabApi oauth2Login(String url, String username, String password,
99+
String secretToken, Map<String, Object> clientConfigProperties, boolean ignoreCertificateErrors)
100+
throws GitLabApiException {
101+
return (GitLabApi.oauth2Login(ApiVersion.V4, url, username, password, secretToken, clientConfigProperties, ignoreCertificateErrors));
102+
}
103+
104+
/**
105+
* <p>Logs into GitLab using OAuth2 with the provided {@code username} and {@code password},
106+
* and creates a new {@code GitLabApi} instance using returned access token.</p>
107+
*
108+
* @param url GitLab URL
109+
* @param apiVersion the ApiVersion specifying which version of the API to use
110+
* @param username user name for which private token should be obtained
111+
* @param password password for a given {@code username}
112+
* @param secretToken use this token to validate received payloads
113+
* @param clientConfigProperties Map instance with additional properties for the Jersey client connection
114+
* @param ignoreCertificateErrors if true will set up the Jersey system ignore SSL certificate errors
115+
* @return new {@code GitLabApi} instance configured for a user-specific token
116+
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
117+
*/
118+
public static GitLabApi oauth2Login(ApiVersion apiVersion, String url, String username, String password,
119+
String secretToken, Map<String, Object> clientConfigProperties, boolean ignoreCertificateErrors)
120+
throws GitLabApiException {
121+
122+
if (username == null || username.trim().length() == 0) {
123+
throw new IllegalArgumentException("both username and email cannot be empty or null");
124+
}
125+
126+
GitLabApi gitLabApi = new GitLabApi(ApiVersion.OAUTH2_CLIENT, url, (String)null);
127+
if (ignoreCertificateErrors) {
128+
gitLabApi.setIgnoreCertificateErrors(true);
129+
}
130+
131+
class Oauth2Api extends AbstractApi {
132+
Oauth2Api(GitLabApi gitlabApi) {
133+
super(gitlabApi);
134+
}
135+
}
136+
137+
GitLabApiForm formData = new GitLabApiForm()
138+
.withParam("grant_type", "password", true)
139+
.withParam("username", username, true)
140+
.withParam("password", password, true);
141+
142+
Response response = new Oauth2Api(gitLabApi).post(Response.Status.OK, formData, "oauth", "token");
143+
OauthTokenResponse oauthToken = response.readEntity(OauthTokenResponse.class);
144+
gitLabApi = new GitLabApi(apiVersion, url, TokenType.ACCESS, oauthToken.getAccessToken(), secretToken, clientConfigProperties);
145+
if (ignoreCertificateErrors) {
146+
gitLabApi.setIgnoreCertificateErrors(true);
147+
}
148+
149+
return (gitLabApi);
150+
}
151+
54152
/**
55153
* <p>Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance
56154
* using returned private token and the specified GitLab API version.</p>
@@ -65,7 +163,7 @@ public String getApiNamespace() {
65163
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
66164
*/
67165
public static GitLabApi login(ApiVersion apiVersion, String url, String username, String password) throws GitLabApiException {
68-
return (login(apiVersion, url, username, password, false));
166+
return (GitLabApi.login(apiVersion, url, username, password, false));
69167
}
70168

71169
/**
@@ -81,7 +179,7 @@ public static GitLabApi login(ApiVersion apiVersion, String url, String username
81179
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
82180
*/
83181
public static GitLabApi login(String url, String username, String password) throws GitLabApiException {
84-
return (login(ApiVersion.V4, url, username, password, false));
182+
return (GitLabApi.login(ApiVersion.V4, url, username, password, false));
85183
}
86184

87185
/**
@@ -105,12 +203,22 @@ public static GitLabApi login(ApiVersion apiVersion, String url, String username
105203
gitLabApi.setIgnoreCertificateErrors(true);
106204
}
107205

108-
SessionApi sessionApi = gitLabApi.getSessionApi();
109-
Session session = sessionApi.login(username, null, password);
110-
gitLabApi = new GitLabApi(apiVersion, url, session);
206+
try {
111207

112-
if (ignoreCertificateErrors) {
113-
gitLabApi.setIgnoreCertificateErrors(true);
208+
SessionApi sessionApi = gitLabApi.getSessionApi();
209+
Session session = sessionApi.login(username, null, password);
210+
gitLabApi = new GitLabApi(apiVersion, url, session);
211+
212+
if (ignoreCertificateErrors) {
213+
gitLabApi.setIgnoreCertificateErrors(true);
214+
}
215+
216+
} catch (GitLabApiException gle) {
217+
if (gle.getHttpStatus() != Response.Status.NOT_FOUND.getStatusCode()) {
218+
throw (gle);
219+
} else {
220+
gitLabApi = GitLabApi.oauth2Login(apiVersion, url, username, password, null, null, ignoreCertificateErrors);
221+
}
114222
}
115223

116224
return (gitLabApi);
@@ -130,7 +238,7 @@ public static GitLabApi login(ApiVersion apiVersion, String url, String username
130238
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
131239
*/
132240
public static GitLabApi login(String url, String username, String password, boolean ignoreCertificateErrors) throws GitLabApiException {
133-
return (login(ApiVersion.V4, url, username, password, ignoreCertificateErrors));
241+
return (GitLabApi.login(ApiVersion.V4, url, username, password, ignoreCertificateErrors));
134242
}
135243

136244
/**
@@ -148,7 +256,7 @@ public static GitLabApi login(String url, String username, String password, bool
148256
*/
149257
@Deprecated
150258
public static GitLabApi create(String url, String username, String password) throws GitLabApiException {
151-
return (login(url, username, password));
259+
return (GitLabApi.login(url, username, password));
152260
}
153261

154262
/**

src/main/java/org/gitlab4j/api/GitLabApiClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,11 @@ public GitLabApiClient(ApiVersion apiVersion, String hostUrl, String privateToke
194194
public GitLabApiClient(ApiVersion apiVersion, String hostUrl, TokenType tokenType, String authToken, String secretToken, Map<String, Object> clientConfigProperties) {
195195

196196
// Remove the trailing "/" from the hostUrl if present
197-
this.hostUrl = (hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl) + apiVersion.getApiNamespace();
197+
this.hostUrl = (hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl);
198+
if (ApiVersion.OAUTH2_CLIENT != apiVersion) {
199+
this.hostUrl += apiVersion.getApiNamespace();
200+
}
201+
198202
this.tokenType = tokenType;
199203
this.authToken = authToken;
200204

src/test/java/org/gitlab4j/api/TestGitLabLogin.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.Assert.assertEquals;
44
import static org.junit.Assert.assertNotNull;
5+
import static org.junit.Assume.assumeFalse;
56
import static org.junit.Assume.assumeTrue;
67

78
import org.gitlab4j.api.GitLabApi.ApiVersion;
@@ -20,7 +21,7 @@
2021
*
2122
* If any of the above are NULL, all tests in this class will be skipped.
2223
*/
23-
public class TestGitLabSession {
24+
public class TestGitLabLogin {
2425

2526
// The following needs to be set to your test repository
2627
private static final String TEST_USERNAME;
@@ -35,8 +36,9 @@ public class TestGitLabSession {
3536
}
3637

3738
private static String problems = "";
39+
private static boolean hasSession;
3840

39-
public TestGitLabSession() {
41+
public TestGitLabLogin() {
4042
super();
4143
}
4244

@@ -62,24 +64,18 @@ public static void setup() {
6264
}
6365

6466
if (problems.isEmpty()) {
65-
String savedVersion = null;
6667
try {
6768
GitLabApi gitLabApi = new GitLabApi(ApiVersion.V4, TEST_HOST_URL, TEST_PRIVATE_TOKEN);
6869
Version version = gitLabApi.getVersion();
69-
savedVersion = version.getVersion();
7070
String[] parts = version.getVersion().split(".", -1);
7171
if (parts.length == 3) {
7272
if (Integer.parseInt(parts[0]) < 10 ||
7373
(Integer.parseInt(parts[0]) == 10 && Integer.parseInt(parts[1]) < 2)) {
74-
savedVersion = null;
74+
hasSession = true;
7575
}
7676
}
7777
} catch (Exception e) {
7878
}
79-
80-
if (savedVersion != null) {
81-
problems += "GitLab version " + savedVersion + " does not support sessions\n";
82-
}
8379
}
8480

8581
if (!problems.isEmpty()) {
@@ -95,6 +91,7 @@ public void beforeMethod() {
9591
@Test
9692
public void testSession() throws GitLabApiException {
9793

94+
assumeTrue(hasSession);
9895
GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V4, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD);
9996
assertNotNull(gitLabApi);
10097
assertNotNull(gitLabApi.getSession());
@@ -104,9 +101,29 @@ public void testSession() throws GitLabApiException {
104101
@Test
105102
public void testSessionV3() throws GitLabApiException {
106103

104+
assumeTrue(hasSession);
107105
GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V3, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD);
108106
assertNotNull(gitLabApi);
109107
assertNotNull(gitLabApi.getSession());
110108
assertEquals(TEST_PRIVATE_TOKEN, gitLabApi.getSession().getPrivateToken());
111109
}
110+
111+
@Test
112+
public void testSessionFallover() throws GitLabApiException {
113+
114+
assumeFalse(hasSession);
115+
GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V4, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD);
116+
assertNotNull(gitLabApi);
117+
Version version = gitLabApi.getVersion();
118+
assertNotNull(version);
119+
}
120+
121+
@Test
122+
public void testOauth2Login() throws GitLabApiException {
123+
124+
GitLabApi gitLabApi = GitLabApi.oauth2Login(TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD, null, null, true);
125+
assertNotNull(gitLabApi);
126+
Version version = gitLabApi.getVersion();
127+
assertNotNull(version);
128+
}
112129
}

0 commit comments

Comments
 (0)