]> source.dussan.org Git - sonarqube.git/commitdiff
Background tasks logs are available for project admin
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Tue, 19 Apr 2016 09:16:13 +0000 (11:16 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Tue, 19 Apr 2016 13:10:34 +0000 (15:10 +0200)
server/sonar-server/src/main/java/org/sonar/server/ce/ws/LogsAction.java
server/sonar-server/src/test/java/org/sonar/server/ce/ws/LogsActionTest.java

index f89b3c7981dbfeb7b437cad7734ecc2ae486ef19..aef36c510872f6dc56d8dfd76673f94c8dda35a7 100644 (file)
@@ -22,18 +22,21 @@ package org.sonar.server.ce.ws;
 import com.google.common.base.Optional;
 import java.io.File;
 import java.io.IOException;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.apache.commons.io.FileUtils;
 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.ce.log.CeLogging;
+import org.sonar.ce.log.LogFileRef;
+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.db.ce.CeActivityDto;
 import org.sonar.db.ce.CeQueueDto;
-import org.sonar.ce.log.CeLogging;
-import org.sonar.ce.log.LogFileRef;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.MediaTypes;
@@ -74,11 +77,10 @@ public class LogsAction implements CeWsAction {
 
   @Override
   public void handle(Request wsRequest, Response wsResponse) throws Exception {
-    userSession.checkPermission(UserRole.ADMIN);
-
     String taskUuid = wsRequest.mandatoryParam(PARAM_TASK_UUID);
-    LogFileRef ref = loadLogRef(taskUuid);
-    Optional<File> logFile = ceLogging.getFile(ref);
+    LogFileRefComponentUuidTuple refAndComponentUuid = loadLogRef(taskUuid);
+    checkPermissions(refAndComponentUuid.componentUuid);
+    Optional<File> logFile = ceLogging.getFile(refAndComponentUuid.logFileRef);
     if (logFile.isPresent()) {
       writeFile(logFile.get(), wsResponse);
     } else {
@@ -86,16 +88,24 @@ public class LogsAction implements CeWsAction {
     }
   }
 
-  private LogFileRef loadLogRef(String taskUuid) {
+  private void checkPermissions(@Nullable String componentUuid) {
+    if (componentUuid == null) {
+      userSession.checkPermission(GlobalPermissions.SYSTEM_ADMIN);
+    } else {
+      userSession.checkComponentUuidPermission(UserRole.ADMIN, componentUuid);
+    }
+  }
+
+  private LogFileRefComponentUuidTuple loadLogRef(String taskUuid) {
     DbSession dbSession = dbClient.openSession(false);
     try {
       Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, taskUuid);
       if (queueDto.isPresent()) {
-        return LogFileRef.from(queueDto.get());
+        return new LogFileRefComponentUuidTuple(LogFileRef.from(queueDto.get()), queueDto.get().getComponentUuid());
       }
       Optional<CeActivityDto> activityDto = dbClient.ceActivityDao().selectByUuid(dbSession, taskUuid);
       if (activityDto.isPresent()) {
-        return LogFileRef.from(activityDto.get());
+        return new LogFileRefComponentUuidTuple(LogFileRef.from(activityDto.get()), activityDto.get().getComponentUuid());
       }
       throw new NotFoundException(format("Task %s not found", taskUuid));
 
@@ -113,4 +123,15 @@ public class LogsAction implements CeWsAction {
       throw new IllegalStateException("Fail to copy compute engine log file to HTTP response: " + file.getAbsolutePath(), e);
     }
   }
+
+  private static class LogFileRefComponentUuidTuple {
+    private final LogFileRef logFileRef;
+    @CheckForNull
+    private final String componentUuid;
+
+    private LogFileRefComponentUuidTuple(LogFileRef logFileRef, @Nullable String componentUuid) {
+      this.logFileRef = logFileRef;
+      this.componentUuid = componentUuid;
+    }
+  }
 }
index ccdb4a9cd1875d07eaf17be5e3eae4fee42dc209..7a5277bb5221c6c7a370a1398338793b976a1a7a 100644 (file)
@@ -62,7 +62,7 @@ public class LogsActionTest {
 
   @Test
   public void return_task_logs_if_available() throws IOException {
-    userSession.setGlobalPermissions(UserRole.ADMIN);
+    globalAdministrator();
 
     // task must exist in database
     insert("TASK_1", null);
@@ -78,13 +78,31 @@ public class LogsActionTest {
     assertThat(response.getInput()).isEqualTo("{logs}");
   }
 
+  @Test
+  public void return_task_logs_when_project_admin() throws Exception {
+    userSession.addProjectUuidPermissions(UserRole.ADMIN, "PROJECT_UUID");
+
+    // task must exist in database
+    insert("TASK_1", "PROJECT_UUID");
+    File logFile = temp.newFile();
+    FileUtils.write(logFile, "{logs}");
+    when(ceLogging.getFile(new LogFileRef(CeTaskTypes.REPORT, "TASK_1", "PROJECT_UUID"))).thenReturn(Optional.of(logFile));
+
+    TestResponse response = tester.newRequest()
+      .setParam("taskId", "TASK_1")
+      .execute();
+
+    assertThat(response.getMediaType()).isEqualTo(MediaTypes.TXT);
+    assertThat(response.getInput()).isEqualTo("{logs}");
+  }
+
   /**
    * The parameter taskId is present but empty. It's considered as
    * a valid task which does not exist
    */
   @Test(expected = NotFoundException.class)
   public void return_404_if_task_id_is_empty() {
-    userSession.setGlobalPermissions(UserRole.ADMIN);
+    globalAdministrator();
     tester.newRequest()
       .setParam("taskId", "")
       .execute();
@@ -92,14 +110,14 @@ public class LogsActionTest {
 
   @Test(expected = IllegalArgumentException.class)
   public void bad_request_if_task_id_is_missing() {
-    userSession.setGlobalPermissions(UserRole.ADMIN);
+    globalAdministrator();
     tester.newRequest()
       .execute();
   }
 
   @Test(expected = NotFoundException.class)
   public void return_404_if_task_logs_are_not_available() {
-    userSession.setGlobalPermissions(UserRole.ADMIN);
+    globalAdministrator();
     insert("TASK_1", null);
     when(ceLogging.getFile(new LogFileRef(CeTaskTypes.REPORT, "TASK_1", null))).thenReturn(Optional.<File>absent());
 
@@ -110,7 +128,7 @@ public class LogsActionTest {
 
   @Test(expected = NotFoundException.class)
   public void return_404_if_task_does_not_exist() {
-    userSession.setGlobalPermissions(UserRole.ADMIN);
+    globalAdministrator();
     tester.newRequest()
       .setParam("taskId", "TASK_1")
       .execute();
@@ -118,11 +136,16 @@ public class LogsActionTest {
 
   @Test(expected = ForbiddenException.class)
   public void require_admin_permission() {
+    insert("TASK_1", null);
     tester.newRequest()
       .setParam("taskId", "TASK_1")
       .execute();
   }
 
+  private void globalAdministrator() {
+    userSession.setGlobalPermissions(UserRole.ADMIN);
+  }
+
   private CeQueueDto insert(String taskUuid, @Nullable String componentUuid) {
     CeQueueDto queueDto = new CeQueueDto();
     queueDto.setTaskType(CeTaskTypes.REPORT);