Skip to content

Commit 96d0fb2

Browse files
committed
Mods to support sudo (#92).
1 parent 1d02552 commit 96d0fb2

File tree

5 files changed

+157
-8
lines changed

5 files changed

+157
-8
lines changed

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

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import org.gitlab4j.api.Constants.TokenType;
88
import org.gitlab4j.api.models.Session;
9+
import org.gitlab4j.api.models.User;
910
import org.gitlab4j.api.models.Version;
1011

1112
/**
@@ -48,6 +49,7 @@ public String getApiNamespace() {
4849

4950
private Session session;
5051

52+
5153
/**
5254
* Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance
5355
* using returned private token and the specified GitLab API version.
@@ -288,6 +290,70 @@ public GitLabApi(ApiVersion apiVersion, String hostUrl, TokenType tokenType, Str
288290
userApi = new UserApi(this);
289291
}
290292

293+
/**
294+
* Sets up all future calls to the GitLab API to be done as another user specified by sudoAsUsername.
295+
* To revert back to normal non-sudo operation you must call unsudo(), or pass null as the username.
296+
*
297+
* @param sudoAsUsername the username to sudo as, null will turn off sudo
298+
* @throws GitLabApiException if any exception occurs
299+
*/
300+
public void sudo(String sudoAsUsername) throws GitLabApiException {
301+
302+
if (sudoAsUsername == null || sudoAsUsername.trim().length() == 0) {
303+
apiClient.setSudoAsId(null);
304+
return;
305+
}
306+
307+
// Get the User specified by username, if you are not an admin or the username is not found, this will fail
308+
User user = getUserApi().getUser(sudoAsUsername);
309+
if (user == null || user.getId() == null) {
310+
throw new GitLabApiException("the specified username was not found");
311+
}
312+
313+
Integer sudoAsId = user.getId();
314+
apiClient.setSudoAsId(sudoAsId);
315+
}
316+
317+
318+
/**
319+
* Turns off the currently configured sudo as ID.
320+
*/
321+
public void unsudo() {
322+
apiClient.setSudoAsId(null);
323+
}
324+
325+
/**
326+
* Sets up all future calls to the GitLab API to be done as another user specified by provided user ID.
327+
* To revert back to normal non-sudo operation you must call unsudo(), or pass null as the sudoAsId.
328+
*
329+
* @param sudoAsId the ID of the user to sudo as, null will turn off sudo
330+
* @throws GitLabApiException if any exception occurs
331+
*/
332+
public void setSudoAsId(Integer sudoAsId) throws GitLabApiException {
333+
334+
if (sudoAsId == null) {
335+
apiClient.setSudoAsId(null);
336+
return;
337+
}
338+
339+
// Get the User specified by the sudoAsId, if you are not an admin or the username is not found, this will fail
340+
User user = getUserApi().getUser(sudoAsId);
341+
if (user == null || user.getId() != sudoAsId) {
342+
throw new GitLabApiException("the specified user ID was not found");
343+
}
344+
345+
apiClient.setSudoAsId(sudoAsId);
346+
}
347+
348+
/**
349+
* Get the current sudo as ID, will return null if not in sudo mode.
350+
*
351+
* @return the current sudo as ID, will return null if not in sudo mode
352+
*/
353+
public Integer getSudoAsId() {
354+
return (this.apiClient.getSudoAsId());
355+
}
356+
291357
/**
292358
* Return the GitLab API version that this instance is using.
293359
*

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
public class GitLabApiClient {
3939

4040
protected static final String PRIVATE_TOKEN_HEADER = "PRIVATE-TOKEN";
41+
protected static final String SUDO_HEADER = "Sudo";
4142
protected static final String AUTHORIZATION_HEADER = "Authorization";
4243
protected static final String X_GITLAB_TOKEN_HEADER = "X-Gitlab-Token";
4344

@@ -50,6 +51,7 @@ public class GitLabApiClient {
5051
private boolean ignoreCertificateErrors;
5152
private SSLContext openSslContext;
5253
private HostnameVerifier openHostnameVerifier;
54+
private Integer sudoAsId;
5355

5456
/**
5557
* Construct an instance to communicate with a GitLab API server using the specified GitLab API version,
@@ -211,6 +213,24 @@ public GitLabApiClient(ApiVersion apiVersion, String hostUrl, TokenType tokenTyp
211213
clientConfig.register(JacksonJson.class);
212214
}
213215

216+
/**
217+
* Set the ID of the user to sudo as.
218+
*
219+
* @param sudoAsId the ID of the user to sudo as
220+
*/
221+
Integer getSudoAsId() {
222+
return (sudoAsId);
223+
}
224+
225+
/**
226+
* Set the ID of the user to sudo as.
227+
*
228+
* @param sudoAsId the ID of the user to sudo as
229+
*/
230+
void setSudoAsId(Integer sudoAsId) {
231+
this.sudoAsId = sudoAsId;
232+
}
233+
214234
/**
215235
* Construct a REST URL with the specified path arguments.
216236
*
@@ -467,10 +487,18 @@ protected Invocation.Builder invocation(URL url, MultivaluedMap<String, String>
467487

468488
String authHeader = (tokenType == TokenType.ACCESS ? AUTHORIZATION_HEADER : PRIVATE_TOKEN_HEADER);
469489
String authValue = (tokenType == TokenType.ACCESS ? "Bearer " + authToken : authToken);
470-
if (accept == null || accept.trim().length() == 0)
471-
return (target.request().header(authHeader, authValue));
472-
else
473-
return (target.request().header(authHeader, authValue).accept(accept));
490+
Invocation.Builder builder = target.request();
491+
if (accept == null || accept.trim().length() == 0) {
492+
builder = builder.header(authHeader, authValue);
493+
} else {
494+
builder = builder.header(authHeader, authValue).accept(accept);
495+
}
496+
497+
// If sudo as ID is set add the Sudo header
498+
if (sudoAsId != null && sudoAsId.intValue() > 0)
499+
builder = builder.header(SUDO_HEADER, sudoAsId);
500+
501+
return (builder);
474502
}
475503

476504
/**

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

Lines changed: 23 additions & 3 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.Assert.fail;
56
import static org.junit.Assume.assumeTrue;
67

78
import java.util.List;
@@ -73,21 +74,40 @@ public void beforeMethod() {
7374
public void testGetNamespaces() throws GitLabApiException {
7475
List<Namespace> namespaces = gitLabApi.getNamespaceApi().getNamespaces();
7576
assertNotNull(namespaces);
76-
assertEquals(TEST_NAMESPACE, namespaces.get(0).getName());
77+
for (Namespace namespace : namespaces) {
78+
if (TEST_NAMESPACE.equals(namespace.getName()))
79+
return;
80+
}
81+
82+
fail(TEST_NAMESPACE + " not found!");
7783
}
7884

7985
@Test
8086
public void testGetNamespacesViaPager() throws GitLabApiException {
8187
Pager<Namespace> pager = gitLabApi.getNamespaceApi().getNamespaces(10);
8288
assertNotNull(pager);
83-
assertEquals(TEST_NAMESPACE, pager.next().get(0).getName());
89+
90+
while (pager.hasNext()) {
91+
List<Namespace> namespaces = pager.next();
92+
for (Namespace namespace : namespaces) {
93+
if (TEST_NAMESPACE.equals(namespace.getName()))
94+
return;
95+
}
96+
}
97+
98+
fail(TEST_NAMESPACE + " not found!");
8499
}
85100

86101
@Test
87102
public void testGetNamespacesByPage() throws GitLabApiException {
88103
List<Namespace> namespaces = gitLabApi.getNamespaceApi().getNamespaces(1, 10);
89104
assertNotNull(namespaces);
90-
assertEquals(TEST_NAMESPACE, namespaces.get(0).getName());
105+
for (Namespace namespace : namespaces) {
106+
if (TEST_NAMESPACE.equals(namespace.getName()))
107+
return;
108+
}
109+
110+
fail(TEST_NAMESPACE + " not found!");
91111
}
92112

93113
@Test

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ public void testProjects() throws GitLabApiException {
354354
public void testProjectPerPage() throws GitLabApiException {
355355
List<Project> projects = gitLabApi.getProjectApi().getProjects(1, 10);
356356
assertNotNull(projects);
357-
assertEquals(10, projects.size());
357+
assertTrue(projects.size() > 0);
358358
}
359359

360360
@Test

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

Lines changed: 35 additions & 0 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.Assert.assertNull;
56
import static org.junit.Assume.assumeTrue;
67

78
import org.gitlab4j.api.GitLabApi.ApiVersion;
@@ -27,10 +28,12 @@ public class TestUserApi {
2728
private static final String TEST_HOST_URL;
2829
private static final String TEST_PRIVATE_TOKEN;
2930
private static final String TEST_USERNAME;
31+
private static final String TEST_SUDO_AS_USERNAME;
3032
static {
3133
TEST_HOST_URL = TestUtils.getProperty("TEST_HOST_URL");
3234
TEST_PRIVATE_TOKEN = TestUtils.getProperty("TEST_PRIVATE_TOKEN");
3335
TEST_USERNAME = TestUtils.getProperty("TEST_USERNAME");
36+
TEST_SUDO_AS_USERNAME = TestUtils.getProperty("TEST_SUDO_AS_USERNAME");
3437
}
3538

3639
private static GitLabApi gitLabApi;
@@ -89,4 +92,36 @@ public void testLookupUser() throws GitLabApiException {
8992
assertNotNull(user);
9093
assertEquals(TEST_USERNAME, user.getUsername());
9194
}
95+
96+
@Test
97+
public void testSudoAsUser() throws GitLabApiException {
98+
99+
assumeTrue(TEST_SUDO_AS_USERNAME != null);
100+
101+
try {
102+
103+
gitLabApi.sudo(TEST_SUDO_AS_USERNAME);
104+
User user = gitLabApi.getUserApi().getCurrentUser();
105+
assertNotNull(user);
106+
assertEquals(TEST_SUDO_AS_USERNAME, user.getUsername());
107+
Integer sudoAsId = user.getId();
108+
109+
gitLabApi.sudo(null);
110+
user = gitLabApi.getUserApi().getCurrentUser();
111+
assertNotNull(user);
112+
assertEquals(TEST_USERNAME, user.getUsername());
113+
114+
gitLabApi.unsudo();
115+
assertNull(gitLabApi.getSudoAsId());
116+
117+
gitLabApi.setSudoAsId(sudoAsId);
118+
user = gitLabApi.getUserApi().getCurrentUser();
119+
assertNotNull(user);
120+
assertEquals(sudoAsId, user.getId());
121+
assertEquals(TEST_SUDO_AS_USERNAME, user.getUsername());
122+
123+
} finally {
124+
gitLabApi.unsudo();
125+
}
126+
}
92127
}

0 commit comments

Comments
 (0)