You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ze...@apache.org on 2024/04/03 07:52:03 UTC
(streampipes) 03/03: fix(#2651): Refactor and deprecate AssetDashboardResource
This is an automated email from the ASF dual-hosted git repository.
zehnder pushed a commit to branch 2651-incorrect-redirect-to-dashboard-instead-of-app-module
in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 30c2f83f532e334302cbfe0a9e4ecceb4c1041cd
Author: Philipp Zehnder <te...@users.noreply.github.com>
AuthorDate: Wed Apr 3 09:51:51 2024 +0200
fix(#2651): Refactor and deprecate AssetDashboardResource
---
.../streampipes/manager/file/FileManager.java | 5 ++
.../streampipes/manager/file/TestFileManager.java | 86 ++++++++++++++++------
.../rest/impl/AssetDashboardResource.java | 50 +++++++++----
3 files changed, 106 insertions(+), 35 deletions(-)
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/file/FileManager.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/file/FileManager.java
index 192d124bbe..5674aaa12e 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/file/FileManager.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/file/FileManager.java
@@ -64,6 +64,7 @@ public class FileManager {
fileInputStream = cleanFile(fileInputStream, filetype);
+
FileMetadata fileMetadata = makeFileMetadata(user, filename, filetype);
new FileHandler().storeFile(filename, fileInputStream);
storeFileMetadata(fileMetadata);
@@ -97,6 +98,10 @@ public class FileManager {
return !fileHash.equals(hash);
}
+ public static String sanitizeFilename(String filename) {
+ return filename.replaceAll("[^a-zA-Z0-9.\\-]", "_");
+ }
+
private static void storeFileMetadata(FileMetadata fileMetadata) {
getFileMetadataStorage().addFileMetadata(fileMetadata);
}
diff --git a/streampipes-pipeline-management/src/test/java/org/apache/streampipes/manager/file/TestFileManager.java b/streampipes-pipeline-management/src/test/java/org/apache/streampipes/manager/file/TestFileManager.java
index 58553e72f6..59e96b1e8c 100644
--- a/streampipes-pipeline-management/src/test/java/org/apache/streampipes/manager/file/TestFileManager.java
+++ b/streampipes-pipeline-management/src/test/java/org/apache/streampipes/manager/file/TestFileManager.java
@@ -18,46 +18,88 @@
package org.apache.streampipes.manager.file;
import org.apache.commons.io.IOUtils;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.io.IOException;
-import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
public class TestFileManager {
@Test
public void testCleanFileWithoutBom() throws IOException {
- String expected = "test";
- InputStream inputStream = IOUtils.toInputStream(expected, StandardCharsets.UTF_8);
- InputStream resultStream = FileManager.cleanFile(inputStream, "CSV");
- String resultString = IOUtils.toString(resultStream, StandardCharsets.UTF_8);
+ var expected = "test";
+ var inputStream = IOUtils.toInputStream(expected, StandardCharsets.UTF_8);
+ var resultStream = FileManager.cleanFile(inputStream, "CSV");
+ var resultString = IOUtils.toString(resultStream, StandardCharsets.UTF_8);
- Assertions.assertEquals(expected, resultString);
+ assertEquals(expected, resultString);
}
@Test
public void testCleanFileWithBom() throws IOException {
- String expected = "test";
- String utf8Bom = "\uFEFF";
- String inputString = utf8Bom + expected;
- InputStream inputStream = IOUtils.toInputStream(inputString, StandardCharsets.UTF_8);
- InputStream resultStream = FileManager.cleanFile(inputStream, "CSV");
- String resultString = IOUtils.toString(resultStream, StandardCharsets.UTF_8);
+ var expected = "test";
+ var utf8Bom = "\uFEFF";
+ var inputString = utf8Bom + expected;
+ var inputStream = IOUtils.toInputStream(inputString, StandardCharsets.UTF_8);
+ var resultStream = FileManager.cleanFile(inputStream, "CSV");
+ var resultString = IOUtils.toString(resultStream, StandardCharsets.UTF_8);
- Assertions.assertEquals(expected, resultString);
+ assertEquals(expected, resultString);
}
@Test
public void testCleanFileWithBomAndUmlauts() throws IOException {
- String expected = "testäüö";
- String utf8Bom = "\uFEFF";
- String inputString = utf8Bom + expected;
- InputStream inputStream = IOUtils.toInputStream(inputString, StandardCharsets.UTF_8);
- InputStream resultStream = FileManager.cleanFile(inputStream, "CSV");
- String resultString = IOUtils.toString(resultStream, StandardCharsets.UTF_8);
-
- Assertions.assertEquals(expected, resultString);
+ var expected = "testäüö";
+ var utf8Bom = "\uFEFF";
+ var inputString = utf8Bom + expected;
+ var inputStream = IOUtils.toInputStream(inputString, StandardCharsets.UTF_8);
+ var resultStream = FileManager.cleanFile(inputStream, "CSV");
+ var resultString = IOUtils.toString(resultStream, StandardCharsets.UTF_8);
+
+ assertEquals(expected, resultString);
+ }
+
+ @Test
+ public void sanitizeFilename_replacesNonAlphanumericCharactersWithUnderscore() {
+ var filename = "file@name#with$special%characters";
+ var sanitizedFilename = FileManager.sanitizeFilename(filename);
+ assertEquals("file_name_with_special_characters", sanitizedFilename);
+ }
+
+ @Test
+ public void sanitizeFilename_keepsAlphanumericAndDotAndHyphenCharacters() {
+ var filename = "file.name-with_alphanumeric123";
+ var sanitizedFilename = FileManager.sanitizeFilename(filename);
+ assertEquals(filename, sanitizedFilename);
+ }
+
+ @Test
+ public void sanitizeFilename_returnsUnderscoreForFilenameWithAllSpecialCharacters() {
+ var filename = "@#$%^&*()";
+ var sanitizedFilename = FileManager.sanitizeFilename(filename);
+ assertEquals("_________", sanitizedFilename);
+ }
+
+ @Test
+ public void sanitizeFilename_returnsEmptyStringForEmptyFilename() {
+ var filename = "";
+ var sanitizedFilename = FileManager.sanitizeFilename(filename);
+ assertEquals("", sanitizedFilename);
+ }
+
+ @Test
+ public void sanitizeFilename_removesSingleParentDirectory() {
+ var filename = "../file";
+ var sanitizedFilename = FileManager.sanitizeFilename(filename);
+ assertEquals(".._file", sanitizedFilename);
+ }
+
+ @Test
+ public void sanitizeFilename_removesDoubleParentDirectoryy() {
+ var filename = "../../file";
+ var sanitizedFilename = FileManager.sanitizeFilename(filename);
+ assertEquals(".._.._file", sanitizedFilename);
}
}
\ No newline at end of file
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetDashboardResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetDashboardResource.java
index 919bea60d9..111ea8ab14 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetDashboardResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/AssetDashboardResource.java
@@ -17,6 +17,7 @@
*/
package org.apache.streampipes.rest.impl;
+import org.apache.streampipes.manager.file.FileManager;
import org.apache.streampipes.model.client.assetdashboard.AssetDashboardConfig;
import org.apache.streampipes.rest.core.base.impl.AbstractRestResource;
import org.apache.streampipes.rest.shared.exception.SpMessageException;
@@ -43,6 +44,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.nio.file.Files;
@@ -51,6 +53,7 @@ import java.util.List;
@RestController
@RequestMapping("/api/v2/asset-dashboards")
+@Deprecated(forRemoval = true, since = "0.95.0")
public class AssetDashboardResource extends AbstractRestResource {
private static final Logger LOG = LoggerFactory.getLogger(AssetDashboardResource.class);
@@ -59,44 +62,52 @@ public class AssetDashboardResource extends AbstractRestResource {
@GetMapping(path = "/{dashboardId}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<AssetDashboardConfig> getAssetDashboard(@PathVariable("dashboardId") String dashboardId) {
- return ok(getNoSqlStorage().getAssetDashboardStorage().getAssetDashboard(dashboardId));
+ return ok(getNoSqlStorage().getAssetDashboardStorage()
+ .getAssetDashboard(dashboardId));
}
@PutMapping(
path = "/{dashboardId}",
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<Void> updateAssetDashboard(@PathVariable("dashboardId") String dashboardId,
- @RequestBody AssetDashboardConfig dashboardConfig) {
+ public ResponseEntity<Void> updateAssetDashboard(
+ @PathVariable("dashboardId") String dashboardId,
+ @RequestBody AssetDashboardConfig dashboardConfig
+ ) {
AssetDashboardConfig dashboard = getAssetDashboardStorage().getAssetDashboard(dashboardId);
dashboardConfig.setRev(dashboard.getRev());
- getNoSqlStorage().getAssetDashboardStorage().updateAssetDashboard(dashboardConfig);
+ getNoSqlStorage().getAssetDashboardStorage()
+ .updateAssetDashboard(dashboardConfig);
return ok();
}
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<AssetDashboardConfig>> getAllDashboards() {
- return ok(getNoSqlStorage().getAssetDashboardStorage().getAllAssetDashboards());
+ return ok(getNoSqlStorage().getAssetDashboardStorage()
+ .getAllAssetDashboards());
}
@PostMapping(
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> storeAssetDashboard(@RequestBody AssetDashboardConfig dashboardConfig) {
- getNoSqlStorage().getAssetDashboardStorage().storeAssetDashboard(dashboardConfig);
+ getNoSqlStorage().getAssetDashboardStorage()
+ .storeAssetDashboard(dashboardConfig);
return ok();
}
@DeleteMapping(path = "/{dashboardId}")
public ResponseEntity<Void> deleteAssetDashboard(@PathVariable("dashboardId") String dashboardId) {
- getNoSqlStorage().getAssetDashboardStorage().deleteAssetDashboard(dashboardId);
+ getNoSqlStorage().getAssetDashboardStorage()
+ .deleteAssetDashboard(dashboardId);
return ok();
}
@GetMapping(path = "/images/{imageName}")
public ResponseEntity<byte[]> getDashboardImage(@PathVariable("imageName") String imageName) {
try {
- java.nio.file.Path path = Paths.get(getTargetFile(imageName));
+ var sanitizedFileName = FileManager.sanitizeFilename(imageName);
+ java.nio.file.Path path = Paths.get(getTargetFile(sanitizedFileName));
File file = new File(path.toString());
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor(file.getName());
@@ -114,16 +125,28 @@ public class AssetDashboardResource extends AbstractRestResource {
@PostMapping(path = "/images", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Void> storeDashboardImage(@RequestPart("file_upload") MultipartFile fileDetail) {
- File targetDirectory = new File(getTargetDirectory());
+ try {
+ storeFile(fileDetail.getName(), fileDetail.getInputStream());
+ return ok();
+ } catch (IOException e) {
+ LOG.error("Could not extract image input stream from request", e);
+ return fail();
+ }
+ }
+
+ private void storeFile(String fileName, InputStream fileInputStream) {
+
+ var targetDirectory = new File(getTargetDirectory());
if (!targetDirectory.exists()) {
targetDirectory.mkdirs();
}
- File targetFile = new File(getTargetFile(fileDetail.getName()));
+ var sanitizedFileName = FileManager.sanitizeFilename(fileName);
+
+ var targetFile = new File(getTargetFile(sanitizedFileName));
try {
- FileUtils.copyInputStreamToFile(fileDetail.getInputStream(), targetFile);
- return ok();
+ FileUtils.copyInputStreamToFile(fileInputStream, targetFile);
} catch (IOException e) {
LOG.error(e.getMessage(), e);
throw new SpMessageException(HttpStatus.INTERNAL_SERVER_ERROR, e);
@@ -140,6 +163,7 @@ public class AssetDashboardResource extends AbstractRestResource {
}
private IAssetDashboardStorage getAssetDashboardStorage() {
- return StorageDispatcher.INSTANCE.getNoSqlStore().getAssetDashboardStorage();
+ return StorageDispatcher.INSTANCE.getNoSqlStore()
+ .getAssetDashboardStorage();
}
}