]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10134 Add organization parameter in api/qualitygates/select
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 6 Dec 2017 18:28:32 +0000 (19:28 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 14 Dec 2017 16:03:35 +0000 (17:03 +0100)
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java

index 1002fd8d0831be024aa1f965521d40236b4a78f5..138510d5cfc548684dc4fb074fb6a59f2b04132d 100644 (file)
  */
 package org.sonar.server.qualitygate.ws;
 
-import com.google.common.base.Optional;
+import java.util.Optional;
 import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.web.UserRole;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
-import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.property.PropertyDto;
+import org.sonar.db.qualitygate.QGateWithOrgDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.component.ComponentFinder.ParamNames;
-import org.sonar.server.user.UserSession;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.qualitygate.QualityGateFinder;
 
+import static java.lang.String.format;
 import static org.sonar.server.qualitygate.QualityGates.SONAR_QUALITYGATE_PROPERTY;
-import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
-import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-import static org.sonar.server.ws.WsUtils.checkFound;
 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_SELECT;
 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_ID;
 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PROJECT_ID;
 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PROJECT_KEY;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
 
 public class SelectAction implements QualityGatesWsAction {
   private final DbClient dbClient;
-  private final UserSession userSession;
   private final ComponentFinder componentFinder;
+  private final QualityGatesWsSupport wsSupport;
+  private final QualityGateFinder qualityGateFinder;
 
-  public SelectAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
+  public SelectAction(DbClient dbClient, ComponentFinder componentFinder, QualityGatesWsSupport wsSupport, QualityGateFinder qualityGateFinder) {
     this.dbClient = dbClient;
-    this.userSession = userSession;
     this.componentFinder = componentFinder;
+    this.wsSupport = wsSupport;
+    this.qualityGateFinder = qualityGateFinder;
   }
 
   @Override
@@ -61,7 +63,7 @@ public class SelectAction implements QualityGatesWsAction {
       .setDescription("Associate a project to a quality gate.<br>" +
         "The '%s' or '%s' must be provided.<br>" +
         "Project id as a numeric value is deprecated since 6.1. Please use the id similar to '%s'.<br>" +
-          "Requires the 'Administer Quality Gates' permission.",
+        "Requires the 'Administer Quality Gates' permission.",
         PARAM_PROJECT_ID, PARAM_PROJECT_KEY,
         Uuids.UUID_EXAMPLE_02)
       .setPost(true)
@@ -81,6 +83,8 @@ public class SelectAction implements QualityGatesWsAction {
       .setDescription("Project key")
       .setExampleValue(KEY_PROJECT_EXAMPLE_001)
       .setSince("6.1");
+
+    wsSupport.createOrganizationParam(action);
   }
 
   @Override
@@ -90,45 +94,41 @@ public class SelectAction implements QualityGatesWsAction {
     String projectKey = request.param(PARAM_PROJECT_KEY);
 
     try (DbSession dbSession = dbClient.openSession(false)) {
-      checkQualityGate(dbSession, gateId);
-      ComponentDto project = getProject(dbSession, projectId, projectKey);
+      OrganizationDto organization = wsSupport.getOrganization(dbSession, request);
+      QGateWithOrgDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, gateId);
+      ComponentDto project = getProject(dbSession, organization, projectId, projectKey);
+      wsSupport.checkCanAdminProject(organization, project);
 
       dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto()
         .setKey(SONAR_QUALITYGATE_PROPERTY)
         .setResourceId(project.getId())
-        .setValue(String.valueOf(gateId)));
+        .setValue(String.valueOf(qualityGate.getId())));
 
       dbSession.commit();
     }
     response.noContent();
   }
 
