From 4c0d81eb984640587557787892ee3f1cbdcc193b Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Fri, 22 Sep 2017 13:55:06 +0200 Subject: [PATCH] SONAR-1330 Remove user permission to edit single quality profile --- .../qualityprofile/QProfileEditUsersDao.java | 4 + .../QProfileEditUsersMapper.java | 2 + .../QProfileEditUsersMapper.xml | 6 + .../QProfileEditUsersDaoTest.java | 13 + .../qualityprofile/ws/RemoveUserAction.java | 29 +- .../ws/RemoveUserActionTest.java | 301 ++++++++++++++++++ .../QualityProfilesService.java | 9 + .../qualityprofile/RemoveUserRequest.java | 93 ++++++ .../QualityProfilesServiceTest.java | 19 ++ 9 files changed, 474 insertions(+), 2 deletions(-) create mode 100644 server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveUserActionTest.java create mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/RemoveUserRequest.java diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java index f5443fb5c11..b173b067332 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java @@ -40,6 +40,10 @@ public class QProfileEditUsersDao implements Dao { mapper(dbSession).insert(dto, system2.now()); } + public void deleteByQProfileAndUser(DbSession dbSession, QProfileDto profile, UserDto user) { + mapper(dbSession).delete(profile.getKee(), user.getId()); + } + private static QProfileEditUsersMapper mapper(DbSession dbSession) { return dbSession.getMapper(QProfileEditUsersMapper.class); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java index 8efa5fd5609..601b03791f8 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java @@ -26,4 +26,6 @@ public interface QProfileEditUsersMapper { QProfileEditUsersDto selectByQProfileAndUser(@Param("qProfileUuid") String qProfileUuid, @Param("userId") int userId); void insert(@Param("dto") QProfileEditUsersDto dto, @Param("now") long now); + + void delete(@Param("qProfileUuid") String qProfileUuid, @Param("userId") int userId); } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml index 1e391294d54..a56278ea9d8 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml @@ -32,5 +32,11 @@ ) + + delete from qprofile_edit_users + where qprofile_uuid = #{qProfileUuid, jdbcType=VARCHAR} + and user_id = #{userId, jdbcType=INTEGER} + + diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java index a3442583975..5f0992e9a8e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java @@ -71,4 +71,17 @@ public class QProfileEditUsersDaoTest { entry("createdAt", NOW)); } + @Test + public void deleteByQProfileAndUser() { + OrganizationDto organization = db.organizations().insert(); + QProfileDto profile = db.qualityProfiles().insert(organization); + UserDto user = db.users().insertUser(); + db.qualityProfiles().addUserPermission(profile, user); + assertThat(underTest.exists(db.getSession(), profile, user)).isTrue(); + + underTest.deleteByQProfileAndUser(db.getSession(), profile, user); + + assertThat(underTest.exists(db.getSession(), profile, user)).isFalse(); + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveUserAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveUserAction.java index 4efdccaf9c8..e299c3fd7b0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveUserAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveUserAction.java @@ -25,19 +25,29 @@ 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.UserDto; 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_USER; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LOGIN; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE; public class RemoveUserAction implements QProfileWsAction { + private final DbClient dbClient; + private final QProfileWsSupport wsSupport; private final Languages languages; - public RemoveUserAction(Languages languages) { + public RemoveUserAction(DbClient dbClient, QProfileWsSupport wsSupport, Languages languages) { + this.dbClient = dbClient; + this.wsSupport = wsSupport; this.languages = languages; } @@ -73,6 +83,21 @@ public class RemoveUserAction 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); + UserDto user = wsSupport.getUser(dbSession, organization, request.mandatoryParam(PARAM_LOGIN)); + removeUser(dbSession, profile, user); + } + response.noContent(); + } + + private void removeUser(DbSession dbSession, QProfileDto profile, UserDto user) { + if (!dbClient.qProfileEditUsersDao().exists(dbSession, profile, user)) { + return; + } + dbClient.qProfileEditUsersDao().deleteByQProfileAndUser(dbSession, profile, user); + dbSession.commit(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveUserActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveUserActionTest.java new file mode 100644 index 00000000000..66329816a4f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveUserActionTest.java @@ -0,0 +1,301 @@ +/* + * 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.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.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LOGIN; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE; + +public class RemoveUserActionTest { + + 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 RemoveUserAction(db.getDbClient(), wsSupport, LANGUAGES)); + + @Test + public void test_definition() { + WebService.Action def = ws.getDef(); + assertThat(def.key()).isEqualTo("remove_user"); + assertThat(def.isPost()).isTrue(); + assertThat(def.isInternal()).isTrue(); + assertThat(def.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("organization", "qualityProfile", "language", "login"); + } + + @Test + public void remove_user() { + OrganizationDto organization = db.organizations().insert(); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + db.qualityProfiles().addUserPermission(profile, user); + userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization); + + TestResponse response = ws.newRequest() + .setParam(PARAM_QUALITY_PROFILE, profile.getName()) + .setParam(PARAM_LANGUAGE, XOO) + .setParam(PARAM_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + + assertThat(response.getStatus()).isEqualTo(204); + assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), profile, user)).isFalse(); + } + + @Test + public void does_nothing_when_user_cannot_edit_profile() { + OrganizationDto organization = db.organizations().insert(); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), profile, user)).isFalse(); + userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization); + + ws.newRequest() + .setParam(PARAM_QUALITY_PROFILE, profile.getName()) + .setParam(PARAM_LANGUAGE, XOO) + .setParam(PARAM_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + + assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), profile, user)).isFalse(); + } + + @Test + public void qp_administers_can_remove_user() { + OrganizationDto organization = db.organizations().insert(); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + db.qualityProfiles().addUserPermission(profile, user); + userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization); + + ws.newRequest() + .setParam(PARAM_QUALITY_PROFILE, profile.getName()) + .setParam(PARAM_LANGUAGE, XOO) + .setParam(PARAM_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + + assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), profile, user)).isFalse(); + } + + @Test + public void qp_editors_can_remove_user() { + OrganizationDto organization = db.organizations().insert(); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + db.qualityProfiles().addUserPermission(profile, user); + 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_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + + assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), profile, user)).isFalse(); + } + + @Test + public void uses_default_organization_when_no_organization() { + OrganizationDto organization = db.getDefaultOrganization(); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + db.qualityProfiles().addUserPermission(profile, user); + userSession.logIn().addPermission(ADMINISTER_QUALITY_PROFILES, organization); + + ws.newRequest() + .setParam(PARAM_QUALITY_PROFILE, profile.getName()) + .setParam(PARAM_LANGUAGE, XOO) + .setParam(PARAM_LOGIN, user.getLogin() ) + .execute(); + + assertThat(db.getDbClient().qProfileEditUsersDao().exists(db.getSession(), profile, user)).isFalse(); + } + + @Test + public void fail_when_user_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("User with login 'unknown' is not found"); + + ws.newRequest() + .setParam(PARAM_QUALITY_PROFILE, profile.getName()) + .setParam(PARAM_LANGUAGE, XOO) + .setParam(PARAM_LOGIN, "unknown") + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + } + + @Test + public void fail_when_qprofile_does_not_exist() { + OrganizationDto organization = db.organizations().insert(); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + 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_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + } + + @Test + public void fail_when_qprofile_does_not_belong_to_organization() { + OrganizationDto organization = db.organizations().insert(); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + 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_LOGIN, user.getLogin()) + .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")); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + 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_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + } + + @Test + public void fail_when_user_is_not_member_of_organization() { + OrganizationDto organization = db.organizations().insert(); + OrganizationDto anotherOrganization = db.organizations().insert(); + UserDto user = db.users().insertUser(); + db.organizations().addMember(anotherOrganization, user); + QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO)); + userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(format("User '%s' is not member of organization '%s'", user.getLogin(), organization.getKey())); + + ws.newRequest() + .setParam(PARAM_QUALITY_PROFILE, profile.getName()) + .setParam(PARAM_LANGUAGE, XOO) + .setParam(PARAM_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + } + + @Test + public void fail_when_qp_is_built_in() { + OrganizationDto organization = db.organizations().insert(); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + 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_LOGIN, user.getLogin()) + .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)); + UserDto user = db.users().insertUser(); + db.organizations().addMember(organization, user); + 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_LOGIN, user.getLogin()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + } +} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesService.java index 38f5c2ca100..340fd30d4a5 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesService.java @@ -39,6 +39,7 @@ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters. import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_DEACTIVATE_RULE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_DELETE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_REMOVE_PROJECT; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_REMOVE_USER; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_RESTORE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_SEARCH; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_SET_DEFAULT; @@ -181,4 +182,12 @@ public class QualityProfilesService extends BaseService { .setParam(PARAM_LANGUAGE, request.getLanguage()) .setParam(PARAM_LOGIN, request.getUserLogin())); } + + public void removeUser(RemoveUserRequest request) { + call(new PostRequest(path(ACTION_REMOVE_USER)) + .setParam(PARAM_ORGANIZATION, request.getOrganization()) + .setParam(PARAM_QUALITY_PROFILE, request.getQualityProfile()) + .setParam(PARAM_LANGUAGE, request.getLanguage()) + .setParam(PARAM_LOGIN, request.getUserLogin())); + } } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/RemoveUserRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/RemoveUserRequest.java new file mode 100644 index 00000000000..609ac00d562 --- /dev/null +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/RemoveUserRequest.java @@ -0,0 +1,93 @@ +/* + * 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.sonarqube.ws.client.qualityprofile; + +import javax.annotation.concurrent.Immutable; + +@Immutable +public class RemoveUserRequest { + + private final String organization; + private final String language; + private final String qualityProfile; + private final String userLogin; + + private RemoveUserRequest(Builder builder) { + this.language = builder.language; + this.organization = builder.organization; + this.qualityProfile = builder.qualityProfile; + this.userLogin = builder.userLogin; + } + + public String getLanguage() { + return language; + } + + public String getOrganization() { + return organization; + } + + public String getQualityProfile() { + return qualityProfile; + } + + public String getUserLogin() { + return userLogin; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String organization; + private String qualityProfile; + private String language; + private String userLogin; + + private Builder() { + // enforce factory method use + } + + public Builder setLanguage(String language) { + this.language = language; + return this; + } + + public Builder setOrganization(String organization) { + this.organization = organization; + return this; + } + + public Builder setQualityProfile(String qualityProfile) { + this.qualityProfile = qualityProfile; + return this; + } + + public Builder setUserLogin(String userLogin) { + this.userLogin = userLogin; + return this; + } + + public RemoveUserRequest build() { + return new RemoveUserRequest(this); + } + } +} diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesServiceTest.java index 591d1690abc..63c4fcc8e8d 100644 --- a/sonar-ws/src/test/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesServiceTest.java +++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesServiceTest.java @@ -216,4 +216,23 @@ public class QualityProfilesServiceTest { .hasParam(PARAM_LOGIN, "john") .andNoOtherParam(); } + + @Test + public void remove_user() { + underTest.removeUser(RemoveUserRequest.builder() + .setOrganization("O1") + .setQualityProfile("P1") + .setLanguage("Xoo") + .setUserLogin("john") + .build()); + PostRequest request = serviceTester.getPostRequest(); + + serviceTester.assertThat(request) + .hasPath("remove_user") + .hasParam(PARAM_ORGANIZATION, "O1") + .hasParam(PARAM_QUALITY_PROFILE, "P1") + .hasParam(PARAM_LANGUAGE, "Xoo") + .hasParam(PARAM_LOGIN, "john") + .andNoOtherParam(); + } } -- 2.39.5