aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-04-19 11:16:13 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-04-19 15:10:34 +0200
commit9b0ff958302e5c2f73787ea9a456dd2b319579d5 (patch)
tree99b06b8e586d4bd2e1ba18da6564da48cea44581
parent2f8a43ac76f1c91754954b75b0ff35c79f4f9248 (diff)
downloadsonarqube-9b0ff958302e5c2f73787ea9a456dd2b319579d5.tar.gz
sonarqube-9b0ff958302e5c2f73787ea9a456dd2b319579d5.zip
Background tasks logs are available for project admin
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/LogsAction.java39
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ce/ws/LogsActionTest.java33
2 files changed, 58 insertions, 14 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/LogsAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/LogsAction.java
index f89b3c7981d..aef36c51087 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/LogsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/LogsAction.java
@@ -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;
+ }
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/LogsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/LogsActionTest.java
index ccdb4a9cd18..7a5277bb522 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/LogsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/LogsActionTest.java
@@ -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);