summaryrefslogtreecommitdiffstats
path: root/dozentenmodulserver
diff options
context:
space:
mode:
authorSimon Rettberg2015-08-10 18:34:03 +0200
committerSimon Rettberg2015-08-10 18:34:03 +0200
commitd7f38f8df8e9f049233ef5878eca8ca416bc210e (patch)
tree286333d2dac603a4f4e88988aed23e8fe751ec93 /dozentenmodulserver
parent[client] improved an error message (diff)
downloadtutor-module-d7f38f8df8e9f049233ef5878eca8ca416bc210e.tar.gz
tutor-module-d7f38f8df8e9f049233ef5878eca8ca416bc210e.tar.xz
tutor-module-d7f38f8df8e9f049233ef5878eca8ca416bc210e.zip
[server] Overhaul permission checking, precalc user permissions, implement download
Diffstat (limited to 'dozentenmodulserver')
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java36
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalImageVersion.java20
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveDownload.java86
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java1
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java37
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java175
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java176
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java15
8 files changed, 340 insertions, 206 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java
index f9a22429..74a3eb96 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java
@@ -11,6 +11,8 @@ import org.openslx.bwlp.sat.database.Database;
import org.openslx.bwlp.sat.database.MysqlConnection;
import org.openslx.bwlp.sat.database.MysqlStatement;
import org.openslx.bwlp.sat.database.Paginator;
+import org.openslx.bwlp.sat.database.models.LocalImageVersion;
+import org.openslx.bwlp.sat.permissions.User;
import org.openslx.bwlp.thrift.iface.ImageBaseWrite;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImagePermissions;
@@ -58,7 +60,7 @@ public class DbImage {
ResultSet rs = stmt.executeQuery();
List<ImageSummaryRead> list = new ArrayList<>(100);
while (rs.next()) {
- list.add(resultSetToSummary(rs));
+ list.add(resultSetToSummary(user, rs));
}
return list;
} catch (SQLException e) {
@@ -93,6 +95,7 @@ public class DbImage {
rs.getLong("createtime"), rs.getLong("updatetime"), rs.getString("ownerid"),
rs.getString("updaterid"), toShareMode(rs.getString("sharemode")),
rs.getByte("istemplate") != 0, defaultPermissions);
+ User.setCombinedUserPermissions(image, user);
return image;
} catch (SQLException e) {
LOGGER.error("Query failed in DbImage.getImageDetails()", e);
@@ -100,6 +103,23 @@ public class DbImage {
}
}
+ public static LocalImageVersion getLocalImageData(String imageVersionId) throws TNotFoundException,
+ SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT imageversionid, imagebaseid, filepath, filesize"
+ + " FROM imageversion WHERE imageversionid = :versionid LIMIT 1");
+ stmt.setString("versionid", imageVersionId);
+ ResultSet rs = stmt.executeQuery();
+ if (!rs.next())
+ throw new TNotFoundException();
+ return new LocalImageVersion(rs.getString("imageversionid"), rs.getString("imagebaseid"),
+ rs.getString("filepath"), rs.getLong("filesize"));
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.getLocalImageData()", e);
+ throw e;
+ }
+ }
+
/**
* Private helper to create an {@link ImageSummaryRead} instance from a
* {@link ResultSet}
@@ -108,7 +128,7 @@ public class DbImage {
* @return
* @throws SQLException
*/
- private static ImageSummaryRead resultSetToSummary(ResultSet rs) throws SQLException {
+ private static ImageSummaryRead resultSetToSummary(UserInfo user, ResultSet rs) throws SQLException {
ImagePermissions defaultPermissions = DbImagePermissions.fromResultSetDefault(rs);
ImageSummaryRead entry = new ImageSummaryRead(rs.getString("imagebaseid"),
rs.getString("latestversionid"), rs.getString("displayname"), rs.getInt("osid"),
@@ -118,6 +138,7 @@ public class DbImage {
rs.getByte("isrestricted") != 0, rs.getByte("isvalid") != 0, rs.getByte("isprocessed") != 0,
rs.getByte("istemplate") != 0, defaultPermissions);
entry.userPermissions = DbImagePermissions.fromResultSetUser(rs);
+ User.setCombinedUserPermissions(entry, user);
return entry;
}
@@ -160,7 +181,7 @@ public class DbImage {
if (!rs.next()) {
throw new TNotFoundException();
}
- return resultSetToSummary(rs);
+ return resultSetToSummary(user, rs);
}
private static List<ImageVersionDetails> getImageVersions(MysqlConnection connection, String imageBaseId)
@@ -268,8 +289,9 @@ public class DbImage {
* @param imageVersionId
* @return
* @throws SQLException
+ * @throws TNotFoundException
*/
- public static String getBaseIdForVersionId(String imageVersionId) throws SQLException {
+ public static String getBaseIdForVersionId(String imageVersionId) throws SQLException, TNotFoundException {
try (MysqlConnection connection = Database.getConnection()) {
return getBaseIdForVersionId(connection, imageVersionId);
} catch (SQLException e) {
@@ -280,20 +302,20 @@ public class DbImage {
/**
* Get the UUID of the image base belonging to the given image version UUID.
- * Returns <code>null</code> if the UUID does not exist.
*
* @param imageVersionId
* @return
* @throws SQLException
+ * @throws TNotFoundException version id is unknown
*/
protected static String getBaseIdForVersionId(MysqlConnection connection, String imageVersionId)
- throws SQLException {
+ throws SQLException, TNotFoundException {
MysqlStatement stmt = connection.prepareStatement("SELECT imagebaseid FROM imageversion"
+ " WHERE imageversionid = :imageversionid LIMIT 1");
stmt.setString("imageversionid", imageVersionId);
ResultSet rs = stmt.executeQuery();
if (!rs.next())
- return null;
+ throw new TNotFoundException();
return rs.getString("imagebaseid");
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalImageVersion.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalImageVersion.java
new file mode 100644
index 00000000..91c5acac
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalImageVersion.java
@@ -0,0 +1,20 @@
+package org.openslx.bwlp.sat.database.models;
+
+public class LocalImageVersion {
+
+ public final String imageVersionId;
+
+ public final String imageBaseId;
+
+ public final String filePath;
+
+ public final long fileSize;
+
+ public LocalImageVersion(String imageVersionId, String imageBaseId, String filePath, long fileSize) {
+ this.imageVersionId = imageVersionId;
+ this.imageBaseId = imageBaseId;
+ this.filePath = filePath;
+ this.fileSize = fileSize;
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveDownload.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveDownload.java
new file mode 100644
index 00000000..7180fe3d
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveDownload.java
@@ -0,0 +1,86 @@
+package org.openslx.bwlp.sat.fileserv;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.sat.util.Constants;
+import org.openslx.bwlp.thrift.iface.TransferState;
+import org.openslx.filetransfer.Uploader;
+
+public class ActiveDownload {
+
+ private static final Logger LOGGER = Logger.getLogger(ActiveDownload.class);
+
+ /**
+ * How many concurrent connections per upload
+ */
+ private static final int MAX_CONNECTIONS = Math.max(Constants.MAX_DOWNLOADS / 4, 1);
+
+ /**
+ * Self reference for inner classes.
+ */
+ private final ActiveDownload activeDownload = this;
+
+ /**
+ * This is a download, so we have uploaders
+ */
+ private List<Uploader> uploads = new ArrayList<>();
+
+ private final File sourceFile;
+
+ private final long fileSize;
+
+ private final String transferId;
+
+ /**
+ * TransferState of this upload
+ */
+ private TransferState state = TransferState.IDLE;
+
+ public ActiveDownload(String uuid, File file) {
+ this.transferId = uuid;
+ this.sourceFile = file;
+ this.fileSize = file.length();
+ }
+
+ /**
+ * Add another connection for this file transfer. Currently only one
+ * connection is allowed, but this might change in the future.
+ *
+ * @param connection
+ * @return true if the connection is accepted, false if it should be
+ * discarded
+ */
+ public synchronized boolean addConnection(final Uploader connection, ThreadPoolExecutor pool) {
+ synchronized (uploads) {
+ if (uploads.size() > MAX_CONNECTIONS)
+ return false;
+ uploads.add(connection);
+ }
+ try {
+ pool.execute(new Runnable() {
+ @Override
+ public void run() {
+ connection.upload(sourceFile.getAbsolutePath());
+ }
+ });
+ } catch (Exception e) {
+ LOGGER.warn("threadpool rejected the incoming file transfer", e);
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isComplete() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public String getId() {
+ return transferId;
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java
index e7841ccd..d03f79de 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/ActiveUpload.java
@@ -161,6 +161,7 @@ public class ActiveUpload implements HashCheckCallback {
if (downloads.size() >= MAX_CONNECTIONS)
return false;
downloads.add(connection);
+ // TODO: Remove when finished or executor rejects...
}
try {
pool.execute(new Runnable() {
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
index 16369745..d1136c2b 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
@@ -14,6 +14,8 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
+import org.openslx.bwlp.sat.database.models.LocalImageVersion;
+import org.openslx.bwlp.sat.util.Configuration;
import org.openslx.bwlp.sat.util.Constants;
import org.openslx.bwlp.sat.util.Formatter;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
@@ -41,6 +43,11 @@ public class FileServer implements IncomingEvent {
*/
private final Map<String, ActiveUpload> uploads = new ConcurrentHashMap<>();
+ /**
+ * All currently running downloads, indexed by token
+ */
+ private final Map<String, ActiveDownload> downloads = new ConcurrentHashMap<>();
+
private static final FileServer globalInstance = new FileServer();
private FileServer() {
@@ -133,4 +140,34 @@ public class FileServer implements IncomingEvent {
return 0; // TODO
}
+ public ActiveDownload createNewUserDownload(LocalImageVersion localImageData)
+ throws TTransferRejectedException {
+ Iterator<ActiveDownload> it = downloads.values().iterator();
+ int activeDownloads = 0;
+ while (it.hasNext()) {
+ ActiveDownload download = it.next();
+ if (download.isComplete()) {
+ // TODO: Check age (short timeout) and remove
+ continue;
+ } else {
+ // Check age (long timeout) and remove
+ }
+ activeDownloads++;
+ }
+ if (activeDownloads > Constants.MAX_DOWNLOADS)
+ throw new TTransferRejectedException("Server busy. Too many running downloads.");
+ // Determine src file and go
+ File srcFile = new File(Configuration.getCurrentVmStorePath(), localImageData.filePath);
+ if (!srcFile.canRead()) {
+ LOGGER.warn("Rejecting download of VID " + localImageData.imageVersionId + ": Missing "
+ + srcFile.getName());
+ // TODO: Mark as invalid in DB
+ throw new TTransferRejectedException("File missing on server");
+ }
+ String key = UUID.randomUUID().toString();
+ ActiveDownload transfer = new ActiveDownload(key, srcFile);
+ downloads.put(key, transfer);
+ return transfer;
+ }
+
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java
deleted file mode 100644
index 6b4af039..00000000
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.openslx.bwlp.sat.permissions;
-
-import java.sql.SQLException;
-
-import org.apache.log4j.Logger;
-import org.openslx.bwlp.sat.database.mappers.DbImage;
-import org.openslx.bwlp.sat.database.mappers.DbLecture;
-import org.openslx.bwlp.thrift.iface.AuthorizationError;
-import org.openslx.bwlp.thrift.iface.ImagePermissions;
-import org.openslx.bwlp.thrift.iface.ImageSummaryRead;
-import org.openslx.bwlp.thrift.iface.LecturePermissions;
-import org.openslx.bwlp.thrift.iface.LectureSummary;
-import org.openslx.bwlp.thrift.iface.TAuthorizationException;
-import org.openslx.bwlp.thrift.iface.TInternalServerError;
-import org.openslx.bwlp.thrift.iface.TNotFoundException;
-import org.openslx.bwlp.thrift.iface.UserInfo;
-
-public class PermCheck {
-
- public static enum Permission {
- LINK,
- DOWNLOAD,
- EDIT,
- ADMIN
- }
-
- private static final Logger LOGGER = Logger.getLogger(Permission.class);
-
- protected static boolean canActionImage(UserInfo user, Permission checkPerm,
- ImagePermissions... imagePermissions) {
- for (ImagePermissions perm : imagePermissions) {
- if (perm == null)
- continue;
- if (checkPerm == Permission.LINK)
- return perm.link;
- if (checkPerm == Permission.DOWNLOAD)
- return perm.download;
- if (checkPerm == Permission.EDIT)
- return perm.edit;
- if (checkPerm == Permission.ADMIN)
- return perm.admin;
- }
- return false;
- }
-
- protected static boolean canActionLecture(UserInfo user, Permission checkPerm,
- LecturePermissions... lecturePermissions) {
- if (checkPerm == Permission.DOWNLOAD || checkPerm == Permission.LINK) {
- LOGGER.warn("Invalid permission check for lecture: " + checkPerm, new RuntimeException(
- "Here's your stack trace"));
- return false;
- }
- for (LecturePermissions perm : lecturePermissions) {
- if (perm == null)
- continue;
- if (checkPerm == Permission.EDIT)
- return perm.edit;
- if (checkPerm == Permission.ADMIN)
- return perm.admin;
- }
- return false;
- }
-
- /**
- * Check if the given user has the given permission for the image identified
- * by the given image base id.
- *
- * @param user
- * @param imageBaseId
- * @param permission
- * @throws TInternalServerError
- * @throws TNotFoundException
- */
- protected static boolean hasImageBasePermission(UserInfo user, String imageBaseId, Permission permission)
- throws TInternalServerError, TNotFoundException {
- // Check general permissions
- ImageSummaryRead localImage;
- try {
- localImage = DbImage.getImageSummary(user, imageBaseId);
- } catch (SQLException e) {
- throw new TInternalServerError();
- }
- // Owner has all permissions
- if (localImage.ownerId.equals(user.userId))
- return true;
- return canActionImage(user, permission, localImage.userPermissions, localImage.defaultPermissions)
- || User.isSuperUser(user);
- }
-
- /**
- * Check if the given user has the given permission for the image identified
- * by the given image base id.
- *
- * @param user
- * @param imageBaseId
- * @param permission
- * @throws TAuthorizationException
- * @throws TInternalServerError
- * @throws TNotFoundException
- */
- protected static void hasImageBasePermissionOrFail(UserInfo user, String imageBaseId, Permission permission)
- throws TAuthorizationException, TInternalServerError, TNotFoundException {
- if (!hasImageBasePermission(user, imageBaseId, permission)) {
- throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, "Required permission: "
- + permission.toString());
- }
- }
-
- /**
- * Check if the given user has the given permission for the image identified
- * by the given image version id.
- *
- * @param user
- * @param imageVersionId
- * @param permission
- * @throws TInternalServerError
- * @throws TNotFoundException
- */
- protected static boolean hasImageVersionPermission(UserInfo user, String imageVersionId,
- Permission permission) throws TInternalServerError, TNotFoundException {
- try {
- String imageBaseId = DbImage.getBaseIdForVersionId(imageVersionId);
- if (imageBaseId == null)
- throw new TNotFoundException();
- return hasImageBasePermission(user, imageBaseId, permission);
- } catch (SQLException e) {
- throw new TInternalServerError();
- }
- }
-
- /**
- * Check if the given user has the given permission for the image identified
- * by the given image version id.
- *
- * @param user
- * @param imageVersionId
- * @param permission
- * @throws TAuthorizationException
- * @throws TInternalServerError
- * @throws TNotFoundException
- */
- protected static void hasImageVersionPermissionOrFail(UserInfo user, String imageVersionId,
- Permission permission) throws TAuthorizationException, TInternalServerError, TNotFoundException {
- if (!hasImageVersionPermission(user, imageVersionId, permission)) {
- throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, "Required image permission: "
- + permission.toString());
- }
- }
-
- protected static boolean hasLecturePermission(UserInfo user, String lectureId, Permission permission)
- throws TInternalServerError, TNotFoundException {
- // Check general permissions
- LectureSummary lecture;
- try {
- lecture = DbLecture.getLectureSummary(user, lectureId);
- } catch (SQLException e) {
- throw new TInternalServerError();
- }
- // Owner has all permissions
- if (lecture.ownerId.equals(user.userId))
- return true;
- return canActionLecture(user, permission, lecture.userPermissions, lecture.defaultPermissions)
- || User.isSuperUser(user);
- }
-
- protected static void hasLecturePermissionOrFail(UserInfo user, String lectureId, Permission permission)
- throws TAuthorizationException, TInternalServerError, TNotFoundException {
- if (!hasLecturePermission(user, lectureId, permission)) {
- throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
- "Required lecture permission: " + permission.toString());
- }
- }
-
-
-}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
index 4096deae..fba1126d 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
@@ -3,13 +3,18 @@ package org.openslx.bwlp.sat.permissions;
import java.sql.SQLException;
import org.openslx.bwlp.sat.database.mappers.DbImage;
+import org.openslx.bwlp.sat.database.mappers.DbLecture;
import org.openslx.bwlp.sat.database.mappers.DbOrganization;
import org.openslx.bwlp.sat.database.models.LocalOrganization;
import org.openslx.bwlp.sat.database.models.LocalUser;
-import org.openslx.bwlp.sat.permissions.PermCheck.Permission;
import org.openslx.bwlp.thrift.iface.AuthorizationError;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
+import org.openslx.bwlp.thrift.iface.ImagePermissions;
+import org.openslx.bwlp.thrift.iface.ImageSummaryRead;
import org.openslx.bwlp.thrift.iface.ImageVersionDetails;
+import org.openslx.bwlp.thrift.iface.LecturePermissions;
+import org.openslx.bwlp.thrift.iface.LectureRead;
+import org.openslx.bwlp.thrift.iface.LectureSummary;
import org.openslx.bwlp.thrift.iface.Role;
import org.openslx.bwlp.thrift.iface.TAuthorizationException;
import org.openslx.bwlp.thrift.iface.TInternalServerError;
@@ -18,6 +23,12 @@ import org.openslx.bwlp.thrift.iface.UserInfo;
public class User {
+ private static final ImagePermissions imageSu = new ImagePermissions(true, true, true, true);
+
+ private static final LecturePermissions lectureSu = new LecturePermissions(true, true);
+
+ private static final LecturePermissions lectureNothing = new LecturePermissions(false, false);
+
public static boolean isTutor(UserInfo user) {
return user.role == Role.TUTOR;
}
@@ -96,7 +107,8 @@ public class User {
*/
public static void canEditBaseImageOrFail(UserInfo user, String imageBaseId) throws TInternalServerError,
TNotFoundException, TAuthorizationException {
- if (!isTutor(user) || !PermCheck.hasImageBasePermission(user, imageBaseId, Permission.EDIT)) {
+ ImageSummaryRead image = getImageFromBaseId(user, imageBaseId);
+ if (!image.userPermissions.edit) {
throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
"No permission to edit this image");
}
@@ -141,22 +153,42 @@ public class User {
} catch (SQLException e) {
throw new TInternalServerError();
}
- // User owns the base image - allow
- if (imageDetails.ownerId.equals(user.userId))
- return;
- // User is image admin - allow
- if (PermCheck.canActionImage(user, Permission.ADMIN, imageDetails.userPermissions,
- imageDetails.defaultPermissions))
+ // Check user permissions
+ if (imageDetails.userPermissions.admin)
return;
- // User uploaded the image version in question - allow
- for (ImageVersionDetails version : imageDetails.versions) {
- if (version.uploaderId.equals(user.userId))
- return;
+ // User uploaded the image version in question and has edit permissions - allow
+ if (imageDetails.userPermissions.edit) {
+ for (ImageVersionDetails version : imageDetails.versions) {
+ if (version.versionId.equals(imageVersionId) && version.uploaderId.equals(user.userId))
+ return;
+ }
}
throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
"No permission to delete this image version");
}
+ public static void canDownloadImageVersionOrFail(UserInfo user, String imageVersionId)
+ throws TAuthorizationException, TNotFoundException, TInternalServerError {
+ ImageDetailsRead image;
+ try {
+ image = DbImage.getImageDetails(user, DbImage.getBaseIdForVersionId(imageVersionId));
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
+ if (user != null && user.role != Role.STUDENT) {
+ if (image.userPermissions.download)
+ return;
+ } else {
+ // User is unknown role or student, check version's restricted flag
+ for (ImageVersionDetails version : image.versions) {
+ if (!version.isRestricted && version.versionId.equals(imageVersionId))
+ return;
+ }
+ }
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to download this image version");
+ }
+
/**
* Checks whether the given user is allowed to create new lectures.
* Throws {@link TAuthorizationException} if permission is not granted.
@@ -170,8 +202,8 @@ public class User {
}
/**
- * Checks whether the given user can edit the image identified by the given
- * image base id
+ * Checks whether the given user can edit the permission list of the image
+ * identified by the given image base id.
*
* @param user
* @param imageBaseId
@@ -181,18 +213,19 @@ public class User {
*/
public static boolean canEditImagePermissions(UserInfo user, String imageBaseId)
throws TInternalServerError, TNotFoundException {
- return isTutor(user) && PermCheck.hasImageBasePermission(user, imageBaseId, Permission.ADMIN);
+ ImageSummaryRead image = getImageFromBaseId(user, imageBaseId);
+ return image.userPermissions.admin;
}
/**
- * Checks whether the given user can edit the image identified by the given
- * image base id.
- * Throws {@link TAuthorizationException} if permission is not granted.
+ * Checks whether the given user can edit the permission list of the image
+ * identified by the given image base id.
*
* @param user
* @param imageBaseId
* @throws TInternalServerError
* @throws TNotFoundException
+ * @throws TAuthorizationException if permission is not granted.
*/
public static void canEditImagePermissionsOrFail(UserInfo user, String imageBaseId)
throws TAuthorizationException, TInternalServerError, TNotFoundException {
@@ -205,7 +238,8 @@ public class User {
throws TAuthorizationException, TInternalServerError, TNotFoundException {
// TODO: Who should be allowed to change the owner? Any admin, or just the owner?
// Currently it's every admin, but this is open for discussion
- if (!isTutor(user) || PermCheck.hasImageBasePermission(user, imageBaseId, Permission.ADMIN)) {
+ ImageSummaryRead image = getImageFromBaseId(user, imageBaseId);
+ if (!image.userPermissions.admin) {
throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
"No permission to change image owner");
}
@@ -213,7 +247,8 @@ public class User {
public static void canEditLectureOrFail(UserInfo user, String lectureId) throws TInternalServerError,
TNotFoundException, TAuthorizationException {
- if (!isTutor(user) || !PermCheck.hasLecturePermission(user, lectureId, Permission.EDIT)) {
+ LectureSummary lecture = getLectureFromId(user, lectureId);
+ if (!lecture.userPermissions.edit) {
throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
"No permission to edit this image");
}
@@ -239,10 +274,109 @@ public class User {
public static void canDeleteLectureOrFail(UserInfo user, String lectureId)
throws TAuthorizationException, TInternalServerError, TNotFoundException {
- if (!isTutor(user) || !PermCheck.hasLecturePermission(user, lectureId, Permission.ADMIN)) {
+ LectureSummary lecture = getLectureFromId(user, lectureId);
+ if (!lecture.userPermissions.admin) {
throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
"No permission to delete this lecture");
}
}
+ public static void setCombinedUserPermissions(ImageSummaryRead image, UserInfo user) {
+ if (hasAllImagePermissions(user, image.ownerId)) {
+ image.userPermissions = imageSu;
+ return;
+ }
+ image.userPermissions = calculateUserImagePermissions(user, image.userPermissions,
+ image.defaultPermissions);
+ }
+
+ public static void setCombinedUserPermissions(ImageDetailsRead image, UserInfo user) {
+ if (hasAllImagePermissions(user, image.ownerId)) {
+ image.userPermissions = imageSu;
+ return;
+ }
+ image.userPermissions = calculateUserImagePermissions(user, image.userPermissions,
+ image.defaultPermissions);
+ }
+
+ private static boolean hasAllImagePermissions(UserInfo user, String imageOwnerId) {
+ if (user != null && user.role == Role.TUTOR) {
+ // Check for owner
+ if (user.userId.equals(imageOwnerId)) {
+ return true;
+ }
+ // Check for super user
+ LocalUser localUser = LocalData.getLocalUser(user);
+ if (localUser != null && localUser.isSuperUser) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static ImagePermissions calculateUserImagePermissions(UserInfo user, ImagePermissions userPerms,
+ ImagePermissions defPerms) {
+ // Standard combining logic
+ if (userPerms == null)
+ userPerms = defPerms;
+ // Reduce student's permissions to be safe
+ if (user == null || user.role == Role.STUDENT) {
+ if (userPerms.link || userPerms.admin || userPerms.edit) {
+ if (userPerms == defPerms) {
+ userPerms = new ImagePermissions(defPerms);
+ }
+ userPerms.link = false;
+ userPerms.edit = false;
+ userPerms.admin = false;
+ }
+ }
+ return userPerms;
+ }
+
+ public static void setCombinedUserPermissions(LectureRead lecture, UserInfo user) {
+ if (user == null || user.role == Role.STUDENT) {
+ lecture.userPermissions = lectureNothing;
+ return;
+ }
+ if (hasAllLecturePermissions(user, lecture.ownerId)) {
+ lecture.userPermissions = lectureSu;
+ return;
+ }
+ if (lecture.userPermissions == null) {
+ lecture.userPermissions = lecture.defaultPermissions;
+ }
+ }
+
+ private static boolean hasAllLecturePermissions(UserInfo user, String lectureOwnerId) {
+ if (user != null && user.role == Role.TUTOR) {
+ // Check for owner
+ if (user.userId.equals(lectureOwnerId)) {
+ return true;
+ }
+ // Check for super user
+ LocalUser localUser = LocalData.getLocalUser(user);
+ if (localUser != null && localUser.isSuperUser) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static ImageSummaryRead getImageFromBaseId(UserInfo user, String imageBaseId)
+ throws TNotFoundException, TInternalServerError {
+ try {
+ return DbImage.getImageSummary(user, imageBaseId);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
+ }
+
+ private static LectureSummary getLectureFromId(UserInfo user, String lectureId)
+ throws TNotFoundException, TInternalServerError {
+ try {
+ return DbLecture.getLectureSummary(user, lectureId);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
+ }
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java
index 20df580d..4392a249 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java
@@ -12,6 +12,7 @@ import org.openslx.bwlp.sat.database.mappers.DbImage;
import org.openslx.bwlp.sat.database.mappers.DbImagePermissions;
import org.openslx.bwlp.sat.database.mappers.DbLecture;
import org.openslx.bwlp.sat.database.mappers.DbUser;
+import org.openslx.bwlp.sat.fileserv.ActiveDownload;
import org.openslx.bwlp.sat.fileserv.ActiveUpload;
import org.openslx.bwlp.sat.fileserv.FileServer;
import org.openslx.bwlp.sat.permissions.User;
@@ -124,9 +125,17 @@ public class ServerHandler implements SatelliteServer.Iface {
@Override
public TransferInformation requestDownload(String userToken, String imageVersionId)
- throws TAuthorizationException {
- // TODO Auto-generated method stub
- return null;
+ throws TAuthorizationException, TInternalServerError, TNotFoundException,
+ TTransferRejectedException {
+ UserInfo user = SessionManager.getOrFail(userToken);
+ User.canDownloadImageVersionOrFail(user, imageVersionId);
+ ActiveDownload transfer;
+ try {
+ transfer = fileServer.createNewUserDownload(DbImage.getLocalImageData(imageVersionId));
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
+ return new TransferInformation(transfer.getId(), fileServer.getPlainPort(), fileServer.getSslPort());
}
@Override