From 47374b5a2600014c577d6fbbc0201b8d376ce133 Mon Sep 17 00:00:00 2001 From: Zipeng WU Date: Fri, 29 Jan 2021 11:28:52 +0100 Subject: [PATCH] SONAR-14372 Move common ALM WS to CE --- .../almsettings/ws/AlmSettingsSupport.java | 101 ++++++++ .../server/almsettings/ws/DeleteAction.java | 79 +++++++ .../server/almsettings/ws/ListAction.java | 111 +++++++++ .../almsettings/ws/ListDefinitionsAction.java | 160 +++++++++++++ .../almsettings/ws/DeleteActionTest.java | 142 ++++++++++++ .../server/almsettings/ws/ListActionTest.java | 218 ++++++++++++++++++ .../ws/ListDefinitionsActionTest.java | 204 ++++++++++++++++ .../server/almsettings/ws/list-example.json | 28 +++ .../ws/list_definitions-example.json | 26 +++ .../platformlevel/PlatformLevel4.java | 8 + 10 files changed, 1077 insertions(+) create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/DeleteAction.java create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListDefinitionsAction.java create mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/DeleteActionTest.java create mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListActionTest.java create mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListDefinitionsActionTest.java create mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list-example.json create mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list_definitions-example.json diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java new file mode 100644 index 00000000000..1357e7aac2e --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java @@ -0,0 +1,101 @@ +/* + * 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.server.almsettings.ws; + +import org.sonar.api.server.ServerSide; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.ALM; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.project.ProjectDto; +import org.sonar.server.almsettings.MultipleAlmFeatureProvider; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.AlmSettings; + +import static java.lang.String.format; +import static org.sonar.api.web.UserRole.ADMIN; + +@ServerSide +public class AlmSettingsSupport { + + private final DbClient dbClient; + private final UserSession userSession; + private final ComponentFinder componentFinder; + private final MultipleAlmFeatureProvider multipleAlmFeatureProvider; + + public AlmSettingsSupport(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder, + MultipleAlmFeatureProvider multipleAlmFeatureProvider) { + this.dbClient = dbClient; + this.userSession = userSession; + this.componentFinder = componentFinder; + this.multipleAlmFeatureProvider = multipleAlmFeatureProvider; + } + + public MultipleAlmFeatureProvider getMultipleAlmFeatureProvider() { + return multipleAlmFeatureProvider; + } + + public void checkAlmSettingDoesNotAlreadyExist(DbSession dbSession, String almSetting) { + dbClient.almSettingDao().selectByKey(dbSession, almSetting) + .ifPresent(a -> { + throw new IllegalArgumentException(format("An ALM setting with key '%s' already exists", a.getKey())); + }); + } + + public void checkAlmMultipleFeatureEnabled(ALM alm) { + try (DbSession dbSession = dbClient.openSession(false)) { + if (!multipleAlmFeatureProvider.enabled() && !dbClient.almSettingDao().selectByAlm(dbSession, alm).isEmpty()) { + throw BadRequestException.create("A " + alm + " setting is already defined"); + } + + } + } + + public ProjectDto getProject(DbSession dbSession, String projectKey) { + ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey); + userSession.checkProjectPermission(ADMIN, project); + return project; + } + + public AlmSettingDto getAlmSetting(DbSession dbSession, String almSetting) { + return dbClient.almSettingDao().selectByKey(dbSession, almSetting) + .orElseThrow(() -> new NotFoundException(format("ALM setting with key '%s' cannot be found", almSetting))); + } + + public static AlmSettings.Alm toAlmWs(ALM alm) { + switch (alm) { + case GITHUB: + return AlmSettings.Alm.github; + case BITBUCKET: + return AlmSettings.Alm.bitbucket; + case BITBUCKET_CLOUD: + return AlmSettings.Alm.bitbucketcloud; + case AZURE_DEVOPS: + return AlmSettings.Alm.azure; + case GITLAB: + return AlmSettings.Alm.gitlab; + default: + throw new IllegalStateException(format("Unknown ALM '%s'", alm.name())); + } + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/DeleteAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/DeleteAction.java new file mode 100644 index 00000000000..84caed6da9f --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/DeleteAction.java @@ -0,0 +1,79 @@ +/* + * 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.server.almsettings.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.server.almsettings.ws.AlmSettingsSupport; +import org.sonar.server.almsettings.ws.AlmSettingsWsAction; +import org.sonar.server.user.UserSession; + +public class DeleteAction implements AlmSettingsWsAction { + + private static final String PARAM_KEY = "key"; + + private final DbClient dbClient; + private final UserSession userSession; + private final AlmSettingsSupport almSettingsSupport; + + public DeleteAction(DbClient dbClient, UserSession userSession, AlmSettingsSupport almSettingsSupport) { + this.dbClient = dbClient; + this.userSession = userSession; + this.almSettingsSupport = almSettingsSupport; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction("delete") + .setDescription("Delete an ALM Settings.
" + + "Requires the 'Administer System' permission") + .setSince("8.1") + .setPost(true) + .setHandler(this); + + action + .createParam(PARAM_KEY) + .setDescription("ALM Setting key") + .setRequired(true); + } + + @Override + public void handle(Request request, Response response) { + userSession.checkIsSystemAdministrator(); + doHandle(request); + response.noContent(); + } + + private void doHandle(Request request) { + String key = request.mandatoryParam(PARAM_KEY); + try (DbSession dbSession = dbClient.openSession(false)) { + AlmSettingDto almSettingDto = almSettingsSupport.getAlmSetting(dbSession, key); + dbClient.projectAlmSettingDao().deleteByAlmSetting(dbSession, almSettingDto); + dbClient.almPatDao().deleteByAlmSetting(dbSession, almSettingDto); + dbClient.almSettingDao().delete(dbSession, almSettingDto); + dbSession.commit(); + } + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java new file mode 100644 index 00000000000..4717d1851a1 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java @@ -0,0 +1,111 @@ +/* + * 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.server.almsettings.ws; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import org.sonar.api.server.ws.Change; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.project.ProjectDto; +import org.sonar.server.almsettings.ws.AlmSettingsSupport; +import org.sonar.server.almsettings.ws.AlmSettingsWsAction; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.AlmSettings.AlmSetting; +import org.sonarqube.ws.AlmSettings.ListWsResponse; + +import static java.util.Optional.ofNullable; +import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; +import static org.sonar.server.ws.WsUtils.writeProtobuf; + +public class ListAction implements AlmSettingsWsAction { + + private static final String PARAM_PROJECT = "project"; + + private final DbClient dbClient; + private final UserSession userSession; + private final ComponentFinder componentFinder; + + public ListAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) { + this.dbClient = dbClient; + this.userSession = userSession; + this.componentFinder = componentFinder; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("list") + .setDescription("List ALM setting available for a given project, sorted by ALM key
" + + "Requires the 'Administer project' permission if the '" + PARAM_PROJECT + "' parameter is provided, requires the 'Create Projects' permission otherwise.") + .setSince("8.1") + .setResponseExample(getClass().getResource("list-example.json")) + .setHandler(this); + + action + .createParam(PARAM_PROJECT) + .setDescription("Project key") + .setRequired(false); + + action.setChangelog( + new Change("8.3", "Permission needed changed to 'Administer project' or 'Create Projects'"), + new Change("8.2", "Permission needed changed from 'Administer project' to 'Create Projects'"), + new Change("8.6", "Field 'URL' added for Azure definitions")); + } + + @Override + public void handle(Request request, Response response) { + ListWsResponse wsResponse = doHandle(request); + writeProtobuf(wsResponse, request, response); + } + + private ListWsResponse doHandle(Request request) { + try (DbSession dbSession = dbClient.openSession(false)) { + Request.StringParam projectKey = request.getParam(PARAM_PROJECT); + if (projectKey.isPresent()) { + ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey.getValue()); + userSession.checkProjectPermission(ADMIN, project); + } else { + userSession.checkPermission(PROVISION_PROJECTS); + } + + List settings = dbClient.almSettingDao().selectAll(dbSession); + List wsAlmSettings = settings + .stream() + .sorted(Comparator.comparing(AlmSettingDto::getKey)) + .map(almSetting -> { + AlmSetting.Builder almSettingBuilder = AlmSetting.newBuilder() + .setKey(almSetting.getKey()) + .setAlm(AlmSettingsSupport.toAlmWs(almSetting.getAlm())); + ofNullable(almSetting.getUrl()).ifPresent(almSettingBuilder::setUrl); + return almSettingBuilder.build(); + }) + .collect(Collectors.toList()); + return ListWsResponse.newBuilder() + .addAllAlmSettings(wsAlmSettings).build(); + } + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListDefinitionsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListDefinitionsAction.java new file mode 100644 index 00000000000..0e71eb9633e --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListDefinitionsAction.java @@ -0,0 +1,160 @@ +/* + * 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.server.almsettings.ws; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import org.sonar.api.server.ws.Change; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.ALM; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.AlmSettings.AlmSettingBitbucketCloud; +import org.sonarqube.ws.AlmSettings.AlmSettingGithub; + +import static java.util.Collections.emptyList; +import static java.util.Objects.requireNonNull; +import static org.sonar.server.ws.WsUtils.writeProtobuf; +import static org.sonarqube.ws.AlmSettings.AlmSettingAzure; +import static org.sonarqube.ws.AlmSettings.AlmSettingBitbucket; +import static org.sonarqube.ws.AlmSettings.AlmSettingGitlab; +import static org.sonarqube.ws.AlmSettings.ListDefinitionsWsResponse; + +public class ListDefinitionsAction implements AlmSettingsWsAction { + + private final DbClient dbClient; + private final UserSession userSession; + + public ListDefinitionsAction(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + context.createAction("list_definitions") + .setDescription("List ALM Settings, sorted by created date.
" + + "Requires the 'Administer System' permission") + .setSince("8.1") + .setResponseExample(getClass().getResource("list_definitions-example.json")) + .setChangelog(new Change("8.2", "Field 'URL' added for GitLab definitions"), + new Change("8.6", "Field 'URL' added for Azure definitions"), + new Change("8.7", "Fields 'personalAccessToken', 'privateKey', and 'clientSecret' are no longer returned")) + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) { + userSession.checkIsSystemAdministrator(); + ListDefinitionsWsResponse wsResponse = doHandle(); + writeProtobuf(wsResponse, request, response); + } + + private ListDefinitionsWsResponse doHandle() { + try (DbSession dbSession = dbClient.openSession(false)) { + List settings = dbClient.almSettingDao().selectAll(dbSession); + Map> settingsByAlm = settings.stream().collect(Collectors.groupingBy(AlmSettingDto::getAlm)); + List githubSettings = settingsByAlm.getOrDefault(ALM.GITHUB, emptyList()) + .stream() + .sorted(Comparator.comparing(AlmSettingDto::getCreatedAt)) + .map(ListDefinitionsAction::toGitHub).collect(Collectors.toList()); + List azureSettings = settingsByAlm.getOrDefault(ALM.AZURE_DEVOPS, emptyList()) + .stream() + .sorted(Comparator.comparing(AlmSettingDto::getCreatedAt)) + .map(ListDefinitionsAction::toAzure).collect(Collectors.toList()); + List bitbucketSettings = settingsByAlm.getOrDefault(ALM.BITBUCKET, emptyList()) + .stream() + .sorted(Comparator.comparing(AlmSettingDto::getCreatedAt)) + .map(ListDefinitionsAction::toBitbucket).collect(Collectors.toList()); + List bitbucketCloudSettings = settingsByAlm.getOrDefault(ALM.BITBUCKET_CLOUD, emptyList()) + .stream() + .sorted(Comparator.comparing(AlmSettingDto::getCreatedAt)) + .map(ListDefinitionsAction::toBitbucketCloud).collect(Collectors.toList()); + List gitlabSettings = settingsByAlm.getOrDefault(ALM.GITLAB, emptyList()) + .stream() + .sorted(Comparator.comparing(AlmSettingDto::getCreatedAt)) + .map(ListDefinitionsAction::toGitlab).collect(Collectors.toList()); + return ListDefinitionsWsResponse.newBuilder() + .addAllGithub(githubSettings) + .addAllAzure(azureSettings) + .addAllBitbucket(bitbucketSettings) + .addAllBitbucketcloud(bitbucketCloudSettings) + .addAllGitlab(gitlabSettings) + .build(); + } + } + + private static AlmSettingGithub toGitHub(AlmSettingDto settingDto) { + AlmSettingGithub.Builder builder = AlmSettingGithub + .newBuilder() + .setKey(settingDto.getKey()) + .setUrl(requireNonNull(settingDto.getUrl(), "URL cannot be null for GitHub ALM setting")) + .setAppId(requireNonNull(settingDto.getAppId(), "App ID cannot be null for GitHub ALM setting")); + // Don't fail if clientId is not set for migration cases + Optional.ofNullable(settingDto.getClientId()).ifPresent(builder::setClientId); + return builder.build(); + } + + private static AlmSettingAzure toAzure(AlmSettingDto settingDto) { + AlmSettingAzure.Builder builder = AlmSettingAzure + .newBuilder() + .setKey(settingDto.getKey()); + + if (settingDto.getUrl() != null) { + builder.setUrl(settingDto.getUrl()); + } + + return builder.build(); + } + + private static AlmSettingGitlab toGitlab(AlmSettingDto settingDto) { + AlmSettingGitlab.Builder builder = AlmSettingGitlab.newBuilder() + .setKey(settingDto.getKey()); + + if (settingDto.getUrl() != null) { + builder.setUrl(settingDto.getUrl()); + } + return builder.build(); + } + + private static AlmSettingBitbucket toBitbucket(AlmSettingDto settingDto) { + return AlmSettingBitbucket + .newBuilder() + .setKey(settingDto.getKey()) + .setUrl(requireNonNull(settingDto.getUrl(), "URL cannot be null for Bitbucket ALM setting")) + .build(); + } + + private static AlmSettingBitbucketCloud toBitbucketCloud(AlmSettingDto settingDto) { + AlmSettingBitbucketCloud.Builder builder = AlmSettingBitbucketCloud + .newBuilder() + .setKey(settingDto.getKey()) + .setWorkspace(requireNonNull(settingDto.getAppId())) + .setClientId(requireNonNull(settingDto.getClientId(), "Client ID cannot be null for Bitbucket Cloud ALM setting")); + return builder.build(); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/DeleteActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/DeleteActionTest.java new file mode 100644 index 00000000000..005532c2213 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/DeleteActionTest.java @@ -0,0 +1,142 @@ +/* + * 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.server.almsettings.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbTester; +import org.sonar.db.alm.pat.AlmPatDto; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.project.ProjectDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.almsettings.MultipleAlmFeatureProvider; +import org.sonar.server.almsettings.ws.AlmSettingsSupport; +import org.sonar.server.almsettings.ws.DeleteAction; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.groups.Tuple.tuple; +import static org.mockito.Mockito.mock; + +public class DeleteActionTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(); + + private WsActionTester ws = new WsActionTester(new DeleteAction(db.getDbClient(), userSession, + new AlmSettingsSupport(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null), + mock(MultipleAlmFeatureProvider.class)))); + + @Test + public void delete() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSettingDto = db.almSettings().insertGitHubAlmSetting(); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .execute(); + + assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession())).isEmpty(); + } + + @Test + public void delete_alm_setting_also_delete_pat() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSettingDto = db.almSettings().insertBitbucketAlmSetting(); + AlmPatDto almPatDto = db.almPats().insert(p -> p.setAlmSettingUuid(almSettingDto.getUuid()), p -> p.setUserUuid(user.getUuid())); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .execute(); + + assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession())).isEmpty(); + assertThat(db.getDbClient().almPatDao().selectByUuid(db.getSession(), almPatDto.getUuid())).isNotPresent(); + } + + @Test + public void delete_project_binding_during_deletion() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting(); + ProjectDto project = db.components().insertPrivateProjectDto(); + db.almSettings().insertGitHubProjectAlmSetting(almSetting, project); + // Second setting having a project bound on it, should not be impacted by the deletion of the first one + AlmSettingDto anotherAlmSetting2 = db.almSettings().insertGitHubAlmSetting(); + ProjectDto anotherProject = db.components().insertPrivateProjectDto(); + db.almSettings().insertGitHubProjectAlmSetting(anotherAlmSetting2, anotherProject); + + ws.newRequest() + .setParam("key", almSetting.getKey()) + .execute(); + + assertThat(db.getDbClient().almSettingDao().selectAll(db.getSession())).extracting(AlmSettingDto::getUuid).containsExactlyInAnyOrder(anotherAlmSetting2.getUuid()); + assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), project)).isEmpty(); + assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), anotherProject)).isNotEmpty(); + } + + @Test + public void fail_when_key_does_not_match_existing_alm_setting() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("ALM setting with key 'unknown' cannot be found"); + + ws.newRequest() + .setParam("key", "unknown") + .execute(); + } + + @Test + public void fail_when_missing_administer_system_permission() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); + AlmSettingDto almSettingDto = db.almSettings().insertGitHubAlmSetting(); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest() + .setParam("key", almSettingDto.getKey()) + .execute(); + } + + @Test + public void definition() { + WebService.Action def = ws.getDef(); + + assertThat(def.since()).isEqualTo("8.1"); + assertThat(def.isPost()).isTrue(); + assertThat(def.params()) + .extracting(WebService.Param::key, WebService.Param::isRequired) + .containsExactlyInAnyOrder(tuple("key", true)); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListActionTest.java new file mode 100644 index 00000000000..3fe63a3e1ba --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListActionTest.java @@ -0,0 +1,218 @@ +/* + * 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.server.almsettings.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbTester; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.project.ProjectDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.almsettings.ws.ListAction; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.WsActionTester; +import org.sonarqube.ws.AlmSettings; +import org.sonarqube.ws.AlmSettings.AlmSetting; +import org.sonarqube.ws.AlmSettings.ListWsResponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.groups.Tuple.tuple; +import static org.mockito.Mockito.mock; +import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.api.web.UserRole.SCAN; +import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; +import static org.sonar.test.JsonAssert.assertJson; + +public class ListActionTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(); + + private final ComponentFinder componentFinder = new ComponentFinder(db.getDbClient(), mock(ResourceTypes.class)); + private final WsActionTester ws = new WsActionTester(new ListAction(db.getDbClient(), userSession, componentFinder)); + + @Test + public void list() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).addPermission(PROVISION_PROJECTS); + AlmSettingDto githubAlmSetting1 = db.almSettings().insertGitHubAlmSetting(); + AlmSettingDto githubAlmSetting2 = db.almSettings().insertGitHubAlmSetting(); + AlmSettingDto azureAlmSetting = db.almSettings().insertAzureAlmSetting(); + AlmSettingDto azureAlmSettingWithoutUrl = db.almSettings().insertAzureAlmSetting(s -> s.setUrl(null)); + AlmSettingDto gitlabAlmSetting = db.almSettings().insertGitlabAlmSetting(); + AlmSettingDto gitlabAlmSettingWithoutUrl = db.almSettings().insertGitlabAlmSetting(s -> s.setUrl(null)); + AlmSettingDto bitbucketAlmSetting = db.almSettings().insertBitbucketAlmSetting(); + AlmSettingDto bitbucketCloudAlmSetting = db.almSettings().insertBitbucketCloudAlmSetting(); + + ListWsResponse response = ws.newRequest().executeProtobuf(ListWsResponse.class); + + assertThat(response.getAlmSettingsList()) + .extracting(AlmSetting::getAlm, AlmSetting::getKey, AlmSetting::hasUrl, AlmSetting::getUrl) + .containsExactlyInAnyOrder( + tuple(AlmSettings.Alm.github, githubAlmSetting1.getKey(), true, githubAlmSetting1.getUrl()), + tuple(AlmSettings.Alm.github, githubAlmSetting2.getKey(), true, githubAlmSetting2.getUrl()), + tuple(AlmSettings.Alm.azure, azureAlmSetting.getKey(), true, azureAlmSetting.getUrl()), + tuple(AlmSettings.Alm.azure, azureAlmSettingWithoutUrl.getKey(), false, ""), + tuple(AlmSettings.Alm.gitlab, gitlabAlmSetting.getKey(), true, gitlabAlmSetting.getUrl()), + tuple(AlmSettings.Alm.gitlab, gitlabAlmSettingWithoutUrl.getKey(), false, ""), + tuple(AlmSettings.Alm.bitbucket, bitbucketAlmSetting.getKey(), true, bitbucketAlmSetting.getUrl()), + tuple(AlmSettings.Alm.bitbucketcloud, bitbucketCloudAlmSetting.getKey(), false, "")); + } + + @Test + public void list_is_ordered_by_alm_key() { + UserDto user = db.users().insertUser(); + db.components().insertPrivateProject(); + userSession.logIn(user).addPermission(PROVISION_PROJECTS); + db.almSettings().insertGitHubAlmSetting(almSetting -> almSetting.setKey("GitHub1")); + db.almSettings().insertGitHubAlmSetting(almSetting -> almSetting.setKey("GitHub2")); + db.almSettings().insertAzureAlmSetting(almSetting -> almSetting.setKey("Azure")); + db.almSettings().insertGitlabAlmSetting(almSetting -> almSetting.setKey("Gitlab")); + db.almSettings().insertBitbucketAlmSetting(almSetting -> almSetting.setKey("Bitbucket")); + + ListWsResponse response = ws.newRequest().executeProtobuf(ListWsResponse.class); + + assertThat(response.getAlmSettingsList()) + .extracting(AlmSetting::getKey) + .containsExactly("Azure", "Bitbucket", "GitHub1", "GitHub2", "Gitlab"); + } + + @Test + public void fail_when_missing_create_project_permission() { + expectedException.expect(ForbiddenException.class); + ws.newRequest().execute(); + } + + @Test + public void fail_when_project_does_not_exist() { + UserDto user = db.users().insertUser(); + ProjectDto project = db.components().insertPrivateProjectDto(); + userSession.logIn(user).addProjectPermission(ADMIN, project); + AlmSettingDto githubAlmSetting = db.almSettings().insertGitHubAlmSetting(); + db.almSettings().insertGitHubProjectAlmSetting(githubAlmSetting, project); + + TestRequest request = ws.newRequest().setParam("project", "unknown"); + assertThatThrownBy(request::execute) + .isInstanceOf(NotFoundException.class) + .hasMessage("Project 'unknown' not found"); + } + + @Test + public void fail_when_missing_administer_permission_on_private_project() { + UserDto user = db.users().insertUser(); + ProjectDto project = db.components().insertPrivateProjectDto(); + userSession.logIn(user).addProjectPermission(USER, project); + AlmSettingDto githubAlmSetting = db.almSettings().insertGitHubAlmSetting(); + db.almSettings().insertGitHubProjectAlmSetting(githubAlmSetting, project); + + TestRequest request = ws.newRequest().setParam("project", project.getKey()); + assertThatThrownBy(request::execute) + .isInstanceOf(ForbiddenException.class) + .hasMessage("Insufficient privileges"); + } + + @Test + public void fail_when_missing_administer_permission_on_public_project() { + UserDto user = db.users().insertUser(); + ProjectDto project = db.components().insertPublicProjectDto(); + userSession.logIn(user).addProjectPermission(SCAN, project); + AlmSettingDto githubAlmSetting = db.almSettings().insertGitHubAlmSetting(); + db.almSettings().insertGitHubProjectAlmSetting(githubAlmSetting, project); + + TestRequest request = ws.newRequest().setParam("project", project.getKey()); + assertThatThrownBy(request::execute) + .isInstanceOf(ForbiddenException.class) + .hasMessage("Insufficient privileges"); + } + + @Test + public void json_example_with_create_project() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).addPermission(PROVISION_PROJECTS); + initAlmSetting(); + + String response = ws.newRequest().execute().getInput(); + + assertJson(response).isSimilarTo(getClass().getResource("list-example.json")); + } + + @Test + public void json_example_with_administer_permission() { + UserDto user = db.users().insertUser(); + ProjectDto project = db.components().insertPrivateProjectDto(); + userSession.logIn(user).addProjectPermission(ADMIN, project); + initAlmSetting(); + + String response = ws.newRequest() + .setParam("project", project.getKey()) + .execute().getInput(); + + assertJson(response).isSimilarTo(getClass().getResource("list-example.json")); + } + + private void initAlmSetting() { + db.almSettings().insertGitHubAlmSetting( + almSettingDto -> almSettingDto + .setKey("GitHub Server - Dev Team") + .setUrl("https://github.enterprise.com")); + db.almSettings().insertAzureAlmSetting( + almSettingDto -> almSettingDto + .setKey("Azure Server - Dev Team") + .setUrl("https://azure.com")); + db.almSettings().insertBitbucketAlmSetting( + almSettingDto -> almSettingDto + .setKey("Bitbucket Server - Dev Team") + .setUrl("https://bitbucket.enterprise.com")); + db.almSettings().insertBitbucketCloudAlmSetting( + almSettingDto -> almSettingDto + .setKey("Bitbucket Cloud - Dev Team") + .setUrl("https://bitbucket.org")); + db.almSettings().insertGitlabAlmSetting( + almSettingDto -> almSettingDto + .setKey("GitLab - Dev Team") + .setUrl("https://www.gitlab.com/api/v4")); + } + + @Test + public void definition() { + WebService.Action def = ws.getDef(); + + assertThat(def.since()).isEqualTo("8.1"); + assertThat(def.isPost()).isFalse(); + assertThat(def.responseExampleAsString()).isNotEmpty(); + assertThat(def.params()) + .extracting(WebService.Param::key, WebService.Param::isRequired) + .containsExactlyInAnyOrder(tuple("project", false)); + } + +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListDefinitionsActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListDefinitionsActionTest.java new file mode 100644 index 00000000000..ba8964dfe4b --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/ListDefinitionsActionTest.java @@ -0,0 +1,204 @@ +/* + * 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.server.almsettings.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.almsettings.ws.ListDefinitionsAction; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; +import org.sonarqube.ws.AlmSettings; +import org.sonarqube.ws.AlmSettings.AlmSettingAzure; +import org.sonarqube.ws.AlmSettings.AlmSettingGithub; +import org.sonarqube.ws.AlmSettings.AlmSettingGitlab; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.junit.rules.ExpectedException.none; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.server.tester.UserSessionRule.standalone; +import static org.sonar.test.JsonAssert.assertJson; +import static org.sonarqube.ws.AlmSettings.ListDefinitionsWsResponse; + +public class ListDefinitionsActionTest { + + @Rule + public ExpectedException expectedException = none(); + @Rule + public UserSessionRule userSession = standalone(); + + private final System2 system2 = mock(System2.class); + + @Rule + public DbTester db = DbTester.create(system2); + + private final WsActionTester ws = new WsActionTester(new ListDefinitionsAction(db.getDbClient(), userSession)); + + @Test + public void list_github_settings() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSetting1 = db.almSettings().insertGitHubAlmSetting(); + AlmSettingDto almSetting2 = db.almSettings().insertGitHubAlmSetting(alm -> alm.setClientId("client_id").setClientSecret("client_secret")); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getGithubList()) + .extracting(AlmSettingGithub::getKey, AlmSettingGithub::getUrl, AlmSettingGithub::getAppId, AlmSettingGithub::getClientId) + .containsExactlyInAnyOrder( + tuple(almSetting1.getKey(), almSetting1.getUrl(), almSetting1.getAppId(), ""), + tuple(almSetting2.getKey(), almSetting2.getUrl(), almSetting2.getAppId(), "client_id")); + } + + @Test + public void list_gitlab_settings() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSetting1 = db.almSettings().insertGitlabAlmSetting(); + AlmSettingDto almSetting2 = db.almSettings().insertGitlabAlmSetting(setting -> setting.setUrl(null)); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getGitlabList()) + .extracting(AlmSettingGitlab::getKey, AlmSettingGitlab::getUrl) + .containsExactlyInAnyOrder( + tuple(almSetting1.getKey(), almSetting1.getUrl()), + tuple(almSetting2.getKey(), "")); + } + + @Test + public void list_azure_settings() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSetting1 = db.almSettings().insertAzureAlmSetting(); + AlmSettingDto almSetting2 = db.almSettings().insertAzureAlmSetting(setting -> setting.setUrl(null)); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getAzureList()) + .extracting(AlmSettingAzure::getKey, AlmSettingAzure::getUrl) + .containsExactlyInAnyOrder( + tuple(almSetting1.getKey(), almSetting1.getUrl()), + tuple(almSetting2.getKey(), "")); + } + + @Test + public void list_bitbucket_cloud_settings() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + AlmSettingDto almSetting1 = db.almSettings().insertBitbucketCloudAlmSetting(alm -> alm.setClientId("1").setClientSecret("2")); + AlmSettingDto almSetting2 = db.almSettings().insertBitbucketCloudAlmSetting(alm -> alm.setClientId("client_id").setClientSecret("client_secret")); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getBitbucketcloudList()) + .extracting(AlmSettings.AlmSettingBitbucketCloud::getKey, AlmSettings.AlmSettingBitbucketCloud::getClientId) + .containsExactlyInAnyOrder( + tuple(almSetting1.getKey(), "1"), + tuple(almSetting2.getKey(), "client_id")); + } + + @Test + public void list_is_ordered_by_create_date() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + when(system2.now()).thenReturn(10_000_000_000L); + AlmSettingDto almSetting1 = db.almSettings().insertGitHubAlmSetting(); + when(system2.now()).thenReturn(30_000_000_000L); + AlmSettingDto almSetting2 = db.almSettings().insertGitHubAlmSetting(); + when(system2.now()).thenReturn(20_000_000_000L); + AlmSettingDto almSetting3 = db.almSettings().insertGitHubAlmSetting(); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getGithubList()) + .extracting(AlmSettingGithub::getKey) + .containsExactly(almSetting1.getKey(), almSetting3.getKey(), almSetting2.getKey()); + } + + @Test + public void return_empty_list_when_no_settings() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + + ListDefinitionsWsResponse wsResponse = ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + + assertThat(wsResponse.getGithubList()).isEmpty(); + } + + @Test + public void fail_when_user_is_not_system_administrator() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); + db.almSettings().insertGitHubAlmSetting(); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest().executeProtobuf(ListDefinitionsWsResponse.class); + } + + @Test + public void json_example() { + UserDto user = db.users().insertUser(); + userSession.logIn(user).setSystemAdministrator(); + db.almSettings().insertGitHubAlmSetting( + almSettingDto -> almSettingDto + .setKey("GitHub Server - Dev Team") + .setUrl("https://github.enterprise.com") + .setAppId("12345") + .setPrivateKey("54684654") + .setClientId("client_id") + .setClientSecret("client_secret")); + db.almSettings().insertAzureAlmSetting( + a -> a.setKey("Azure Devops Server - Dev Team") + .setPersonalAccessToken("12345") + .setUrl("https://ado.sonarqube.com/")); + db.almSettings().insertBitbucketAlmSetting( + a -> a.setKey("Bitbucket Server - Dev Team") + .setUrl("https://bitbucket.enterprise.com") + .setPersonalAccessToken("abcdef")); + db.almSettings().insertGitlabAlmSetting( + a -> a.setKey("Gitlab - Dev Team") + .setPersonalAccessToken("12345")); + + String response = ws.newRequest().execute().getInput(); + + assertJson(response).isSimilarTo(getClass().getResource("list_definitions-example.json")); + } + + @Test + public void definition() { + WebService.Action def = ws.getDef(); + + assertThat(def.since()).isEqualTo("8.1"); + assertThat(def.params()).isEmpty(); + assertThat(def.changelog()).hasSize(3); + assertThat(def.isPost()).isFalse(); + assertThat(def.responseExampleAsString()).isNotEmpty(); + } +} diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list-example.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list-example.json new file mode 100644 index 00000000000..ff49519340c --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list-example.json @@ -0,0 +1,28 @@ +{ + "almSettings": [ + { + "key": "GitHub Server - Dev Team", + "alm": "github", + "url": "https://github.enterprise.com" + }, + { + "key": "Azure Server - Dev Team", + "alm": "azure" + }, + { + "key": "Bitbucket Server - Dev Team", + "alm": "bitbucket", + "url": "https://bitbucket.enterprise.com" + }, + { + "key": "Bitbucket Cloud - Dev Team", + "alm": "bitbucketcloud", + "url": "https://bitbucket.org" + }, + { + "key": "GitLab - Dev Team", + "alm": "gitlab", + "url": "https://www.gitlab.com/api/v4" + } + ] +} diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list_definitions-example.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list_definitions-example.json new file mode 100644 index 00000000000..9c4f14f8285 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/list_definitions-example.json @@ -0,0 +1,26 @@ +{ + "github": [ + { + "key": "GitHub Server - Dev Team", + "url": "https://github.enterprise.com", + "appId": "12345", + "clientId": "client_id" + } + ], + "azure": [ + { + "key": "Azure Devops Server - Dev Team" + } + ], + "bitbucket": [ + { + "key": "Bitbucket Server - Dev Team", + "url": "https://bitbucket.enterprise.com" + } + ], + "gitlab": [ + { + "key": "Gitlab - Dev Team" + } + ] +} diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index b20b6ab2fd5..a2e1dafc76d 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -48,7 +48,11 @@ import org.sonar.core.platform.PlatformEditionProvider; import org.sonar.server.almintegration.ws.AlmIntegrationsWSModule; import org.sonar.server.almintegration.ws.ImportHelper; import org.sonar.server.almsettings.MultipleAlmFeatureProvider; +import org.sonar.server.almsettings.ws.AlmSettingsSupport; import org.sonar.server.almsettings.ws.AlmSettingsWs; +import org.sonar.server.almsettings.ws.DeleteAction; +import org.sonar.server.almsettings.ws.ListAction; +import org.sonar.server.almsettings.ws.ListDefinitionsAction; import org.sonar.server.authentication.AuthenticationModule; import org.sonar.server.authentication.DefaultAdminCredentialsVerifierNotificationHandler; import org.sonar.server.authentication.DefaultAdminCredentialsVerifierNotificationTemplate; @@ -505,6 +509,10 @@ public class PlatformLevel4 extends PlatformLevel { // ALM settings AlmSettingsWs.class, + AlmSettingsSupport.class, + DeleteAction.class, + ListAction.class, + ListDefinitionsAction.class, // Branch BranchFeatureProxyImpl.class, -- 2.39.5