aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-alm-client/src/main/java
diff options
context:
space:
mode:
authorAurelien Poscia <aurelien.poscia@sonarsource.com>2023-10-16 11:09:16 +0200
committersonartech <sonartech@sonarsource.com>2023-10-20 20:02:40 +0000
commit8445ca39a9f46b228f693fbb259f623ba6d05414 (patch)
treefa2d714624e16a1254c931057d6f8d2386f3a8fc /server/sonar-alm-client/src/main/java
parentf5f71fdbe1482d7b132a9923419672459d762aad (diff)
downloadsonarqube-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')
-rw-r--r--server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClient.java9
-rw-r--r--server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java58
-rw-r--r--server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryCollaborator.java29
-rw-r--r--server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/GsonRepositoryTeam.java31
-rw-r--r--server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/api/package-info.java23
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;