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