diff --git a/armadillo/src/main/java/org/molgenis/armadillo/exceptions/InvalidObjectNameException.java b/armadillo/src/main/java/org/molgenis/armadillo/exceptions/InvalidObjectNameException.java new file mode 100644 index 000000000..10a2114ee --- /dev/null +++ b/armadillo/src/main/java/org/molgenis/armadillo/exceptions/InvalidObjectNameException.java @@ -0,0 +1,17 @@ +package org.molgenis.armadillo.exceptions; + +import static java.lang.String.format; +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(BAD_REQUEST) +public class InvalidObjectNameException extends RuntimeException { + + public InvalidObjectNameException(String objectName) { + super( + format( + "Object name '%s' is invalid. Object format should be in the following format: folder/file.", + objectName)); + } +} diff --git a/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloLinkFile.java b/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloLinkFile.java index 7de019254..6b65790dc 100644 --- a/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloLinkFile.java +++ b/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloLinkFile.java @@ -30,6 +30,9 @@ public ArmadilloLinkFile( String variables, String linkObject, String project) { + if (!isValidLinkObject(linkObject)) { + throw new IllegalArgumentException(format("Invalid link object: %s", linkObject)); + } this.linkObject = linkObject; this.sourceProject = sourceProject; this.sourceObject = sourceObject; @@ -70,6 +73,22 @@ public ArmadilloLinkFile(InputStream armadilloLinkStream, String linkProject, St } } + static Boolean isValidLinkObject(String linkObject) { + if (linkObject.endsWith("/")) { + return false; + } + int count = 0; + for (int i = 0; i < linkObject.length(); i++) { + if (linkObject.charAt(i) == '/') { + count++; + if (count > 1) { + return false; + } + } + } + return count == 1; + } + public String getSourceProject() { return this.sourceProject; } diff --git a/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloStorageService.java b/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloStorageService.java index 2252aa7d4..09eff3640 100644 --- a/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloStorageService.java +++ b/armadillo/src/main/java/org/molgenis/armadillo/storage/ArmadilloStorageService.java @@ -90,7 +90,7 @@ public void createLinkedObject( String linkName, String linkProject, String variables) - throws IOException { + throws IOException, StorageException { throwIfUnknown(sourceProject, sourceObject + PARQUET); throwIfUnknown(linkProject); throwIfDuplicate(linkProject, linkName + LINK_FILE); @@ -102,11 +102,15 @@ public void createLinkedObject( throw new UnknownVariableException( sourceProject, sourceObject, unavailableVariables.toString()); } - ArmadilloLinkFile armadilloLinkFile = - createLinkFileFromSource(sourceProject, sourceObject, variables, linkName, linkProject); - InputStream is = armadilloLinkFile.toStream(); - storageService.save( - is, SHARED_PREFIX + linkProject, armadilloLinkFile.getFileName(), APPLICATION_JSON); + try { + ArmadilloLinkFile armadilloLinkFile = + createLinkFileFromSource(sourceProject, sourceObject, variables, linkName, linkProject); + InputStream is = armadilloLinkFile.toStream(); + storageService.save( + is, SHARED_PREFIX + linkProject, armadilloLinkFile.getFileName(), APPLICATION_JSON); + } catch (IllegalArgumentException e) { + throw new InvalidObjectNameException(linkName); + } } public ArmadilloLinkFile createArmadilloLinkFileFromStream( @@ -223,17 +227,18 @@ private static Workspace toWorkspace(ObjectMetadata item) { .build(); } - private void trySaveWorkspace (ArmadilloWorkspace workspace, Principal principal, String id) { + private void trySaveWorkspace(ArmadilloWorkspace workspace, Principal principal, String id) { try { storageService.save( - workspace.createInputStream(), - getUserBucketName(principal), - getWorkspaceObjectName(id), - APPLICATION_OCTET_STREAM); + workspace.createInputStream(), + getUserBucketName(principal), + getWorkspaceObjectName(id), + APPLICATION_OCTET_STREAM); } catch (StorageException e) { throw new StorageException(e); } } + public void saveWorkspace(InputStream is, Principal principal, String id) { // Load root dir File drive = new File("/"); diff --git a/armadillo/src/test/java/org/molgenis/armadillo/storage/ArmadilloLinkFileTest.java b/armadillo/src/test/java/org/molgenis/armadillo/storage/ArmadilloLinkFileTest.java index deb20698f..119abb93b 100644 --- a/armadillo/src/test/java/org/molgenis/armadillo/storage/ArmadilloLinkFileTest.java +++ b/armadillo/src/test/java/org/molgenis/armadillo/storage/ArmadilloLinkFileTest.java @@ -1,7 +1,8 @@ package org.molgenis.armadillo.storage; import static java.lang.String.format; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; +import static org.molgenis.armadillo.storage.ArmadilloLinkFile.isValidLinkObject; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; @@ -102,6 +103,30 @@ public void testLoadLinkFileFromStreamInvalidProject() { } } + @Test + public void testIsValidLinkObjectTooManySlashes() { + String tooManySlashes = "/this/is/too/many"; + assertFalse(isValidLinkObject(tooManySlashes)); + } + + @Test + public void testIsValidLinkObjectEndsWithSlash() { + String endsWithSlash = "endswith/"; + assertFalse(isValidLinkObject(endsWithSlash)); + } + + @Test + public void testIsValidLinkObjectNotEnoughSlashes() { + String noSlash = "no slash"; + assertFalse(isValidLinkObject(noSlash)); + } + + @Test + public void testIsValidLinkObjectSucceeds() { + String object = "folder/file"; + assertTrue(isValidLinkObject(object)); + } + @Test public void testLoadLinkFileFromStreamInvalidVariables() { String testData =