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;
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;
@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();
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();
+ }
+ }
}
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;
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);
@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);
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);
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();
@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");
dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
dbTester.commit();
+ expectedException.expect(ForbiddenException.class);
ws.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
.setParam("id", "TASK_1")
}
@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();
}
+
}