From 507b48119ff55f19585651e6931457fe4724bab5 Mon Sep 17 00:00:00 2001 From: Belen Pruvost Date: Fri, 16 Apr 2021 15:18:21 +0200 Subject: [PATCH] SONAR-14660 - Fix logs download --- .../sonar/server/platform/ws/LogsAction.java | 39 +++++++++++++++---- .../server/platform/ws/LogsActionTest.java | 15 +++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/LogsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/LogsAction.java index cd8d3519beb..715fdde6d18 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/LogsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/LogsAction.java @@ -20,7 +20,14 @@ 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 stream = Files.list(Paths.get(logsDir.getPath()))) { + Optional 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); } } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/LogsActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/LogsActionTest.java index 3855c105868..5d31994b631 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/LogsActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/LogsActionTest.java @@ -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}"); -- 2.39.5