diff options
7 files changed, 435 insertions, 129 deletions
diff --git a/dozentenmodulserver/setup/sat-01-schema.sql b/dozentenmodulserver/setup/sat-01-schema.sql index 0c52f68b..3dbf5317 100644 --- a/dozentenmodulserver/setup/sat-01-schema.sql +++ b/dozentenmodulserver/setup/sat-01-schema.sql @@ -10,7 +10,7 @@ CREATE DATABASE IF NOT EXISTS `sat` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb USE `sat`; DELIMITER $$ -CREATE DEFINER=`root`@`localhost` PROCEDURE `setversionbase`(IN baseid CHAR(36) CHARACTER SET ascii) +CREATE PROCEDURE `setversionbase`(IN baseid CHAR(36) CHARACTER SET ascii) BEGIN -- Variables DECLARE l_current, l_latest VARCHAR(36) CHARACTER SET ascii; @@ -175,6 +175,7 @@ CREATE TABLE IF NOT EXISTS `lecture` ( `displayname` varchar(100) NOT NULL, `description` text NOT NULL, `imageversionid` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT 'We reference a specific image version here, not the base image.\nOn update of an image, we update the lecture table for all matching lectures that used the current image version.\nThis way, a tutor can explicitly switch back to an older version of an image.', + `autoupdate` tinyint(1) NOT NULL, `isenabled` tinyint(1) NOT NULL, `starttime` bigint(20) NOT NULL, `endtime` bigint(20) NOT NULL, @@ -185,6 +186,7 @@ CREATE TABLE IF NOT EXISTS `lecture` ( `ownerid` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, `updaterid` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, `runscript` text DEFAULT NULL, + `nics` VARCHAR(200) CHARACTER SET ascii COLLATE ascii_bin NULL COMMENT 'Freeform text field for future extendability. Format is specified at application layer.', `isexam` tinyint(1) NOT NULL, `hasinternetaccess` tinyint(1) NOT NULL, `caneditdefault` tinyint(1) NOT NULL, @@ -200,6 +202,7 @@ CREATE TABLE IF NOT EXISTS `lecturenetrule` ( `lectureid` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, `direction` enum('IN','OUT') NOT NULL, `host` varchar(45) NOT NULL, + `port` INT NULL, PRIMARY KEY (`ruleid`), KEY `fk_lecturenetrule_1_idx` (`lectureid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -269,6 +272,14 @@ CREATE TABLE IF NOT EXISTS `virtualizer` ( PRIMARY KEY (`virtid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `lectureuser` ( + `lectureid` char(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, + `userlogin` VARCHAR(45) NOT NULL, + PRIMARY KEY (`lectureid`, `userlogin`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +ALTER TABLE `lectureuser` + ADD CONSTRAINT `fk_lectureuser_1` FOREIGN KEY (`lectureid`) REFERENCES `sat`.`lecture` (`lectureid`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `imagebase` ADD CONSTRAINT `fk_imagebase_os` FOREIGN KEY (`osid`) REFERENCES `operatingsystem` (`osid`), @@ -279,23 +290,23 @@ ALTER TABLE `imagebase` ADD CONSTRAINT `latestversion` FOREIGN KEY (`latestversionid`) REFERENCES `imageversion` (`imageversionid`) ON UPDATE CASCADE; ALTER TABLE `imagebase_x_tag` - ADD CONSTRAINT `fk_imagebase_x_tag_1` FOREIGN KEY (`imagebaseid`) REFERENCES `imagebase` (`imagebaseid`) ON UPDATE CASCADE, - ADD CONSTRAINT `fk_imagebase_x_tag_2` FOREIGN KEY (`tagid`) REFERENCES `tag` (`tagid`) ON UPDATE CASCADE; + ADD CONSTRAINT `fk_imagebase_x_tag_1` FOREIGN KEY (`imagebaseid`) REFERENCES `imagebase` (`imagebaseid`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `fk_imagebase_x_tag_2` FOREIGN KEY (`tagid`) REFERENCES `tag` (`tagid`) ON UPDATE CASCADE ON DELETE CASCADE; ALTER TABLE `imageblock` - ADD CONSTRAINT `fk_imageblocksha1_1` FOREIGN KEY (`imageversionid`) REFERENCES `imageversion` (`imageversionid`) ON UPDATE CASCADE; + ADD CONSTRAINT `fk_imageblocksha1_1` FOREIGN KEY (`imageversionid`) REFERENCES `imageversion` (`imageversionid`) ON UPDATE CASCADE ON DELETE CASCADE; ALTER TABLE `imagepermission` - ADD CONSTRAINT `fk_imagepermission_1` FOREIGN KEY (`imagebaseid`) REFERENCES `imagebase` (`imagebaseid`) ON UPDATE CASCADE, - ADD CONSTRAINT `fk_imagepermission_2` FOREIGN KEY (`userid`) REFERENCES `user` (`userid`) ON UPDATE CASCADE; + ADD CONSTRAINT `fk_imagepermission_1` FOREIGN KEY (`imagebaseid`) REFERENCES `imagebase` (`imagebaseid`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `fk_imagepermission_2` FOREIGN KEY (`userid`) REFERENCES `user` (`userid`) ON UPDATE CASCADE ON DELETE CASCADE; ALTER TABLE `imageversion` ADD CONSTRAINT `fk_imageversion_base` FOREIGN KEY (`imagebaseid`) REFERENCES `imagebase` (`imagebaseid`) ON UPDATE CASCADE, ADD CONSTRAINT `fk_imageversion_creator` FOREIGN KEY (`uploaderid`) REFERENCES `user` (`userid`) ON UPDATE CASCADE; ALTER TABLE `imageversion_x_software` - ADD CONSTRAINT `fk_imageversion_x_software_1` FOREIGN KEY (`imageversionid`) REFERENCES `imageversion` (`imageversionid`) ON UPDATE CASCADE, - ADD CONSTRAINT `fk_imageversion_x_software_2` FOREIGN KEY (`softwareid`) REFERENCES `software` (`softwareid`) ON UPDATE CASCADE; + ADD CONSTRAINT `fk_imageversion_x_software_1` FOREIGN KEY (`imageversionid`) REFERENCES `imageversion` (`imageversionid`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `fk_imageversion_x_software_2` FOREIGN KEY (`softwareid`) REFERENCES `software` (`softwareid`) ON UPDATE CASCADE ON DELETE CASCADE; ALTER TABLE `lecture` ADD CONSTRAINT `fk_lecture_image` FOREIGN KEY (`imageversionid`) REFERENCES `imageversion` (`imageversionid`) ON UPDATE CASCADE, @@ -303,22 +314,22 @@ ALTER TABLE `lecture` ADD CONSTRAINT `fk_lecture_updater` FOREIGN KEY (`updaterid`) REFERENCES `user` (`userid`) ON UPDATE CASCADE; ALTER TABLE `lecturenetrule` - ADD CONSTRAINT `fk_lecturenetrule_1` FOREIGN KEY (`lectureid`) REFERENCES `lecture` (`lectureid`) ON UPDATE CASCADE; + ADD CONSTRAINT `fk_lecturenetrule_1` FOREIGN KEY (`lectureid`) REFERENCES `lecture` (`lectureid`) ON UPDATE CASCADE ON DELETE CASCADE; ALTER TABLE `lecturepermission` - ADD CONSTRAINT `fk_lecturepermission_1` FOREIGN KEY (`lectureid`) REFERENCES `lecture` (`lectureid`) ON UPDATE CASCADE, - ADD CONSTRAINT `fk_lecturepermission_2` FOREIGN KEY (`userid`) REFERENCES `user` (`userid`) ON UPDATE CASCADE; + ADD CONSTRAINT `fk_lecturepermission_1` FOREIGN KEY (`lectureid`) REFERENCES `lecture` (`lectureid`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `fk_lecturepermission_2` FOREIGN KEY (`userid`) REFERENCES `user` (`userid`) ON UPDATE CASCADE ON DELETE CASCADE; ALTER TABLE `os_x_virt` - ADD CONSTRAINT `fk_os_x_virt_1` FOREIGN KEY (`osid`) REFERENCES `operatingsystem` (`osid`), - ADD CONSTRAINT `fk_os_x_virt_2` FOREIGN KEY (`virtid`) REFERENCES `virtualizer` (`virtid`); + ADD CONSTRAINT `fk_os_x_virt_1` FOREIGN KEY (`osid`) REFERENCES `operatingsystem` (`osid`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `fk_os_x_virt_2` FOREIGN KEY (`virtid`) REFERENCES `virtualizer` (`virtid`) ON UPDATE CASCADE ON DELETE CASCADE; ALTER TABLE `user` ADD CONSTRAINT `fk_user_1` FOREIGN KEY (`organizationid`) REFERENCES `organization` (`organizationid`) ON UPDATE CASCADE; ALTER TABLE `software_x_tag` - ADD CONSTRAINT `fk_software_x_tag_1` FOREIGN KEY (`softwareid`) REFERENCES `software` (`softwareid`) ON UPDATE CASCADE, - ADD CONSTRAINT `fk_software_x_tag_2` FOREIGN KEY (`tagid`) REFERENCES `tag` (`tagid`) ON UPDATE CASCADE; + ADD CONSTRAINT `fk_software_x_tag_1` FOREIGN KEY (`softwareid`) REFERENCES `software` (`softwareid`) ON UPDATE CASCADE ON DELETE CASCADE, + ADD CONSTRAINT `fk_software_x_tag_2` FOREIGN KEY (`tagid`) REFERENCES `tag` (`tagid`) ON UPDATE CASCADE ON DELETE CASCADE; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 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 bbb5dad9..51daed49 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 @@ -21,6 +21,16 @@ public class DbImage { private static final Logger LOGGER = Logger.getLogger(DbImage.class); + public static ImageSummaryRead getImageSummary(UserInfo user, String imageBaseId) throws SQLException, + TNotFoundException { + try (MysqlConnection connection = Database.getConnection()) { + return getImageSummary(connection, user, imageBaseId); + } catch (SQLException e) { + LOGGER.error("Query failed in DbImage.getImageSummary()", e); + throw e; + } + } + /** * Get list of all images visible to the given user, optionally filtered by * the given list of tags. @@ -51,17 +61,7 @@ public class DbImage { ResultSet rs = stmt.executeQuery(); List<ImageSummaryRead> list = new ArrayList<>(); while (rs.next()) { - ImagePermissions defaultPermissions = DbImagePermissions.fromResultSetDefault(rs); - ImageSummaryRead entry = new ImageSummaryRead(rs.getString("imagebaseid"), - rs.getString("currentversionid"), rs.getString("latestversionid"), - rs.getString("displayname"), rs.getInt("osid"), rs.getString("virtid"), - rs.getLong("createtime"), rs.getLong("updatetime"), rs.getLong("expiretime"), - rs.getString("ownerid"), rs.getString("uploaderid"), - toShareMode(rs.getString("sharemode")), rs.getLong("filesize"), - rs.getByte("isrestricted") != 0, rs.getByte("isvalid") != 0, - rs.getByte("isprocessed") != 0, rs.getByte("istemplate") != 0, defaultPermissions); - entry.userPermissions = DbImagePermissions.fromResultSetUser(rs); - list.add(entry); + list.add(resultSetToSummary(rs)); } return list; } catch (SQLException e) { @@ -103,7 +103,51 @@ public class DbImage { } } - public static List<ImageVersionDetails> getImageVersions(MysqlConnection connection, String imageBaseId) + /** + * Private helper to create an {@link ImageSummaryRead} instance from a + * {@link ResultSet} + * + * @param rs + * @return + * @throws SQLException + */ + private static ImageSummaryRead resultSetToSummary(ResultSet rs) throws SQLException { + ImagePermissions defaultPermissions = DbImagePermissions.fromResultSetDefault(rs); + ImageSummaryRead entry = new ImageSummaryRead(rs.getString("imagebaseid"), + rs.getString("currentversionid"), rs.getString("latestversionid"), + rs.getString("displayname"), rs.getInt("osid"), rs.getString("virtid"), + rs.getLong("createtime"), rs.getLong("updatetime"), rs.getLong("expiretime"), + rs.getString("ownerid"), rs.getString("uploaderid"), toShareMode(rs.getString("sharemode")), + rs.getLong("filesize"), rs.getByte("isrestricted") != 0, rs.getByte("isvalid") != 0, + rs.getByte("isprocessed") != 0, rs.getByte("istemplate") != 0, defaultPermissions); + entry.userPermissions = DbImagePermissions.fromResultSetUser(rs); + return entry; + } + + private static ImageSummaryRead getImageSummary(MysqlConnection connection, UserInfo user, + String imageBaseId) throws SQLException, TNotFoundException { + MysqlStatement stmt = connection.prepareStatement("SELECT" + + " i.imagebaseid, i.currentversionid, i.latestversionid, i.displayname," + + " i.osid, i.virtid, i.createtime, i.updatetime, i.ownerid," + + " i.sharemode, i.istemplate, i.canlinkdefault, i.candownloaddefault," + + " i.caneditdefault, i.canadmindefault," + + " cur.expiretime, cur.filesize, cur.isenabled, cur.isrestricted, cur.isvalid," + + " lat.uploaderid, lat.isprocessed," + + " perm.canlink, perm.candownload, perm.canedit, perm.canadmin" + + " 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)" + + " WHERE i.imagebaseid = :imagebaseid"); + stmt.setString("userid", user.userId); + stmt.setString("imagebaseid", imageBaseId); + ResultSet rs = stmt.executeQuery(); + if (!rs.next()) + throw new TNotFoundException(); + return resultSetToSummary(rs); + } + + private static List<ImageVersionDetails> getImageVersions(MysqlConnection connection, String imageBaseId) throws SQLException { List<ImageVersionDetails> versionList = new ArrayList<>(); MysqlStatement stmt = connection.prepareStatement("SELECT" @@ -124,6 +168,42 @@ public class DbImage { return versionList; } + /** + * 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 + */ + public static String getBaseIdForVersionId(String imageVersionId) throws SQLException { + try (MysqlConnection connection = Database.getConnection()) { + return getBaseIdForVersionId(connection, imageVersionId); + } catch (SQLException e) { + LOGGER.error("Query failed in DbImage.getBaseIdForVersionId()", e); + throw e; + } + } + + /** + * 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 + */ + private static String getBaseIdForVersionId(MysqlConnection connection, String imageVersionId) + throws SQLException { + 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; + return rs.getString("imagebaseid"); + } + private static ShareMode toShareMode(String string) { return ShareMode.valueOf(string); } diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImagePermissions.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImagePermissions.java index e254b085..9f089b42 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImagePermissions.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImagePermissions.java @@ -2,11 +2,19 @@ package org.openslx.bwlp.sat.database.mappers; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +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.thrift.iface.ImagePermissions; public class DbImagePermissions { + private static final Logger LOGGER = Logger.getLogger(DbImagePermissions.class); + /** * Build an instance of {@link ImagePermissions} by reading the given * columns from the given {@link ResultSet}. If there are no permissions @@ -61,4 +69,36 @@ public class DbImagePermissions { return fromResultSet(rs, "canlinkdefault", "candownloaddefault", "caneditdefault", "canadmindefault"); } + /** + * Get permissions for the given image. IF <code>adminOnly</code> is true, + * only users with admin permissions will be returned. + * + * @param imageBaseId UUID of image + * @param adminOnly Only return users with admin permission + * @return + * @throws SQLException + */ + public static Map<String, ImagePermissions> getForImageBase(String imageBaseId, boolean adminOnly) + throws SQLException { + try (MysqlConnection connection = Database.getConnection()) { + MysqlStatement stmt = connection.prepareStatement("SELECT userid, canlink, candownload, canedit, canadmin" + + " FROM imagepermission WHERE imagebaseid = :imagebaseid"); + stmt.setString("imagebaseid", imageBaseId); + ResultSet rs = stmt.executeQuery(); + Map<String, ImagePermissions> list = new HashMap<>(); + while (rs.next()) { + boolean admin = rs.getBoolean("canadmin"); + if (adminOnly && !admin) + continue; + ImagePermissions perm = new ImagePermissions(rs.getBoolean("canlink"), + rs.getBoolean("candownload"), rs.getBoolean("canedit"), admin); + list.put(rs.getString("userid"), perm); + } + return list; + } catch (SQLException e) { + LOGGER.error("Query failed in DbImagePermissions.getForImageBase()", e); + throw e; + } + } + } diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java new file mode 100644 index 00000000..6106fab5 --- /dev/null +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java @@ -0,0 +1,49 @@ +package org.openslx.bwlp.sat.database.mappers; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +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.thrift.iface.UserInfo; + +public class DbUser { + + private static final Logger LOGGER = Logger.getLogger(DbUser.class); + + private static final int PER_PAGE = 200; + + /** + * Get all users, starting at page <code>page</code>. + * This function will return a maximum of {@link #PER_PAGE}(200) results, so + * you might need to call this method several times. + * + * @param page Page to return. The first page is page 0. + * @return List of {@link UserInfo} + * @throws SQLException + */ + public static List<UserInfo> getAll(int page) throws SQLException { + if (page < 0) + return new ArrayList<>(1); + final int offset = page * 200; + try (MysqlConnection connection = Database.getConnection()) { + MysqlStatement stmt = connection.prepareStatement("SELECT userid, firstname, lastname, email, organizationid" + + " FROM user ORDER BY userid ASC LIMIT " + offset + ", " + PER_PAGE); + ResultSet rs = stmt.executeQuery(); + List<UserInfo> list = new ArrayList<>(); + while (rs.next()) { + list.add(new UserInfo(rs.getString("userid"), rs.getString("firstname"), + rs.getString("lastname"), rs.getString("email"), rs.getString("organizationid"))); + } + return list; + } catch (SQLException e) { + LOGGER.error("Query failed in DbUser.getAll()", e); + throw e; + } + } + +} 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 new file mode 100644 index 00000000..51041df9 --- /dev/null +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java @@ -0,0 +1,145 @@ +package org.openslx.bwlp.sat.permissions; + +import java.sql.SQLException; + +import org.openslx.bwlp.sat.database.mappers.DbImage; +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.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; + +public class User { + + public enum Permission { + LINK, + DOWNLOAD, + EDIT, + ADMIN + } + + private static boolean canActionImage(UserInfo ui, 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 isSuperUser(ui); + } + + public static boolean isSuperUser(UserInfo ui) { + // TODO: for superuser override, read from DB + 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 + */ + public static boolean hasImageBasePermission(UserInfo user, String imageBaseId, Permission permission) + throws TInternalServerError, TNotFoundException { + ImageSummaryRead localImage; + try { + localImage = DbImage.getImageSummary(user, imageBaseId); + } catch (SQLException e) { + throw new TInternalServerError(); + } + if (localImage.ownerId.equals(user.userId)) + return true; + return canActionImage(user, permission, localImage.userPermissions, localImage.defaultPermissions); + } + + /** + * 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 + */ + 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()); + } + } + + /** + * 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 + */ + public 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 + */ + 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 permission: " + + permission.toString()); + } + } + + /** + * Checks whether the given user is allowed to create new images. + * + * @param user {@link UserInfo} instance representing the user in question + * @return true or false + */ + public static boolean canCreateImage(UserInfo user) { + return user.role == Role.TUTOR; + } + + public static void canCreateImageOrFail(UserInfo user) throws TAuthorizationException { + if (!canCreateImage(user)) + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "No permission to create new image"); + } + +} diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/UserPermissions.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/UserPermissions.java deleted file mode 100644 index d741aa4b..00000000 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/UserPermissions.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.openslx.bwlp.sat.permissions; - -import org.openslx.bwlp.thrift.iface.ImagePermissions; -import org.openslx.bwlp.thrift.iface.UserInfo; - -public class UserPermissions { - - private enum Permission { - LINK, - DOWNLOAD, - EDIT, - ADMIN - } - - public static boolean canLinkImage(UserInfo ui, ImagePermissions... imagePermissions) { - return canActionImage(Permission.LINK, imagePermissions) || isSuperUser(ui); - } - - public static boolean canDownloadImage(UserInfo ui, ImagePermissions... imagePermissions) { - return canActionImage(Permission.DOWNLOAD, imagePermissions) || isSuperUser(ui); - } - - public static boolean canEditImage(UserInfo ui, ImagePermissions... imagePermissions) { - return canActionImage(Permission.EDIT, imagePermissions) || isSuperUser(ui); - } - - public static boolean canAdminImage(UserInfo ui, ImagePermissions... imagePermissions) { - return canActionImage(Permission.ADMIN, imagePermissions) || isSuperUser(ui); - } - - private static boolean canActionImage(Permission checkPerm, ImagePermissions... imagePermissions) { - for (ImagePermissions perm : imagePermissions) { - if (perm == null) - continue; - if (checkPerm == Permission.LINK && perm.link) - return true; - if (checkPerm == Permission.DOWNLOAD && perm.download) - return true; - if (checkPerm == Permission.EDIT && perm.edit) - return true; - if (checkPerm == Permission.ADMIN && perm.admin) - return true; - } - return false; - } - - public static boolean isSuperUser(UserInfo ui) { - // TODO: for superuser override - return false; - } - -} 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 cc8bc975..7e743e14 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 @@ -6,10 +6,13 @@ import java.util.List; import java.util.Map; import org.apache.log4j.Logger; -import org.apache.thrift.TException; import org.openslx.bwlp.sat.database.mappers.DbImage; +import org.openslx.bwlp.sat.database.mappers.DbImagePermissions; +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; @@ -38,25 +41,28 @@ import org.openslx.sat.thrift.version.Version; public class ServerHandler implements SatelliteServer.Iface { - private static final Logger log = Logger.getLogger(ServerHandler.class); + private static final Logger LOGGER = Logger.getLogger(ServerHandler.class); private static final FileServer fileServer = FileServer.instance(); @Override - public long getVersion() throws TException { + public long getVersion() { return Version.VERSION; } + /* + * File Transfer + */ + @Override public TransferInformation requestImageVersionUpload(String userToken, String imageBaseId, long fileSize, - List<ByteBuffer> blockHashes) throws TTransferRejectedException, TAuthorizationException, - TException { + List<ByteBuffer> blockHashes) throws TTransferRejectedException, TAuthorizationException { // TODO Auto-generated method stub return null; } @Override - public void cancelUpload(String uploadToken) throws TException { + public void cancelUpload(String uploadToken) { ActiveUpload upload = fileServer.getUploadByToken(uploadToken); if (upload != null) upload.cancel(); @@ -64,52 +70,64 @@ public class ServerHandler implements SatelliteServer.Iface { } @Override - public UploadStatus queryUploadStatus(String uploadToken) throws TInvalidTokenException, TException { + public UploadStatus queryUploadStatus(String uploadToken) throws TInvalidTokenException { // TODO Auto-generated method stub return null; } @Override public TransferInformation requestDownload(String userToken, String imageVersionId) - throws TAuthorizationException, TException { + throws TAuthorizationException { // TODO Auto-generated method stub return null; } @Override - public void cancelDownload(String downloadToken) throws TException { + public void cancelDownload(String downloadToken) { // TODO Auto-generated method stub } + /* + * Authentication/Validation + */ + @Override - public boolean isAuthenticated(String userToken) throws TException { + public boolean isAuthenticated(String userToken) { return SessionManager.get(userToken) != null; } @Override - public void invalidateSession(String userToken) throws TException { + public void invalidateSession(String userToken) { SessionManager.remove(userToken); } + /* + * Query basic information which doesn't require authentication + */ + @Override - public List<OperatingSystem> getOperatingSystems() throws TException { + public List<OperatingSystem> getOperatingSystems() { return OperatingSystemList.get(); } @Override - public List<Virtualizer> getVirtualizers() throws TException { + public List<Virtualizer> getVirtualizers() { return VirtualizerList.get(); } @Override - public List<Organization> getAllOrganizations() throws TException { + public List<Organization> getAllOrganizations() { return OrganizationList.get(); } + /* + * Everything below required at least a valid session + */ + @Override public List<ImageSummaryRead> getImageList(String userToken, List<String> tagSearch) - throws TAuthorizationException, TException { + throws TAuthorizationException, TInternalServerError { UserInfo user = SessionManager.getOrFail(userToken); try { return DbImage.getAllVisible(user, tagSearch); @@ -120,7 +138,7 @@ public class ServerHandler implements SatelliteServer.Iface { @Override public ImageDetailsRead getImageDetails(String userToken, String imageBaseId) - throws TAuthorizationException, TNotFoundException, TException { + throws TAuthorizationException, TNotFoundException, TInternalServerError { UserInfo user = SessionManager.getOrFail(userToken); try { return DbImage.getImageDetails(user, imageBaseId); @@ -130,109 +148,124 @@ public class ServerHandler implements SatelliteServer.Iface { } @Override + public boolean createImage(String userToken, String imageName) throws TAuthorizationException { + UserInfo user = SessionManager.getOrFail(userToken); + User.canCreateImageOrFail(user); + // TODO: Create image + return true; + } + + @Override public boolean updateImageBase(String userToken, String imageBaseId, ImageBaseWrite image) - throws TAuthorizationException, TException { - // TODO Auto-generated method stub + throws TAuthorizationException, TInternalServerError, TNotFoundException { + UserInfo user = SessionManager.getOrFail(userToken); + User.hasImageBasePermissionOrFail(user, imageBaseId, Permission.EDIT); + // TODO: Permissions cleared; Now update image base data return false; } @Override public boolean updateImageVersion(String userToken, String imageVersionId, ImageVersionWrite image) - throws TAuthorizationException, TException { - // TODO Auto-generated method stub + throws TAuthorizationException, TInternalServerError, TNotFoundException { + UserInfo user = SessionManager.getOrFail(userToken); + User.hasImageVersionPermissionOrFail(user, imageVersionId, Permission.EDIT); + // TODO: Permissions cleared; Now update image version data return false; } @Override public boolean deleteImageVersion(String userToken, String imageVersionId) - throws TAuthorizationException, TNotFoundException, TException { - // TODO Auto-generated method stub + throws TAuthorizationException, TNotFoundException, TInternalServerError { + UserInfo user = SessionManager.getOrFail(userToken); + User.hasImageVersionPermissionOrFail(user, imageVersionId, Permission.ADMIN); + // TODO: Permissions cleared; Now mark image for deletion (set expire time in the past...) return false; } @Override - public boolean writeImagePermissions(String userToken, String imageId, + public boolean writeImagePermissions(String userToken, String imageBaseId, Map<String, ImagePermissions> permissions) throws TAuthorizationException, TNotFoundException, - TException { - // TODO Auto-generated method stub + TInternalServerError { + UserInfo user = SessionManager.getOrFail(userToken); + User.hasImageBasePermissionOrFail(user, imageBaseId, Permission.ADMIN); + // TODO: Permissions cleared; Now update image base data return false; } @Override public Map<String, ImagePermissions> getImagePermissions(String userToken, String imageBaseId) - throws TAuthorizationException, TNotFoundException, TException { - // TODO Auto-generated method stub - return null; + throws TAuthorizationException, TNotFoundException, TInternalServerError { + UserInfo user = SessionManager.getOrFail(userToken); + boolean adminOnly = !User.hasImageBasePermission(user, imageBaseId, Permission.ADMIN); + try { + return DbImagePermissions.getForImageBase(imageBaseId, adminOnly); + } catch (SQLException e) { + throw new TInternalServerError(); + } } @Override - public String createLecture(String userToken, LectureWrite lecture) throws TAuthorizationException, - TException { + public String createLecture(String userToken, LectureWrite lecture) throws TAuthorizationException { // TODO Auto-generated method stub return null; } @Override public boolean updateLecture(String userToken, String lectureId, LectureWrite lecture) - throws TAuthorizationException, TNotFoundException, TException { + throws TAuthorizationException, TNotFoundException { // TODO Auto-generated method stub return false; } @Override - public List<LectureSummary> getLectureList(String userToken) throws TAuthorizationException, TException { + public List<LectureSummary> getLectureList(String userToken) throws TAuthorizationException { // TODO Auto-generated method stub return null; } @Override public LectureRead getLectureDetails(String userToken, String lectureId) throws TAuthorizationException, - TNotFoundException, TException { + TNotFoundException { // TODO Auto-generated method stub return null; } @Override public List<LectureSummary> getLecturesByImageVersion(String userToken, String imageVersionId) - throws TAuthorizationException, TNotFoundException, TException { + throws TAuthorizationException, TNotFoundException { // TODO Auto-generated method stub return null; } @Override public boolean deleteLecture(String userToken, String lectureId) throws TAuthorizationException, - TNotFoundException, TException { + TNotFoundException { // TODO Auto-generated method stub return false; } @Override public boolean writeLecturePermissions(String userToken, String lectureId, - Map<String, LecturePermissions> permissions) throws TAuthorizationException, TNotFoundException, - TException { + Map<String, LecturePermissions> permissions) throws TAuthorizationException, TNotFoundException { // TODO Auto-generated method stub return false; } @Override public Map<String, LecturePermissions> getLecturePermissions(String userToken, String lectureId) - throws TAuthorizationException, TNotFoundException, TException { + throws TAuthorizationException, TNotFoundException { // TODO Auto-generated method stub return null; } @Override - public List<UserInfo> getUserList(String userToken, int page) - throws TAuthorizationException, TException { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean createImage(String userToken, String imageName) - throws TAuthorizationException, TException { - // TODO Auto-generated method stub - return false; + public List<UserInfo> getUserList(String userToken, int page) throws TAuthorizationException, + TInternalServerError { + try { + return DbUser.getAll(page); + } catch (SQLException e) { + throw new TInternalServerError(); + } } -}// end class +} |