]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-1330 Remove user permission to edit single quality profile
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 22 Sep 2017 11:55:06 +0000 (13:55 +0200)
committerStas Vilchik <stas.vilchik@sonarsource.com>
Mon, 2 Oct 2017 15:18:15 +0000 (17:18 +0200)
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QProfileEditUsersMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QProfileEditUsersMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/QProfileEditUsersDaoTest.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RemoveUserAction.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RemoveUserActionTest.java [new file with mode: 0644]
sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesService.java
sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/RemoveUserRequest.java [new file with mode: 0644]
sonar-ws/src/test/java/org/sonarqube/ws/client/qualityprofile/QualityProfilesServiceTest.java

index f5443fb5c11d0abbed96dca521cf9908c6aef39c..b173b0673321e42c427af02d098ff4d89ffeaad4 100644 (file)
@@ -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);
   }
index 8efa5fd560994e96edced380d8572e41d573429e..601b03791f8060723aa0df9dff6eb254463556fe 100644 (file)
@@ -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);
 }
index 1e391294d5460466fa075790c7671d78788b25eb..a56278ea9d8695bf6b4e73c3a7e6e6f0d9bf27e5 100644 (file)
     )
   </insert>
 
+  <delete id="delete" parameterType="map">
+    delete from qprofile_edit_users
+    where qprofile_uuid = #{qProfileUuid, jdbcType=VARCHAR}
+    and user_id = #{userId, jdbcType=INTEGER}
+  </delete>
+
 </mapper>
 
index a34425839751dfdc09646d9b2c82a9578dd410d3..5f0992e9a8e9c9801923ae791c076a4fe2d60499 100644 (file)
@@ -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();
+  }
+
 }
index 4efdccaf9c878f9f15971b1a6bac46d6d55f0321..e299c3fd7b083fd6b3860b3e1a704f3780a0d871 100644 (file)
@@ -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 (file)
index 0000000..6632981
--- /dev/null
@@ -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();
+  }
+}
index 38f5c2ca100a4d7a319732e6edbd9924255cc05d..340fd30d4a577533af57313a3ffdf7e227e98fa9 100644 (file)
@@ -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 (file)
index 0000000..609ac00
--- /dev/null
@@ -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);
+    }
+  }
+}
index 591d1690abc8edf515839a759a8af21fc01b60fd..63c4fcc8e8d145176f361fd6394b16e5cb084f94 100644 (file)
@@ -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();
+  }
 }