From 2a97a1bf4a35c4bb08b7bb1abb23bfbac560ea1e Mon Sep 17 00:00:00 2001 From: Belen Pruvost Date: Tue, 19 Oct 2021 12:27:16 +0200 Subject: [PATCH] SONAR-15441 - QG Groups Remove Endpoint --- .../QualityGateGroupPermissionsDao.java | 4 + .../QualityGateGroupPermissionsMapper.java | 3 + .../QualityGateGroupPermissionsMapper.xml | 6 + .../QualityGateGroupPermissionsDaoTest.java | 13 ++ .../qualitygate/ws/AbstractGroupAction.java | 79 ++++++++ .../server/qualitygate/ws/AddGroupAction.java | 49 +---- .../qualitygate/ws/QualityGateWsModule.java | 31 +-- .../ws/QualityGatesWsParameters.java | 2 +- .../qualitygate/ws/RemoveGroupAction.java | 62 ++++++ .../ws/QualityGateWsModuleTest.java | 2 +- .../qualitygate/ws/RemoveGroupActionTest.java | 186 ++++++++++++++++++ 11 files changed, 375 insertions(+), 62 deletions(-) create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AbstractGroupAction.java create mode 100644 server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/RemoveGroupAction.java create mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/RemoveGroupActionTest.java diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDao.java index a95d8f5235f..e3c38741111 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDao.java @@ -68,4 +68,8 @@ public class QualityGateGroupPermissionsDao implements Dao { public int countByQuery(DbSession dbSession, SearchPermissionQuery query) { return mapper(dbSession).countByQuery(query); } + + public void deleteByQualityGateAndGroup(DbSession dbSession, QualityGateDto qualityGate, GroupDto group) { + mapper(dbSession).delete(qualityGate.getUuid(), group.getUuid()); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.java index 2d0800155cf..eef27294b42 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.java @@ -36,4 +36,7 @@ public interface QualityGateGroupPermissionsMapper { List selectByQuery(@Param("query") SearchPermissionQuery query, @Param("pagination") Pagination pagination); int countByQuery(@Param("query") SearchPermissionQuery query); + + void delete(@Param("qualityGateUuid") String qualityGateUuid, @Param("groupUuid") String groupUuid); + } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.xml index 740123d047f..95e7ad615c1 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateGroupPermissionsMapper.xml @@ -97,4 +97,10 @@ ) + + delete from qgate_group_permissions + where quality_gate_uuid = #{qualityGateUuid, jdbcType=VARCHAR} + and group_uuid = #{groupUuid, jdbcType=VARCHAR} + + diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDaoTest.java index 1f8d10b9a86..cd8d5894106 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateGroupPermissionsDaoTest.java @@ -202,6 +202,19 @@ public class QualityGateGroupPermissionsDaoTest { .containsExactly(group1.getUuid(), group2.getUuid(), group3.getUuid()); } + @Test + public void deleteByQProfileAndGroup() { + QualityGateDto qualityGateDto = insertQualityGate(); + GroupDto group = dbTester.users().insertGroup(); + insertQualityGateGroupPermission(qualityGateDto.getUuid(), group.getUuid()); + + assertThat(underTest.exists(dbSession, qualityGateDto, group)).isTrue(); + + underTest.deleteByQualityGateAndGroup(dbSession, qualityGateDto, group); + + assertThat(underTest.exists(dbSession, qualityGateDto, group)).isFalse(); + } + private QualityGateDto insertQualityGate() { QualityGateDto qg = new QualityGateDto() .setUuid(randomAlphabetic(5)) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AbstractGroupAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AbstractGroupAction.java new file mode 100644 index 00000000000..78fba113620 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AbstractGroupAction.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.qualitygate.ws; + +import java.util.Optional; +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.qualitygate.QualityGateDto; +import org.sonar.db.user.GroupDto; + +import static org.sonar.server.exceptions.NotFoundException.checkFoundWithOptional; +import static org.sonar.server.qualitygate.ws.CreateAction.NAME_MAXIMUM_LENGTH; +import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; + +public abstract class AbstractGroupAction implements QualityGatesWsAction { + protected final DbClient dbClient; + protected final QualityGatesWsSupport wsSupport; + + protected AbstractGroupAction(DbClient dbClient, QualityGatesWsSupport wsSupport) { + this.dbClient = dbClient; + this.wsSupport = wsSupport; + } + + protected void defineGateAndGroupParameters(WebService.NewAction action) { + action.createParam(PARAM_GATE_NAME) + .setDescription("Quality Gate name") + .setRequired(true) + .setMaximumLength(NAME_MAXIMUM_LENGTH) + .setExampleValue("SonarSource Way"); + + action.createParam(PARAM_GROUP_NAME) + .setDescription("Group name or 'anyone' (case insensitive)") + .setRequired(true) + .setExampleValue("sonar-administrators"); + } + + @Override + public void handle(Request request, Response response) throws Exception { + final String groupName = request.mandatoryParam(PARAM_GROUP_NAME); + final String qualityGateName = request.mandatoryParam(PARAM_GATE_NAME); + + try (DbSession dbSession = dbClient.openSession(false)) { + QualityGateDto qualityGateDto = wsSupport.getByName(dbSession, qualityGateName); + wsSupport.checkCanLimitedEdit(dbSession, qualityGateDto); + GroupDto group = getGroup(dbSession, groupName); + apply(dbSession, qualityGateDto, group); + } + response.noContent(); + } + + protected abstract void apply(DbSession dbSession, QualityGateDto qualityGate, GroupDto group); + + private GroupDto getGroup(DbSession dbSession, String groupName) { + Optional group = dbClient.groupDao().selectByName(dbSession, groupName); + checkFoundWithOptional(group, "Group with name '%s' is not found", groupName); + return group.get(); + } +} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AddGroupAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AddGroupAction.java index c3cfa0c7c6b..2924ac68ca9 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AddGroupAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/AddGroupAction.java @@ -19,10 +19,6 @@ */ package org.sonar.server.qualitygate.ws; -import java.util.Optional; -import org.jetbrains.annotations.NotNull; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; @@ -31,21 +27,14 @@ import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.db.qualitygate.QualityGateGroupPermissionsDto; import org.sonar.db.user.GroupDto; -import static org.sonar.server.exceptions.NotFoundException.checkFoundWithOptional; -import static org.sonar.server.qualitygate.ws.CreateAction.NAME_MAXIMUM_LENGTH; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_ADD_GROUP; -import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME; -import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; -public class AddGroupAction implements QualityGatesWsAction { - private final DbClient dbClient; +public class AddGroupAction extends AbstractGroupAction { private final UuidFactory uuidFactory; - private final QualityGatesWsSupport wsSupport; public AddGroupAction(DbClient dbClient, UuidFactory uuidFactory, QualityGatesWsSupport wsSupport) { - this.dbClient = dbClient; + super(dbClient, wsSupport); this.uuidFactory = uuidFactory; - this.wsSupport = wsSupport; } @Override @@ -63,41 +52,11 @@ public class AddGroupAction implements QualityGatesWsAction { .setInternal(true) .setSince("9.2"); - action.createParam(PARAM_GATE_NAME) - .setDescription("Quality Gate name") - .setRequired(true) - .setMaximumLength(NAME_MAXIMUM_LENGTH) - .setExampleValue("SonarSource Way"); - - action.createParam(PARAM_GROUP_NAME) - .setDescription("Group name or 'anyone' (case insensitive)") - .setRequired(true) - .setExampleValue("sonar-administrators"); - + super.defineGateAndGroupParameters(action); } @Override - public void handle(Request request, Response response) throws Exception { - final String groupName = request.mandatoryParam(PARAM_GROUP_NAME); - final String qualityGateName = request.mandatoryParam(PARAM_GATE_NAME); - - try (DbSession dbSession = dbClient.openSession(false)) { - QualityGateDto qualityGateDto = wsSupport.getByName(dbSession, qualityGateName); - wsSupport.checkCanLimitedEdit(dbSession, qualityGateDto); - GroupDto group = getGroup(dbSession, groupName); - addGroup(dbSession, qualityGateDto, group); - } - response.noContent(); - } - - @NotNull - private GroupDto getGroup(DbSession dbSession, String groupName) { - Optional group = dbClient.groupDao().selectByName(dbSession, groupName); - checkFoundWithOptional(group, "Group with name '%s' is not found", groupName); - return group.get(); - } - - private void addGroup(DbSession dbSession, QualityGateDto qualityGate, GroupDto group) { + protected void apply(DbSession dbSession, QualityGateDto qualityGate, GroupDto group) { if (dbClient.qualityGateGroupPermissionsDao().exists(dbSession, qualityGate, group)) { return; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGateWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGateWsModule.java index 1a37844f61a..a8b3afc1d3a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGateWsModule.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGateWsModule.java @@ -25,27 +25,28 @@ public class QualityGateWsModule extends Module { @Override protected void configureModule() { add( + AddGroupAction.class, AddUserAction.class, - QualityGatesWsSupport.class, - QualityGatesWs.class, - ListAction.class, - SearchAction.class, - ShowAction.class, - CreateAction.class, - RenameAction.class, CopyAction.class, - DestroyAction.class, - SetAsDefaultAction.class, - SelectAction.class, - DeselectAction.class, + CreateAction.class, CreateConditionAction.class, DeleteConditionAction.class, - UpdateConditionAction.class, - ProjectStatusAction.class, + DeselectAction.class, + DestroyAction.class, GetByProjectAction.class, - AddGroupAction.class, + ListAction.class, + ProjectStatusAction.class, + QualityGatesWs.class, + QualityGatesWsSupport.class, + RemoveGroupAction.class, + RenameAction.class, + SearchAction.class, SearchGroupsAction.class, - SearchUsersAction.class + SearchUsersAction.class, + SelectAction.class, + SetAsDefaultAction.class, + ShowAction.class, + UpdateConditionAction.class ); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsParameters.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsParameters.java index 202714cd08a..dd4e5825aaf 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsParameters.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsParameters.java @@ -31,6 +31,7 @@ public class QualityGatesWsParameters { public static final String ACTION_UPDATE_CONDITION = "update_condition"; public static final String ACTION_ADD_GROUP = "add_group"; public static final String ACTION_ADD_USER = "add_user"; + public static final String ACTION_REMOVE_GROUP = "remove_group"; public static final String ACTION_SEARCH_GROUPS = "search_groups"; public static final String ACTION_SEARCH_USERS = "search_users"; @@ -55,5 +56,4 @@ public class QualityGatesWsParameters { private QualityGatesWsParameters() { // prevent instantiation } - } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/RemoveGroupAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/RemoveGroupAction.java new file mode 100644 index 00000000000..ccdf7b36342 --- /dev/null +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/RemoveGroupAction.java @@ -0,0 +1,62 @@ +/* + * 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.qualitygate.ws; + +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.qualitygate.QualityGateDto; +import org.sonar.db.user.GroupDto; + +import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_REMOVE_GROUP; + +public class RemoveGroupAction extends AbstractGroupAction { + + public RemoveGroupAction(DbClient dbClient, QualityGatesWsSupport wsSupport) { + super(dbClient, wsSupport); + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction(ACTION_REMOVE_GROUP) + .setDescription("Remove the ability from a group to edit a Quality Gate.
" + + "Requires one of the following permissions:" + + "
    " + + "
  • 'Administer Quality Gates'
  • " + + "
  • Edit right on the specified quality gate
  • " + + "
") + .setHandler(this) + .setPost(true) + .setInternal(true) + .setSince("9.2"); + + super.defineGateAndGroupParameters(action); + } + + @Override + protected void apply(DbSession dbSession, QualityGateDto qualityGate, GroupDto group) { + if (!dbClient.qualityGateGroupPermissionsDao().exists(dbSession, qualityGate, group)) { + return; + } + dbClient.qualityGateGroupPermissionsDao().deleteByQualityGateAndGroup(dbSession, qualityGate, group); + dbSession.commit(); + } +} diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/QualityGateWsModuleTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/QualityGateWsModuleTest.java index ec01f5a680b..f3748dd3ed6 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/QualityGateWsModuleTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/QualityGateWsModuleTest.java @@ -30,7 +30,7 @@ public class QualityGateWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new QualityGateWsModule().configure(container); - assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 21); + assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 22); } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/RemoveGroupActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/RemoveGroupActionTest.java new file mode 100644 index 00000000000..bbb5ec364b0 --- /dev/null +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/RemoveGroupActionTest.java @@ -0,0 +1,186 @@ +/* + * 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.qualitygate.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.DbClient; +import org.sonar.db.DbTester; +import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.qualitygate.QualityGateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.component.TestComponentFinder; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; + +public class RemoveGroupActionTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(); + + private final DbClient dbClient = db.getDbClient(); + private final QualityGatesWsSupport wsSupport = new QualityGatesWsSupport(dbClient, userSession, TestComponentFinder.from(db)); + private final WsActionTester ws = new WsActionTester(new RemoveGroupAction(dbClient, wsSupport)); + + @Test + public void test_definition() { + WebService.Action def = ws.getDef(); + assertThat(def.key()).isEqualTo("remove_group"); + assertThat(def.isPost()).isTrue(); + assertThat(def.isInternal()).isTrue(); + assertThat(def.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("groupName", "gateName"); + } + + @Test + public void remove_group() { + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + GroupDto group = db.users().insertGroup(); + db.qualityGates().addGroupPermission(qualityGate, group); + userSession.logIn().addPermission(GlobalPermission.ADMINISTER_QUALITY_GATES); + + TestResponse response = ws.newRequest() + .setParam(PARAM_GATE_NAME, qualityGate.getName()) + .setParam(PARAM_GROUP_NAME, group.getName()) + .execute(); + + assertThat(response.getStatus()).isEqualTo(204); + assertThat(dbClient.qualityGateGroupPermissionsDao().exists(db.getSession(), qualityGate, group)).isFalse(); + } + + @Test + public void does_nothing_when_group_cannot_edit_gate() { + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + GroupDto group = db.users().insertGroup(); + + assertThat(dbClient.qualityGateGroupPermissionsDao().exists(db.getSession(), qualityGate, group)).isFalse(); + + userSession.logIn().addPermission(GlobalPermission.ADMINISTER_QUALITY_GATES); + + ws.newRequest() + .setParam(PARAM_GATE_NAME, qualityGate.getName()) + .setParam(PARAM_GROUP_NAME, group.getName()) + .execute(); + + assertThat(dbClient.qualityGateGroupPermissionsDao().exists(db.getSession(), qualityGate, group)).isFalse(); + } + + @Test + public void qg_administrators_can_remove_group() { + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + GroupDto group = db.users().insertGroup(); + db.qualityGates().addGroupPermission(qualityGate, group); + userSession.logIn().addPermission(GlobalPermission.ADMINISTER_QUALITY_GATES); + + ws.newRequest() + .setParam(PARAM_GATE_NAME, qualityGate.getName()) + .setParam(PARAM_GROUP_NAME, group.getName()) + .execute(); + + assertThat(dbClient.qualityGateGroupPermissionsDao().exists(db.getSession(), qualityGate, group)).isFalse(); + } + + @Test + public void qg_editors_can_remove_group() { + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + GroupDto group = db.users().insertGroup(); + db.qualityGates().addGroupPermission(qualityGate, group); + UserDto userAllowedToEditGate = db.users().insertUser(); + db.qualityGates().addUserPermission(qualityGate, userAllowedToEditGate); + userSession.logIn(userAllowedToEditGate); + + ws.newRequest() + .setParam(PARAM_GATE_NAME, qualityGate.getName()) + .setParam(PARAM_GROUP_NAME, group.getName()) + .execute(); + + assertThat(dbClient.qualityGateGroupPermissionsDao().exists(db.getSession(), qualityGate, group)).isFalse(); + } + + @Test + public void fail_when_group_does_not_exist() { + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + userSession.logIn().addPermission(GlobalPermission.ADMINISTER_QUALITY_GATES); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Group with name 'unknown' is not found"); + + ws.newRequest() + .setParam(PARAM_GATE_NAME, qualityGate.getName()) + .setParam(PARAM_GROUP_NAME, "unknown") + .execute(); + } + + @Test + public void fail_when_qgate_does_not_exist() { + GroupDto group = db.users().insertGroup(); + userSession.logIn().addPermission(GlobalPermission.ADMINISTER_QUALITY_GATES); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage(String.format("No quality gate has been found for name unknown")); + + ws.newRequest() + .setParam(PARAM_GATE_NAME, "unknown") + .setParam(PARAM_GROUP_NAME, group.getName()) + .execute(); + } + + @Test + public void fail_when_qg_is_built_in() { + GroupDto group = db.users().insertGroup(); + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qg -> qg.setBuiltIn(true)); + userSession.logIn().addPermission(GlobalPermission.ADMINISTER_QUALITY_GATES); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(String.format("Operation forbidden for built-in Quality Gate '%s'", qualityGate.getName())); + + ws.newRequest() + .setParam(PARAM_GATE_NAME, qualityGate.getName()) + .setParam(PARAM_GROUP_NAME, group.getName()) + .execute(); + } + + @Test + public void fail_when_not_enough_permission() { + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + GroupDto group = db.users().insertGroup(); + userSession.logIn(db.users().insertUser()).addPermission(GlobalPermission.ADMINISTER_QUALITY_PROFILES); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest() + .setParam(PARAM_GATE_NAME, qualityGate.getName()) + .setParam(PARAM_GROUP_NAME, group.getName()) + .execute(); + } +} -- 2.39.5