]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14660 - Fix logs download
authorBelen Pruvost <belen.pruvost@sonarsource.com>
Fri, 16 Apr 2021 13:18:21 +0000 (15:18 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 16 Apr 2021 20:03:44 +0000 (20:03 +0000)
server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/LogsAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/LogsActionTest.java

index cd8d3519beb4348a8fc24ddb1120056baccfa99d..715fdde6d185c2dfdffb0048f7681915450496b3 100644 (file)
 package org.sonar.server.platform.ws;
 
 import java.io.File;
+import java.io.IOException;
 import java.net.HttpURLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.stream.Stream;
 import org.apache.commons.io.FileUtils;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -72,14 +79,30 @@ public class LogsAction implements SystemWsAction {
     ProcessId processId = ProcessId.fromKey(processKey);
 
     File logsDir = serverLogging.getLogsDir();
-    File file = new File(logsDir, processId.getLogFilenamePrefix() + ".log");
-    // filenames are defined in the enum LogProcess. Still to prevent any vulnerability,
-    // path is double-checked to prevent returning any file present on the file system.
-    if (file.exists() && file.getParentFile().equals(logsDir)) {
-      wsResponse.stream().setMediaType(MediaTypes.TXT);
-      FileUtils.copyFile(file, wsResponse.stream().output());
-    } else {
-      wsResponse.stream().setStatus(HttpURLConnection.HTTP_NOT_FOUND);
+
+    try (Stream<Path> stream = Files.list(Paths.get(logsDir.getPath()))) {
+      Optional<Path> path = stream
+        .filter(p -> p.getFileName().toString().contains(processId.getLogFilenamePrefix())
+          && p.getFileName().toString().endsWith(".log"))
+        .max(Comparator.comparing(Path::toString));
+
+      if (!path.isPresent()) {
+        wsResponse.stream().setStatus(HttpURLConnection.HTTP_NOT_FOUND);
+        return;
+      }
+
+      File file = new File(logsDir, path.get().getFileName().toString());
+
+      // filenames are defined in the enum LogProcess. Still to prevent any vulnerability,
+      // path is double-checked to prevent returning any file present on the file system.
+      if (file.exists() && file.getParentFile().equals(logsDir)) {
+        wsResponse.stream().setMediaType(MediaTypes.TXT);
+        FileUtils.copyFile(file, wsResponse.stream().output());
+      } else {
+        wsResponse.stream().setStatus(HttpURLConnection.HTTP_NOT_FOUND);
+      }
+    } catch (IOException e) {
+      throw new RuntimeException("Could not fetch logs", e);
     }
   }
 }
index 3855c1058689bbcdde1c9eb26ff09558962c1e7d..5d31994b631fa3b8b8fa6c4283e151451191217d 100644 (file)
@@ -149,6 +149,21 @@ public class LogsActionTest {
     assertThat(response.getInput()).isEqualTo("{recent}");
   }
 
+  @Test
+  public void create_latest_created_file() throws IOException {
+    logInAsSystemAdministrator();
+
+    File dir = createLogsDir();
+    FileUtils.write(new File(dir, "sonar.20210101.log"), "{old}");
+    FileUtils.write(new File(dir, "sonar.20210201.log"), "{recent}");
+
+    TestResponse response = actionTester.newRequest()
+      .setParam("process", "app")
+      .execute();
+    assertThat(response.getMediaType()).isEqualTo(MediaTypes.TXT);
+    assertThat(response.getInput()).isEqualTo("{recent}");
+  }
+
   private File createAllLogsFiles() throws IOException {
     File dir = createLogsDir();
     FileUtils.write(new File(dir, "sonar.log"), "{app}");