summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-06-30 18:21:47 +0200
committerSimon Rettberg2015-06-30 18:21:47 +0200
commita3cb5ed720dec67fd01759c631e69d6a988e3313 (patch)
treeb47ffce0f885112950752d2462ec4cd92c3ea4e9
parentFixed some comments and variable names (diff)
downloadtutor-module-a3cb5ed720dec67fd01759c631e69d6a988e3313.tar.gz
tutor-module-a3cb5ed720dec67fd01759c631e69d6a988e3313.tar.xz
tutor-module-a3cb5ed720dec67fd01759c631e69d6a988e3313.zip
[server] Refactored permission checking classes a bit
-rw-r--r--dozentenmodulserver/setup/sat-01-schema.sql2
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java2
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java23
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java72
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/LocalData.java65
-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.java296
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java89
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java13
9 files changed, 500 insertions, 237 deletions
diff --git a/dozentenmodulserver/setup/sat-01-schema.sql b/dozentenmodulserver/setup/sat-01-schema.sql
index 08a63be8..e07156f8 100644
--- a/dozentenmodulserver/setup/sat-01-schema.sql
+++ b/dozentenmodulserver/setup/sat-01-schema.sql
@@ -58,7 +58,7 @@ CREATE TABLE IF NOT EXISTS `imagebase` (
`updatetime` bigint(20) NOT NULL,
`ownerid` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`updaterid` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
- `sharemode` enum('LOCAL','PUBLISH','DOWNLOAD') NOT NULL,
+ `sharemode` enum('LOCAL','PUBLISH','DOWNLOAD', 'FROZEN') NOT NULL,
`istemplate` tinyint(1) NOT NULL,
`canlinkdefault` tinyint(1) NOT NULL,
`candownloaddefault` tinyint(1) NOT NULL,
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
index aaa344f8..03ae5dd4 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
@@ -67,7 +67,7 @@ public class App {
Database.printCharsetInformation();
List<ImageSummaryRead> allVisible;
try {
- allVisible = DbImage.getAllVisible(new UserInfo("bla", "blu", null, null, null), null);
+ allVisible = DbImage.getAllVisible(new UserInfo("bla", "blu", null, null, null), null, 0);
log.info("Got " + allVisible.size());
} catch (SQLException e) {
log.warn("could not test query getallvisible");
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 1fb19121..4ca2aef6 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
@@ -10,6 +10,7 @@ import org.apache.log4j.Logger;
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.thrift.iface.ImageBaseWrite;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImagePermissions;
@@ -42,10 +43,11 @@ public class DbImage {
* question
* @param tagSearch list of tags an image must have to be included in the
* list.
+ * @param page page to return
* @return {@link List} of {@link ImageSummaryRead}
* @throws SQLException
*/
- public static List<ImageSummaryRead> getAllVisible(UserInfo user, List<String> tagSearch)
+ public static List<ImageSummaryRead> getAllVisible(UserInfo user, List<String> tagSearch, int page)
throws SQLException {
// TODO: Implement tag search functionality
try (MysqlConnection connection = Database.getConnection()) {
@@ -60,10 +62,11 @@ public class DbImage {
+ " FROM imagebase i"
+ " LEFT JOIN imageversion cur ON (cur.imageversionid = i.currentversionid)"
+ " LEFT JOIN imageversion lat ON (lat.imageversionid = i.latestversionid)"
- + " LEFT JOIN imagepermission perm ON (i.imagebaseid = perm.imagebaseid AND perm.userid = :userid)");
+ + " LEFT JOIN imagepermission perm ON (i.imagebaseid = perm.imagebaseid AND perm.userid = :userid)"
+ + Paginator.limitStatement(page));
stmt.setString("userid", user.userId);
ResultSet rs = stmt.executeQuery();
- List<ImageSummaryRead> list = new ArrayList<>();
+ List<ImageSummaryRead> list = new ArrayList<>(100);
while (rs.next()) {
list.add(resultSetToSummary(rs));
}
@@ -342,4 +345,18 @@ public class DbImage {
}
}
+ public static void setShareMode(String imageBaseId, ImageBaseWrite newData) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("UPDATE imagebase"
+ + " SET sharemode = :sharemode WHERE imagebaseid = :baseid LIMIT 1");
+ stmt.setString("baseid", imageBaseId);
+ stmt.setString("sharemode", newData.shareMode.toString());
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.setShareMode()", e);
+ throw e;
+ }
+ }
+
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java
index 7f2fa4c5..18f21498 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java
@@ -2,12 +2,15 @@ package org.openslx.bwlp.sat.database.mappers;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.UUID;
import org.apache.log4j.Logger;
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.permissions.User;
import org.openslx.bwlp.sat.util.Json;
import org.openslx.bwlp.thrift.iface.LecturePermissions;
import org.openslx.bwlp.thrift.iface.LectureSummary;
@@ -116,22 +119,71 @@ public class DbLecture {
ResultSet rs = stmt.executeQuery();
if (!rs.next())
throw new TNotFoundException();
- return resultSetToSummary(rs);
+ LectureSummary lecture = new LectureSummary();
+ lecture.setLectureId(rs.getString("lectureid"));
+ lecture.setLectureName(rs.getString("lecturename"));
+ lecture.setImageVersionId(rs.getString("imageversionid"));
+ lecture.setIsEnabled(rs.getBoolean("isenabled"));
+ lecture.setStartTime(rs.getLong("starttime"));
+ lecture.setEndTime(rs.getLong("endtime"));
+ lecture.setLastUsed(rs.getLong("lastused"));
+ lecture.setUseCount(rs.getInt("usecount"));
+ lecture.setOwnerId(rs.getString("ownerid"));
+ lecture.setUpdaterId(rs.getString("updaterid"));
+ lecture.setIsExam(rs.getBoolean("isexam"));
+ lecture.setHasInternetAccess(rs.getBoolean("hasinternetaccess"));
+ lecture.setDefaultPermissions(DbLecturePermissions.fromResultSetDefault(rs));
+ lecture.setUserPermissions(DbLecturePermissions.fromResultSetUser(rs));
+ return lecture;
} catch (SQLException e) {
LOGGER.error("Query failed in DbLecture.getLectureSummary()", e);
throw e;
}
}
- private static LectureSummary resultSetToSummary(ResultSet rs) throws SQLException {
- LecturePermissions defaultPermissions = DbLecturePermissions.fromResultSetDefault(rs);
- LectureSummary entry = new LectureSummary(rs.getString("lectureid"), rs.getString("lecturename"),
- rs.getString("imageversionid"), null, rs.getBoolean("isenabled"), rs.getLong("starttime"),
- rs.getLong("endtime"), rs.getLong("lastused"), rs.getInt("usecount"),
- rs.getString("ownerid"), rs.getString("updaterid"), rs.getBoolean("isexam"),
- rs.getBoolean("hasinternetaccess"), defaultPermissions, false);
- entry.userPermissions = DbLecturePermissions.fromResultSetUser(rs);
- return entry;
+ public static List<LectureSummary> getAll(UserInfo user, int page) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT"
+ + " l.lectureid, l.displayname AS lecturename, l.imageversionid, i.imagebaseid,"
+ + " l.isenabled, l.starttime, l.endtime, l.lastused, l.usecount, l.ownerid, l.updaterid,"
+ + " l.isexam, l.hasinternetaccess, l.caneditdefault, l.canadmindefault,"
+ + " i.isenabled AS imgenabled, i.isvalid AS imgvalid, p.canedit, p.canadmin"
+ + " FROM lecture l "
+ + " INNER JOIN imageversion i USING (imageversionid)"
+ + " LEFT JOIN lecturepermission p ON (p.lectureid = l.lectureid AND p.userid = :userid)"
+ + (User.isStudent(user) ? " WHERE i.isrestricted = 0" : ""));
+ if (user == null) {
+ stmt.setString("userid", "-");
+ } else {
+ stmt.setString("userid", user.userId);
+ }
+ ResultSet rs = stmt.executeQuery();
+ List<LectureSummary> list = new ArrayList<>(100);
+ while (rs.next()) {
+ LectureSummary lecture = new LectureSummary();
+ lecture.setLectureId(rs.getString("lectureid"));
+ lecture.setLectureName(rs.getString("lecturename"));
+ lecture.setImageVersionId(rs.getString("imageversionid"));
+ lecture.setImageBaseId(rs.getString("imagebaseid"));
+ lecture.setIsEnabled(rs.getBoolean("isenabled"));
+ lecture.setStartTime(rs.getLong("starttime"));
+ lecture.setEndTime(rs.getLong("endtime"));
+ lecture.setLastUsed(rs.getLong("lastused"));
+ lecture.setUseCount(rs.getInt("usecount"));
+ lecture.setOwnerId(rs.getString("ownerid"));
+ lecture.setUpdaterId(rs.getString("updaterid"));
+ lecture.setIsExam(rs.getBoolean("isexam"));
+ lecture.setHasInternetAccess(rs.getBoolean("hasinternetaccess"));
+ lecture.setDefaultPermissions(DbLecturePermissions.fromResultSetDefault(rs));
+ lecture.setUserPermissions(DbLecturePermissions.fromResultSetUser(rs));
+ lecture.setIsImageVersionUsable(rs.getBoolean("imgenabled") && rs.getBoolean("imgvalid"));
+ list.add(lecture);
+ }
+ return list;
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbLecture.getAll()", e);
+ throw e;
+ }
}
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/LocalData.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/LocalData.java
new file mode 100644
index 00000000..3468d69a
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/LocalData.java
@@ -0,0 +1,65 @@
+package org.openslx.bwlp.sat.permissions;
+
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.openslx.bwlp.sat.database.mappers.DbOrganization;
+import org.openslx.bwlp.sat.database.mappers.DbUser;
+import org.openslx.bwlp.sat.database.models.LocalOrganization;
+import org.openslx.bwlp.sat.database.models.LocalUser;
+import org.openslx.bwlp.thrift.iface.UserInfo;
+import org.openslx.util.TimeoutHashMap;
+
+public class LocalData {
+
+ /**
+ * Cache local user data, might be called quite often.
+ */
+ private static final Map<String, LocalUser> localUserCache = new TimeoutHashMap<>(60000);
+
+ protected static LocalUser getLocalUser(UserInfo user) {
+ synchronized (localUserCache) {
+ LocalUser local = localUserCache.get(user.userId);
+ if (local != null)
+ return local;
+ }
+ LocalUser localData;
+ try {
+ localData = DbUser.getLocalData(user);
+ } catch (SQLException e) {
+ return null;
+ }
+ if (localData == null)
+ return null;
+ synchronized (localUserCache) {
+ localUserCache.put(user.userId, localData);
+ }
+ return localData;
+ }
+
+ /**
+ * Cache local organization data, might be called quite often.
+ */
+ private static final Map<String, LocalOrganization> localOrganizationCache = new TimeoutHashMap<>(60000);
+
+ protected static LocalOrganization getLocalOrganization(String organizationId) {
+ synchronized (localOrganizationCache) {
+ LocalOrganization local = localOrganizationCache.get(organizationId);
+ if (local != null)
+ return local;
+ }
+ LocalOrganization localData;
+ try {
+ localData = DbOrganization.getLocalData(organizationId);
+ } catch (SQLException e) {
+ return null;
+ }
+ if (localData == null)
+ return null;
+ synchronized (localOrganizationCache) {
+ localOrganizationCache.put(organizationId, localData);
+ }
+ return localData;
+ }
+
+}
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
new file mode 100644
index 00000000..6b4af039
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java
@@ -0,0 +1,175 @@
+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 2ffd281a..74c9a441 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
@@ -1,121 +1,27 @@
package org.openslx.bwlp.sat.permissions;
import java.sql.SQLException;
-import java.util.Map;
-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.sat.database.mappers.DbOrganization;
-import org.openslx.bwlp.sat.database.mappers.DbUser;
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.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.Role;
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;
-import org.openslx.util.TimeoutHashMap;
public class User {
- private static final Logger LOGGER = Logger.getLogger(User.class);
-
- public static enum Permission {
- LINK,
- DOWNLOAD,
- EDIT,
- ADMIN
- }
-
- private 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;
- }
-
- private 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;
- }
-
- /**
- * Cache local user data, might be called quite often.
- */
- private static final Map<String, LocalUser> localUserCache = new TimeoutHashMap<>(60000);
-
- private static LocalUser getLocalUser(UserInfo user) {
- synchronized (localUserCache) {
- LocalUser local = localUserCache.get(user.userId);
- if (local != null)
- return local;
- }
- LocalUser localData;
- try {
- localData = DbUser.getLocalData(user);
- } catch (SQLException e) {
- return null;
- }
- if (localData == null)
- return null;
- synchronized (localUserCache) {
- localUserCache.put(user.userId, localData);
- }
- return localData;
+ public static boolean isTutor(UserInfo user) {
+ return user.role == Role.TUTOR;
}
- /**
- * Cache local organization data, might be called quite often.
- */
- private static final Map<String, LocalOrganization> localOrganizationCache = new TimeoutHashMap<>(60000);
-
- private static LocalOrganization getLocalOrganization(String organizationId) {
- synchronized (localOrganizationCache) {
- LocalOrganization local = localOrganizationCache.get(organizationId);
- if (local != null)
- return local;
- }
- LocalOrganization localData;
- try {
- localData = DbOrganization.getLocalData(organizationId);
- } catch (SQLException e) {
- return null;
- }
- if (localData == null)
- return null;
- synchronized (localOrganizationCache) {
- localOrganizationCache.put(organizationId, localData);
- }
- return localData;
+ public static boolean isStudent(UserInfo user) {
+ return user.role == Role.STUDENT;
}
/**
@@ -125,7 +31,7 @@ public class User {
* @return
*/
public static boolean isSuperUser(UserInfo user) {
- LocalUser localData = getLocalUser(user);
+ LocalUser localData = LocalData.getLocalUser(user);
return localData != null && localData.isSuperUser;
}
@@ -136,10 +42,10 @@ public class User {
* @return true if user is allowed to login to this satellite
*/
public static boolean canLogin(UserInfo user) {
- LocalUser localData = getLocalUser(user);
+ LocalUser localData = LocalData.getLocalUser(user);
if (localData != null)
return localData.canLogin; // User locally known, use user-specific permission
- LocalOrganization local = getLocalOrganization(user.organizationId);
+ LocalOrganization local = LocalData.getLocalOrganization(user.organizationId);
// User unknown, check per-organization login permission
if (local == null)
return false;
@@ -159,150 +65,146 @@ public class User {
}
/**
- * Check if the given user has the given permission for the image identified
- * by the given image base id.
+ * Checks whether the given user is allowed to create new images.
+ * Throws {@link TAuthorizationException} if permission is not granted.
*
- * @param user
- * @param imageBaseId
- * @param permission
- * @throws TInternalServerError
- * @throws TNotFoundException
+ * @param user {@link UserInfo} instance representing the user in question
*/
- public static boolean hasImageBasePermission(UserInfo user, String imageBaseId, Permission permission)
- throws TInternalServerError, TNotFoundException {
- // Students can download only, so return false right away if we're not checking for download
- if (user.role == Role.STUDENT && permission != Permission.DOWNLOAD)
- return false;
- // 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)
- || isSuperUser(user);
+ public static void canCreateImageOrFail(UserInfo user) throws TAuthorizationException {
+ if (!isTutor(user))
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to create new image");
}
/**
- * Check if the given user has the given permission for the image identified
- * by the given image base id.
+ * Is given user allowed to edit/update the image identified by the given
+ * image base id? Throws {@link TAuthorizationException} if permission is
+ * not granted.
*
* @param user
* @param imageBaseId
- * @param permission
- * @throws TAuthorizationException
- * @throws TInternalServerError
* @throws TNotFoundException
+ * @throws TInternalServerError
+ * @throws TAuthorizationException
*/
- public 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());
+ public static void canEditBaseImageOrFail(UserInfo user, String imageBaseId) throws TInternalServerError,
+ TNotFoundException, TAuthorizationException {
+ if (!isTutor(user) || !PermCheck.hasImageBasePermission(user, imageBaseId, Permission.EDIT)) {
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to edit this image");
}
}
/**
- * Check if the given user has the given permission for the image identified
- * by the given image version id.
+ * Is given user allowed to edit/update the image identified by the given
+ * image version id? Throws {@link TAuthorizationException} if permission is
+ * not granted.
*
* @param user
* @param imageVersionId
- * @param permission
- * @throws TInternalServerError
* @throws TNotFoundException
+ * @throws TInternalServerError
+ * @throws TAuthorizationException
*/
- public static boolean hasImageVersionPermission(UserInfo user, String imageVersionId,
- Permission permission) throws TInternalServerError, TNotFoundException {
+ public static void canEditImageVersionOrFail(UserInfo user, String imageVersionId)
+ throws TInternalServerError, TNotFoundException, TAuthorizationException {
try {
- String imageBaseId = DbImage.getBaseIdForVersionId(imageVersionId);
- if (imageBaseId == null)
- throw new TNotFoundException();
- return hasImageBasePermission(user, imageBaseId, permission);
+ canEditBaseImageOrFail(user, DbImage.getBaseIdForVersionId(imageVersionId));
} 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.
+ * Is given user allowed to delete the image identified by the given
+ * image version id? Throws {@link TAuthorizationException} if permission is
+ * not granted.
*
* @param user
* @param imageVersionId
- * @param permission
* @throws TAuthorizationException
- * @throws TInternalServerError
* @throws TNotFoundException
+ * @throws TInternalServerError
*/
- public 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());
- }
+ public static void canDeleteImageVersionOrFail(UserInfo user, String imageVersionId)
+ throws TInternalServerError, TNotFoundException, TAuthorizationException {
+ // Currently, editing an image also means we can delete it, but let's
+ // keep this a separate function in case we want to change it some time.
+ canEditImageVersionOrFail(user, imageVersionId);
}
- public static boolean hasLecturePermission(UserInfo user, String lectureId, Permission permission)
- throws TInternalServerError, TNotFoundException {
- if (user.role != Role.TUTOR)
- return false;
- // 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)
- || isSuperUser(user);
+ /**
+ * Checks whether the given user is allowed to create new lectures.
+ * Throws {@link TAuthorizationException} if permission is not granted.
+ *
+ * @param user {@link UserInfo} instance representing the user in question
+ */
+ public static void canCreateLectureOrFail(UserInfo user) throws TAuthorizationException {
+ if (!isTutor(user))
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to create new lecture");
}
- public 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());
- }
+ /**
+ * Checks whether the given user can edit the image identified by the given
+ * image base id
+ *
+ * @param user
+ * @param imageBaseId
+ * @return
+ * @throws TInternalServerError
+ * @throws TNotFoundException
+ */
+ public static boolean canEditImagePermissions(UserInfo user, String imageBaseId)
+ throws TInternalServerError, TNotFoundException {
+ return isTutor(user) && PermCheck.hasImageBasePermission(user, imageBaseId, Permission.ADMIN);
}
/**
- * Checks whether the given user is allowed to create new images.
+ * Checks whether the given user can edit the image identified by the given
+ * image base id.
+ * Throws {@link TAuthorizationException} if permission is not granted.
*
- * @param user {@link UserInfo} instance representing the user in question
- * @return true or false
+ * @param user
+ * @param imageBaseId
+ * @throws TInternalServerError
+ * @throws TNotFoundException
*/
- public static boolean canCreateImage(UserInfo user) {
- return user.role == Role.TUTOR;
+ public static void canEditImagePermissionsOrFail(UserInfo user, String imageBaseId)
+ throws TAuthorizationException, TInternalServerError, TNotFoundException {
+ if (!canEditImagePermissions(user, imageBaseId))
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to edit this image's permissions");
}
- public static void canCreateImageOrFail(UserInfo user) throws TAuthorizationException {
- if (!canCreateImage(user))
+ public static void canChangeImageOwnerOrFail(UserInfo user, String imageBaseId)
+ 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)) {
throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
- "No permission to create new image");
+ "No permission to change image owner");
+ }
}
- /**
- * Checks whether the given user is allowed to create new lectures.
- *
- * @param user {@link UserInfo} instance representing the user in question
- * @return true or false
- */
- public static boolean canCreateLecture(UserInfo user) {
- return user.role == Role.TUTOR;
+ public static void canEditLectureOrFail(UserInfo user, String lectureId) throws TInternalServerError,
+ TNotFoundException, TAuthorizationException {
+ if (!isTutor(user) || !PermCheck.hasLecturePermission(user, lectureId, Permission.EDIT)) {
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to edit this image");
+ }
}
- public static void canCreateLectureOrFail(UserInfo user) throws TAuthorizationException {
- if (!canCreateLecture(user))
+ public static void canListImagesOrFail(UserInfo user) throws TAuthorizationException {
+ if (!isTutor(user))
throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
- "No permission to create new lecture");
+ "No permission to see list of images");
+ }
+
+ public static void canSeeImageDetailsOrFail(UserInfo user) throws TAuthorizationException {
+ if (!isTutor(user))
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to see list of images");
}
}
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 cab355a7..5cf28713 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
@@ -14,11 +14,11 @@ import org.openslx.bwlp.sat.database.mappers.DbUser;
import org.openslx.bwlp.sat.fileserv.ActiveUpload;
import org.openslx.bwlp.sat.fileserv.FileServer;
import org.openslx.bwlp.sat.permissions.User;
-import org.openslx.bwlp.sat.permissions.User.Permission;
import org.openslx.bwlp.sat.thrift.cache.OperatingSystemList;
import org.openslx.bwlp.sat.thrift.cache.OrganizationList;
import org.openslx.bwlp.sat.thrift.cache.VirtualizerList;
import org.openslx.bwlp.sat.util.Util;
+import org.openslx.bwlp.thrift.iface.AuthorizationError;
import org.openslx.bwlp.thrift.iface.ImageBaseWrite;
import org.openslx.bwlp.thrift.iface.ImageDataError;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
@@ -32,6 +32,7 @@ import org.openslx.bwlp.thrift.iface.LectureWrite;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.bwlp.thrift.iface.Organization;
import org.openslx.bwlp.thrift.iface.SatelliteServer;
+import org.openslx.bwlp.thrift.iface.ShareMode;
import org.openslx.bwlp.thrift.iface.TAuthorizationException;
import org.openslx.bwlp.thrift.iface.TImageDataException;
import org.openslx.bwlp.thrift.iface.TInternalServerError;
@@ -131,11 +132,12 @@ public class ServerHandler implements SatelliteServer.Iface {
*/
@Override
- public List<ImageSummaryRead> getImageList(String userToken, List<String> tagSearch)
+ public List<ImageSummaryRead> getImageList(String userToken, List<String> tagSearch, int page)
throws TAuthorizationException, TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
+ User.canListImagesOrFail(user);
try {
- return DbImage.getAllVisible(user, tagSearch);
+ return DbImage.getAllVisible(user, tagSearch, page);
} catch (SQLException e) {
throw new TInternalServerError();
}
@@ -145,6 +147,7 @@ public class ServerHandler implements SatelliteServer.Iface {
public ImageDetailsRead getImageDetails(String userToken, String imageBaseId)
throws TAuthorizationException, TNotFoundException, TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
+ User.canSeeImageDetailsOrFail(user);
try {
return DbImage.getImageDetails(user, imageBaseId);
} catch (SQLException e) {
@@ -167,17 +170,36 @@ public class ServerHandler implements SatelliteServer.Iface {
}
@Override
- public void updateImageBase(String userToken, String imageBaseId, ImageBaseWrite image)
+ public void updateImageBase(String userToken, String imageBaseId, ImageBaseWrite newData)
throws TAuthorizationException, TInternalServerError, TNotFoundException, TImageDataException {
UserInfo user = SessionManager.getOrFail(userToken);
- User.hasImageBasePermissionOrFail(user, imageBaseId, Permission.EDIT);
- if (!Util.isPrintable(image.imageName) || Util.isEmptyString(image.imageName))
+ User.canEditBaseImageOrFail(user, imageBaseId);
+ // Check image name for invalid characters
+ if (!Util.isPrintable(newData.imageName) || Util.isEmptyString(newData.imageName))
throw new TImageDataException(ImageDataError.INVALID_DATA, "Invalid or empty name");
- // TODO: Should other fields be validated? Most fields should be protected by fk constraints,
- // but the user would only get a generic error, with no hint at the actual problem.
+ // Check if image is marked for replication. If so, only allow changing the syncmode to FROZEN/DOWNLOAD
try {
- DbImage.updateImageMetadata(user, imageBaseId, image);
- } catch (SQLException e) {
+ ImageSummaryRead imageSummary = DbImage.getImageSummary(user, imageBaseId);
+ if (imageSummary.shareMode == ShareMode.DOWNLOAD || imageSummary.shareMode == ShareMode.FROZEN) {
+ if (newData.shareMode != ShareMode.DOWNLOAD && newData.shareMode != ShareMode.FROZEN) {
+ throw new TImageDataException(ImageDataError.INVALID_SHARE_MODE,
+ "Cannot change share mode from remote to local");
+ } else {
+ // Share mode is valid and changed, but ignore all other fields
+ DbImage.setShareMode(imageBaseId, newData);
+ return;
+ }
+ } else {
+ // Likewise, if share mode is local or publish, don't allow changing to FROZEN/DOWNLOAD
+ if (newData.shareMode != ShareMode.LOCAL && newData.shareMode != ShareMode.PUBLISH) {
+ throw new TImageDataException(ImageDataError.INVALID_SHARE_MODE,
+ "Cannot change share mode from local to remote");
+ }
+ }
+ // TODO: Should other fields be validated? Most fields should be protected by fk constraints,
+ // but the user would only get a generic error, with no hint at the actual problem.
+ DbImage.updateImageMetadata(user, imageBaseId, newData);
+ } catch (SQLException e1) {
throw new TInternalServerError();
}
}
@@ -186,10 +208,17 @@ public class ServerHandler implements SatelliteServer.Iface {
public void updateImageVersion(String userToken, String imageVersionId, ImageVersionWrite image)
throws TAuthorizationException, TInternalServerError, TNotFoundException {
UserInfo user = SessionManager.getOrFail(userToken);
- User.hasImageVersionPermissionOrFail(user, imageVersionId, Permission.EDIT);
+ User.canEditImageVersionOrFail(user, imageVersionId);
try {
+ // Do not allow editing remote images
+ ImageSummaryRead imageSummary = DbImage.getImageSummary(user,
+ DbImage.getBaseIdForVersionId(imageVersionId));
+ if (imageSummary.shareMode == ShareMode.DOWNLOAD || imageSummary.shareMode == ShareMode.FROZEN) {
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "Cannot edit image coming from master server");
+ }
DbImage.updateImageVersion(user, imageVersionId, image);
- } catch (SQLException e) {
+ } catch (SQLException e1) {
throw new TInternalServerError();
}
}
@@ -198,8 +227,17 @@ public class ServerHandler implements SatelliteServer.Iface {
public void deleteImageVersion(String userToken, String imageVersionId) throws TAuthorizationException,
TNotFoundException, TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
- User.hasImageVersionPermissionOrFail(user, imageVersionId, Permission.ADMIN);
+ User.canDeleteImageVersionOrFail(user, imageVersionId);
try {
+ // Do not allow deleting remote images if share mode is set to "auto download" and
+ // the version to delete is the latest
+ ImageSummaryRead imageSummary = DbImage.getImageSummary(user,
+ DbImage.getBaseIdForVersionId(imageVersionId));
+ if (imageSummary.shareMode == ShareMode.DOWNLOAD
+ && imageSummary.latestVersionId.equals(imageVersionId)) {
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "Cannot delete latest version of image if auto-download is enabled");
+ }
DbImage.markForDeletion(imageVersionId);
} catch (SQLException e) {
throw new TInternalServerError();
@@ -211,7 +249,7 @@ public class ServerHandler implements SatelliteServer.Iface {
Map<String, ImagePermissions> permissions) throws TAuthorizationException, TNotFoundException,
TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
- User.hasImageBasePermissionOrFail(user, imageBaseId, Permission.ADMIN);
+ User.canEditImagePermissionsOrFail(user, imageBaseId);
try {
DbImagePermissions.writeForImageBase(imageBaseId, permissions);
} catch (SQLException e) {
@@ -223,7 +261,7 @@ public class ServerHandler implements SatelliteServer.Iface {
public Map<String, ImagePermissions> getImagePermissions(String userToken, String imageBaseId)
throws TAuthorizationException, TNotFoundException, TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
- boolean adminOnly = !User.hasImageBasePermission(user, imageBaseId, Permission.ADMIN);
+ boolean adminOnly = !User.canEditImagePermissions(user, imageBaseId);
try {
return DbImagePermissions.getForImageBase(imageBaseId, adminOnly);
} catch (SQLException e) {
@@ -235,8 +273,13 @@ public class ServerHandler implements SatelliteServer.Iface {
public void setImageOwner(String userToken, String imageBaseId, String newOwnerId)
throws TAuthorizationException, TNotFoundException, TInternalServerError, TException {
UserInfo user = SessionManager.getOrFail(userToken);
- User.hasImageBasePermissionOrFail(user, imageBaseId, Permission.ADMIN);
+ User.canChangeImageOwnerOrFail(user, imageBaseId);
try {
+ ImageSummaryRead imageSummary = DbImage.getImageSummary(user, imageBaseId);
+ if (imageSummary.shareMode == ShareMode.DOWNLOAD || imageSummary.shareMode == ShareMode.FROZEN) {
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "Cannot change owner of image that gets downloaded from master server");
+ }
DbImage.setImageOwner(imageBaseId, newOwnerId);
} catch (SQLException e) {
throw new TInternalServerError();
@@ -259,7 +302,7 @@ public class ServerHandler implements SatelliteServer.Iface {
public void updateLecture(String userToken, String lectureId, LectureWrite lecture)
throws TAuthorizationException, TNotFoundException, TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
- User.hasLecturePermissionOrFail(user, lectureId, Permission.EDIT);
+ User.canEditLectureOrFail(user, lectureId);
try {
DbLecture.update(user, lectureId, lecture);
} catch (SQLException e) {
@@ -268,9 +311,15 @@ public class ServerHandler implements SatelliteServer.Iface {
}
@Override
- public List<LectureSummary> getLectureList(String userToken) throws TAuthorizationException {
- // TODO Auto-generated method stub
- return null;
+ public List<LectureSummary> getLectureList(String userToken, int page) throws TAuthorizationException,
+ TInternalServerError {
+ UserInfo user = SessionManager.getOrFail(userToken);
+ try {
+ // If user is student, getAll() will only return lectures where the current linked image is not restricted
+ return DbLecture.getAll(user, page);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java
index 3fdadfb1..ec1c42d3 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java
@@ -12,6 +12,7 @@ import org.openslx.bwlp.sat.database.mappers.DbUser;
import org.openslx.bwlp.sat.permissions.User;
import org.openslx.bwlp.sat.util.QuickTimer;
import org.openslx.bwlp.thrift.iface.AuthorizationError;
+import org.openslx.bwlp.thrift.iface.Role;
import org.openslx.bwlp.thrift.iface.TAuthorizationException;
import org.openslx.bwlp.thrift.iface.TInvalidTokenException;
import org.openslx.bwlp.thrift.iface.UserInfo;
@@ -126,11 +127,13 @@ public class SessionManager {
// Valid reply, check if user is allowed to communicate with this satellite server
if (!User.canLogin(ui))
return null;
- // Is valid, insert/update db record
- try {
- DbUser.writeUserOnLogin(ui);
- } catch (SQLException e) {
- return null;
+ // Is valid, insert/update db record, but ignore students
+ if (ui.role != Role.STUDENT) {
+ try {
+ DbUser.writeUserOnLogin(ui);
+ } catch (SQLException e) {
+ return null;
+ }
}
tokenManager.put(token, new Entry(ui));
return ui;