-  private ComponentDto getProject(DbSession dbSession, @Nullable String projectId, @Nullable String projectKey) {
+  private ComponentDto getProject(DbSession dbSession, OrganizationDto organization, @Nullable String projectId, @Nullable String projectKey) {
     ComponentDto project = selectProjectById(dbSession, projectId)
-      .or(() -> componentFinder.getByUuidOrKey(dbSession, projectId, projectKey, ParamNames.PROJECT_ID_AND_KEY));
-
-    if (!userSession.hasPermission(OrganizationPermission.ADMINISTER_QUALITY_GATES, project.getOrganizationUuid()) &&
-      !userSession.hasComponentPermission(UserRole.ADMIN, project)) {
-      throw insufficientPrivilegesException();
+      .orElseGet(() -> componentFinder.getByUuidOrKey(dbSession, projectId, projectKey, ParamNames.PROJECT_ID_AND_KEY));
+    if (project.getOrganizationUuid().equals(organization.getUuid())) {
+      return project;
     }
-
-    return project;
+    throw new NotFoundException(format("Project '%s' doesn't exist in organization '%s'", project.getKey(), organization.getKey()));
   }
 
   private Optional<ComponentDto> selectProjectById(DbSession dbSession, @Nullable String projectId) {
     if (projectId == null) {
-      return Optional.absent();
+      return Optional.empty();
     }
 
     try {
       long dbId = Long.parseLong(projectId);
-      return dbClient.componentDao().selectById(dbSession, dbId);
+      return Optional.ofNullable(dbClient.componentDao().selectById(dbSession, dbId).orNull());
     } catch (NumberFormatException e) {
-      return Optional.absent();
+      return Optional.empty();
     }
   }
 
-  private void checkQualityGate(DbSession dbSession, long id) {
-    checkFound(dbClient.qualityGateDao().selectById(dbSession, id), "There is no quality gate with id=" + id);
-  }
 }
index 6b8127ed5c6130328058ca0a4a7286ba8fcd1ebd..0a6b0377215d6d731d2fe08fab70a873ed1af257 100644 (file)
@@ -31,14 +31,11 @@ import org.mockito.runners.MockitoJUnitRunner;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.WebService.Action;
 import org.sonar.api.server.ws.WebService.Controller;
-import org.sonar.db.DbClient;
 import org.sonar.db.qualitygate.ProjectQgateAssociation;
 import org.sonar.db.qualitygate.ProjectQgateAssociationQuery;
-import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.qualitygate.QgateProjectFinder;
 import org.sonar.server.qualitygate.QgateProjectFinder.Association;
 import org.sonar.server.qualitygate.QualityGates;
-import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.RemovedWebServiceHandler;
 import org.sonar.server.ws.WsTester;
 
@@ -65,13 +62,10 @@ public class QualityGatesWsTest {
 
   @Before
   public void setUp() {
-    SelectAction selectAction = new SelectAction(mock(DbClient.class), mock(UserSessionRule.class), mock(ComponentFinder.class));
-
     tester = new WsTester(new QualityGatesWs(
       new SearchAction(projectFinder),
       new CreateAction(null, null, null, null),
-      new SetAsDefaultAction(qGates),
-      selectAction));
+      new SetAsDefaultAction(qGates)));
   }
 
   @Test
index b08a915d318dabd1558bebbd4307aa6eb8a5a68d..cbb7e770f67713ab9d555fdbe2794612e68c7580 100644 (file)
@@ -23,21 +23,24 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.utils.System2;
-import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.qualitygate.QGateWithOrgDto;
 import org.sonar.db.qualitygate.QualityGateDto;
 import org.sonar.server.component.TestComponentFinder;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.qualitygate.QualityGateFinder;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsActionTester;
 
 import static java.lang.String.format;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
 import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
 import static org.sonar.server.qualitygate.QualityGates.SONAR_QUALITYGATE_PROPERTY;
 
@@ -51,18 +54,22 @@ public class SelectActionTest {
   public DbTester db = DbTester.create(System2.INSTANCE);
 
   private DbClient dbClient = db.getDbClient();
-  private SelectAction underTest = new SelectAction(dbClient, userSession, TestComponentFinder.from(db));
+  private SelectAction underTest = new SelectAction(dbClient, TestComponentFinder.from(db),
+    new QualityGatesWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db)),
+    new QualityGateFinder(db.getDbClient()));
   private WsActionTester ws = new WsActionTester(underTest);
 
   @Test
   public void select_by_id() {
-    userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization());
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
 
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectId", project.getId().toString())
+      .setParam("organization", organization.getKey())
       .execute();
 
     assertSelected(qualityGate, project);
