diff options
author | Michal Duda <michal.duda@sonarsource.com> | 2021-06-09 10:53:16 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2021-06-10 20:03:27 +0000 |
commit | 0350d33470a3b9bab4023b785ea583b69f652e23 (patch) | |
tree | ebe8008f4c5381a5a37fab37b045502471739268 /server/sonar-alm-client | |
parent | 1caaacfcbf21b4d12b6ee428684331e464b9ac5f (diff) | |
download | sonarqube-0350d33470a3b9bab4023b785ea583b69f652e23.tar.gz sonarqube-0350d33470a3b9bab4023b785ea583b69f652e23.zip |
SONAR-14871 Add handling group shared projects to GitLab PR decoration validation
Diffstat (limited to 'server/sonar-alm-client')
5 files changed, 67 insertions, 161 deletions
diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/AccessLevel.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/AccessLevel.java deleted file mode 100644 index 4e8d43b0b8a..00000000000 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/AccessLevel.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2021 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.alm.client.gitlab; - -import com.google.gson.annotations.SerializedName; - -public class AccessLevel { - public static final int REPORTER_ACCESS_LEVEL = 20; - - @SerializedName("access_level") - private int level; - - public AccessLevel() { - // http://stackoverflow.com/a/18645370/229031 - } - - public AccessLevel(int level) { - this.level = level; - } - - public int getLevel() { - return level; - } - -} diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabHttpClient.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabHttpClient.java index a91a7ad7a4c..ffe6e647de6 100644 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabHttpClient.java +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabHttpClient.java @@ -212,7 +212,7 @@ public class GitlabHttpClient { return false; } - public ProjectDetails getProject(String gitlabUrl, String pat, Long gitlabProjectId) { + public Project getProject(String gitlabUrl, String pat, Long gitlabProjectId) { String url = String.format("%s/projects/%s", gitlabUrl, gitlabProjectId); LOG.debug(String.format("get project : [%s]", url)); Request request = new Request.Builder() @@ -225,7 +225,40 @@ public class GitlabHttpClient { checkResponseIsSuccessful(response); String body = response.body().string(); LOG.trace(String.format("loading project payload result : [%s]", body)); - return new GsonBuilder().create().fromJson(body, ProjectDetails.class); + return new GsonBuilder().create().fromJson(body, Project.class); + } catch (JsonSyntaxException e) { + throw new IllegalArgumentException("Could not parse GitLab answer to retrieve a project. Got a non-json payload as result."); + } catch (IOException e) { + logException(url, e); + throw new IllegalStateException(e.getMessage(), e); + } + } + + // + // This method is used to check if a user has REPORTER level access to the project, which is a requirement for PR decoration. + // As of June 9, 2021 there is no better way to do this check and still support GitLab 11.7. + // + public Optional<Project> getReporterLevelAccessProject(String gitlabUrl, String pat, Long gitlabProjectId) { + String url = String.format("%s/projects?min_access_level=20&id_after=%s&id_before=%s", gitlabUrl, gitlabProjectId - 1, + gitlabProjectId + 1); + LOG.debug(String.format("get project : [%s]", url)); + Request request = new Request.Builder() + .addHeader(PRIVATE_TOKEN, pat) + .get() + .url(url) + .build(); + + try (Response response = client.newCall(request).execute()) { + checkResponseIsSuccessful(response); + String body = response.body().string(); + LOG.trace(String.format("loading project payload result : [%s]", body)); + + List<Project> projects = Project.parseJsonArray(body); + if (projects.isEmpty()) { + return Optional.empty(); + } else { + return Optional.of(projects.get(0)); + } } catch (JsonSyntaxException e) { throw new IllegalArgumentException("Could not parse GitLab answer to retrieve a project. Got a non-json payload as result."); } catch (IOException e) { diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/Permissions.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/Permissions.java deleted file mode 100644 index a8a0808763d..00000000000 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/Permissions.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2021 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.alm.client.gitlab; - -import com.google.gson.annotations.SerializedName; -import javax.annotation.CheckForNull; - -public class Permissions { - // https://docs.gitlab.com/ee/api/projects.html#get-single-project - - @SerializedName("project_access") - private AccessLevel projectAccess; - - @SerializedName("group_access") - private AccessLevel groupAccess; - - public Permissions() { - // http://stackoverflow.com/a/18645370/229031 - } - - public Permissions(AccessLevel projectAccess, AccessLevel groupAccess) { - this.projectAccess = projectAccess; - this.groupAccess = groupAccess; - } - - @CheckForNull - public AccessLevel getProjectAccess() { - return projectAccess; - } - - @CheckForNull - public AccessLevel getGroupAccess() { - return groupAccess; - } -} diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/ProjectDetails.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/ProjectDetails.java deleted file mode 100644 index ce73db54dea..00000000000 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/ProjectDetails.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2021 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.alm.client.gitlab; - -public class ProjectDetails extends Project { - // https://docs.gitlab.com/ee/api/projects.html#get-single-project - - private Permissions permissions; - - public ProjectDetails(String name, String pathWithNamespace) { - super(name, pathWithNamespace); - } - - public ProjectDetails() { - // http://stackoverflow.com/a/18645370/229031 - this(0, "", "", "", "", ""); - } - - public ProjectDetails(long id, String name, String nameWithNamespace, String path, String pathWithNamespace, - String webUrl) { - super(id, name, nameWithNamespace, path, pathWithNamespace, webUrl); - } - - public Permissions getPermissions() { - return permissions; - } - - public ProjectDetails setPermissions(Permissions permissions) { - this.permissions = permissions; - return this; - } -} diff --git a/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabHttpClientTest.java b/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabHttpClientTest.java index 9869ec4f28d..283371f2cb4 100644 --- a/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabHttpClientTest.java +++ b/server/sonar-alm-client/src/test/java/org/sonar/alm/client/gitlab/GitlabHttpClientTest.java @@ -20,6 +20,7 @@ package org.sonar.alm.client.gitlab; import java.io.IOException; +import java.util.Optional; import java.util.concurrent.TimeUnit; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; @@ -285,7 +286,7 @@ public class GitlabHttpClientTest { @Test public void get_project_details() throws InterruptedException { - MockResponse projectDetails = new MockResponse() + MockResponse projectResponse = new MockResponse() .setResponseCode(200) .setBody("{" + " \"id\": 1234," @@ -293,29 +294,17 @@ public class GitlabHttpClientTest { + " \"name_with_namespace\": \"SonarSource / SonarQube / SonarQube example 2\"," + " \"path\": \"sonarqube-example-2\"," + " \"path_with_namespace\": \"sonarsource/sonarqube/sonarqube-example-2\"," - + " \"web_url\": \"https://example.gitlab.com/sonarsource/sonarqube/sonarqube-example-2\"," - + " \"permissions\": {" - + " \"project_access\": {" - + " \"access_level\": 50," - + " \"notification_level\": 3" - + " }," - + " \"group_access\": {" - + " \"access_level\": 10," - + " \"notification_level\": 3" - + " }" - + " }" + + " \"web_url\": \"https://example.gitlab.com/sonarsource/sonarqube/sonarqube-example-2\"" + "}"); - server.enqueue(projectDetails); + server.enqueue(projectResponse); - ProjectDetails project = underTest.getProject(gitlabUrl, "pat", 1234L); + Project project = underTest.getProject(gitlabUrl, "pat", 1234L); RecordedRequest projectGitlabRequest = server.takeRequest(10, TimeUnit.SECONDS); String gitlabUrlCall = projectGitlabRequest.getRequestUrl().toString(); assertThat(project).isNotNull(); - assertThat(project.getPermissions().getProjectAccess().getLevel()).isEqualTo(50); - assertThat(project.getPermissions().getGroupAccess().getLevel()).isEqualTo(10); assertThat(gitlabUrlCall).isEqualTo( server.url("") + "projects/1234"); @@ -323,6 +312,33 @@ public class GitlabHttpClientTest { } @Test + public void get_reporter_level_access_project() throws InterruptedException { + MockResponse projectResponse = new MockResponse() + .setResponseCode(200) + .setBody("[{" + + " \"id\": 1234," + + " \"name\": \"SonarQube example 2\"," + + " \"name_with_namespace\": \"SonarSource / SonarQube / SonarQube example 2\"," + + " \"path\": \"sonarqube-example-2\"," + + " \"path_with_namespace\": \"sonarsource/sonarqube/sonarqube-example-2\"," + + " \"web_url\": \"https://example.gitlab.com/sonarsource/sonarqube/sonarqube-example-2\"" + + "}]"); + + server.enqueue(projectResponse); + + Optional<Project> project = underTest.getReporterLevelAccessProject(gitlabUrl, "pat", 1234L); + + RecordedRequest projectGitlabRequest = server.takeRequest(10, TimeUnit.SECONDS); + String gitlabUrlCall = projectGitlabRequest.getRequestUrl().toString(); + + assertThat(project).isNotNull(); + + assertThat(gitlabUrlCall).isEqualTo( + server.url("") + "projects?min_access_level=20&id_after=1233&id_before=1235"); + assertThat(projectGitlabRequest.getMethod()).isEqualTo("GET"); + } + + @Test public void search_projects_fail_if_could_not_parse_pagination_number() { MockResponse projects = new MockResponse() .setResponseCode(200) |