]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10134 Add organization parameter in project_status action
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 7 Dec 2017 14:23:51 +0000 (15:23 +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/ProjectStatusAction.java
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java

index 7bd685e3203a43da4dffa523ed975f2df16e7b29..7e2c818de9daf7b13f00a7abf3d7ad0e2eb18813 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.measure.LiveMeasureDto;
 import org.sonar.db.measure.MeasureDto;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.component.ComponentFinder.ParamNames;
 import org.sonar.server.exceptions.BadRequestException;
@@ -45,14 +46,14 @@ import org.sonar.server.ws.KeyExamples;
 import org.sonarqube.ws.Qualitygates.ProjectStatusResponse;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
-import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
-import static org.sonar.server.ws.WsUtils.checkRequest;
-import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_PROJECT_STATUS;
 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ANALYSIS_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.user.AbstractUserSession.insufficientPrivilegesException;
+import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
+import static org.sonar.server.ws.WsUtils.checkRequest;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
 
 public class ProjectStatusAction implements QualityGatesWsAction {
   private static final String QG_STATUSES_ONE_LINE = Arrays.stream(ProjectStatusResponse.Status.values())
@@ -63,11 +64,13 @@ public class ProjectStatusAction implements QualityGatesWsAction {
   private final DbClient dbClient;
   private final ComponentFinder componentFinder;
   private final UserSession userSession;
+  private final QualityGatesWsSupport wsSupport;
 
-  public ProjectStatusAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession) {
+  public ProjectStatusAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, QualityGatesWsSupport wsSupport) {
     this.dbClient = dbClient;
     this.componentFinder = componentFinder;
     this.userSession = userSession;
+    this.wsSupport = wsSupport;
   }
 
   @Override
@@ -102,6 +105,8 @@ public class ProjectStatusAction implements QualityGatesWsAction {
       .setSince("5.4")
       .setDescription("Project key")
       .setExampleValue(KeyExamples.KEY_PROJECT_EXAMPLE_001);
+
+    wsSupport.createOrganizationParam(action);
   }
 
   @Override
@@ -114,22 +119,25 @@ public class ProjectStatusAction implements QualityGatesWsAction {
         ^ !isNullOrEmpty(projectId)
         ^ !isNullOrEmpty(projectKey),
       MSG_ONE_PARAMETER_ONLY);
-    ProjectStatusResponse projectStatusResponse = doHandle(analysisId, projectId, projectKey);
-    writeProtobuf(projectStatusResponse, request, response);
-  }
 
-  private ProjectStatusResponse doHandle(@Nullable String analysisId, @Nullable String projectId, @Nullable String projectKey) {
     try (DbSession dbSession = dbClient.openSession(false)) {
-      ProjectAndSnapshot projectAndSnapshot = getProjectAndSnapshot(dbSession, analysisId, projectId, projectKey);
-      checkPermission(projectAndSnapshot.project);
-      Optional<String> measureData = loadQualityGateDetails(dbSession, projectAndSnapshot, analysisId != null);
-
-      return ProjectStatusResponse.newBuilder()
-        .setProjectStatus(new QualityGateDetailsFormatter(measureData, projectAndSnapshot.snapshotDto).format())
-        .build();
+      OrganizationDto organization = wsSupport.getOrganization(dbSession, request);
+      ProjectStatusResponse projectStatusResponse = doHandle(dbSession, organization, analysisId, projectId, projectKey);
+      writeProtobuf(projectStatusResponse, request, response);
     }
   }
 
+  private ProjectStatusResponse doHandle(DbSession dbSession, OrganizationDto organization, @Nullable String analysisId, @Nullable String projectId, @Nullable String projectKey) {
+    ProjectAndSnapshot projectAndSnapshot = getProjectAndSnapshot(dbSession, analysisId, projectId, projectKey);
+    wsSupport.checkProjectBelongsToOrganization(organization, projectAndSnapshot.project);
+    checkPermission(projectAndSnapshot.project);
+    Optional<String> measureData = loadQualityGateDetails(dbSession, projectAndSnapshot, analysisId != null);
+
+    return ProjectStatusResponse.newBuilder()
+      .setProjectStatus(new QualityGateDetailsFormatter(measureData, projectAndSnapshot.snapshotDto).format())
+      .build();
+  }
+
   private ProjectAndSnapshot getProjectAndSnapshot(DbSession dbSession, @Nullable String analysisId, @Nullable String projectId, @Nullable String projectKey) {
     if (!isNullOrEmpty(analysisId)) {
       return getSnapshotThenProject(dbSession, analysisId);
index 7fa0d673a72fe6b7350aea57f079795a153ccd73..a1a0d00be910ba7f8e92d222acfcf4c751a6c9d2 100644 (file)
@@ -33,7 +33,6 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.metric.MetricDto;
 import org.sonar.db.organization.OrganizationDto;
@@ -41,6 +40,7 @@ import org.sonar.server.component.TestComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.Qualitygates.ProjectStatusResponse;
@@ -54,6 +54,7 @@ import static org.sonar.db.measure.MeasureTesting.newLiveMeasure;
 import static org.sonar.db.measure.MeasureTesting.newMeasureDto;
 import static org.sonar.db.metric.MetricTesting.newMetricDto;
 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ANALYSIS_ID;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ORGANIZATION;
 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.test.JsonAssert.assertJson;
@@ -71,19 +72,27 @@ public class ProjectStatusActionTest {
   private DbClient dbClient = db.getDbClient();
   private DbSession dbSession = db.getSession();
 
-  private WsActionTester ws = new WsActionTester(new ProjectStatusAction(dbClient, TestComponentFinder.from(db), userSession));
+  private WsActionTester ws = new WsActionTester(new ProjectStatusAction(dbClient, TestComponentFinder.from(db), userSession,
+    new QualityGatesWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db))));
 
   @Test
   public void test_definition() {
-    WebService.Action def = ws.getDef();
-    assertThat(def.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("analysisId", "projectKey", "projectId");
-    assertThat(def.changelog()).extracting(Change::getVersion, Change::getDescription).containsExactly(
+    WebService.Action action = ws.getDef();
+    assertThat(action.changelog()).extracting(Change::getVersion, Change::getDescription).containsExactly(
       tuple("6.4", "The field 'ignoredConditions' is added to the response"));
+    assertThat(action.params())
+      .extracting(WebService.Param::key, WebService.Param::isRequired)
+      .containsExactlyInAnyOrder(
+        tuple("analysisId", false),
+        tuple("projectKey", false),
+        tuple("projectId", false),
+        tuple("organization", false));
   }
 
   @Test
   public void test_json_example() throws IOException {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     userSession.addProjectPermission(UserRole.USER, project);
     MetricDto gateDetailsMetric = insertGateDetailMetric();
 
@@ -98,6 +107,7 @@ public class ProjectStatusActionTest {
 
     String response = ws.newRequest()
       .setParam("analysisId", snapshot.getUuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .execute().getInput();
 
     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
@@ -105,7 +115,8 @@ public class ProjectStatusActionTest {
 
   @Test
   public void return_past_status_when_project_is_referenced_by_past_analysis_id() throws IOException {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     SnapshotDto pastAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
       .setLast(false)
       .setPeriodMode("last_version")
@@ -128,6 +139,7 @@ public class ProjectStatusActionTest {
 
     String response = ws.newRequest()
       .setParam(PARAM_ANALYSIS_ID, pastAnalysis.getUuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .execute().getInput();
 
     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
@@ -135,7 +147,8 @@ public class ProjectStatusActionTest {
 
   @Test
   public void return_live_status_when_project_is_referenced_by_its_id() throws IOException {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
       .setPeriodMode("last_version")
       .setPeriodParam("2015-12-07")
@@ -149,6 +162,7 @@ public class ProjectStatusActionTest {
 
     String response = ws.newRequest()
       .setParam(PARAM_PROJECT_ID, project.uuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .execute().getInput();
 
     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
@@ -156,7 +170,8 @@ public class ProjectStatusActionTest {
 
   @Test
   public void return_live_status_when_project_is_referenced_by_its_key() throws IOException {
-    ComponentDto project = db.components().insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()).setDbKey("project-key"));
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
       .setPeriodMode("last_version")
       .setPeriodParam("2015-12-07")
@@ -169,7 +184,8 @@ public class ProjectStatusActionTest {
     userSession.addProjectPermission(UserRole.USER, project);
 
     String response = ws.newRequest()
-      .setParam(PARAM_PROJECT_KEY, "project-key")
+      .setParam(PARAM_PROJECT_KEY, project.getKey())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .execute().getInput();
 
     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
@@ -177,13 +193,15 @@ public class ProjectStatusActionTest {
 
   @Test
   public void return_undefined_status_if_specified_analysis_is_not_found() {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
     dbSession.commit();
     userSession.addProjectPermission(UserRole.USER, project);
 
     ProjectStatusResponse result = ws.newRequest()
       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .executeProtobuf(ProjectStatusResponse.class);
 
     assertThat(result.getProjectStatus().getStatus()).isEqualTo(Status.NONE);
@@ -192,11 +210,13 @@ public class ProjectStatusActionTest {
 
   @Test
   public void return_undefined_status_if_project_is_not_analyzed() {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     userSession.addProjectPermission(UserRole.USER, project);
 
     ProjectStatusResponse result = ws.newRequest()
       .setParam(PARAM_PROJECT_ID, project.uuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .executeProtobuf(ProjectStatusResponse.class);
 
     assertThat(result.getProjectStatus().getStatus()).isEqualTo(Status.NONE);
@@ -205,30 +225,66 @@ public class ProjectStatusActionTest {
 
   @Test
   public void project_administrator_is_allowed_to_get_project_status() {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
     dbSession.commit();
     userSession.addProjectPermission(UserRole.ADMIN, project);
 
     ws.newRequest()
       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .executeProtobuf(ProjectStatusResponse.class);
   }
 
   @Test
   public void project_user_is_allowed_to_get_project_status() {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
     dbSession.commit();
     userSession.addProjectPermission(UserRole.USER, project);
 
     ws.newRequest()
       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
+      .executeProtobuf(ProjectStatusResponse.class);
+  }
+
+  @Test
+  public void default_organization_is_used_when_no_organization_parameter() {
+    OrganizationDto organization = db.getDefaultOrganization();
+    ComponentDto project = db.components().insertPrivateProject(organization);
+    userSession.logIn().addProjectPermission(UserRole.USER, project);
+
+    ProjectStatusResponse result = ws.newRequest()
+      .setParam(PARAM_PROJECT_ID, project.uuid())
+      .executeProtobuf(ProjectStatusResponse.class);
+
+    assertThat(result.getProjectStatus().getStatus()).isEqualTo(Status.NONE);
+  }
+
+  @Test
+  public void fail_when_project_does_not_not_belong_to_organization() {
+    OrganizationDto organization = db.organizations().insert();
+    OrganizationDto otherOrganization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(otherOrganization);
+    SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
+    dbSession.commit();
+    userSession.addProjectPermission(UserRole.ADMIN, project);
+
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage(String.format("Project '%s' doesn't exist in organization '%s'", project.getKey(), organization.getKey()));
+
+    ws.newRequest()
+      .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .executeProtobuf(ProjectStatusResponse.class);
   }
 
   @Test
   public void fail_if_no_snapshot_id_found() {
+    OrganizationDto organization = db.organizations().insert();
     logInAsSystemAdministrator();
 
     expectedException.expect(NotFoundException.class);
@@ -236,12 +292,14 @@ public class ProjectStatusActionTest {
 
     ws.newRequest()
       .setParam(PARAM_ANALYSIS_ID, ANALYSIS_ID)
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .executeProtobuf(ProjectStatusResponse.class);
   }
 
   @Test
   public void fail_if_insufficient_privileges() {
-    ComponentDto project = db.components().insertPrivateProject(db.organizations().insert());
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
     dbSession.commit();
     userSession.logIn();
@@ -250,11 +308,14 @@ public class ProjectStatusActionTest {
 
     ws.newRequest()
       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .executeProtobuf(ProjectStatusResponse.class);
   }
 
   @Test
   public void fail_if_project_id_and_ce_task_id_provided() {
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = db.components().insertPrivateProject(organization);
     logInAsSystemAdministrator();
 
     expectedException.expect(BadRequestException.class);
@@ -263,6 +324,7 @@ public class ProjectStatusActionTest {
     ws.newRequest()
       .setParam(PARAM_ANALYSIS_ID, "analysis-id")
       .setParam(PARAM_PROJECT_ID, "project-uuid")
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .execute().getInput();
   }
 
@@ -273,7 +335,9 @@ public class ProjectStatusActionTest {
     expectedException.expect(BadRequestException.class);
     expectedException.expectMessage("Either 'analysisId', 'projectId' or 'projectKey' must be provided");
 
-    ws.newRequest().execute().getInput();
+    ws.newRequest()
+      .execute()
+      .getInput();
   }
 
   @Test
@@ -289,6 +353,7 @@ public class ProjectStatusActionTest {
 
     ws.newRequest()
       .setParam(PARAM_PROJECT_KEY, branch.getDbKey())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .execute();
   }
 
@@ -305,6 +370,7 @@ public class ProjectStatusActionTest {
 
     ws.newRequest()
       .setParam("projectId", branch.uuid())
+      .setParam(PARAM_ORGANIZATION, organization.getKey())
       .execute();
   }