@@ -70,13 +77,15 @@ public class SelectActionTest {
 
   @Test
   public void select_by_uuid() {
-    userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization());
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
 
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectId", project.uuid())
+      .setParam("organization", organization.getKey())
       .execute();
 
     assertSelected(qualityGate, project);
@@ -84,13 +93,15 @@ public class SelectActionTest {
 
   @Test
   public void select_by_key() {
-    userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization());
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
 
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
-      .setParam("projectKey", project.getDbKey())
+      .setParam("projectKey", project.getKey())
+      .setParam("organization", organization.getKey())
       .execute();
 
     assertSelected(qualityGate, project);
@@ -98,13 +109,15 @@ public class SelectActionTest {
 
   @Test
   public void project_admin() {
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
+    OrganizationDto organization = db.organizations().insert();
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
     userSession.logIn().addProjectPermission(ADMIN, project);
 
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
-      .setParam("projectKey", project.getDbKey())
+      .setParam("projectKey", project.getKey())
+      .setParam("organization", organization.getKey())
       .execute();
 
     assertSelected(qualityGate, project);
@@ -112,103 +125,148 @@ public class SelectActionTest {
 
   @Test
   public void gate_administrator_can_associate_a_gate_to_a_project() {
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
-    userSession.logIn().addPermission(ADMINISTER_QUALITY_GATES, project.getOrganizationUuid());
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
 
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
-      .setParam("projectKey", project.getDbKey())
+      .setParam("projectKey", project.getKey())
+      .setParam("organization", organization.getKey())
+      .execute();
+
+    assertSelected(qualityGate, project);
+  }
+
+  @Test
+  public void default_organization_is_used_when_no_organization_parameter() {
+    OrganizationDto organization = db.getDefaultOrganization();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
+
+    ws.newRequest()
+      .setParam("gateId", qualityGate.getId().toString())
+      .setParam("projectKey", project.getKey())
       .execute();
 
     assertSelected(qualityGate, project);
   }
 
+  @Test
+  public void fail_when_project_belongs_to_another_organization() {
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    OrganizationDto anotherOrganization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(anotherOrganization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage(format("Project '%s' doesn't exist in organization '%s'", project.getKey(), organization.getKey()));
+
+    ws.newRequest()
+      .setParam("gateId", qualityGate.getId().toString())
+      .setParam("projectKey", project.getKey())
+      .setParam("organization", organization.getKey())
+      .execute();
+  }
+
   @Test
   public void fail_when_no_quality_gate() {
-    userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization());
-    ComponentDto project = db.components().insertPrivateProject();
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
 
     expectedException.expect(NotFoundException.class);
 
     ws.newRequest()
       .setParam("gateId", String.valueOf("1"))
-      .setParam("projectKey", project.getDbKey())
+      .setParam("projectKey", project.getKey())
+      .setParam("organization", organization.getKey())
       .execute();
   }
 
   @Test
   public void fail_when_no_project_id() {
-    userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization());
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
 
     expectedException.expect(NotFoundException.class);
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectId", String.valueOf((Long) 1L))
+      .setParam("organization", organization.getKey())
       .execute();
   }
 
   @Test
   public void fail_when_no_project_key() {
-    userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization());
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
+    OrganizationDto organization = db.organizations().insert();
+    userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
 
     expectedException.expect(NotFoundException.class);
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectKey", "unknown")
+      .setParam("organization", organization.getKey())
       .execute();
   }
 
   @Test
   public void fail_when_anonymous() {
-    userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization());
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
-
+    OrganizationDto organization = db.organizations().insert();
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
     userSession.anonymous();
 
     expectedException.expect(ForbiddenException.class);
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
-      .setParam("projectKey", project.getDbKey())
+      .setParam("projectKey", project.getKey())
+      .setParam("organization", organization.getKey())
       .execute();
   }
 
   @Test
   public void fail_when_not_project_admin() {
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
-    userSession.logIn().addProjectPermission(UserRole.ISSUE_ADMIN, project);
+    OrganizationDto organization = db.organizations().insert();
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
+    userSession.logIn().addProjectPermission(ISSUE_ADMIN, project);
 
     expectedException.expect(ForbiddenException.class);
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectKey", project.getDbKey())
+      .setParam("organization", organization.getKey())
       .execute();
   }
 
   @Test
   public void fail_when_not_quality_gates_admin() {
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
-    ComponentDto project = db.components().insertPrivateProject();
+    OrganizationDto organization = db.organizations().insert();
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
+    ComponentDto project = db.components().insertPrivateProject(organization);
     userSession.logIn();
 
     expectedException.expect(ForbiddenException.class);
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectKey", project.getDbKey())
+      .setParam("organization", organization.getKey())
       .execute();
   }
 
   @Test
   public void fail_when_using_branch_db_key() throws Exception {
     OrganizationDto organization = db.organizations().insert();
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
     ComponentDto project = db.components().insertMainBranch(organization);
     userSession.logIn().addProjectPermission(ADMIN, project);
     ComponentDto branch = db.components().insertProjectBranch(project);
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
 
     expectedException.expect(NotFoundException.class);
     expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey()));
@@ -216,16 +274,17 @@ public class SelectActionTest {
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectKey", branch.getDbKey())
+      .setParam("organization", organization.getKey())
       .execute();
   }
 
   @Test
   public void fail_when_using_branch_id() {
     OrganizationDto organization = db.organizations().insert();
+    QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization);
     ComponentDto project = db.components().insertMainBranch(organization);
     userSession.logIn().addProjectPermission(ADMIN, project);
     ComponentDto branch = db.components().insertProjectBranch(project);
-    QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
 
     expectedException.expect(NotFoundException.class);
     expectedException.expectMessage(format("Component id '%s' not found", branch.uuid()));
@@ -233,6 +292,7 @@ public class SelectActionTest {
     ws.newRequest()
       .setParam("gateId", qualityGate.getId().toString())
       .setParam("projectId", branch.uuid())
+      .setParam("organization", organization.getKey())
       .execute();
   }