]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16453 Access api/qualitygates/project_status with Execute Analysis permission
authorMatteo Mara <matteo.mara@sonarsource.com>
Wed, 1 Jun 2022 07:14:05 +0000 (09:14 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 1 Jun 2022 20:03:02 +0000 (20:03 +0000)
server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java

index 124ca66af80115178894fdb0f4fa69de682e2765..fb0737da42c847547c8cf360a3b038bd9717c9f6 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.measure.LiveMeasureDto;
 import org.sonar.db.measure.MeasureDto;
+import org.sonar.db.permission.GlobalPermission;
 import org.sonar.db.project.ProjectDto;
 import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
@@ -77,7 +78,7 @@ public class ProjectStatusAction implements QualityGatesWsAction {
   public void define(WebService.NewController controller) {
     WebService.NewAction action = controller.createAction(ACTION_PROJECT_STATUS)
       .setDescription(String.format("Get the quality gate status of a project or a Compute Engine task.<br />" +
-        MSG_ONE_PROJECT_PARAMETER_ONLY + "<br />" +
+        "%s <br />" +
         "The different statuses returned are: %s. The %s status is returned when there is no quality gate associated with the analysis.<br />" +
         "Returns an HTTP code 404 if the analysis associated with the task is not found or does not exist.<br />" +
         "Requires one of the following permissions:" +
@@ -85,11 +86,13 @@ public class ProjectStatusAction implements QualityGatesWsAction {
         "<li>'Administer System'</li>" +
         "<li>'Administer' rights on the specified project</li>" +
         "<li>'Browse' on the specified project</li>" +
-        "</ul>", QG_STATUSES_ONE_LINE, ProjectStatusResponse.Status.NONE))
+        "<li>'Execute Analysis' on the specified project</li>" +
+        "</ul>",MSG_ONE_PROJECT_PARAMETER_ONLY, QG_STATUSES_ONE_LINE, ProjectStatusResponse.Status.NONE))
       .setResponseExample(getClass().getResource("project_status-example.json"))
       .setSince("5.3")
       .setHandler(this)
       .setChangelog(
+        new Change("9.5", "The 'Execute Analysis' permission also allows to access the endpoint"),
         new Change("8.5", "The field 'periods' in the response is deprecated. Use 'period' instead"),
         new Change("7.7", "The parameters 'branch' and 'pullRequest' were added"),
         new Change("7.6", "The field 'warning' in the response is deprecated"),
@@ -212,7 +215,9 @@ public class ProjectStatusAction implements QualityGatesWsAction {
 
   private void checkPermission(ProjectDto project) {
     if (!userSession.hasProjectPermission(UserRole.ADMIN, project) &&
-      !userSession.hasProjectPermission(UserRole.USER, project)) {
+      !userSession.hasProjectPermission(UserRole.USER, project) &&
+      !userSession.hasProjectPermission(UserRole.SCAN, project) &&
+      !userSession.hasPermission(GlobalPermission.SCAN)) {
       throw insufficientPrivilegesException();
     }
   }
index 49dfe24439a479c631e0ddd8947cd4cfb9c6eabb..f3132c3aa397ffa3fe4bcb9a1ce1ce4469a30c1a 100644 (file)
@@ -35,6 +35,7 @@ import org.sonar.db.component.BranchType;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.metric.MetricDto;
+import org.sonar.db.permission.GlobalPermission;
 import org.sonar.server.component.TestComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
@@ -310,6 +311,32 @@ public class ProjectStatusActionTest {
       .executeProtobuf(ProjectStatusResponse.class);
   }
 
+  @Test
+  public void user_with_project_scan_permission_is_allowed_to_get_project_status() {
+    ComponentDto project = db.components().insertPrivateProject();
+    SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
+    dbSession.commit();
+    userSession.addProjectPermission(UserRole.SCAN, project);
+
+    var response = ws.newRequest()
+      .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid()).execute();
+
+    assertThat(response.getStatus()).isEqualTo(200);
+  }
+
+  @Test
+  public void user_with_global_scan_permission_is_allowed_to_get_project_status() {
+    ComponentDto project = db.components().insertPrivateProject();
+    SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
+    dbSession.commit();
+    userSession.addPermission(GlobalPermission.SCAN);
+
+    var response = ws.newRequest()
+      .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid()).execute();
+
+    assertThat(response.getStatus()).isEqualTo(200);
+  }
+
   @Test
   public void fail_if_no_snapshot_id_found() {
     logInAsSystemAdministrator();