]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7174 Check scan permission per project in /api/ce/task WS
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 8 Jan 2016 15:47:30 +0000 (16:47 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 12 Jan 2016 14:34:25 +0000 (15:34 +0100)
server/sonar-server/src/main/java/org/sonar/server/computation/ws/TaskAction.java
server/sonar-server/src/test/java/org/sonar/server/computation/ws/TaskActionTest.java

index d7b8987c5f166c68eaeaace92ec3864695b92df8..d3d76149dd5b05914edb272e76413f4363367734 100644 (file)
 package org.sonar.server.computation.ws;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
+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.core.permission.GlobalPermissions;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -35,13 +33,15 @@ import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.WsCe;
 
+import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 
 public class TaskAction implements CeWsAction {
 
   public static final String ACTION = "task";
   public static final String PARAM_TASK_UUID = "id";
-  private static final Set<String> AUTHORIZED_PERMISSIONS = ImmutableSet.of(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.SYSTEM_ADMIN);
 
   private final DbClient dbClient;
   private final TaskFormatter wsTaskFormatter;
@@ -71,18 +71,18 @@ public class TaskAction implements CeWsAction {
 
   @Override
   public void handle(Request wsRequest, Response wsResponse) throws Exception {
-    userSession.checkAnyPermissions(AUTHORIZED_PERMISSIONS);
-
     String taskUuid = wsRequest.mandatoryParam(PARAM_TASK_UUID);
     DbSession dbSession = dbClient.openSession(false);
     try {
       WsCe.TaskResponse.Builder wsTaskResponse = WsCe.TaskResponse.newBuilder();
       Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, taskUuid);
       if (queueDto.isPresent()) {
+        checkPermission(queueDto.get().getComponentUuid());
         wsTaskResponse.setTask(wsTaskFormatter.formatQueue(dbSession, queueDto.get()));
       } else {
         Optional<CeActivityDto> activityDto = dbClient.ceActivityDao().selectByUuid(dbSession, taskUuid);
         if (activityDto.isPresent()) {
+          checkPermission(activityDto.get().getComponentUuid());
           wsTaskResponse.setTask(wsTaskFormatter.formatActivity(dbSession, activityDto.get()));
         } else {
           throw new NotFoundException();
@@ -94,4 +94,13 @@ public class TaskAction implements CeWsAction {
       dbClient.closeSession(dbSession);
     }
   }
+
+  private void checkPermission(@Nullable String projectUuid) {
+    if (!userSession.hasPermission(SYSTEM_ADMIN)
+      && !userSession.hasPermission(SCAN_EXECUTION)
+      && (projectUuid == null || !userSession.hasComponentUuidPermission(SCAN_EXECUTION, projectUuid))
+      ) {
+      throw insufficientPrivilegesException();
+    }
+  }
 }
index 3f8c274627ab7893de43c1662c2ecf24447bcaae..2dd1083029a5373a7c77c0e12c9a3352179b4078 100644 (file)
@@ -26,7 +26,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.utils.System2;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.util.Protobuf;
 import org.sonar.db.DbTester;
 import org.sonar.db.ce.CeActivityDto;
@@ -48,13 +47,23 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonar.core.permission.GlobalPermissions.PREVIEW_EXECUTION;
+import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 
 public class TaskActionTest {
+
+  static final ComponentDto PROJECT = ComponentTesting.newProjectDto()
+    .setUuid("PROJECT_1")
+    .setName("Project One")
+    .setKey("P1");
+
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone();
+
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
+
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
@@ -65,19 +74,18 @@ public class TaskActionTest {
 
   @Before
   public void setUp() {
+    dbTester.getDbClient().componentDao().insert(dbTester.getSession(), PROJECT);
     when(ceLogging.getFile(any(LogFileRef.class))).thenReturn(Optional.<File>absent());
-    userSession.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
   }
 
   @Test
   public void task_is_in_queue() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto().setUuid("PROJECT_1").setName("Project One").setKey("P1");
-    dbTester.getDbClient().componentDao().insert(dbTester.getSession(), project);
+    userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);
 
     CeQueueDto queueDto = new CeQueueDto();
     queueDto.setTaskType(CeTaskTypes.REPORT);
     queueDto.setUuid("TASK_1");
-    queueDto.setComponentUuid(project.uuid());
+    queueDto.setComponentUuid(PROJECT.uuid());
     queueDto.setStatus(CeQueueDto.Status.PENDING);
     queueDto.setSubmitterLogin("john");
     dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
@@ -92,22 +100,21 @@ public class TaskActionTest {
     assertThat(taskResponse.getTask().getId()).isEqualTo("TASK_1");
     assertThat(taskResponse.getTask().getStatus()).isEqualTo(WsCe.TaskStatus.PENDING);
     assertThat(taskResponse.getTask().getSubmitterLogin()).isEqualTo("john");
-    assertThat(taskResponse.getTask().getComponentId()).isEqualTo(project.uuid());
-    assertThat(taskResponse.getTask().getComponentKey()).isEqualTo(project.key());
-    assertThat(taskResponse.getTask().getComponentName()).isEqualTo(project.name());
+    assertThat(taskResponse.getTask().getComponentId()).isEqualTo(PROJECT.uuid());
+    assertThat(taskResponse.getTask().getComponentKey()).isEqualTo(PROJECT.key());
+    assertThat(taskResponse.getTask().getComponentName()).isEqualTo(PROJECT.name());
     assertThat(taskResponse.getTask().hasExecutionTimeMs()).isFalse();
     assertThat(taskResponse.getTask().getLogs()).isFalse();
   }
 
   @Test
   public void task_is_archived() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto().setUuid("PROJECT_1").setName("Project One").setKey("P1");
-    dbTester.getDbClient().componentDao().insert(dbTester.getSession(), project);
+    userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);
 
     CeQueueDto queueDto = new CeQueueDto();
     queueDto.setTaskType(CeTaskTypes.REPORT);
     queueDto.setUuid("TASK_1");
-    queueDto.setComponentUuid(project.uuid());
+    queueDto.setComponentUuid(PROJECT.uuid());
     CeActivityDto activityDto = new CeActivityDto(queueDto);
     activityDto.setStatus(CeActivityDto.Status.FAILED);
     activityDto.setExecutionTimeMs(500L);
@@ -124,9 +131,9 @@ public class TaskActionTest {
     WsCe.Task task = taskResponse.getTask();
     assertThat(task.getId()).isEqualTo("TASK_1");
     assertThat(task.getStatus()).isEqualTo(WsCe.TaskStatus.FAILED);
-    assertThat(task.getComponentId()).isEqualTo(project.uuid());
-    assertThat(task.getComponentKey()).isEqualTo(project.key());
-    assertThat(task.getComponentName()).isEqualTo(project.name());
+    assertThat(task.getComponentId()).isEqualTo(PROJECT.uuid());
+    assertThat(task.getComponentKey()).isEqualTo(PROJECT.key());
+    assertThat(task.getComponentName()).isEqualTo(PROJECT.name());
     assertThat(task.getAnalysisId()).isEqualTo("123456");
     assertThat(task.getExecutionTimeMs()).isEqualTo(500L);
     assertThat(task.getLogs()).isFalse();
@@ -134,17 +141,52 @@ public class TaskActionTest {
 
   @Test
   public void task_not_found() throws Exception {
-    expectedException.expect(NotFoundException.class);
+    userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);
 
+    expectedException.expect(NotFoundException.class);
     ws.newRequest()
       .setParam("id", "DOES_NOT_EXIST")
       .execute();
   }
 
   @Test
-  public void fail_if_not_admin_nor_scan_permission() {
-    expectedException.expect(ForbiddenException.class);
-    userSession.setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+  public void not_fail_on_queue_task_not_linked_on_project_with_system_admin_permissions() {
+    userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN);
+
+    CeQueueDto queueDto = new CeQueueDto();
+    queueDto.setTaskType("fake");
+    queueDto.setUuid("TASK_1");
+    queueDto.setStatus(CeQueueDto.Status.PENDING);
+    dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
+    dbTester.commit();
+
+    ws.newRequest()
+      .setMediaType(MediaTypes.JSON)
+      .setParam("id", "TASK_1")
+      .execute();
+  }
+
+  @Test
+  public void not_fail_on_queue_task_not_linked_on_project_with_global_scan_permissions() {
+    userSession.login("john").setGlobalPermissions(SCAN_EXECUTION);
+
+    CeQueueDto queueDto = new CeQueueDto();
+    queueDto.setTaskType("fake");
+    queueDto.setUuid("TASK_1");
+    queueDto.setStatus(CeQueueDto.Status.PENDING);
+    dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
+    dbTester.commit();
+
+    ws.newRequest()
+      .setMediaType(MediaTypes.JSON)
+      .setParam("id", "TASK_1")
+      .execute();
+  }
+
+  @Test
+  public void fail_on_queue_task_not_linked_on_project_if_not_admin_nor_scan_permission() {
+    userSession.login("john").setGlobalPermissions(PREVIEW_EXECUTION);
+
     CeQueueDto queueDto = new CeQueueDto();
     queueDto.setTaskType("fake");
     queueDto.setUuid("TASK_1");
@@ -152,6 +194,7 @@ public class TaskActionTest {
     dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
     dbTester.commit();
 
+    expectedException.expect(ForbiddenException.class);
     ws.newRequest()
       .setMediaType(MediaTypes.PROTOBUF)
       .setParam("id", "TASK_1")
@@ -159,20 +202,43 @@ public class TaskActionTest {
   }
 
   @Test
-  public void support_json_response_with_scan_permissions() {
-    userSession.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+  public void not_fail_on_queue_task_linked_on_project_with_project_scan_permission() {
+    userSession.login("john").addProjectUuidPermissions(SCAN_EXECUTION, PROJECT.uuid());
+
     CeQueueDto queueDto = new CeQueueDto();
     queueDto.setTaskType("fake");
     queueDto.setUuid("TASK_1");
     queueDto.setStatus(CeQueueDto.Status.PENDING);
+    queueDto.setComponentUuid(PROJECT.uuid());
     dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
     dbTester.commit();
 
-    TestResponse wsResponse = ws.newRequest()
+    ws.newRequest()
       .setMediaType(MediaTypes.JSON)
       .setParam("id", "TASK_1")
       .execute();
+  }
+
+  @Test
+  public void not_fail_on_archived_task_linked_on_project_with_project_scan_permission() throws Exception {
+    userSession.login("john").addProjectUuidPermissions(SCAN_EXECUTION, PROJECT.uuid());
 
-    assertJson(wsResponse.getInput()).isSimilarTo("{\"task\":{}}");
+    CeQueueDto queueDto = new CeQueueDto();
+    queueDto.setTaskType(CeTaskTypes.REPORT);
+    queueDto.setUuid("TASK_1");
+    queueDto.setComponentUuid(PROJECT.uuid());
+    CeActivityDto activityDto = new CeActivityDto(queueDto);
+    activityDto.setStatus(CeActivityDto.Status.FAILED);
+    activityDto.setExecutionTimeMs(500L);
+    activityDto.setSnapshotId(123_456L);
+    activityDto.setComponentUuid(PROJECT.uuid());
+    dbTester.getDbClient().ceActivityDao().insert(dbTester.getSession(), activityDto);
+    dbTester.commit();
+
+    ws.newRequest()
+      .setMediaType(MediaTypes.PROTOBUF)
+      .setParam("id", "TASK_1")
+      .execute();
   }
+
 }