From 605faa8195f85f7dfcbfb6a4a3764bc1572a4d00 Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Tue, 13 Dec 2022 22:44:04 +0100 Subject: [PATCH] WIP: file storage refactoring: directory --- .../backend/transaction/CheckTargetPath.java | 56 +++++++++++++++---- .../org/caosdb/server/jobs/EntityFlagJob.java | 10 +++- .../server/jobs/core/AutoCreateDirs.java | 7 ++- .../jobs/core/CheckTargetPathValid.java | 3 +- .../caosdb/server/utils/ServerMessages.java | 6 ++ 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/CheckTargetPath.java b/src/main/java/org/caosdb/server/database/backend/transaction/CheckTargetPath.java index 5e714ec3..e72b4556 100644 --- a/src/main/java/org/caosdb/server/database/backend/transaction/CheckTargetPath.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/CheckTargetPath.java @@ -4,6 +4,7 @@ import org.caosdb.server.database.BackendTransaction; import org.caosdb.server.database.exceptions.EntityDoesNotExistException; import org.caosdb.server.entity.EntityInterface; import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.container.TransactionContainer; import org.caosdb.server.filesystem.Path; import org.caosdb.server.filesystem.VirtualFSODescriptorInterface; import org.caosdb.server.utils.ServerMessages; @@ -19,33 +20,58 @@ import org.caosdb.server.utils.ServerMessages; public class CheckTargetPath extends BackendTransaction { private final EntityInterface entity; + private TransactionContainer container; - public CheckTargetPath(final EntityInterface entity) { + public CheckTargetPath(final EntityInterface entity, TransactionContainer container) { + this.container = container; this.entity = entity; } @Override protected void execute() { try { - checkTarget(entity); + checkTarget(entity, container); } catch (final Message e) { entity.addError(e); } } - public void checkTarget(final EntityInterface entity) throws Message { - // TODO move to transaction - final VirtualFSODescriptorInterface fd = entity.getFSODescriptor(); - final Path targetPath = fd.getPath(); + public void checkTarget(final EntityInterface entity, TransactionContainer container) + throws Message { - // TODO move to FileSystem or Path - for (final String segment : targetPath.getSegments()) { - if (segment.matches("^\\.{1,3}$")) { - throw ServerMessages.TARGET_PATH_NOT_ALLOWED; + checkNastyPath(entity.getFSODescriptor().getPath()); + checkOwner(entity); + checkParentExists(entity, container); + } + + private void checkParentExists(EntityInterface entity, TransactionContainer container) + throws Message { + Path path = entity.getFSODescriptor().getPath().getParent(); + if (path == null) { + // root is parent + return; + } + for (EntityInterface e : container) { + if (e.getFSODescriptor() != null && e.getFSODescriptor().getPath() != null) { + if (e.getFSODescriptor().getPath().equals(path)) { + // found the parent in the current container + return; + } } } - final GetFileEntityByPath t = new GetFileEntityByPath(targetPath, true); + GetFileEntityByPath t = new GetFileEntityByPath(path, false); + try { + execute(t); + } catch (final EntityDoesNotExistException e) { + throw ServerMessages.TARGET_PARENT_DIRECTORY_DOES_NOT_EXIST; + } + } + + private void checkOwner(EntityInterface entity) throws Message { + final VirtualFSODescriptorInterface fd = entity.getFSODescriptor(); + final Path path = fd.getPath(); + final GetFileEntityByPath t = new GetFileEntityByPath(path, false); try { execute(t); } catch (final EntityDoesNotExistException e) { @@ -60,4 +86,12 @@ public class CheckTargetPath extends BackendTransaction { throw ServerMessages.TARGET_PATH_EXISTS; } } + + private void checkNastyPath(Path path) throws Message { + for (final String segment : path.getSegments()) { + if (segment.matches("^\\.{1,3}$")) { + throw ServerMessages.TARGET_PATH_NOT_ALLOWED; + } + } + } } diff --git a/src/main/java/org/caosdb/server/jobs/EntityFlagJob.java b/src/main/java/org/caosdb/server/jobs/EntityFlagJob.java index 374de7b1..286b5453 100644 --- a/src/main/java/org/caosdb/server/jobs/EntityFlagJob.java +++ b/src/main/java/org/caosdb/server/jobs/EntityFlagJob.java @@ -38,7 +38,15 @@ public abstract class EntityFlagJob extends EntityJob { @Override protected void run() { if (this.value == null) { - this.value = this.getClass().getAnnotation(JobAnnotation.class).defaultValue(); + JobAnnotation annotation = getClass().getAnnotation(JobAnnotation.class); + if (getContainer().getFlags() != null) { + this.value = + this.getContainer() + .getFlags() + .getOrDefault(annotation.flag(), annotation.defaultValue()); + } else { + this.value = annotation.defaultValue(); + } } job(this.value); } diff --git a/src/main/java/org/caosdb/server/jobs/core/AutoCreateDirs.java b/src/main/java/org/caosdb/server/jobs/core/AutoCreateDirs.java index afbadcbe..a2644c63 100644 --- a/src/main/java/org/caosdb/server/jobs/core/AutoCreateDirs.java +++ b/src/main/java/org/caosdb/server/jobs/core/AutoCreateDirs.java @@ -12,9 +12,14 @@ import org.caosdb.server.filesystem.Path; import org.caosdb.server.filesystem.VirtualFSODescriptorInterface; import org.caosdb.server.jobs.EntityFlagJob; import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.TransactionStage; import org.caosdb.server.permissions.EntityACL; -@JobAnnotation(flag = "autoCreateDirs", defaultValue = "true", loadAlways = true) +@JobAnnotation( + flag = "autoCreateDirs", + defaultValue = "true", + loadAlways = true, + stage = TransactionStage.PRE_CHECK) public class AutoCreateDirs extends EntityFlagJob { @Override diff --git a/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java b/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java index 25755876..6d381553 100644 --- a/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java @@ -48,7 +48,8 @@ public class CheckTargetPathValid extends FilesJob { return; } - final CheckTargetPath t = new CheckTargetPath(getEntity()); + // check that target path is not owned by another entity. + final CheckTargetPath t = new CheckTargetPath(getEntity(), getContainer()); execute(t); } } diff --git a/src/main/java/org/caosdb/server/utils/ServerMessages.java b/src/main/java/org/caosdb/server/utils/ServerMessages.java index 58e8fde9..ed048f3c 100644 --- a/src/main/java/org/caosdb/server/utils/ServerMessages.java +++ b/src/main/java/org/caosdb/server/utils/ServerMessages.java @@ -126,6 +126,12 @@ public class ServerMessages { MessageCode.MESSAGE_CODE_TARGET_PATH_EXISTS, "This target path does already exist."); + public static final Message TARGET_PARENT_DIRECTORY_DOES_NOT_EXIST = + new Message( + MessageType.Error, + MessageCode.MESSAGE_CODE_UNKNOWN, + "The parent directory of the target path does not exist."); + public static final Message PROPERTY_HAS_NO_UNIT = new Message( MessageType.Error, -- GitLab