From abac15b65f1719f5da651fdf4fa0599076175334 Mon Sep 17 00:00:00 2001 From: Daniel Hornung <d.hornung@indiscale.com> Date: Wed, 18 Sep 2024 14:37:32 +0200 Subject: [PATCH] MAINT: Removed DropOffBox functionality. It was about time. --- conf/core/server.conf | 11 - misc/chown_script/README | 37 --- misc/chown_script/chown_script_template | 83 ------- misc/chown_script/install | 220 ------------------ misc/chown_script/test_functions | 62 ----- src/doc/specification/Fileserver.md | 29 +-- .../java/org/caosdb/server/CaosDBServer.java | 4 - .../java/org/caosdb/server/FileSystem.java | 111 --------- .../org/caosdb/server/ServerProperties.java | 2 - .../java/org/caosdb/server/entity/Entity.java | 10 +- .../caosdb/server/entity/FileProperties.java | 10 - .../server/jobs/core/InsertFilesInDir.java | 5 +- .../org/caosdb/server/jobs/core/PickUp.java | 85 ------- .../server/transaction/Transaction.java | 6 - .../server/transaction/WriteTransaction.java | 7 +- .../org/caosdb/server/utils/FileUtils.java | 71 ------ .../java/org/caosdb/server/utils/Info.java | 56 ----- .../caosdb/server/utils/ServerMessages.java | 4 - .../caosdb/server/utils/FileUtilsTest.java | 20 -- 19 files changed, 6 insertions(+), 827 deletions(-) delete mode 100644 misc/chown_script/README delete mode 100755 misc/chown_script/chown_script_template delete mode 100755 misc/chown_script/install delete mode 100644 misc/chown_script/test_functions delete mode 100644 src/main/java/org/caosdb/server/jobs/core/PickUp.java diff --git a/conf/core/server.conf b/conf/core/server.conf index 70648545..48d1d883 100644 --- a/conf/core/server.conf +++ b/conf/core/server.conf @@ -31,10 +31,6 @@ SERVER_SIDE_SCRIPTING_HOME_DIR=./scripting/home/ # An absolute file path of File objects within CaosDB is relative to this folder. FILE_SYSTEM_ROOT=./CaosDBFileSystem/FileSystemRoot/ -# Path to the drop off box. -# This is were users can place files that should be picked up by the CaosDB drop off box program. -DROP_OFF_BOX=./CaosDBFileSystem/DropOffBox/ - # Location of temporary files # All temporary files with the exception of files created by the scripting API will go into this folder. TMP_FILES=./CaosDBFileSystem/TMP/ @@ -44,9 +40,6 @@ TMP_FILES=./CaosDBFileSystem/TMP/ # In contrast to the script's working directory, these subdirectories are publicly accessible. SHARED_FOLDER=./CaosDBFileSystem/Shared/ -# Path to the chown script which is needed by the drop off box in order to change permissions of files. -CHOWN_SCRIPT=./misc/chown_script/caosdb_chown_dropoffbox - # This file is responsible for setting individual user and group permissions. USER_SOURCES_INI_FILE=./conf/ext/usersources.ini # The default state of users which are added to the internal user source. @@ -195,10 +188,6 @@ CACHE_DISABLE=false INSERT_FILES_IN_DIR_ALLOWED_DIRS= #INSERT_FILES_IN_DIR_ALLOWED_DIRS=/data/caosdb,/fileserver01/caosdb -# Sudo password of the system. -# Needed by the drop off box to set file permissions. -SUDO_PASSWORD= - # If set to false ACL checks are circumvented during querying. This may leak information but is a lot faster. QUERY_FILTER_ENTITIES_WITHOUT_RETRIEVE_PERMISSIONS=TRUE diff --git a/misc/chown_script/README b/misc/chown_script/README deleted file mode 100644 index 03f24071..00000000 --- a/misc/chown_script/README +++ /dev/null @@ -1,37 +0,0 @@ -* The chown_script for the caosdb DropOffBox. -* @author: Timm Fitschen (timm.fitschen@ds.mpg.de) -* @date: 2015-10-12 - -========================= README ============================== - -*** INSTALL *** -run ./install [-s] - -The optional `-s` means that the install script will not request any input from the user. In this case all parameters need to be defined in the CONFIG file. - -*** UNINSTALL *** -run ./uninstall - -This script is generated by the install script and removes the generated files. - - -*** CONFIG file *** -COPY this into a file called "CONFIG" (upper case) and edit it to your own needs: - ---- copy below this line --- -#This config file defines the parameters needed for the installation as a KEY/VALUE list. A line beginning with `#` will be ignored. - -#DB_USER is the unix user who runs the caosdb server -DB_USER=caosdb - -#LOC_DROPOFFBOX is the directory of the DropOffBox. ATTENTION: The path must not end with `/`! -LOC_DROPOFFBOX=/path/to/dropOffBox - -#LOC_SUDOERS is a directory which files are included by the sudoers file. ATTENTION: The path must not end with `/`! -LOC_SUDOERS=/etc/sudoers.d - -#LOC_PREFIX is the folder which the caosdb_chown_script is stored to. ATTENTION: The path must not end with `/`! -LOC_PREFIX=/usr/local/sbin - ---- copy above this line --- - diff --git a/misc/chown_script/chown_script_template b/misc/chown_script/chown_script_template deleted file mode 100755 index bd006f7e..00000000 --- a/misc/chown_script/chown_script_template +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash -# -# ** header v3.0 -# This file is a part of the CaosDB Project. -# -# Copyright (C) 2018 Research Group Biomedical Physics, -# Max-Planck-Institute for Dynamics and Self-Organization Göttingen -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# -# ** end header -# - -LOC_DROPOFFBOX=$(awk < ./conf/ext/server.conf '{ if ($1 == "DROP_OFF_BOX") print $3 }') -DB_USER=__DB_USER__ -DB_GROUP=__DB_GROUP__ -CMD_CHOWN=__CMD_CHOWN__ - -if [[ "$1" = "--test" ]]; then - exit 0 -fi - -# Tests whether file/folder is in the DropOffBox. -# This does not actually test whether the file/folder exists! -# @return: true/false -function file_is_in_DropOffBox { - # $1 : absolute filename - if [ "${1##$LOC_DROPOFFBOX}" != "${1}" ]; then - true - else - false - fi -} - -# Echoes the absolute filename (in case a relative path is given). -# @return: absolute filename -function get_abs_filename { - # $1 : relative filename - if [ -d "$(dirname "$1")" ]; then - echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")" - fi -} - -# one argument expected. -if [[ $# -ne 1 ]]; then - # wrong number of arguments -> exit with error. - >&2 echo "One argument expected." - exit 1 -fi - -# file exists? -if [ ! -e $1 ]; then - # file does not exist -> exit with error. - >&2 echo "File $1 does not exist." - exit 2 -fi - -# convert to absolute path -FILE_PATH=$(get_abs_filename $1) - -# file in DropOffBox? -if ! file_is_in_DropOffBox $FILE_PATH ; then - # file not in DropOffBox -> exit with error - >&2 echo "File is not in DropOffBox." - exit 3 -fi - -# make $DB_USER the file-owner and -$CMD_CHOWN -R $DB_USER:$DB_GROUP $FILE_PATH - - - diff --git a/misc/chown_script/install b/misc/chown_script/install deleted file mode 100755 index 55ab1fa2..00000000 --- a/misc/chown_script/install +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/bash -# -# ** header v3.0 -# This file is a part of the CaosDB Project. -# -# Copyright (C) 2018 Research Group Biomedical Physics, -# Max-Planck-Institute for Dynamics and Self-Organization Göttingen -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# -# ** end header -# - -DB_USER=caosdb -LOC_SUDOERS=/etc/sudoers.d -LOC_PREFIX=/usr/local/sbin -CMD_CHOWN=chown -SCRIPT_TMP=chown_script_template - -# silent mode??? -if [[ "$1" = "-s" ]]; then - SILENT="yes" -fi - -# remove old files -if [ -r uninstall ]; then - source uninstall > /dev/null -fi - -# load config if existent -if [ -e CONFIG ]; then - source CONFIG -fi - -# check if all parameters are defined and valid -function check_parameters { - if [ ! -e $LOC_DROPOFFBOX ]; then - >&2 echo "DropOffBox $LOC_DROPOFFBOX does not exist." - exit 11 - fi - if [ ! -e $LOC_PREFIX ]; then - >&2 echo "$LOC_PREFIX does not exist." - exit 12 - fi - if [ ! -e $LOC_SUDOERS ]; then - >&2 echo "$LOC_SUDOERS does not exist." - exit 13 - fi - local ret=false - getent passwd $DB_USER >/dev/null 2>&1 && ret=true - if [[ $ret = false ]]; then - >&2 echo "User $DB_USER does not exist." - exit 14 - fi -} - -# Echoes the absolute filename (in case a relative path is given). -# @return: absolute filename -function get_abs_filename { - # $1 : relative filename - if [ -d "$(dirname "$1")" ]; then - echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")" - fi -} - -# Promt for an input by the user (fancily). -# @arg $1: A description of the variable that the user has to specify. -# @arg $2: The name of the global variable the return value is to be stored in. -# @arg $3: Optional "-f". Indicates, that the user has to specify a file/folder. -# In this case, the tab completion is enabled, the existens of the -# file/folder is tested, and relative paths are converted to absolute ones. -function prompt { - if [[ "$SILENT" = "yes" ]]; then - return 0 - fi - local __ret=$2 - local default=$(eval echo \${$2}) - local new_val - if [[ "$3" = "-f" ]]; then - local par="-e" - fi - - while [[ 0 = 0 ]]; do - if [[ -z "$default" ]]; then - PROMPT="Please insert $1: " - read $par -p "${PROMPT}" new_val - else - PROMPT="Please insert $1 or press ENTER for default [$default]: " - read $par -p "${PROMPT}" new_val - if [[ -z "$new_val" ]]; then - new_val=$default - echo -en "\033[1A\033[2K" - echo $PROMPT $new_val - fi - fi - if [[ -z "$new_val" ]]; then - # no value -> repeat while loop - continue - fi - - if [[ "$3" = "-f" ]]; then - # check whether file exists - if [ ! -e "$new_val" ]; then - # file does not exist -> repeat - echo "Directory/file does not exist. " - continue - fi - fi - - # no problem occured -> leave while loop - break - done - - eval $__ret="'$new_val'" -} - -# make sure this is root -[[ $(id -u) -eq 0 ]] || ! echo "You need to run this script as a root user." || exit 1 - -# make sure sudo is installed -sudo -v -if [[ ! $? -eq 0 ]]; then - >&2 echo -e "\ncommand 'sudo -v' failed. Did you install sudo?" - exit 1 -fi - -# promt for dbuser -# default: caosdb -prompt "the unix user which who runs the caosdb server" DB_USER - -# TODO -DB_GROUP=$DB_USER - -# promt for sudoers.d -# default: /etc/sudoers.d/ -prompt "the location of sudoers.d" LOC_SUDOERS -f -LOC_SUDOERS=$(get_abs_filename $LOC_SUDOERS) -LOC_SUDO_SCRIPT="${LOC_SUDOERS}/caosdb_chown_script" - -# promt for prefix -# default: /usr/local/sbin/ -prompt "the location of the script which is to be generated" LOC_PREFIX -f -LOC_PREFIX=$(get_abs_filename $LOC_PREFIX) -LOC_SCRIPT="${LOC_PREFIX}/caosdb_chown_dropoffbox" - -check_parameters - -# print info: -echo -e "\nDB_USER=$DB_USER" -echo "DB_GROUP=$DB_GROUP" -echo "LOC_SUDO_SCRIPT=$LOC_SUDO_SCRIPT" -echo "LOC_SCRIPT=$LOC_SCRIPT" -echo "CMD_CHOWN=$CMD_CHOWN" -echo -e "\n" - -prompt "continue? [yes/no]" CONT - -if [[ -n $CONT && "$CONT" != "yes" ]]; then - echo "Installation aborted by the user." - exit 0 -fi - -echo '#!/bin/bash' > uninstall -echo '[[ $(id -u) -eq 0 ]] || ! echo "You need to run this script as a root user." || exit 1' >> uninstall -echo "rm $LOC_SCRIPT" >> uninstall -echo "unlink ${LOC_SCRIPT##$LOC_PREFIX/}" >> uninstall -echo "rm $LOC_SUDO_SCRIPT" >> uninstall -echo 'rm uninstall' >> uninstall -echo 'echo -e "\nDone."' >> uninstall -chmod ug+x uninstall - -# configure script and store it -awk "BEGIN { - rep[\"__DB_USER__\"] = \"$DB_USER\"; - rep[\"__DB_GROUP__\"] = \"$DB_GROUP\"; - rep[\"__CMD_CHOWN__\"] = \"$CMD_CHOWN\" - } - { - for (key in rep) { - gsub(key, rep[key]) - } - print - }" < $SCRIPT_TMP > $LOC_SCRIPT - -# create symbolic link in working directory -ln -s $LOC_SCRIPT - -# chown/chgrp to root -$CMD_CHOWN root:root $LOC_SCRIPT -# chmod 500 script -chmod 500 $LOC_SCRIPT - -## configure sudo -echo -en "# Generated by caosdb install script. Do not edit! -# CONTACT: Timm Fitschen (timm.fitschen@ds.mpg.de) -# DATE: 2015-10-09 -$DB_USER ALL = (root) NOPASSWD: $LOC_SCRIPT -" > $LOC_SUDO_SCRIPT -$CMD_CHOWN root:root $LOC_SUDO_SCRIPT -chmod 440 $LOC_SUDO_SCRIPT - -# some tests -. test_functions -test1 - - -echo -e "\nDone." - - diff --git a/misc/chown_script/test_functions b/misc/chown_script/test_functions deleted file mode 100644 index 303f612f..00000000 --- a/misc/chown_script/test_functions +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# -# ** header v3.0 -# This file is a part of the CaosDB Project. -# -# Copyright (C) 2018 Research Group Biomedical Physics, -# Max-Planck-Institute for Dynamics and Self-Organization Göttingen -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <https://www.gnu.org/licenses/>. -# -# ** end header -# - - - -# create file in dropoffbox, owned by root, change-mod/own/grp to dbuser -function test1 { - echo -n "Test 1 " - local FILENAME=$LOC_DROPOFFBOX/chmod_test.dat - echo "blablabla" > $FILENAME - $CMD_CHOWN root:root $FILENAME - - if [ ! -e $FILENAME ]; then - echo "[FAILED] - could not create a testfile in the DropOffBox." - return 1 - fi - - - local lsstr=$(ls -la $FILENAME) - local matchlen=$(expr match "$lsstr" "[-drwx]\{10\}\s[0-9]*\sroot\sroot\s[0-9]") - if [ $matchlen -lt 24 ]; then - echo -e "[FAILED] - 'ls -la' did not indicate that the owner was root at the beginning of this test." - rm $FILENAME - return 2 - fi - - sudo -u $DB_USER -H sh -c "sudo $LOC_SCRIPT $FILENAME" - - local lsstr=$(ls -la $FILENAME) - local matchlen=$(expr match "$lsstr" "[-drwx]\{10\}\s[0-9]*\s$DB_USER\s$DB_GROUP\s[0-9]") - if [ $matchlen -lt 18 ]; then - echo -e "[FAILED] - 'ls -la' did not indicate that the owner has changed successfully." - rm $FILENAME - return 3 - fi - - rm $FILENAME - - echo "[OK]" - return 0 -} diff --git a/src/doc/specification/Fileserver.md b/src/doc/specification/Fileserver.md index dd3e0f37..a3fa8b42 100644 --- a/src/doc/specification/Fileserver.md +++ b/src/doc/specification/Fileserver.md @@ -1,36 +1,9 @@ # Fileserver ## Info -There are several ways to utilize the file server component of CaosDB. It is possible to upload a file or a whole folder including subfolders via HTTP and the _drop off box_. It is possible to download a file via HTTP identified by its ID or by its path in the internal file system. Furthermore, it is possible to get the files metadata via HTTP as an xml. +There are several ways to utilize the file server component of CaosDB. It is possible to upload a file or a whole folder including subfolders via HTTP, directly or via the `InsertFilesInDir` flag. It is possible to download a file via HTTP identified by its ID or by its path in the internal file system. Furthermore, it is possible to get the files metadata via HTTP as an xml. ## File upload -### Drop off box - -The drop off box is a directory on the CaosDB server's local file system, specified in the `server.conf` file in the server's basepath (something like `~/CaosDB/server/server.conf`). The key in the `server.conf` is called `dropoffbox`. Since the drop off box directory is writable for all, users can push their files or complete folders via a `mv` or a `cp` (recommended!) in that folder. The server deletes files older than their maximum lifetime (24 hours by default, specified `in server.conf`). But within their lifetime a user can prompt the server to pick up the file (or folder) from the drop off box in order to transfer it to the internal file system. - -Now, the user may send a pick up request to `POST http://host:port/mpidsserver/FilesDropOff` with a similar body: - - <Post> - <File pickup="$path_dropoffbox" destination="$path_filesystem" description="$description" generator="$generator"/> - ... - </Post> - -where -* $path_dropoffbox is the actual relative path of the dropped file or folder in the DropOffBox, -* $path_filesystem is the designated relative path of that object in the internal file system, -* $description is a description of the file to be uploaded, -* $generator is the tool or client used for pushing this file. - -After a successful pick up the server will return: - - <Response> - <File description="$description" path="$path" id="$id" checksum="$checksum" size="$size" /> - ... - </Response> - -where -* $id is the new generated id of that file and -* $path is the path of the submitted file or folder relative to the file system's root. ### HTTP upload stream #### Files diff --git a/src/main/java/org/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java index 4b7c0fe1..103920ce 100644 --- a/src/main/java/org/caosdb/server/CaosDBServer.java +++ b/src/main/java/org/caosdb/server/CaosDBServer.java @@ -84,7 +84,6 @@ import org.caosdb.server.resource.transaction.EntityNamesResource; import org.caosdb.server.resource.transaction.EntityResource; import org.caosdb.server.scripting.ScriptingPermissions; import org.caosdb.server.transaction.ChecksumUpdater; -import org.caosdb.server.utils.FileUtils; import org.caosdb.server.utils.Initialization; import org.caosdb.server.utils.Observable; import org.caosdb.server.utils.Observer; @@ -363,9 +362,6 @@ public class CaosDBServer extends Application { // Data types initDatatypes(init.getAccess()); - // check for chown script - FileUtils.testChownScript(); - // ChecksumUpdater ChecksumUpdater.start(); diff --git a/src/main/java/org/caosdb/server/FileSystem.java b/src/main/java/org/caosdb/server/FileSystem.java index c0531465..f9989a53 100644 --- a/src/main/java/org/caosdb/server/FileSystem.java +++ b/src/main/java/org/caosdb/server/FileSystem.java @@ -24,7 +24,6 @@ package org.caosdb.server; -import com.google.common.io.Files; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -49,7 +48,6 @@ import org.caosdb.server.utils.Utils; public class FileSystem { private static String filesystem = null; - private static String dropOffBox = null; private static String tmpdir = null; private static String sharedDir = null; public static final Pattern base32Pattern = Pattern.compile("^[-A-Z2-7]+$"); @@ -62,12 +60,6 @@ public class FileSystem { } filesystem = f.getCanonicalPath() + "/"; - f = new File(dropOffBox); - if (!f.exists()) { - f.mkdirs(); - } - dropOffBox = f.getCanonicalPath() + "/"; - f = new File(tmpdir); if (!f.exists()) { f.mkdirs(); @@ -86,13 +78,6 @@ public class FileSystem { return filesystem; } - public static String getDropOffBox() { - if (dropOffBox == null) { - init(); - } - return dropOffBox; - } - public static String getTmp() { if (tmpdir == null) { init(); @@ -109,7 +94,6 @@ public class FileSystem { public static void init() { filesystem = CaosDBServer.getServerProperty(ServerProperties.KEY_FILE_SYSTEM_ROOT); - dropOffBox = CaosDBServer.getServerProperty(ServerProperties.KEY_DROP_OFF_BOX); tmpdir = CaosDBServer.getServerProperty(ServerProperties.KEY_TMP_FILES); sharedDir = CaosDBServer.getServerProperty(ServerProperties.KEY_SHARED_FOLDER); check(); @@ -200,101 +184,6 @@ public class FileSystem { return file; } - /** - * Pick up file from DropOffBox and load it into tmp dir. - * - * @param path - * @param session - * @return A FileProperties Object which represents the object in the tmp dir. - * @throws NoSuchAlgorithmException - * @throws IOException - * @throws Message - * @throws CaosDBException - * @throws InterruptedException - */ - public static final FileProperties pickUp(final String path, final String session) - throws Message { - - File file = new File(getDropOffBox() + path); - - // is the file in the DropOffBox? - boolean inDropOffBox = true; - if (!file.exists()) { - if (path.startsWith("/")) { - file = new File(path); - if (!file.exists()) { - throw ServerMessages.FILE_NOT_FOUND; - } - } else { - throw ServerMessages.FILE_NOT_IN_DROPOFFBOX; - } - inDropOffBox = false; - } - File thumbnail = - new File(file.getParentFile().getAbsolutePath() + "/.thumbnails/" + file.getName()); - - if (inDropOffBox) { - // chown - FileUtils.runChownScript(file); - - // mv to tmp directory. - final File tmp = new File(getTmp() + session + path); - if (!file.renameTo(tmp)) { - throw ServerMessages.CANNOT_MOVE_FILE_TO_TMP; - } - if (thumbnail.exists()) { - final File tmpThumbnail = - new File(tmp.getParentFile().getAbsolutePath() + "/.thumbnails/" + tmp.getName()); - if (!thumbnail.renameTo(tmpThumbnail)) { - throw ServerMessages.CANNOT_MOVE_FILE_TO_TMP; - } - thumbnail = tmpThumbnail; - } else { - thumbnail = null; - } - - file = tmp; - } else { - // copy to tmp dir - final File tmp = new File(getTmp() + session + file.getName()); - if (!file.canRead()) { - throw ServerMessages.CANNOT_READ_FILE; - } - try { - Files.copy(file, tmp); - } catch (final IOException e) { - throw ServerMessages.CANNOT_MOVE_FILE_TO_TMP; - } - - if (thumbnail.exists()) { - final File tmpThumbnail = - new File(tmp.getParentFile().getAbsolutePath() + "/.thumbnails/" + tmp.getName()); - if (!thumbnail.canRead()) { - throw ServerMessages.CANNOT_READ_THUMBNAIL; - } - try { - Files.copy(thumbnail, tmpThumbnail); - } catch (final IOException e) { - throw ServerMessages.CANNOT_MOVE_FILE_TO_TMP; - } - thumbnail = tmpThumbnail; - } else { - thumbnail = null; - } - - file = tmp; - } - - // get checksum and size - final Long size = file.length(); - final String checksum = FileUtils.getChecksum(file); - - final FileProperties ret = new FileProperties(checksum, null, size); - ret.setFile(file); - ret.setThumbnail(thumbnail); - return ret; - } - /** * Checks if a target path is consistent with the server's configuration and the file system. * diff --git a/src/main/java/org/caosdb/server/ServerProperties.java b/src/main/java/org/caosdb/server/ServerProperties.java index 93a0c747..4d353a67 100644 --- a/src/main/java/org/caosdb/server/ServerProperties.java +++ b/src/main/java/org/caosdb/server/ServerProperties.java @@ -45,11 +45,9 @@ public class ServerProperties extends Properties implements Observable { private static Logger logger = LoggerFactory.getLogger(ServerProperties.class.getName()); public static final String KEY_FILE_SYSTEM_ROOT = "FILE_SYSTEM_ROOT"; - public static final String KEY_DROP_OFF_BOX = "DROP_OFF_BOX"; public static final String KEY_TMP_FILES = "TMP_FILES"; public static final String KEY_SHARED_FOLDER = "SHARED_FOLDER"; public static final String KEY_USER_FOLDERS = "USER_FOLDERS"; - public static final String KEY_CHOWN_SCRIPT = "CHOWN_SCRIPT"; public static final String KEY_AUTH_OPTIONAL = "AUTH_OPTIONAL"; public static final String KEY_MYSQL_HOST = "MYSQL_HOST"; diff --git a/src/main/java/org/caosdb/server/entity/Entity.java b/src/main/java/org/caosdb/server/entity/Entity.java index 8179375d..b5820548 100644 --- a/src/main/java/org/caosdb/server/entity/Entity.java +++ b/src/main/java/org/caosdb/server/entity/Entity.java @@ -805,12 +805,7 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa // Parse TMPIDENTIFYER. String tmpIdentifier = null; - boolean pickup = false; - if (element.getAttribute("pickup") != null && !element.getAttributeValue("pickup").equals("")) { - tmpIdentifier = element.getAttributeValue("pickup"); - pickup = true; - } else if (element.getAttribute("upload") != null - && !element.getAttributeValue("upload").equals("")) { + if (element.getAttribute("upload") != null && !element.getAttributeValue("upload").equals("")) { tmpIdentifier = element.getAttributeValue("upload"); } if (tmpIdentifier != null && tmpIdentifier.endsWith("/")) { @@ -819,8 +814,7 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa // Store PATH, HASH, SIZE, TMPIDENTIFYER if (tmpIdentifier != null || checksum != null || path != null || size != null) { - setFileProperties( - new FileProperties(checksum, path, size, tmpIdentifier).setPickupable(pickup)); + setFileProperties(new FileProperties(checksum, path, size, tmpIdentifier)); } // Parse flags diff --git a/src/main/java/org/caosdb/server/entity/FileProperties.java b/src/main/java/org/caosdb/server/entity/FileProperties.java index eaf4246f..ebf061e2 100644 --- a/src/main/java/org/caosdb/server/entity/FileProperties.java +++ b/src/main/java/org/caosdb/server/entity/FileProperties.java @@ -253,18 +253,8 @@ public class FileProperties { return this.thumbnail; } - private boolean pickupable = false; private String tempPath = null; - public FileProperties setPickupable(final boolean b) { - this.pickupable = b; - return this; - } - - public boolean isPickupable() { - return this.pickupable; - } - public void cleanUpTmpDir() { if (this.tempPath != null) { new File(this.tempPath).delete(); diff --git a/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java b/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java index 6390ad7c..39dac22e 100644 --- a/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java +++ b/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java @@ -365,7 +365,7 @@ public class InsertFilesInDir extends FlagJob { * @throws IOException */ private void checkDirIsAllowed(final File dir) throws Message { - // check if server's working dir, file system, tmp dir, or drop off box + // check if server's working dir, file system or tmp dir // overlaps the directory to be inserted. if (!dir.isDirectory()) { @@ -381,14 +381,11 @@ public class InsertFilesInDir extends FlagJob { } final File base = new File(FileSystem.getBasepath()); - final File box = new File(FileSystem.getDropOffBox()); final File tmp = new File(FileSystem.getTmp()); final File root = new File("."); if (isSubDir(dir, base) || isSubDir(base, dir) - || isSubDir(dir, box) - || isSubDir(box, dir) || isSubDir(dir, tmp) || isSubDir(tmp, dir) || isSubDir(dir, root) diff --git a/src/main/java/org/caosdb/server/jobs/core/PickUp.java b/src/main/java/org/caosdb/server/jobs/core/PickUp.java deleted file mode 100644 index b0e04529..00000000 --- a/src/main/java/org/caosdb/server/jobs/core/PickUp.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package org.caosdb.server.jobs.core; - -import java.io.File; -import org.caosdb.server.FileSystem; -import org.caosdb.server.entity.Entity; -import org.caosdb.server.entity.EntityInterface; -import org.caosdb.server.entity.FileProperties; -import org.caosdb.server.entity.Message; -import org.caosdb.server.jobs.EntityJob; -import org.caosdb.server.jobs.JobAnnotation; -import org.caosdb.server.jobs.TransactionStage; -import org.caosdb.server.utils.EntityStatus; -import org.caosdb.server.utils.Observable; -import org.caosdb.server.utils.Observer; - -@JobAnnotation(stage = TransactionStage.INIT) -public class PickUp extends EntityJob implements Observer { - - @Override - protected void run() { - final EntityInterface entity = getEntity(); - if (entity.hasFileProperties()) { - final FileProperties normativeFileProperties = entity.getFileProperties(); - if (normativeFileProperties.isPickupable()) { - try { - entity.acceptObserver(this); - this.dropOffBoxPath = normativeFileProperties.getTmpIdentifier(); - final FileProperties descriptiveFileProperties = - FileSystem.pickUp(this.dropOffBoxPath, getRequestId()); - normativeFileProperties.setFile(descriptiveFileProperties.getFile()); - normativeFileProperties.setThumbnail(descriptiveFileProperties.getThumbnail()); - normativeFileProperties.setTmpIdentifier(null); - if (!normativeFileProperties.hasSize()) { - normativeFileProperties.setSize(normativeFileProperties.getFile().length()); - } - } catch (final Message m) { - entity.addMessage(m); - if (m.getType().equalsIgnoreCase("Error")) { - entity.setEntityStatus(EntityStatus.UNQUALIFIED); - } - } - this.rollBack = true; - } - } - } - - private boolean rollBack = false; - private String dropOffBoxPath = null; - - @Override - public boolean notifyObserver(final String e, final Observable o) { - if (e == Entity.ENTITY_STATUS_CHANGED_EVENT - && o == getEntity() - && this.rollBack - && getEntity().getEntityStatus() == EntityStatus.UNQUALIFIED) { - final File target = new File(FileSystem.getDropOffBox() + this.dropOffBoxPath); - getEntity().getFileProperties().getFile().renameTo(target); - this.rollBack = false; - return false; - } - return true; - } -} diff --git a/src/main/java/org/caosdb/server/transaction/Transaction.java b/src/main/java/org/caosdb/server/transaction/Transaction.java index b460085d..873f6210 100644 --- a/src/main/java/org/caosdb/server/transaction/Transaction.java +++ b/src/main/java/org/caosdb/server/transaction/Transaction.java @@ -47,7 +47,6 @@ import org.caosdb.server.jobs.core.AccessControl; import org.caosdb.server.jobs.core.CheckDatatypePresent; import org.caosdb.server.jobs.core.CheckEntityACLRoles; import org.caosdb.server.jobs.core.JobFailureSeverity; -import org.caosdb.server.jobs.core.PickUp; import org.caosdb.server.permissions.EntityACL; import org.caosdb.server.utils.AbstractObservable; import org.caosdb.server.utils.Info; @@ -200,11 +199,6 @@ public abstract class Transaction<C extends TransactionContainer> extends Abstra if (e.hasValue() || e.hasDatatype()) { this.schedule.add(new CheckDatatypePresent().init(JobFailureSeverity.ERROR, e, this)); } - - // load pickup job if necessary - if (e.hasFileProperties() && e.getFileProperties().isPickupable()) { - this.schedule.add(new PickUp().init(JobFailureSeverity.ERROR, e, this)); - } } } diff --git a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java index 08f80915..c53b2603 100644 --- a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java @@ -181,9 +181,7 @@ public class WriteTransaction extends Transaction<WritableContainer> entity.setEntityStatus(EntityStatus.UNQUALIFIED); } else { // dereference files (upload only) - if (entity.hasFileProperties() - && entity.getFileProperties().hasTmpIdentifier() - && !entity.getFileProperties().isPickupable()) { + if (entity.hasFileProperties() && entity.getFileProperties().hasTmpIdentifier()) { // get file by tmpIdentifier final FileProperties f = @@ -252,8 +250,7 @@ public class WriteTransaction extends Transaction<WritableContainer> } else if (entity instanceof InsertEntity && entity.hasFileProperties() - && entity.getFileProperties().hasTmpIdentifier() - && !entity.getFileProperties().isPickupable()) { + && entity.getFileProperties().hasTmpIdentifier()) { // dereference files (file upload only) final FileProperties f = getContainer().getFiles().get(entity.getFileProperties().getTmpIdentifier()); diff --git a/src/main/java/org/caosdb/server/utils/FileUtils.java b/src/main/java/org/caosdb/server/utils/FileUtils.java index eb4270f8..5a1c5dd2 100644 --- a/src/main/java/org/caosdb/server/utils/FileUtils.java +++ b/src/main/java/org/caosdb/server/utils/FileUtils.java @@ -38,19 +38,13 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import org.caosdb.server.CaosDBException; -import org.caosdb.server.CaosDBServer; import org.caosdb.server.FileSystem; -import org.caosdb.server.ServerProperties; import org.caosdb.server.database.exceptions.TransactionException; import org.caosdb.server.entity.Message; import org.eclipse.jetty.io.RuntimeIOException; public class FileUtils { - // This flag controls whether the chown-script is enabled: - // (This would make more sense in a singleton-context.) - private static boolean chown_enabled = true; - /** * Guess the MIME type of a file. This is based on the unix program 'file --mime-type' and might * not work on other systems. @@ -187,71 +181,6 @@ public class FileUtils { } } - public static String chownScript = - CaosDBServer.getServerProperty(ServerProperties.KEY_CHOWN_SCRIPT); - - public static void runChownScript(final File file) { - if (chown_enabled) { - try { - final String sudopw = CaosDBServer.getServerProperty(ServerProperties.KEY_SUDO_PASSWORD); - final Process cmd = - Runtime.getRuntime() - .exec( - new String[] { - "/bin/bash", - "-c", - "echo '" - + sudopw - + "' | sudo -S -- " - + chownScript - + " " - + file.getAbsolutePath() - }); - if (cmd.waitFor() != 0) { - throw new TransactionException("caosdb_chown_dropoffbox failed."); - } - } catch (final InterruptedException e) { - throw new TransactionException(e); - } catch (final IOException e) { - throw new TransactionException(e); - } - } - } - - /** - * @deprecated Soon to be removed. - * @throws IOException - * @throws InterruptedException - * @throws CaosDBException - */ - @Deprecated - public static void testChownScript() throws IOException, InterruptedException, CaosDBException { - final String sudopw = CaosDBServer.getServerProperty(ServerProperties.KEY_SUDO_PASSWORD); - final Process cmd = - Runtime.getRuntime() - .exec( - new String[] { - "/bin/bash", "-c", "echo '" + sudopw + "' | sudo -S -- " + chownScript + " --test" - }); - if (cmd.waitFor() != 0) { - - final BufferedReader bufferedReader = - new BufferedReader(new InputStreamReader(cmd.getErrorStream())); - String line = null; - while ((line = bufferedReader.readLine()) != null) { - System.err.println(line); - } - - final BufferedReader bufferedReader2 = - new BufferedReader(new InputStreamReader(cmd.getInputStream())); - while ((line = bufferedReader2.readLine()) != null) { - System.err.println(line); - } - System.out.println("WARNING: chown for dropoffbox will be disabled."); - chown_enabled = false; - } - } - public static Undoable createFolders(final File folder) throws Message { if (folder.getParentFile().exists()) { if (!folder.mkdir()) { diff --git a/src/main/java/org/caosdb/server/utils/Info.java b/src/main/java/org/caosdb/server/utils/Info.java index 644239fc..26e8bf5f 100644 --- a/src/main/java/org/caosdb/server/utils/Info.java +++ b/src/main/java/org/caosdb/server/utils/Info.java @@ -74,7 +74,6 @@ public class Info extends AbstractObservable implements Observer, TransactionInt } private Long lastSync = 0L; - private static File dropOffBox = null; private static int filesCount = -1; private static int propertiesCount = -1; private static int recordsCount = -1; @@ -98,39 +97,6 @@ public class Info extends AbstractObservable implements Observer, TransactionInt return recordTypesCount; } - /** - * Utility function that takes an array of file objects and returns a linked list containing XML - * representations of all files within each contained directory. All files in the array that are - * directories are recursively traversed. This function is used for files within the drop off box - * only. - * - * @param files An array of file objects. - * @return A linked list containing XML elements. The path attribute of these elements is set to - * the absolute path of the filenames where the path to the drop off box is removed at the - * beginning. - * @fixme Should check if the files are inside the DropOffBox path. - */ - private static LinkedList<Element> getFlatList(final File[] files) { - try { - final LinkedList<Element> ret = new LinkedList<Element>(); - for (final File file : files) { - if (file.isDirectory()) { - ret.addAll(getFlatList(file.listFiles())); - } else { - final Element element = new Element("file"); - final String tempPath = - file.getCanonicalPath().substring(dropOffBox.getCanonicalPath().length() + 1); - element.setAttribute("path", tempPath); - ret.add(element); - } - } - return ret; - } catch (final IOException e) { - e.printStackTrace(); - } - return null; - } - private static LinkedList<Element> getTree(final File[] files) { final LinkedList<Element> ret = new LinkedList<Element>(); for (final File file : files) { @@ -194,16 +160,12 @@ public class Info extends AbstractObservable implements Observer, TransactionInt * <li>The number of files * <li>The total file size * <li>The number of temp files - * <li>The path of the DropOffBox - * <li>A tree of files in the DropOffBox * </ul> - * TODO: The error format for missing or not readable drop off box has to be specified. */ public static Element toElement(final boolean tree) throws Exception, SQLException { if (filesCount == -1 && recordsCount == -1) { getInstance().syncDatabase(); } - dropOffBox = new File(FileSystem.getDropOffBox()); final Element info = new Element("Stats"); final Element counts = new Element("counts"); counts.setAttribute("records", Integer.toString(recordsCount)); @@ -215,25 +177,7 @@ public class Info extends AbstractObservable implements Observer, TransactionInt if (CaosDBServer.isDebugMode()) { counts.setAttribute("debug", "true"); } - final Element e = new Element("dropOffBox"); - if (dropOffBox.isDirectory()) { - if (dropOffBox.canRead()) { - if (tree) { - e.setAttribute("path", dropOffBox.getAbsolutePath()); - e.addContent(getTree(dropOffBox.listFiles())); - } else { - e.setAttribute("path", dropOffBox.getAbsolutePath()); - e.addContent(getFlatList(dropOffBox.listFiles())); - } - } else { - // TODO: return a message that the DropOffBox is not readable. - } - } else { - // TODO: This function should at least return a message that the DropOffBox is disabled or not - // present. - } info.addContent(counts); - info.addContent(e); return info; } diff --git a/src/main/java/org/caosdb/server/utils/ServerMessages.java b/src/main/java/org/caosdb/server/utils/ServerMessages.java index 9e18ca90..80feeeac 100644 --- a/src/main/java/org/caosdb/server/utils/ServerMessages.java +++ b/src/main/java/org/caosdb/server/utils/ServerMessages.java @@ -217,10 +217,6 @@ public class ServerMessages { MessageCode.MESSAGE_CODE_UNKNOWN, "Request body didn't contain the expected elements."); - public static final Message FILE_NOT_IN_DROPOFFBOX = - new Message( - MessageType.Error, MessageCode.MESSAGE_CODE_UNKNOWN, "File is not in drop-off box."); - public static final Message FILE_NOT_FOUND = new Message( MessageType.Error, MessageCode.MESSAGE_CODE_FILE_NOT_FOUND, "File could not be found."); diff --git a/src/test/java/org/caosdb/server/utils/FileUtilsTest.java b/src/test/java/org/caosdb/server/utils/FileUtilsTest.java index 36851c4e..3eba8554 100644 --- a/src/test/java/org/caosdb/server/utils/FileUtilsTest.java +++ b/src/test/java/org/caosdb/server/utils/FileUtilsTest.java @@ -96,7 +96,6 @@ public class FileUtilsTest { tempDirectory = Files.createTempDirectory(null); testRoot = newFolder("fileutils_testfolder"); File basePath = newFolder("caosdbRoot"); - File dropOffBox = newFolder("dropOffBox"); someDir = testRoot.toPath().resolve("some_dir").toFile(); linkToSomeDir = testRoot.toPath().resolve("link_to_some_dir").toFile(); someFile = testRoot.toPath().resolve("some_file").toFile(); @@ -105,7 +104,6 @@ public class FileUtilsTest { tmpFolderCaosDB = newFolder("tmpFolderCaosDB"); CaosDBServer.setProperty(ServerProperties.KEY_FILE_SYSTEM_ROOT, basePath.toString()); - CaosDBServer.setProperty(ServerProperties.KEY_DROP_OFF_BOX, dropOffBox.toString()); CaosDBServer.setProperty(ServerProperties.KEY_TMP_FILES, tmpFolderCaosDB.toString()); FileSystem.init(); @@ -116,9 +114,6 @@ public class FileUtilsTest { assertTrue(new File(FileSystem.getTmp()).canWrite()); assertTrue(new File(FileSystem.getTmp()).canRead()); assertTrue(new File(FileSystem.getTmp()).canExecute()); - assertTrue(new File(FileSystem.getDropOffBox()).canWrite()); - assertTrue(new File(FileSystem.getDropOffBox()).canRead()); - assertTrue(new File(FileSystem.getDropOffBox()).canExecute()); deleteTmp(); // FileUtils.createFolders(testRoot); @@ -282,21 +277,6 @@ public class FileUtilsTest { assertFalse(child.exists()); } - @Test - public void TestChownScript() throws IOException, InterruptedException, CaosDBException { - FileUtils.testChownScript(); - - final File f = new File(FileSystem.getDropOffBox() + "chown_test_file"); - f.createNewFile(); - try { - FileUtils.runChownScript(f); - } finally { - if (f.exists()) { - f.delete(); - } - } - } - @Test public void testCreateFolders() throws Message { final File f = new File(testRoot.getAbsoluteFile() + "/testfolder/testsubfolder/testfile"); -- GitLab