Skip to content

Commit a8ce9ec

Browse files
authored
Merge pull request #666 from GJKrupa/master
#665 - [Feature Request] Get PGP keys in user API
2 parents e8aa3de + 4880422 commit a8ce9ec

File tree

3 files changed

+212
-5
lines changed

3 files changed

+212
-5
lines changed

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

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.gitlab4j.api.GitLabApi.ApiVersion;
1515
import org.gitlab4j.api.models.CustomAttribute;
1616
import org.gitlab4j.api.models.Email;
17+
import org.gitlab4j.api.models.GpgKey;
1718
import org.gitlab4j.api.models.ImpersonationToken;
1819
import org.gitlab4j.api.models.ImpersonationToken.Scope;
1920
import org.gitlab4j.api.models.Membership;
@@ -1214,6 +1215,87 @@ public void deleteEmail(final Object userIdOrUsername, final Long emailId) throw
12141215
delete(Response.Status.NO_CONTENT, null, "users", getUserIdOrUsername(userIdOrUsername), "emails", emailId);
12151216
}
12161217

1218+
/**
1219+
* Get all GPG keys for the current user.
1220+
*
1221+
* <pre><code>GitLab Endpoint: GET /user/gpg_keys</code></pre>
1222+
*
1223+
* @throws GitLabApiException if any exception occurs
1224+
*/
1225+
public List<GpgKey> listGpgKeys() throws GitLabApiException {
1226+
Response response = get(Response.Status.OK, null, "user", "gpg_keys");
1227+
return (response.readEntity(new GenericType<List<GpgKey>>() {}));
1228+
}
1229+
1230+
/**
1231+
* Add a GPG key for the current user
1232+
*
1233+
* <pre><code>GitLab Endpoint: POST /user/gpg_keys</code></pre>
1234+
*
1235+
* @param key the ASCII-armored exported public GPG key to add
1236+
* @throws GitLabApiException if any exception occurs
1237+
*/
1238+
public GpgKey addGpgKey(final String key) throws GitLabApiException {
1239+
GitLabApiForm formData = new GitLabApiForm()
1240+
.withParam("key", key, true);
1241+
Response response = post(Response.Status.CREATED, formData, "user", "gpg_keys");
1242+
return (response.readEntity(GpgKey.class));
1243+
}
1244+
1245+
/**
1246+
* Remove a specific GPG key for the current user
1247+
*
1248+
* <pre><code>GitLab Endpoint: DELETE /user/gpg_keys/:keyId</code></pre>
1249+
*
1250+
* @param keyId the key ID in the form if an Integer(ID)
1251+
* @throws GitLabApiException if any exception occurs
1252+
*/
1253+
public void deleteGpgKey(final Integer keyId) throws GitLabApiException {
1254+
delete(Response.Status.NO_CONTENT, null, "user", "gpg_keys", keyId);
1255+
}
1256+
1257+
/**
1258+
* Get all GPG keys for a given user.
1259+
*
1260+
* <pre><code>GitLab Endpoint: GET /users/:id/gpg_keys</code></pre>
1261+
*
1262+
* @param userId the user in the form of an Integer(ID)
1263+
* @throws GitLabApiException if any exception occurs
1264+
*/
1265+
public List<GpgKey> listGpgKeys(final Integer userId) throws GitLabApiException {
1266+
Response response = get(Response.Status.OK, null, "users", userId, "gpg_keys");
1267+
return (response.readEntity(new GenericType<List<GpgKey>>() {}));
1268+
}
1269+
1270+
/**
1271+
* Add a GPG key for a specific user
1272+
*
1273+
* <pre><code>GitLab Endpoint: POST /users/:id/gpg_keys</code></pre>
1274+
*
1275+
* @param userId the user in the form of an Integer(ID)
1276+
* @param key the ASCII-armored exported public GPG key to add
1277+
* @throws GitLabApiException if any exception occurs
1278+
*/
1279+
public GpgKey addGpgKey(final Integer userId, final String key) throws GitLabApiException {
1280+
GitLabApiForm formData = new GitLabApiForm()
1281+
.withParam("key", key, true);
1282+
Response response = post(Response.Status.CREATED, formData, "users", userId, "gpg_keys");
1283+
return (response.readEntity(GpgKey.class));
1284+
}
1285+
1286+
/**
1287+
* Remove a specific GPG key for a specific user
1288+
*
1289+
* <pre><code>GitLab Endpoint: DELETE /users/:id/gpg_keys/:keyId</code></pre>
1290+
*
1291+
* @param userId the user in the form of an Integer(ID)
1292+
* @param keyId the key ID in the form if an Integer(ID)
1293+
* @throws GitLabApiException if any exception occurs
1294+
*/
1295+
public void deleteGpgKey(final Integer userId, final Integer keyId) throws GitLabApiException {
1296+
delete(Response.Status.NO_CONTENT, null, "users", userId, "gpg_keys", keyId);
1297+
}
1298+
12171299
/**
12181300
* Lists all projects and groups a user is a member of. (admin only)
12191301
*
@@ -1229,5 +1311,4 @@ public List<Membership> getMemberships(Integer userId) throws GitLabApiException
12291311
Response response = get(Response.Status.OK, formData.asMap(), "users", userId, "memberships");
12301312
return (response.readEntity(new GenericType<List<Membership>>() {}));
12311313
}
1232-
12331314
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.gitlab4j.api.models;
2+
3+
import java.util.Date;
4+
5+
public class GpgKey {
6+
7+
private Integer id;
8+
private String key;
9+
private Date created_at;
10+
11+
public Integer getId() {
12+
return id;
13+
}
14+
15+
public void setId(Integer id) {
16+
this.id = id;
17+
}
18+
19+
public String getKey() {
20+
return key;
21+
}
22+
23+
public void setKey(String key) {
24+
this.key = key;
25+
}
26+
27+
public Date getCreated_at() {
28+
return created_at;
29+
}
30+
31+
public void setCreated_at(Date created_at) {
32+
this.created_at = created_at;
33+
}
34+
}

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

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.gitlab4j.api.models.AccessLevel;
2222
import org.gitlab4j.api.models.Email;
23+
import org.gitlab4j.api.models.GpgKey;
2324
import org.gitlab4j.api.models.ImpersonationToken;
2425
import org.gitlab4j.api.models.ImpersonationToken.Scope;
2526
import org.gitlab4j.api.models.Membership;
@@ -60,14 +61,66 @@ public class TestUserApi extends AbstractIntegrationTest {
6061
private static final String TEST_SUDO_AS_USERNAME = HelperUtils.getProperty(SUDO_AS_USERNAME_KEY);
6162

6263
private static final String TEST_IMPERSONATION_TOKEN_NAME = "token1";
63-
private static final String TEST_SSH_KEY =
64+
private static final String TEST_SSH_KEY =
6465
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3rWzl/oPAD+Em2iGTmR81HcYZsopvnKp7jelI4XS91fT1NjCRrGsxf5Mw/" +
6566
"KnmtBjhk+kQjkhIrnsBDcs6DZWtNcHJtyWJZrYsfxMTqWCaQv+OTRwVboqS2pmPcbK3gizUd5GCLFTKbg4OMpdywTwi6NAPwQ" +
6667
"rtn3xwiVnGGCfBSyRFppcYP81otALctrlAW57V5+bQwFIJteJ+NWe1UmPxrqQ0N/a+dEEoJHzwX8RtVSkULafrRw8avn6Zp2x" +
6768
"1OlD2aIEMQWvepNTRW6UDMSmWFc61ycy1pF5sCT5rij+b/fN4qCEvQs6R7GmCzaaZzbWuAqaxLRdITm/WUxdG6rjh";
6869

6970
private static final String TEST_USER_EMAIL = "[email protected]";
7071

72+
// Key for [email protected] - set to never expire
73+
private static final String TEST_GPG_KEY = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n" +
74+
"mQINBGBHltIBEADW8zSGAs/XEkwWI36xOusuOqSINhTDVuqq3n50Oazb+a9Ai/MM\n" +
75+
"8GTm900ZZghGBVUXGm8PkWuSmabcpbDbjYmJx8aIY71UipXxXrfBzr8S2yOx7IjU\n" +
76+
"m6AEw0HwNUF6ayBwsklUFFWMyCeCVSCeZNldFwKRQApP6YOlTlwmZFESv32J6AHz\n" +
77+
"goeEsIcoea484nVJKOl7unneb8TyuF6kmViyZtiDkjeiH5vNy8XjSWH9xl5tcBxy\n" +
78+
"70NxkZt9EKnMq8izy51OBdzA+oWByGIGRjRPrW+5niMCGltV0w12M0uMDa2pJU2B\n" +
79+
"Z0U7uL/Lj3srMnD54OjbjK++wtYbshhGKXhAzshk9RgZq5fEN7Jjn1CTvue5EcHz\n" +
80+
"D27RD4yy35MledJ0hrvcTVVxvFmTg3TfDFdQBVLHjRATdXo7xT1Wg35M3z3aVSRt\n" +
81+
"PoynOxGNSotKUGfW5bhCB9XjUNpNY7+IphLS4LuQ3vZdEs9MTTWagoOoDx5w2PRS\n" +
82+
"7VNccRsqgIbNkpPjy78wN9m1QV97ytFs57eE+FfNDkKYeeCQDeHbeBlOmoEP/vSc\n" +
83+
"plOb6K3mdJgs0d5klXTOrFRVCYHHQ84p1YyQDKZO2Qd6JtHo5FNeqvgj5JwnBdfH\n" +
84+
"NGUdnaSn6hQTd8UB0AfwB+CC7cJq/fhbgcNvfK0ErHd24tsCif8vP9AG4QARAQAB\n" +
85+
"tBtGYWtlIFBlcnNvbiA8ZmFrZUBmYWtlLmNvbT6JAk4EEwEIADgWIQSE5/Jy7XYO\n" +
86+
"8riBcF/RhpwhMYJMpwUCYEeW0gIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAK\n" +
87+
"CRDRhpwhMYJMp+ESD/99LNCF1bqg/jhQOC4UIdwzCCVkUP8imrL6NnBUso+FAwH6\n" +
88+
"AT+Pbg8JLpM0lfcjzD5PV+ekLtWTZZVsyObfdRo7GrtBt/wcLKfJU5uQmrJfRClN\n" +
89+
"mdiHbh8LyVwfhLp20JRqV6NiEWSdWwNBq8zMZGgZ6HONC7JPGokak0MKpU2Woyc3\n" +
90+
"BlAU+998mdoDPKWT8XEr8cnHFFuUpZb4oWhqNV36mFrkdBZovEbnfefA+JvcxwEs\n" +
91+
"khAeaNLmpZWZ95YSimJuL4sKUjPCXlkHs9nayTFeDdNcZPAuZwfBCLpdCSj4ErYV\n" +
92+
"MyMHs/8J7CibulJB/o8qpp07oa3Qlcd62XNpqDOEIxiWHefnaYgkyIHtmzhXH4Fa\n" +
93+
"O7Ir3zGcwARXpQfobRUmtFdzeJT3zVVdUWjkKr5rgwYZZraADXGvOo8xJ5cvdrzq\n" +
94+
"4/yvOaNNoIA4KkuZcXbnqsh31pT77PxsqK60+TpLzw/jyzTqmVTEG+6SUobW7o6D\n" +
95+
"qrpqR2RPH0GtyzKHuGKSCJClDmiLF+XSyjScGUAlQ9hcFquI6F1Vddy88yURaESK\n" +
96+
"qy2agvhSkgpRxeuglytl6ZbWp/AIXrkh3F6qJozMNMFzEokapRYsQe+QdXCDSGDQ\n" +
97+
"DNvXXfIvxrFv+vQLy4jjM+DwJfrw0eN2XZ+U3E9sP0uloiVgU1zg1wc2tyPv77kC\n" +
98+
"DQRgR5bSARAAwumSlVvzb3JORu2ezPsCh8C+VJe2nPo8m+vR1Dni58UB3xnixZnF\n" +
99+
"lPaEprnIO5TSDwELJJN3oNM+AVAPjUJYHotKny5iBSFPIbHYYHs/mGRqo4jHa4b6\n" +
100+
"riNRWJ1xoYdvzH7PKAcV36tl27Y4SuQVMYmnaSXbDkGOqd9cenqVHikhj9+SJxNr\n" +
101+
"yIHrw/SNbNbRl3cMVfke2vgRp9Eso5Ivpl6tjNoohAwDp3L6MGbHliEYQgk8pjzq\n" +
102+
"bIR4lakKNVdRQoW/ZaQM2GkDlbCIEuY/7Rr4ZA1L0tsALY+bnv+9SMtA1OnMvNQ7\n" +
103+
"7Pn2uTSHeIbSVxsRk9aWmK63l20OEcB/YPmTSeNvq0JVzJ2fLG2ZL6NUHBBF2DB4\n" +
104+
"x66FA8mu9cK3Y9Jnc/3KWdzGA74R4HSIcuDPGkZmPtDMXSgXArRuD0s71QgH5E3U\n" +
105+
"9/QJ8g4s9Mjb/8aBhbg+7lm8HzN3XANmbR+y/s71Askw/ewlbhfmwxK+/XI3xDr0\n" +
106+
"1jkf42cmoLq4/Y292mQjFkcq6cCFIxDOXM89Qopbtm6PnaQsKyz0GoiyHsP846yS\n" +
107+
"RdiHTVHrUdiLl+6TIK90cm8CzNoiF+UGvdD4HObWbySh8O8n1nno+lX9EwSoq20o\n" +
108+
"0WobXesDjNIrzJHow0WGGbx5gTxlZq0WwmgXgwYM0PbqlfjxFjct+98AEQEAAYkC\n" +
109+
"NgQYAQgAIBYhBITn8nLtdg7yuIFwX9GGnCExgkynBQJgR5bSAhsMAAoJENGGnCEx\n" +
110+
"gkynbOkQAI+N/wFxOTbewuTiy0P11saqqYr7Jwc7NLhqOVZ1tHKaTB6ZDbIrlWjN\n" +
111+
"u2tFk7PqsA4/zI6KO9JoKiQYbopZ+xjd1nCJUjkUKI/wi4rl0t7ELQKhlSlUC11f\n" +
112+
"Nz0C6Q+9cwRQCCT4sX/ZkzVQbGWx9fkAYVHzezDqh43xorXJ2ix5y63pr1NGuUgx\n" +
113+
"EujMlUbXFzXpUrCmdUVWujlp4gSEfd6tLW0WMw0tYJe6UY7xx4EmWsT+kAGj7QLH\n" +
114+
"L06yFigDQ0eUkGQ1T7Z0AjG4EXGETbX6lSLwzIBnmaZXQxdx4LiRy9TcaNtcowH4\n" +
115+
"U2yxCoG0o0kS7sS/rI77TV6WZ46DPCJmlNJ+MP8lt0j/nsDA3AECB1AA+8SNepbA\n" +
116+
"LSZY7MJmh4nsqJ+iy/XMosipluZx2u6ZwlXAHxAzHhs7FBsvdMtq/gLNAlZzVyeH\n" +
117+
"UqzRaMJps7xIbap5d5jZT5jaZwFeGi+63YVRx3Jm6dkiBCPFffLyWdrzkFTZdWqZ\n" +
118+
"PkiRbJ64wYPIWQgAN/RhmCcRBhxJE8f7kgo/nBkZ5dwmfXgnXpheEaaCSzvJ4nMh\n" +
119+
"TUdg6ZLna12QndjI5gy5aenrr5H/HmDKKSNkuWZv0+NS4GhwnL8NFs+MRk6znpLN\n" +
120+
"aEjPdfYxINCMz+uotKJV9NieDWIbEJLlfZUf2hJwuwwjQGAyVf7b\n" +
121+
"=ryCD\n" +
122+
"-----END PGP PUBLIC KEY BLOCK-----";
123+
71124
private static final String TEST_EXTERNAL_USERNAME = HelperUtils.getProperty(EXTERNAL_USERNAME_KEY);
72125
private static final String TEST_EXTERNAL_PROVIDER = HelperUtils.getProperty(EXTERNAL_PROVIDER_KEY);
73126
private static final String TEST_EXTERNAL_UID = HelperUtils.getProperty(EXTERNAL_UID_KEY);
@@ -153,7 +206,7 @@ public void testGetVersion() throws GitLabApiException {
153206
assertNotNull(version.getVersion());
154207
assertNotNull(version.getRevision());
155208
}
156-
209+
157210
@Test
158211
public void testGetCurrentUser() throws GitLabApiException {
159212
User currentUser = gitLabApi.getUserApi().getCurrentUser();
@@ -271,7 +324,7 @@ public void testCreateImpersonationToken() throws GitLabApiException, ParseExcep
271324

272325
User user = gitLabApi.getUserApi().getCurrentUser();
273326

274-
// NOTE: READ_REGISTRY scope is left out because the GitLab server docker instance does not have the
327+
// NOTE: READ_REGISTRY scope is left out because the GitLab server docker instance does not have the
275328
// registry configured and the test would thus fail.
276329
Scope[] scopes = {Scope.API, Scope.READ_USER, Scope.READ_REPOSITORY, Scope.WRITE_REPOSITORY, Scope.SUDO};
277330
Date expiresAt = ISO8601.toDate("2018-01-01T00:00:00Z");
@@ -443,7 +496,7 @@ public void testEmails() throws GitLabApiException {
443496
assertTrue(emails.size() == currentSize + 1);
444497
Email found = emails.stream().filter(e -> e.getEmail().equals(TEST_USER_EMAIL)).findAny().orElse(null);
445498
assertNotNull(found);
446-
499+
447500
gitLabApi.getUserApi().deleteEmail(currentUser, email.getId());
448501
emails = gitLabApi.getUserApi().getEmails(currentUser);
449502
assertEquals(currentSize, emails.size());
@@ -452,6 +505,45 @@ public void testEmails() throws GitLabApiException {
452505
}
453506

454507
@Test
508+
public void testGpgKeys() throws GitLabApiException {
509+
User currentUser = gitLabApi.getUserApi().getCurrentUser();
510+
assertNotNull(currentUser);
511+
List<GpgKey> keys = gitLabApi.getUserApi().listGpgKeys(currentUser.getId());
512+
assertNotNull(keys);
513+
int currentSize = keys.size();
514+
515+
GpgKey key = gitLabApi.getUserApi().addGpgKey(currentUser.getId(), TEST_GPG_KEY);
516+
keys = gitLabApi.getUserApi().listGpgKeys(currentUser.getId());
517+
assertTrue(keys.size() == currentSize + 1);
518+
GpgKey found = keys.stream().filter(e -> e.getKey().equals(TEST_GPG_KEY)).findAny().orElse(null);
519+
assertNotNull(found);
520+
521+
gitLabApi.getUserApi().deleteGpgKey(currentUser.getId(), key.getId());
522+
keys = gitLabApi.getUserApi().listGpgKeys(currentUser.getId());
523+
assertEquals(currentSize, keys.size());
524+
found = keys.stream().filter(e -> e.getKey().equals(TEST_GPG_KEY)).findAny().orElse(null);
525+
assertNull(found);
526+
}
527+
528+
@Test
529+
public void testGpgKeysCurrentUser() throws GitLabApiException {
530+
List<GpgKey> keys = gitLabApi.getUserApi().listGpgKeys();
531+
assertNotNull(keys);
532+
int currentSize = keys.size();
533+
534+
GpgKey key = gitLabApi.getUserApi().addGpgKey(TEST_GPG_KEY);
535+
keys = gitLabApi.getUserApi().listGpgKeys();
536+
assertTrue(keys.size() == currentSize + 1);
537+
GpgKey found = keys.stream().filter(e -> e.getKey().equals(TEST_GPG_KEY)).findAny().orElse(null);
538+
assertNotNull(found);
539+
540+
gitLabApi.getUserApi().deleteGpgKey(key.getId());
541+
keys = gitLabApi.getUserApi().listGpgKeys();
542+
assertEquals(currentSize, keys.size());
543+
found = keys.stream().filter(e -> e.getKey().equals(TEST_GPG_KEY)).findAny().orElse(null);
544+
assertNull(found);
545+
}
546+
455547
public void testGetMemberships() throws GitLabApiException {
456548
User currentUser = gitLabApi.getUserApi().getCurrentUser();
457549
assertNotNull(currentUser);

0 commit comments

Comments
 (0)