diff options
author | Aurelien Poscia <aurelien.poscia@sonarsource.com> | 2023-12-13 09:54:59 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-12-22 20:03:02 +0000 |
commit | d237a80b07c1a99151bb61f492ab27dfdfd65594 (patch) | |
tree | 92ad30044b9dfa5a8e727813a61a8ed122625a86 | |
parent | b2cd0f3ff50d504cd88ecf7eec9887ef4fb46ea3 (diff) | |
download | sonarqube-d237a80b07c1a99151bb61f492ab27dfdfd65594.tar.gz sonarqube-d237a80b07c1a99151bb61f492ab27dfdfd65594.zip |
SONAR-21244 Add step to fetch GitLab groups membership
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); |