aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-09-25 15:43:10 +0200
committerStas Vilchik <stas.vilchik@sonarsource.com>2017-10-02 17:18:15 +0200
commitbb0bd260f3742c010b9e7034ea5d6947e694a130 (patch)
tree172e2e72927424fcb131c0cfcce75fcd4c33b348 /server
parente212b5945cbd0fdfda9caeac6cf969732f11f74e (diff)
downloadsonarqube-bb0bd260f3742c010b9e7034ea5d6947e694a130.tar.gz
sonarqube-bb0bd260f3742c010b9e7034ea5d6947e694a130.zip
SONAR-1330 Remove group permission to edit single quality profile
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsDao.java4
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.java2
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.xml6
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditGroupsDaoTest.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveGroupAction.java53
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveGroupActionTest.java290
6 files changed, 362 insertions, 6 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsDao.java
index 1f429dc112e..b690eecdb09 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsDao.java
@@ -40,6 +40,10 @@ public class QProfileEditGroupsDao implements Dao {
mapper(dbSession).insert(dto, system2.now());
}
+ public void deleteByQProfileAndGroup(DbSession dbSession, QProfileDto profile, GroupDto group) {
+ mapper(dbSession).delete(profile.getKee(), group.getId());
+ }
+
private static QProfileEditGroupsMapper mapper(DbSession dbSession) {
return dbSession.getMapper(QProfileEditGroupsMapper.class);
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.java
index ce96f4ea4af..d4eb535299a 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.java
@@ -27,4 +27,6 @@ public interface QProfileEditGroupsMapper {
void insert(@Param("dto") QProfileEditGroupsDto dto, @Param("now") long now);
+ void delete(@Param("qProfileUuid") String qProfileUuid, @Param("groupId") int groupId);
+
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.xml
index 40622269330..9be145a233e 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditGroupsMapper.xml
@@ -32,5 +32,11 @@
)
</insert>
+ <delete id="delete" parameterType="map">
+ delete from qprofile_edit_groups
+ where qprofile_uuid = #{qProfileUuid, jdbcType=VARCHAR}
+ and group_id = #{groupId, jdbcType=INTEGER}
+ </delete>
+
</mapper>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditGroupsDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditGroupsDaoTest.java
index 41ed91c6e04..d19ccf125ca 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditGroupsDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditGroupsDaoTest.java
@@ -71,4 +71,17 @@ public class QProfileEditGroupsDaoTest {
entry("createdAt", NOW));
}
+ @Test
+ public void deleteByQProfileAndGroup() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization);
+ GroupDto group = db.users().insertGroup(organization);
+ db.qualityProfiles().addGroupPermission(profile, group);
+ assertThat(underTest.exists(db.getSession(), profile, group)).isTrue();
+
+ underTest.deleteByQProfileAndGroup(db.getSession(), profile, group);
+
+ assertThat(underTest.exists(db.getSession(), profile, group)).isFalse();
+ }
+
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveGroupAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveGroupAction.java
index 2df9637a2db..9c94c4f3289 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveGroupAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveGroupAction.java
@@ -19,18 +19,38 @@
*/
package org.sonar.server.qualityprofile.ws;
+import java.util.Arrays;
+import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Languages;
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.organization.OrganizationDto;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.user.GroupDto;
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.server.qualityprofile.ws.QProfileWsSupport.createOrganizationParam;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_REMOVE_GROUP;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_GROUP;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROFILE;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
public class RemoveGroupAction implements QProfileWsAction {
+ private final DbClient dbClient;
+ private final QProfileWsSupport wsSupport;
+ private final Languages languages;
+
+ public RemoveGroupAction(DbClient dbClient, QProfileWsSupport wsSupport, Languages languages) {
+ this.dbClient = dbClient;
+ this.wsSupport = wsSupport;
+ this.languages = languages;
+ }
+
@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context
@@ -42,10 +62,16 @@ public class RemoveGroupAction implements QProfileWsAction {
.setInternal(true)
.setSince("6.6");
- action.createParam(PARAM_PROFILE)
- .setDescription("Quality Profile key.")
+ action.createParam(PARAM_QUALITY_PROFILE)
+ .setDescription("Quality Profile name")
.setRequired(true)
- .setExampleValue(UUID_EXAMPLE_01);
+ .setExampleValue("Recommended quality profile");
+
+ action
+ .createParam(PARAM_LANGUAGE)
+ .setDescription("Quality profile language")
+ .setRequired(true)
+ .setPossibleValues(Arrays.stream(languages.all()).map(Language::getKey).collect(toSet()));
action.createParam(PARAM_GROUP)
.setDescription("Group name")
@@ -57,6 +83,21 @@ public class RemoveGroupAction implements QProfileWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
- // TODO
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ OrganizationDto organization = wsSupport.getOrganizationByKey(dbSession, request.param(PARAM_ORGANIZATION));
+ QProfileDto profile = wsSupport.getProfile(dbSession, organization, request.mandatoryParam(PARAM_QUALITY_PROFILE), request.mandatoryParam(PARAM_LANGUAGE));
+ wsSupport.checkCanEdit(dbSession, profile);
+ GroupDto group = wsSupport.getGroup(dbSession, organization, request.mandatoryParam(PARAM_GROUP));
+ removeGroup(dbSession, profile, group);
+ }
+ response.noContent();
+ }
+
+ private void removeGroup(DbSession dbSession, QProfileDto profile, GroupDto group) {
+ if (!dbClient.qProfileEditGroupsDao().exists(dbSession, profile, group)) {
+ return;
+ }
+ dbClient.qProfileEditGroupsDao().deleteByQProfileAndGroup(dbSession, profile, group);
+ dbSession.commit();
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveGroupActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveGroupActionTest.java
new file mode 100644
index 00000000000..7e1321cd38a
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveGroupActionTest.java
@@ -0,0 +1,290 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.qualityprofile.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.language.LanguageTesting;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestResponse;
+import org.sonar.server.ws.WsActionTester;
+
+import static java.lang.String.format;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_GROUP;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
+
+public class RemoveGroupActionTest {
+
+ private static final String XOO = "xoo";
+ private static final Languages LANGUAGES = LanguageTesting.newLanguages(XOO);
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ @Rule
+ public DbTester db = DbTester.create();
+
+ private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db));
+
+ private WsActionTester ws = new WsActionTester(new RemoveGroupAction(db.getDbClient(), wsSupport, LANGUAGES));
+
+ @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("organization", "qualityProfile", "language", "group");
+ }
+
+ @Test
+ public void remove_group() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ GroupDto group = db.users().insertGroup(organization);
+ db.qualityProfiles().addGroupPermission(profile, group);
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ TestResponse response = ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+
+ assertThat(response.getStatus()).isEqualTo(204);
+ assertThat(db.getDbClient().qProfileEditGroupsDao().exists(db.getSession(), profile, group)).isFalse();
+ }
+
+ @Test
+ public void does_nothing_when_group_cannot_edit_profile() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ GroupDto group = db.users().insertGroup(organization);
+ assertThat(db.getDbClient().qProfileEditGroupsDao().exists(db.getSession(), profile, group)).isFalse();
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+
+ assertThat(db.getDbClient().qProfileEditGroupsDao().exists(db.getSession(), profile, group)).isFalse();
+ }
+
+ @Test
+ public void qp_administers_can_remove_group() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ GroupDto group = db.users().insertGroup(organization);
+ db.qualityProfiles().addGroupPermission(profile, group);
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+
+ assertThat(db.getDbClient().qProfileEditGroupsDao().exists(db.getSession(), profile, group)).isFalse();
+ }
+
+ @Test
+ public void qp_editors_can_remove_group() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ GroupDto group = db.users().insertGroup(organization);
+ db.qualityProfiles().addGroupPermission(profile, group);
+ UserDto userAllowedToEditProfile = db.users().insertUser();
+ db.qualityProfiles().addUserPermission(profile, userAllowedToEditProfile);
+ userSession.logIn(userAllowedToEditProfile);
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+
+ assertThat(db.getDbClient().qProfileEditGroupsDao().exists(db.getSession(), profile, group)).isFalse();
+ }
+
+ @Test
+ public void uses_default_organization_when_no_organization() {
+ OrganizationDto organization = db.getDefaultOrganization();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ GroupDto group = db.users().insertGroup(organization);
+ db.qualityProfiles().addGroupPermission(profile, group);
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .execute();
+
+ assertThat(db.getDbClient().qProfileEditGroupsDao().exists(db.getSession(), profile, group)).isFalse();
+ }
+
+ @Test
+ public void fail_when_group_does_not_exist() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(format("No group with name 'unknown' in organization '%s'", organization.getKey()));
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, "unknown")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+ }
+
+ @Test
+ public void fail_when_qprofile_does_not_exist() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto group = db.users().insertGroup(organization);
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(format("Quality Profile for language 'xoo' and name 'unknown' does not exist in organization '%s'", organization.getKey()));
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, "unknown")
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+ }
+
+ @Test
+ public void fail_when_qprofile_does_not_belong_to_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto group = db.users().insertGroup(organization);
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(anotherOrganization, p -> p.setLanguage(XOO));
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(format("Quality Profile for language 'xoo' and name '%s' does not exist in organization '%s'", profile.getName(), organization.getKey()));
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+ }
+
+ @Test
+ public void fail_when_wrong_language() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("unknown"));
+ GroupDto group = db.users().insertGroup(organization);
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(format("Quality Profile for language 'xoo' and name '%s' does not exist in organization '%s'", profile.getName(), organization.getKey()));
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+ }
+
+ @Test
+ public void fail_when_group_does_not_belong_to_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ GroupDto group = db.users().insertGroup(anotherOrganization);
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(format("No group with name '%s' in organization '%s'", group.getName(), organization.getKey()));
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+ }
+
+ @Test
+ public void fail_when_qp_is_built_in() {
+ OrganizationDto organization = db.organizations().insert();
+ GroupDto group = db.users().insertGroup(organization);
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO).setIsBuiltIn(true));
+ userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(String.format("Operation forbidden for built-in Quality Profile '%s' with language 'xoo'", profile.getName()));
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+ }
+
+ @Test
+ public void fail_when_not_enough_permission() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO));
+ GroupDto group = db.users().insertGroup(organization);
+ userSession.logIn(db.users().insertUser()).addPermission(OrganizationPermission.ADMINISTER_QUALITY_GATES, organization);
+
+ expectedException.expect(ForbiddenException.class);
+
+ ws.newRequest()
+ .setParam(PARAM_QUALITY_PROFILE, profile.getName())
+ .setParam(PARAM_LANGUAGE, XOO)
+ .setParam(PARAM_GROUP, group.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .execute();
+ }
+}