diff options
author | Aurelien Poscia <aurelien.poscia@sonarsource.com> | 2023-10-16 11:09:16 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-10-20 20:02:40 +0000 |
commit | 8445ca39a9f46b228f693fbb259f623ba6d05414 (patch) | |
tree | fa2d714624e16a1254c931057d6f8d2386f3a8fc /server/sonar-alm-client/src/main/java | |
parent | f5f71fdbe1482d7b132a9923419672459d762aad (diff) | |
download | sonarqube-8445ca39a9f46b228f693fbb259f623ba6d05414.tar.gz sonarqube-8445ca39a9f46b228f693fbb259f623ba6d05414.zip |
SONAR-20700 Move getRepositoryCollaborators/getRepositoryTeams from GithubUserClient to GithubApplicationClient (and make it accessible for commmunity edition)
Diffstat (limited to 'server/sonar-alm-client/src/main/java')
5 files changed, 142 insertions, 8 deletions
diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClient.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClient.java index 9a7db826bb3..7ef05182cd0 100644 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClient.java +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClient.java @@ -22,9 +22,12 @@ package org.sonar.alm.client.github; import com.google.gson.annotations.SerializedName; import java.util.List; import java.util.Optional; +import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.sonar.alm.client.github.api.GsonRepositoryCollaborator; +import org.sonar.alm.client.github.api.GsonRepositoryTeam; import org.sonar.alm.client.github.config.GithubAppConfiguration; import org.sonar.alm.client.github.config.GithubAppInstallation; import org.sonar.alm.client.github.security.AccessToken; @@ -93,6 +96,12 @@ public interface GithubApplicationClient { */ Optional<Repository> getRepository(String appUrl, AccessToken accessToken, String repositoryKey); + + + Set<GsonRepositoryTeam> getRepositoryTeams(String appUrl, AppInstallationToken accessToken, String orgName, String repoName); + + Set<GsonRepositoryCollaborator> getRepositoryCollaborators(String appUrl, AppInstallationToken accessToken, String orgName, String repoName); + class Repositories { private int total; private List<Repository> repositories; diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java index be6914fa8a5..9403377c59f 100644 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java @@ -32,6 +32,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; import org.slf4j.Logger; @@ -40,6 +41,8 @@ import org.sonar.alm.client.github.GithubApplicationHttpClient.GetResponse; import org.sonar.alm.client.github.GithubBinding.GsonGithubRepository; import org.sonar.alm.client.github.GithubBinding.GsonInstallations; import org.sonar.alm.client.github.GithubBinding.GsonRepositorySearch; +import org.sonar.alm.client.github.api.GsonRepositoryCollaborator; +import org.sonar.alm.client.github.api.GsonRepositoryTeam; import org.sonar.alm.client.github.config.GithubAppConfiguration; import org.sonar.alm.client.github.config.GithubAppInstallation; import org.sonar.alm.client.github.security.AccessToken; @@ -66,6 +69,12 @@ public class GithubApplicationClientImpl implements GithubApplicationClient { protected static final String WRITE_PERMISSION_NAME = "write"; protected static final String READ_PERMISSION_NAME = "read"; protected static final String FAILED_TO_REQUEST_BEGIN_MSG = "Failed to request "; + + private static final String EXCEPTION_MESSAGE = "SonarQube was not able to retrieve resources from GitHub. " + + "This is likely due to a connectivity problem or a temporary network outage"; + + private static final Type REPOSITORY_TEAM_LIST_TYPE = TypeToken.getParameterized(List.class, GsonRepositoryTeam.class).getType(); + private static final Type REPOSITORY_COLLABORATORS_LIST_TYPE = TypeToken.getParameterized(List.class, GsonRepositoryCollaborator.class).getType(); private static final Type ORGANIZATION_LIST_TYPE = TypeToken.getParameterized(List.class, GithubBinding.GsonInstallation.class).getType(); protected final GithubApplicationHttpClient appHttpClient; protected final GithubAppSecurity appSecurity; @@ -232,13 +241,8 @@ public class GithubApplicationClientImpl implements GithubApplicationClient { private List<GithubBinding.GsonInstallation> fetchAppInstallationsFromGithub(GithubAppConfiguration githubAppConfiguration) { AppToken appToken = appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey()); String endpoint = "/app/installations"; - try { - return githubPaginatedHttpClient.get(githubAppConfiguration.getApiEndpoint(), appToken, endpoint, resp -> GSON.fromJson(resp, ORGANIZATION_LIST_TYPE)); - } catch (IOException e) { - LOG.warn(FAILED_TO_REQUEST_BEGIN_MSG + endpoint, e); - throw new IllegalStateException("An error occurred when retrieving your GitHup App installations. " - + "It might be related to your GitHub App configuration or a connectivity problem."); - } + + return executePaginatedQuery(githubAppConfiguration.getApiEndpoint(), appToken, endpoint, resp -> GSON.fromJson(resp, ORGANIZATION_LIST_TYPE)); } protected <T> Optional<T> get(String baseUrl, AccessToken token, String endPoint, Class<T> gsonClass) { @@ -292,7 +296,7 @@ public class GithubApplicationClientImpl implements GithubApplicationClient { .map(GsonGithubRepository::toRepository); } catch (Exception e) { throw new IllegalStateException(format("Failed to get repository '%s' on '%s' (this might be related to the GitHub App installation scope)", - organizationAndRepository, appUrl), e); + organizationAndRepository, appUrl), e); } } @@ -363,4 +367,42 @@ public class GithubApplicationClientImpl implements GithubApplicationClient { return Optional.empty(); } } + + @Override + public Set<GsonRepositoryTeam> getRepositoryTeams(String appUrl, AppInstallationToken accessToken, String orgName, String repoName) { + return Set + .copyOf(executePaginatedQuery(appUrl, accessToken, format("/repos/%s/%s/teams", orgName, repoName), resp -> GSON.fromJson(resp, REPOSITORY_TEAM_LIST_TYPE))); + } + + @Override + public Set<GsonRepositoryCollaborator> getRepositoryCollaborators(String appUrl, AppInstallationToken accessToken, String orgName, String repoName) { + return Set + .copyOf( + executePaginatedQuery( + appUrl, + accessToken, + format("/repos/%s/%s/collaborators?affiliation=direct", orgName, repoName), + resp -> GSON.fromJson(resp, REPOSITORY_COLLABORATORS_LIST_TYPE))); + } + + private <E> List<E> executePaginatedQuery(String appUrl, AccessToken token, String query, Function<String, List<E>> responseDeserializer) { + try { + return githubPaginatedHttpClient.get(appUrl, token, query, responseDeserializer); + } catch (IOException ioException) { + throw logAndCreateException(ioException, format("Error while executing a paginated call to GitHub - appUrl: %s, path: %s.", appUrl, query)); + } + } + + private static IllegalStateException logAndCreateException(IOException ioException, String errorMessage) { + log(errorMessage, ioException); + return new IllegalStateException(EXCEPTION_MESSAGE + ": " + errorMessage + " " + ioException.getMessage()); + } + + private static void log(String message, Exception e) { + if (LOG.isDebugEnabled()) { + LOG.warn(message, e); + } else { + LOG.warn(message); + } + } } diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryCollaborator.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryCollaborator.java new file mode 100644 index 00000000000..d7f43cc4e12 --- /dev/null +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryCollaborator.java @@ -0,0 +1,29 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 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.github.api; + +import com.google.gson.annotations.SerializedName; +import org.sonar.auth.github.GsonRepositoryPermissions; + +public record GsonRepositoryCollaborator(@SerializedName("login") String name, + @SerializedName("id") Integer id, + @SerializedName("role_name") String roleName, + @SerializedName("permissions") GsonRepositoryPermissions permissions) { +} diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryTeam.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryTeam.java new file mode 100644 index 00000000000..806b5de9e27 --- /dev/null +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryTeam.java @@ -0,0 +1,31 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 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.github.api; + +import com.google.gson.annotations.SerializedName; +import org.sonar.auth.github.GsonRepositoryPermissions; + +public record GsonRepositoryTeam( + @SerializedName("name") String name, + @SerializedName("id") Integer id, + @SerializedName("slug") String slug, + @SerializedName("permission") String permission, + @SerializedName("permissions") GsonRepositoryPermissions permissions) { +} diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/package-info.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/package-info.java new file mode 100644 index 00000000000..4c1a2f9b0a9 --- /dev/null +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/package-info.java @@ -0,0 +1,23 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.alm.client.github.api; + +import javax.annotation.ParametersAreNonnullByDefault; |