From ff629d2d809c702f572994456145a80167152073 Mon Sep 17 00:00:00 2001 From: Stephan Schwär Date: Wed, 21 Apr 2021 15:13:07 +0200 Subject: [server] Fix download of images for students ImageDetailsRead object is filled with bogus information or null for variables not needed for downloading when students request to download an image linked to a lecture, as students don't have sufficient permissions to request all that information. Also check "isrestricted" flag server-side and don't supply images to students that have it set. --- .../src/main/properties/i18n/thrift.properties | 4 +- .../openslx/bwlp/sat/database/mappers/DbImage.java | 112 ++++++++++++--------- 2 files changed, 64 insertions(+), 52 deletions(-) diff --git a/dozentenmodul/src/main/properties/i18n/thrift.properties b/dozentenmodul/src/main/properties/i18n/thrift.properties index 9770aef0..0ddcffef 100644 --- a/dozentenmodul/src/main/properties/i18n/thrift.properties +++ b/dozentenmodul/src/main/properties/i18n/thrift.properties @@ -2,8 +2,8 @@ GuiErrorCallback.Message.error.notAuthenticatedOrInvalidToken=Invalid session token or failed \ authentication on {0}!\nPlease restart the program. Exit now? GuiErrorCallback.thriftError.String.errMsg=(Error {0}) -GuiErrorCallback.Message.error.transportException=The communication with {0} is interrupted. \ - Calling the function {1} is failed {2}.\n\n\ +GuiErrorCallback.Message.error.transportException=The communication with {0} was interrupted. \ + Calling the function {1} has failed {2}.\n\n\ Do you want to retry the call? # ImageLocalDetailsActions 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 1d501c7a..5b821881 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 @@ -88,35 +88,23 @@ public class DbImage { public static ImageDetailsRead getImageDetails(UserInfo user, String imageBaseId) throws TNotFoundException, SQLException { try (MysqlConnection connection = Database.getConnection()) { - - // if Student is trying to download only needed information is filled MysqlStatement stmt = null; - if (user.role == Role.STUDENT) - { - stmt = connection.prepareStatement("SELECT i.imagebaseid, i.latestversionid," - + " null, null, null, null, null, null, null, null," - + " null, null," - + " null, null, null, null," - + " null, null, null, null" - + " FROM imagebase i" - + " LEFT JOIN imagepermission perm ON (i.imagebaseid = perm.imagebaseid AND perm.userid = :userid)" - + " WHERE i.imagebaseid = :imagebaseid"); + // Students should only be able to request a download of an image. Therefore not all information is needed for this task. + if (user.role == Role.STUDENT) { + stmt = connection.prepareStatement("SELECT i.imagebaseid, i.latestversionid, i.virtid" + + " FROM imagebase i" + + " LEFT JOIN imagepermission perm ON (i.imagebaseid = perm.imagebaseid AND perm.userid = :userid)" + + " WHERE i.imagebaseid = :imagebaseid"); } else { stmt = connection.prepareStatement("SELECT i.imagebaseid, i.latestversionid," - + " i.displayname, i.description, i.osid, i.virtid, i.createtime, i.updatetime, i.ownerid, i.updaterid," - + " i.sharemode, i.istemplate," - + " i.canlinkdefault, i.candownloaddefault, i.caneditdefault, i.canadmindefault," - + " perm.canlink, perm.candownload, perm.canedit, perm.canadmin" - + " FROM imagebase i" - + " LEFT JOIN imagepermission perm ON (i.imagebaseid = perm.imagebaseid AND perm.userid = :userid)" - + " WHERE i.imagebaseid = :imagebaseid"); + + " i.displayname, i.description, i.osid, i.virtid, i.createtime, i.updatetime, i.ownerid, i.updaterid," + + " i.sharemode, i.istemplate," + + " i.canlinkdefault, i.candownloaddefault, i.caneditdefault, i.canadmindefault," + + " perm.canlink, perm.candownload, perm.canedit, perm.canadmin" + + " FROM imagebase i" + + " LEFT JOIN imagepermission perm ON (i.imagebaseid = perm.imagebaseid AND perm.userid = :userid)" + + " WHERE i.imagebaseid = :imagebaseid"); } - - - - // if Student is trying to download only needed information is filled - - stmt.setString("userid", user == null ? "-" : user.userId); stmt.setString("imagebaseid", imageBaseId); ResultSet rs = stmt.executeQuery(); @@ -125,14 +113,26 @@ public class DbImage { // Exists: List tags = DbSoftwareTag.getImageTags(connection, imageBaseId); List versions = getImageVersions(connection, imageBaseId, user); - ImagePermissions defaultPermissions = DbImagePermissions.fromResultSetDefault(rs); - ImageDetailsRead image = new ImageDetailsRead(rs.getString("imagebaseid"), - rs.getString("latestversionid"), versions, rs.getString("displayname"), - rs.getString("description"), tags, rs.getInt("osid"), rs.getString("virtid"), - rs.getLong("createtime"), rs.getLong("updatetime"), rs.getString("ownerid"), - rs.getString("updaterid"), toShareMode(rs.getString("sharemode")), - rs.getByte("istemplate") != 0, defaultPermissions); - image.setUserPermissions(DbImagePermissions.fromResultSetUser(rs)); + + ImageDetailsRead image; + if (user.role == Role.STUDENT) { + // Students should only have download permissions. + // todo evaluate if this is needed and if there is a nicer way to create ImageDetailsRead object + ImagePermissions defaultPermissions = new ImagePermissions(false, true, false, false); + image = new ImageDetailsRead(rs.getString("imagebaseid"), rs.getString("latestversionid"), + versions, "DownloadedImage", null, tags, 0, rs.getString("virtid"), 0, 0, null, null, + null, false, defaultPermissions); + image.setUserPermissions(defaultPermissions); + } else { + ImagePermissions defaultPermissions = DbImagePermissions.fromResultSetDefault(rs); + image = new ImageDetailsRead(rs.getString("imagebaseid"), rs.getString("latestversionid"), + versions, rs.getString("displayname"), rs.getString("description"), tags, + rs.getInt("osid"), rs.getString("virtid"), rs.getLong("createtime"), + rs.getLong("updatetime"), rs.getString("ownerid"), rs.getString("updaterid"), + toShareMode(rs.getString("sharemode")), rs.getByte("istemplate") != 0, + defaultPermissions); + image.setUserPermissions(DbImagePermissions.fromResultSetUser(rs)); + } User.setCombinedUserPermissions(image, user); return image; } catch (SQLException e) { @@ -275,25 +275,32 @@ public class DbImage { MysqlStatement stmt = null; if (user.role == Role.STUDENT) { stmt = connection.prepareStatement("SELECT" - + " imageversionid, createtime, expiretime, filesize, null," - + " isrestricted, isvalid, isprocessed" + " FROM imageversion" - + " WHERE imagebaseid = :imagebaseid"); + + " imageversionid, createtime, expiretime, filesize," + + " isrestricted, isvalid, isprocessed" + + " FROM imageversion" + + " WHERE imagebaseid = :imagebaseid AND isrestricted = 0"); } else { stmt = connection.prepareStatement("SELECT" - + " imageversionid, createtime, expiretime, filesize, uploaderid," - + " isrestricted, isvalid, isprocessed" + " FROM imageversion" - + " WHERE imagebaseid = :imagebaseid"); - + + " imageversionid, createtime, expiretime, filesize, uploaderid," + + " isrestricted, isvalid, isprocessed" + + " FROM imageversion" + + " WHERE imagebaseid = :imagebaseid"); } stmt.setString("imagebaseid", imageBaseId); ResultSet rs = stmt.executeQuery(); + while (rs.next()) { String imageVersionId = rs.getString("imageversionid"); + String uploaderID = ""; + // Only student doesn't know the uploaderid + if (user.role != Role.STUDENT) { + uploaderID = rs.getString("uploaderid"); + } versionList.add(new ImageVersionDetails(imageVersionId, rs.getLong("createtime"), - rs.getLong("expiretime"), rs.getLong("filesize"), rs.getString("uploaderid"), + rs.getLong("expiretime"), rs.getLong("filesize"), uploaderID, rs.getByte("isrestricted") != 0, rs.getByte("isvalid") != 0, - rs.getByte("isprocessed") != 0, DbSoftwareTag.getImageVersionSoftwareList(connection, - imageVersionId))); + rs.getByte("isprocessed") != 0, + DbSoftwareTag.getImageVersionSoftwareList(connection, imageVersionId))); } stmt.close(); return versionList; @@ -383,7 +390,8 @@ public class DbImage { + " canlinkdefault = :canlink," + " candownloaddefault = :candownload, caneditdefault = :canedit," + (user != null ? " updaterid = :updaterid, updatetime = UNIX_TIMESTAMP()," : "") - + " canadmindefault = :canadmin" + " WHERE imagebaseid = :baseid"); + + " canadmindefault = :canadmin" + + " WHERE imagebaseid = :baseid"); stmt.setString("baseid", imageBaseId); stmt.setString("imagename", image.imageName); stmt.setString("description", image.description); @@ -492,7 +500,8 @@ public class DbImage { throw new TNotFoundException(); // First update version table MysqlStatement stmtVersion = connection.prepareStatement("UPDATE imageversion v SET" - + " v.isrestricted = :isrestricted" + " WHERE v.imageversionid = :versionid"); + + " v.isrestricted = :isrestricted" + + " WHERE v.imageversionid = :versionid"); stmtVersion.setString("versionid", imageVersionId); stmtVersion.setBoolean("isrestricted", image.isRestricted); if (stmtVersion.executeUpdate() != 0) { @@ -528,11 +537,13 @@ public class DbImage { try (MysqlConnection connection = Database.getConnection()) { { // Disable version in question - MysqlStatement checkStmt = connection.prepareStatement("SELECT imageversionid FROM" - + " imageversion WHERE imageversionid = :versionid AND" + MysqlStatement checkStmt = connection.prepareStatement("SELECT imageversionid" + + " FROM imageversion" + + " WHERE imageversionid = :versionid AND" + " (expiretime > UNIX_TIMESTAMP() OR isvalid <> 0)"); - MysqlStatement disableStmt = connection.prepareStatement("UPDATE imageversion SET" - + " expiretime = 1234567890, isvalid = 0" + " WHERE imageversionid = :versionid"); + MysqlStatement disableStmt = connection.prepareStatement("UPDATE imageversion" + + " SET expiretime = 1234567890, isvalid = 0" + + " WHERE imageversionid = :versionid"); affectedList = new ArrayList<>(imageVersionIds.length); for (String imageVersionId : imageVersionIds) { if (imageVersionId == null) @@ -832,7 +843,8 @@ public class DbImage { // Determine manually if anything changed, as executeQuery() always returns 1 for some reason boolean latestVersionChanged = true; do { - MysqlStatement ds = connection.prepareStatement("SELECT latestversionid FROM imagebase WHERE imagebaseid = :imagebaseid"); + MysqlStatement ds = connection.prepareStatement( + "SELECT latestversionid FROM imagebase WHERE imagebaseid = :imagebaseid"); ds.setString("imagebaseid", imageBaseId); ResultSet drs = ds.executeQuery(); if (drs.next()) { -- cgit v1.2.3-55-g7522