aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurelien Poscia <aurelien.poscia@sonarsource.com>2023-12-13 09:54:59 +0100
committersonartech <sonartech@sonarsource.com>2023-12-22 20:03:02 +0000
commitd237a80b07c1a99151bb61f492ab27dfdfd65594 (patch)
tree92ad30044b9dfa5a8e727813a61a8ed122625a86
parentb2cd0f3ff50d504cd88ecf7eec9887ef4fb46ea3 (diff)
downloadsonarqube-d237a80b07c1a99151bb61f492ab27dfdfd65594.tar.gz
sonarqube-d237a80b07c1a99151bb61f492ab27dfdfd65594.zip
SONAR-21244 Add step to fetch GitLab groups membership
-rw-r--r--server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java13
-rw-r--r--server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabApplicationClientTest.java48
-rw-r--r--server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GsonUser.java8
3 files changed, 58 insertions, 11 deletions
diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java
index cb260fcec33..0abe8f4e39e 100644
--- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java
+++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabApplicationClient.java
@@ -62,6 +62,7 @@ public class GitlabApplicationClient {
private static final Type GITLAB_USER = TypeToken.getParameterized(List.class, GsonUser.class).getType();
protected static final String PRIVATE_TOKEN = "Private-Token";
+ private static final String GITLAB_GROUPS_MEMBERS_ENDPOINT = "/groups/%s/members";
protected final OkHttpClient client;
private final GitlabPaginatedHttpClient gitlabPaginatedHttpClient;
@@ -355,8 +356,16 @@ public class GitlabApplicationClient {
return Set.copyOf(executePaginatedQuery(gitlabUrl, token, "/groups", resp -> GSON.fromJson(resp, GITLAB_GROUP)));
}
- public Set<GsonUser> getGroupMembers(String gitlabUrl, String token, String groupId) {
- return Set.copyOf(executePaginatedQuery(gitlabUrl, token, format("/groups/%s/members", groupId), resp -> GSON.fromJson(resp, GITLAB_USER)));
+ public Set<GsonUser> getDirectGroupMembers(String gitlabUrl, String token, String groupId) {
+ return getMembers(gitlabUrl, token, format(GITLAB_GROUPS_MEMBERS_ENDPOINT, groupId));
+ }
+
+ public Set<GsonUser> getAllGroupMembers(String gitlabUrl, String token, String groupId) {
+ return getMembers(gitlabUrl, token, format(GITLAB_GROUPS_MEMBERS_ENDPOINT + "/all", groupId));
+ }
+
+ private Set<GsonUser> getMembers(String gitlabUrl, String token, String endpoint) {
+ return Set.copyOf(executePaginatedQuery(gitlabUrl, token, endpoint, resp -> GSON.fromJson(resp, GITLAB_USER)));
}
private <E> List<E> executePaginatedQuery(String appUrl, String token, String query, Function<String, List<E>> responseDeserializer) {
diff --git a/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabApplicationClientTest.java b/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabApplicationClientTest.java
index a16c0bfc79b..8311abf26f7 100644
--- a/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabApplicationClientTest.java
+++ b/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabApplicationClientTest.java
@@ -584,18 +584,18 @@ public class GitlabApplicationClientTest {
}
@Test
- public void getGroupMembers_whenCallIsInError_rethrows() throws IOException {
+ public void getDirectGroupMembers_whenCallIsInError_rethrows() {
String token = "token-toto";
GitlabToken gitlabToken = new GitlabToken(token);
when(gitlabPaginatedHttpClient.get(eq(gitlabUrl), eq(gitlabToken), eq("/groups/42/members"), any())).thenThrow(new IllegalStateException("exception"));
assertThatIllegalStateException()
- .isThrownBy(() -> underTest.getGroupMembers(gitlabUrl, token, "42"))
+ .isThrownBy(() -> underTest.getDirectGroupMembers(gitlabUrl, token, "42"))
.withMessage("exception");
}
@Test
- public void getGroupMembers_whenCallIsSuccessful_deserializesAndReturnsCorrectlyGroupMembers() throws IOException {
+ public void getDirectGroupMembers_whenCallIsSuccessful_deserializesAndReturnsCorrectlyGroupMembers() throws IOException {
ArgumentCaptor<Function<String, List<GsonUser>>> deserializerCaptor = ArgumentCaptor.forClass(Function.class);
String token = "token-toto";
@@ -603,7 +603,36 @@ public class GitlabApplicationClientTest {
List<GsonUser> expectedGroupMembers = expectedGroupMembers();
when(gitlabPaginatedHttpClient.get(eq(gitlabUrl), eq(gitlabToken), eq("/groups/42/members"), deserializerCaptor.capture())).thenReturn(expectedGroupMembers);
- Set<GsonUser> actualGroupMembers = underTest.getGroupMembers(gitlabUrl, token, "42");
+ Set<GsonUser> actualGroupMembers = underTest.getDirectGroupMembers(gitlabUrl, token, "42");
+ assertThat(actualGroupMembers).containsExactlyInAnyOrderElementsOf(expectedGroupMembers);
+
+ String responseContent = getResponseContent("group-members-full-response.json");
+
+ List<GsonUser> deserializedUsers = deserializerCaptor.getValue().apply(responseContent);
+ assertThat(deserializedUsers).usingRecursiveComparison().isEqualTo(expectedGroupMembers);
+ }
+
+ @Test
+ public void getDirectGroupMembersWithInheritedMembers_whenCallIsInError_rethrows() {
+ String token = "token-toto";
+ GitlabToken gitlabToken = new GitlabToken(token);
+ when(gitlabPaginatedHttpClient.get(eq(gitlabUrl), eq(gitlabToken), eq("/groups/42/members/all"), any())).thenThrow(new IllegalStateException("exception"));
+
+ assertThatIllegalStateException()
+ .isThrownBy(() -> underTest.getAllGroupMembers(gitlabUrl, token, "42"))
+ .withMessage("exception");
+ }
+
+ @Test
+ public void getAllGroupMembers_whenCallIsSuccessful_deserializesAndReturnsCorrectlyGroupMembers() throws IOException {
+ ArgumentCaptor<Function<String, List<GsonUser>>> deserializerCaptor = ArgumentCaptor.forClass(Function.class);
+
+ String token = "token-toto";
+ GitlabToken gitlabToken = new GitlabToken(token);
+ List<GsonUser> expectedGroupMembers = expectedGroupMembers();
+ when(gitlabPaginatedHttpClient.get(eq(gitlabUrl), eq(gitlabToken), eq("/groups/42/members/all"), deserializerCaptor.capture())).thenReturn(expectedGroupMembers);
+
+ Set<GsonUser> actualGroupMembers = underTest.getAllGroupMembers(gitlabUrl, token, "42");
assertThat(actualGroupMembers).containsExactlyInAnyOrderElementsOf(expectedGroupMembers);
String responseContent = getResponseContent("group-members-full-response.json");
@@ -613,17 +642,18 @@ public class GitlabApplicationClientTest {
}
private static List<GsonUser> expectedGroupMembers() {
- GsonUser user1 = createGsonUser(12818153L, "aurelien-poscia-sonarsource", "Aurelien");
- GsonUser user2 = createGsonUser(10941672L, "antoine.vigneau", "Antoine Vigneau");
- GsonUser user3 = createGsonUser(13569073L, "wojciech.wajerowicz.sonarsource", "Wojciech Wajerowicz");
+ GsonUser user1 = createGsonUser(12818153, "aurelien-poscia-sonarsource", "Aurelien", 50);
+ GsonUser user2 = createGsonUser(10941672, "antoine.vigneau", "Antoine Vigneau", 30);
+ GsonUser user3 = createGsonUser(13569073, "wojciech.wajerowicz.sonarsource", "Wojciech Wajerowicz", 30);
return List.of(user1, user2, user3);
}
- private static GsonUser createGsonUser(Long id, String username, String name) {
+ private static GsonUser createGsonUser(int id, String username, String name, int accessLevel) {
GsonUser gsonUser = mock();
- when(gsonUser.getId()).thenReturn(id);
+ when(gsonUser.getId()).thenReturn((long) id);
when(gsonUser.getUsername()).thenReturn(username);
when(gsonUser.getName()).thenReturn(name);
+ when(gsonUser.getAccessLevel()).thenReturn(accessLevel);
return gsonUser;
}
diff --git a/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GsonUser.java b/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GsonUser.java
index 9587f81aab4..433572aa070 100644
--- a/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GsonUser.java
+++ b/server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GsonUser.java
@@ -20,6 +20,7 @@
package org.sonar.auth.gitlab;
import com.google.gson.Gson;
+import com.google.gson.annotations.SerializedName;
/**
* Lite representation of JSON response of GET https://gitlab.com/api/v4/user
@@ -30,6 +31,9 @@ public class GsonUser {
private String name;
private String email;
+ @SerializedName("access_level")
+ private int accessLevel;
+
public GsonUser() {
// even if empty constructor is not required for Gson, it is strongly
// recommended:
@@ -52,6 +56,10 @@ public class GsonUser {
return email;
}
+ public int getAccessLevel() {
+ return accessLevel;
+ }
+
public static GsonUser parse(String json) {
Gson gson = new Gson();
return gson.fromJson(json, GsonUser.class);