Skip to content
Snippets Groups Projects
Commit 72b6b9f4 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

Initial Commit

AGPLv3 Veröffentlichung gemäß Dienstanweisung vom 15. August 2018.
parents
Branches
Tags
No related merge requests found
Showing
with 419 additions and 0 deletions
/*
* ** 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 caosdb.server;
import java.util.LinkedList;
import org.restlet.Server;
public class CaosDBServerConnectorHelper extends org.restlet.ext.jetty.HttpsServerHelper {
private static LinkedList<CaosDBServerConnectorHelper> instances =
new LinkedList<CaosDBServerConnectorHelper>();
public CaosDBServerConnectorHelper(final Server server) {
super(server);
}
public static LinkedList<CaosDBServerConnectorHelper> getInstances() {
return instances;
}
@Override
public synchronized void start() throws Exception {
super.start();
getInstances().add(this);
}
}
/*
* ** 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 caosdb.server;
import caosdb.server.database.Database;
import caosdb.server.database.access.Access;
import caosdb.server.database.backend.transaction.GetFileRecordByPath;
import caosdb.server.entity.EntityInterface;
import caosdb.server.entity.FileProperties;
import caosdb.server.entity.Message;
import caosdb.server.utils.FileUtils;
import caosdb.server.utils.ServerMessages;
import com.google.common.io.Files;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.fileupload.FileItemStream;
public class FileSystem {
private static String filesystem = null;
private static Boolean userfolders = null;
private static String dropOffBox = null;
private static String tmpdir = null;
private static void check() {
try {
File f = new File(filesystem);
if (!f.exists()) {
f.mkdirs();
}
filesystem = f.getCanonicalPath() + "/";
f = new File(dropOffBox);
if (!f.exists()) {
f.mkdirs();
}
dropOffBox = f.getCanonicalPath() + "/";
f = new File(tmpdir);
if (!f.exists()) {
f.mkdirs();
}
tmpdir = f.getCanonicalPath() + "/";
} catch (final IOException e) {
e.printStackTrace();
System.exit(1);
}
}
@Deprecated
public static String getBasepath() {
if (filesystem == null) {
init();
}
return filesystem;
}
public static String getDropOffBox() {
if (dropOffBox == null) {
init();
}
return dropOffBox;
}
public static String getTmp() {
if (tmpdir == null) {
init();
}
return tmpdir;
}
private static void init() {
filesystem = CaosDBServer.getServerProperty(ServerProperties.KEY_FILE_SYSTEM_ROOT);
userfolders = new Boolean(CaosDBServer.getServerProperty(ServerProperties.KEY_USER_FOLDERS));
dropOffBox = CaosDBServer.getServerProperty(ServerProperties.KEY_DROP_OFF_BOX);
tmpdir = CaosDBServer.getServerProperty(ServerProperties.KEY_TMP_FILES);
check();
}
public static boolean isUserfolders() throws IOException {
if (userfolders == null) {
init();
}
return userfolders;
}
private FileSystem() {}
/**
* Reads a FileItemStream and stores the file into the tmpfolder. Generates FileProperties.
*
* @param item
* @param session
* @return FileProperties of the uploaded File.
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws CaosDBException
*/
public static final FileProperties upload(final FileItemStream item, final String session)
throws NoSuchAlgorithmException, IOException, CaosDBException {
String checksum = null;
// Name of the temporary FILE object.
final String tempPath = FileSystem.getTmp() + session + item.getName();
final InputStream stream = item.openStream();
final File tmpFile = new File(tempPath);
if (tempPath.endsWith("/")) {
// this is a directory, not a file
stream.close();
if (!tmpFile.exists()) {
tmpFile.mkdirs();
}
} else {
// this is actually a file
tmpFile.getParentFile().mkdirs();
if (tmpFile.isDirectory()) {
// TODO this should generate an error. This means that the
// tmpIdentifyers are inconsistent
}
final OutputStream outputStream = new FileOutputStream(tmpFile);
final MessageDigest md = MessageDigest.getInstance("SHA-512");
final byte[] buf = new byte[1024];
int bufSize = 0;
// store temporary file and calculate hash
while ((bufSize = stream.read(buf)) != -1) {
md.update(buf, 0, bufSize);
outputStream.write(buf, 0, bufSize);
}
outputStream.close();
// get hash result
final byte[] result = md.digest();
checksum = FileUtils.toHex(result);
}
final FileProperties file = new FileProperties(checksum, tempPath, tmpFile.length());
file.setFile(tmpFile);
file.removeOnCleanUp(tempPath);
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.
*
* @param entity
* @return
* @throws Message
*/
public static boolean checkTarget(final EntityInterface entity, final Access access)
throws Message {
final FileProperties file = entity.getFileProperties();
// target file name = where the file is to be stored.
final String targetName = getPath(file.getPath());
final File target = new File(targetName);
// check if target's directory is a sub directory of the file
// system's root
if (!target.getAbsolutePath().matches("^" + getBasepath() + ".*$")) {
throw ServerMessages.TARGET_PATH_NOT_ALLOWED;
}
// check if the target exists.
if (target.exists()) {
// if the file already is located at its target location, the
// target is correct.
if (file.getFile() != null && file.getFile().equals(target)) {
return true;
} else {
final GetFileRecordByPath t =
Database.execute(new GetFileRecordByPath(file.getPath()), access);
if (t.getEntity() != null) {
final Integer foreign = t.getId();
if (foreign != null && foreign.equals(entity.getId())) {
return true;
}
throw ServerMessages.TARGET_PATH_EXISTS;
}
}
}
return true;
}
/**
* Get the file from the internal file system. Returns null if the file does not exist.
*
* @param path
* @return
*/
public static File getFromFileSystem(final String path) {
File ret;
ret = getFile(path);
if (ret.exists()) {
return ret;
}
return null;
}
/**
* Return the canonical path on the native file system of the server's host which is guaranteed to
* be a valid path under the server's internal file system.
*
* @param location
* @return A canonical path.
* @throws Message TARGET_PATH_NOT_ALLOWED if location does not belong to the file system.
*/
public static String getPath(final String location) throws Message {
String canonicalPath;
canonicalPath = getFile(location).getAbsolutePath();
if (canonicalPath.startsWith(getBasepath().replaceFirst("/$", ""))) {
return canonicalPath;
}
throw ServerMessages.TARGET_PATH_NOT_ALLOWED;
}
private static File getFile(final String path) {
return new File(getBasepath() + path);
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* ** 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 caosdb.server.accessControl;
public interface CredentialsValidator<T> {
public boolean isValid(final T credential);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment