summaryrefslogtreecommitdiffstats
path: root/dozentenmodulserver/src/main/java
diff options
context:
space:
mode:
authorStephan Schwaer2015-06-26 16:06:16 +0200
committerStephan Schwaer2015-06-26 16:06:16 +0200
commit744238941b639c69d4b727b5b67eb8075ee88263 (patch)
tree788560e8b79371dc807382fe8fc69ccf87a7965c /dozentenmodulserver/src/main/java
parentAdded disclaimer, main window and vmware info windows. Fixed some layout. (diff)
parent[server] Fnished image-related methods so far, started implementing lecture-r... (diff)
downloadtutor-module-744238941b639c69d4b727b5b67eb8075ee88263.tar.gz
tutor-module-744238941b639c69d4b727b5b67eb8075ee88263.tar.xz
tutor-module-744238941b639c69d4b727b5b67eb8075ee88263.zip
Merge branch 'v1.1' of git.openslx.org:openslx-ng/tutor-module into v1.1
Diffstat (limited to 'dozentenmodulserver/src/main/java')
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlStatement.java18
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Paginator.java11
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java134
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImagePermissions.java27
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java137
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecturePermissions.java63
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOrganization.java79
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbUser.java60
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalOrganization.java11
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalUser.java15
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java179
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java111
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java66
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Json.java35
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Util.java18
15 files changed, 908 insertions, 56 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlStatement.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlStatement.java
index 3d5f9065..620ee2e4 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlStatement.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/MysqlStatement.java
@@ -113,7 +113,7 @@ public class MysqlStatement implements Closeable {
* @param value parameter value
* @throws SQLException if an error occurred
* @throws IllegalArgumentException if the parameter does not exist
- * @see PreparedStatement#setInt(int, int)
+ * @see PreparedStatement#setLong(int, long)
*/
public void setLong(String name, long value) throws SQLException {
List<Integer> indexes = getIndexes(name);
@@ -123,6 +123,22 @@ public class MysqlStatement implements Closeable {
}
/**
+ * Sets a parameter.
+ *
+ * @param name parameter name
+ * @param value parameter value
+ * @throws SQLException if an error occurred
+ * @throws IllegalArgumentException if the parameter does not exist
+ * @see PreparedStatement#setBoolean(int, boolean)
+ */
+ public void setBoolean(String name, boolean value) throws SQLException {
+ List<Integer> indexes = getIndexes(name);
+ for (Integer index : indexes) {
+ statement.setBoolean(index, value);
+ }
+ }
+
+ /**
* Executes the statement.
*
* @return true if the first result is a {@link ResultSet}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Paginator.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Paginator.java
new file mode 100644
index 00000000..285d7aa3
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Paginator.java
@@ -0,0 +1,11 @@
+package org.openslx.bwlp.sat.database;
+
+public class Paginator {
+
+ public static final int PER_PAGE = 200;
+
+ public static String limitStatement(int page) {
+ return " LIMIT " + (page * PER_PAGE) + ", " + PER_PAGE;
+ }
+
+}
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 51daed49..1fb19121 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
@@ -4,15 +4,18 @@ 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.thrift.iface.ImageBaseWrite;
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.ImageVersionWrite;
import org.openslx.bwlp.thrift.iface.ShareMode;
import org.openslx.bwlp.thrift.iface.TNotFoundException;
import org.openslx.bwlp.thrift.iface.UserInfo;
@@ -44,6 +47,7 @@ public class DbImage {
*/
public static List<ImageSummaryRead> getAllVisible(UserInfo user, List<String> tagSearch)
throws SQLException {
+ // TODO: Implement tag search functionality
try (MysqlConnection connection = Database.getConnection()) {
MysqlStatement stmt = connection.prepareStatement("SELECT"
+ " i.imagebaseid, i.currentversionid, i.latestversionid, i.displayname,"
@@ -169,6 +173,86 @@ public class DbImage {
}
/**
+ * Create new row in the imagebase table.
+ *
+ * @param user the user the image will belong to
+ * @param imageName name of the image to be created
+ * @return UUID of the newly created image
+ * @throws SQLException
+ */
+ public static String createImage(UserInfo user, String imageName) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("INSERT INTO imagebase"
+ + " (imagebaseid, displayname, createtime, updatetime, ownerid, updaterid, sharemode,"
+ + " istemplate, canlinkdefault, candownloaddefault, caneditdefault, canadmindefault)"
+ + " VALUES"
+ + " (:baseid, :name, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), :userid, :userid, 'LOCAL',"
+ + " 0, 0, 0, 0, 0)");
+ String imageUuid = UUID.randomUUID().toString();
+ stmt.setString("baseid", imageUuid);
+ stmt.setString("name", imageName);
+ stmt.setString("userid", user.userId);
+ stmt.executeUpdate();
+ connection.commit();
+ return imageUuid;
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.createImage()", e);
+ throw e;
+ }
+ }
+
+ public static void updateImageMetadata(UserInfo user, String imageBaseId, ImageBaseWrite image)
+ throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ /*
+ 1: string imageName,
+ 2: string description,
+ 3: i32 osId,
+ 4: bool isTemplate,
+ 5: ImagePermissions defaultPermissions,
+ 6: ShareMode shareMode,
+ 7: optional UUID ownerId,
+ */
+ MysqlStatement stmt = connection.prepareStatement("UPDATE imagebase"
+ + " SET displayname = :imagename, description = :description,"
+ + " osid = :osid, virtid = :virtid, istemplate = :istemplate, canlinkdefault = :canlink,"
+ + " candownloaddefault = :candownload, caneditdefault = :canedit,"
+ + " updaterid = :updaterid, updatetime = UNIX_TIMESTAMP(),"
+ + " canadmindefault = :canadmin" + " WHERE imagebaseid = :baseid");
+ stmt.setString("baseid", imageBaseId);
+ stmt.setString("imagename", image.imageName);
+ stmt.setString("description", image.description);
+ stmt.setInt("osid", image.osId);
+ stmt.setString("virtid", image.virtId);
+ stmt.setBoolean("istemplate", image.isTemplate);
+ stmt.setBoolean("canlink", image.defaultPermissions.link);
+ stmt.setBoolean("candownload", image.defaultPermissions.download);
+ stmt.setBoolean("canedit", image.defaultPermissions.edit);
+ stmt.setBoolean("canadmin", image.defaultPermissions.admin);
+ stmt.setString("updaterid", user.userId);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.updateImageMetadata()", e);
+ throw e;
+ }
+ }
+
+ public static void setImageOwner(String imageBaseId, String newOwnerId) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("UPDATE imagebase"
+ + " SET ownerid = :ownerid WHERE imagebaseid = :baseid");
+ stmt.setString("ownerid", newOwnerId);
+ stmt.setString("baseid", imageBaseId);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.setImageOwner()", 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.
*
@@ -208,4 +292,54 @@ public class DbImage {
return ShareMode.valueOf(string);
}
+ /**
+ * Update meta data of a specific image version.
+ *
+ * @param user user doing the edit
+ * @param imageVersionId UUID of image version
+ * @param image meta data to set
+ * @throws SQLException
+ */
+ public static void updateImageVersion(UserInfo user, String imageVersionId, ImageVersionWrite image)
+ throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("UPDATE imageversion v, imagebase b SET"
+ + " v.isenabled = :isenabled, v.isrestricted = :isrestricted,"
+ + " b.updaterid = :userid, b.updatetime = UNIX_TIMESTAMP()"
+ + " WHERE v.imageversionid = :versionid AND v.imagebaseid = b.imagebaseid");
+ stmt.setString("versionid", imageVersionId);
+ stmt.setString("userid", user.userId);
+ stmt.setBoolean("isenabled", image.isEnabled);
+ stmt.setBoolean("isrestricted", image.isRestricted);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.updateImageVersion()", e);
+ throw e;
+ }
+ }
+
+ /**
+ * Mark given image for deletion. The image is marked for deletion by
+ * setting the expire timestamp to the current date, and by setting the
+ * image disabled and invalid. Next time the cleanup task runs, the image
+ * will be deleted.
+ *
+ * @param imageVersionId UUID of image version to delete
+ * @throws SQLException
+ */
+ public static void markForDeletion(String imageVersionId) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("UPDATE imageversion SET"
+ + " expiretime = UNIX_TIMESTAMP() - 1, isenabled = 0, isvalid = 0"
+ + " WHERE imageversionid = :versionid");
+ stmt.setString("versionid", imageVersionId);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.markForDeletion()", e);
+ throw e;
+ }
+ }
+
}
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 9f089b42..7f8bf33f 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
@@ -101,4 +101,31 @@ public class DbImagePermissions {
}
}
+ public static void writeForImageBase(String imageBaseId, Map<String, ImagePermissions> permissions)
+ throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("DELETE FROM imagepermission"
+ + " WHERE imagebaseid = :baseid");
+ stmt.setString("imagebaseid", imageBaseId);
+ stmt.executeUpdate();
+ stmt = connection.prepareStatement("INSERT INTO imagepermission"
+ + " (imagebaseid, userid, canlink, candownload, canedit, canadmin)"
+ + " VALUES (:baseid, :userid, :canlink, :candownload, :canedit, :canadmin)");
+ stmt.setString("baseid", imageBaseId);
+ for (Map.Entry<String, ImagePermissions> entry : permissions.entrySet()) {
+ ImagePermissions perm = entry.getValue();
+ stmt.setString("userid", entry.getKey());
+ stmt.setBoolean("canlink", perm.link);
+ stmt.setBoolean("candownload", perm.download);
+ stmt.setBoolean("canedit", perm.edit);
+ stmt.setBoolean("canadmin", perm.admin);
+ stmt.executeUpdate();
+ }
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImagePermissions.writeForImageBase()", 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
new file mode 100644
index 00000000..7f2fa4c5
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java
@@ -0,0 +1,137 @@
+package org.openslx.bwlp.sat.database.mappers;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+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.util.Json;
+import org.openslx.bwlp.thrift.iface.LecturePermissions;
+import org.openslx.bwlp.thrift.iface.LectureSummary;
+import org.openslx.bwlp.thrift.iface.LectureWrite;
+import org.openslx.bwlp.thrift.iface.TNotFoundException;
+import org.openslx.bwlp.thrift.iface.UserInfo;
+
+public class DbLecture {
+
+ private static final Logger LOGGER = Logger.getLogger(DbLecture.class);
+
+ public static String create(UserInfo user, LectureWrite lecture) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("INSERT INTO lecture"
+ + " (lectureid, displayname, description, imageversionid, autoupdate,"
+ + " isenabled, starttime, endtime, createtime, updatetime,"
+ + " ownerid, updaterid, runscript, nics, netrules, isexam,"
+ + " hasinternetaccess, caneditdefault, canadmindefault)"
+ + " VALUES "
+ + " (:lectureid, '<defunct>', '<defunct>', :imageversionid, 0,"
+ + " 0, 0, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),"
+ + " :userid, :userid, NULL, NULL, NULL, 0, 0, 0, 0)");
+ String lectureId = UUID.randomUUID().toString();
+ stmt.setString("lectureid", lectureId);
+ stmt.setString("imageversionid", lecture.imageVersionId);
+ stmt.setString("userid", user.userId);
+ stmt.executeUpdate();
+ update(connection, user, lectureId, lecture);
+ connection.commit();
+ return lectureId;
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbLecture.create()", e);
+ throw e;
+ }
+ }
+
+ public static void setOwner(UserInfo user, String lectureId, String newOwnerId) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("UPDATE lecture"
+ + " SET ownerid = :ownerid, updaterid = :userid, updatetime = UNIX_TIMESTAMP()"
+ + " WHERE lectureid = :lectureid");
+ stmt.setString("ownerid", newOwnerId);
+ stmt.setString("userid", user.userId);
+ stmt.setString("lectureid", lectureId);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbLecture.setOwner()", e);
+ throw e;
+ }
+ }
+
+ public static void update(UserInfo user, String lectureId, LectureWrite lecture) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ update(connection, user, lectureId, lecture);
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbLecture.update()", e);
+ throw e;
+ }
+ }
+
+ private static void update(MysqlConnection connection, UserInfo user, String lectureId,
+ LectureWrite lecture) throws SQLException {
+ String nicsJson = Json.serialize(lecture.nics);
+ String netruleJson = Json.serialize(lecture.networkExceptions);
+ MysqlStatement stmt = connection.prepareStatement("UPDATE lecture SET "
+ + " displayname = :displayname, description = :description, imageversionid = :imageversionid,"
+ + " autoupdate = :autoupdate, isenabled = :isenabled, starttime = :starttime,"
+ + " endtime = :endtime, createtime = :createtime, updatetime = :updatetime,"
+ + " updaterid = :updaterid, runscript = :runscript, nics = :nics,"
+ + " netrules = :netrules, isexam = :isexam, hasinternetaccess = :hasinternetaccess,"
+ + " caneditdefault = :caneditdefault, canadmindefault = :canadmindefault"
+ + " WHERE lectureid = :lectureid");
+ stmt.setString("lectureid", lectureId);
+ stmt.setString("displayname", lecture.lectureName);
+ stmt.setString("description", lecture.description);
+ stmt.setString("imageversionid", lecture.imageVersionId);
+ stmt.setBoolean("autoupdate", lecture.autoUpdate);
+ stmt.setBoolean("isenabled", lecture.isEnabled);
+ stmt.setLong("starttime", lecture.startTime);
+ stmt.setLong("endtime", lecture.endTime);
+ stmt.setString("updaterid", user.userId);
+ stmt.setString("runscript", lecture.runscript);
+ stmt.setString("nics", nicsJson);
+ stmt.setString("netrules", netruleJson);
+ stmt.setBoolean("isexam", lecture.isExam);
+ stmt.setBoolean("hasinternetaccess", lecture.hasInternetAccess);
+ stmt.setBoolean("caneditdefault", lecture.defaultPermissions.edit);
+ stmt.setBoolean("canadmindefault", lecture.defaultPermissions.admin);
+ stmt.executeUpdate();
+ }
+
+ public static LectureSummary getLectureSummary(UserInfo user, String lectureId) throws SQLException,
+ TNotFoundException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT"
+ + " l.lectureid, l.displayname AS lecturename, l.imageversionid, l.isenabled,"
+ + " l.starttime, l.endtime, l.lastused, l.usecount, l.ownerid, l.updaterid,"
+ + " l.isexam, l.hasinternetaccess, l.caneditdefault, l.canadmindefault,"
+ + " perm.canedit, perm.canadmin"
+ + " LEFT JOIN lecturepermission perm ON (perm.lectureid = l.lectureid AND perm.userid = :userid)"
+ + " WHERE lectureid = :lectureid");
+ stmt.setString("lectureid", lectureId);
+ stmt.setString("userid", user.userId);
+ ResultSet rs = stmt.executeQuery();
+ if (!rs.next())
+ throw new TNotFoundException();
+ return resultSetToSummary(rs);
+ } 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;
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecturePermissions.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecturePermissions.java
new file mode 100644
index 00000000..e8bd8a07
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecturePermissions.java
@@ -0,0 +1,63 @@
+package org.openslx.bwlp.sat.database.mappers;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.openslx.bwlp.thrift.iface.LecturePermissions;
+
+public class DbLecturePermissions {
+
+ /**
+ * Build an instance of {@link LecturePermissions} by reading the given
+ * columns from the given {@link ResultSet}. If there are no permissions
+ * given in the ResultSet, <code>null</code> is returned.
+ *
+ * @param rs the {@link ResultSet} to read from
+ * @param canLink Name of the column to read the "can link" permission from
+ * @param canDownload Name of the column to read the "can download"
+ * permission from
+ * @param canEdit Name of the column to read the "can edit" permission from
+ * @param canAdmin Name of the column to read the "can admin" permission
+ * from
+ * @return instance of {@link LecturePermissions}, or <code>null</code>
+ * @throws SQLException
+ */
+ private static LecturePermissions fromResultSet(ResultSet rs, String canEdit, String canAdmin)
+ throws SQLException {
+ boolean edit = rs.getBoolean(canEdit);
+ if (rs.wasNull())
+ return null;
+ return new LecturePermissions(edit, rs.getBoolean(canAdmin));
+ }
+
+ /**
+ * Build an instance of {@link LecturePermissions} by reading the
+ * columns <code>canlink</code>, <code>candownload</code>,
+ * <code>canedit</code>, <code>canadmin</code> from the given
+ * {@link ResultSet}. If there are no permissions
+ * given in the ResultSet, <code>null</code> is returned.
+ *
+ * @param rs the {@link ResultSet} to read from
+ * @return instance of {@link LecturePermissions}, or <code>null</code>
+ * @throws SQLException
+ */
+ public static LecturePermissions fromResultSetUser(ResultSet rs) throws SQLException {
+ return fromResultSet(rs, "canedit", "canadmin");
+ }
+
+ /**
+ * Build an instance of {@link LecturePermissions} by reading the
+ * columns <code>canlinkdefault</code>, <code>candownloaddefault</code>,
+ * <code>caneditdefault</code>, <code>canadmindefault</code> from the given
+ * {@link ResultSet}. If there are no permissions
+ * given in the ResultSet, <code>null</code> is returned.
+ *
+ * @param rs the {@link ResultSet} to read from
+ * @return instance of {@link LecturePermissions}, or <code>null</code>
+ * @throws SQLException
+ */
+ public static LecturePermissions fromResultSetDefault(ResultSet rs) throws SQLException {
+ return fromResultSet(rs, "caneditdefault", "canadmindefault");
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOrganization.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOrganization.java
index cc401af9..8c0cf79a 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOrganization.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOrganization.java
@@ -1,18 +1,29 @@
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.sat.database.models.LocalOrganization;
import org.openslx.bwlp.thrift.iface.Organization;
public class DbOrganization {
private static final Logger LOGGER = Logger.getLogger(DbOrganization.class);
+ /**
+ * Store the given list of organizations (coming from the master server) to
+ * the database, or update the meta data of the organizations, if already
+ * existent.
+ *
+ * @param organizations
+ * @return
+ */
public static boolean storeOrganizations(List<Organization> organizations) {
try (MysqlConnection connection = Database.getConnection()) {
MysqlStatement stmt = connection.prepareStatement("INSERT INTO organization"
@@ -31,4 +42,72 @@ public class DbOrganization {
}
}
+ /**
+ * Get local-only data for the given organization. Local-only data is not
+ * supplied by the master server and might differ between satellites.
+ *
+ * @param organizationId
+ * @return
+ * @throws SQLException
+ */
+ public static LocalOrganization getLocalData(String organizationId) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT canlogin FROM organization"
+ + " WHERE organizationid = :organizationid");
+ stmt.setString("organizationid", organizationId);
+ ResultSet rs = stmt.executeQuery();
+ if (!rs.next())
+ return null;
+ return new LocalOrganization(rs.getBoolean("canlogin"));
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbOrganization.getLocalData()", e);
+ throw e;
+ }
+ }
+
+ /**
+ * Get list of organizations where users are allowed to login to the local
+ * satellite.
+ *
+ * @return
+ * @throws SQLException
+ */
+ public static List<Organization> getLoginAllowedOrganizations() throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT organizationid, displayname"
+ + " FROM organization WHERE canlogin = 1");
+ ResultSet rs = stmt.executeQuery();
+ List<Organization> list = new ArrayList<>();
+ while (rs.next()) {
+ list.add(new Organization(rs.getString("organizationid"), rs.getString("displayname"), null,
+ null));
+ }
+ return list;
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbOrganization.getLoginAllowedOrganizations()", e);
+ throw e;
+ }
+ }
+
+ /**
+ * Change the "canlogin" flag of the given organization.
+ *
+ * @param organizationId
+ * @param canlogin
+ * @throws SQLException
+ */
+ public static void setCanLogin(String organizationId, boolean canlogin) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("UPDATE organization"
+ + " SET canlogin = :canlogin WHERE organizationid = :organizationid");
+ stmt.setString("organizationid", organizationId);
+ stmt.setBoolean("canlogin", canlogin);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbOrganization.setCanLogin()", 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
index 6106fab5..451b3217 100644
--- 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
@@ -9,17 +9,17 @@ 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.sat.database.models.LocalUser;
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
+ * This function will return a maximum of {@link #PER_PAGE} results, so
* you might need to call this method several times.
*
* @param page Page to return. The first page is page 0.
@@ -29,10 +29,9 @@ public class DbUser {
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);
+ + " FROM user ORDER BY userid ASC " + Paginator.limitStatement(page));
ResultSet rs = stmt.executeQuery();
List<UserInfo> list = new ArrayList<>();
while (rs.next()) {
@@ -46,4 +45,55 @@ public class DbUser {
}
}
+ /**
+ * Get local-only information for given user.
+ *
+ * @param user {@link UserInfo} instance representing the user
+ * @return {@link LocalUser} instance matching the given user, or null if
+ * not found
+ * @throws SQLException
+ */
+ public static LocalUser getLocalData(UserInfo user) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT lastlogin, canlogin, issuperuser"
+ + " FROM user WHERE userid = :userid LIMIT 1");
+ stmt.setString("userid", user.userId);
+ ResultSet rs = stmt.executeQuery();
+ if (!rs.next())
+ return null;
+ return new LocalUser(rs.getLong("lastlogin"), rs.getBoolean("canlogin"),
+ rs.getBoolean("issuperuser"));
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbUser.getLocalData()", e);
+ throw e;
+ }
+ }
+
+ /**
+ * Insert given user into db (if not already existent), otherwise just
+ * update the "lastlogin" field.
+ *
+ * @param ui {@link UserInfo}
+ * @throws SQLException
+ */
+ public static void writeUserOnLogin(UserInfo ui) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("INSERT INTO user"
+ + " (userid, firstname, lastname, email, organizationid, lastlogin, canlogin, issuperuser)"
+ + " VALUES"
+ + " (:userid, :firstname, :lastname, :email, :organizationid, UNIX_TIMESTAMP(), 1, 0)"
+ + " ON DUPLICATE KEY UPDATE lastlogin = UNIX_TIMESTAMP()");
+ stmt.setString("userid", ui.userId);
+ stmt.setString("firstname", ui.firstName);
+ stmt.setString("lastname", ui.lastName);
+ stmt.setString("email", ui.eMail);
+ stmt.setString("organizationid", ui.organizationId);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbUser.writeUserOnLogin()", e);
+ throw e;
+ }
+ }
+
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalOrganization.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalOrganization.java
new file mode 100644
index 00000000..36165fad
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalOrganization.java
@@ -0,0 +1,11 @@
+package org.openslx.bwlp.sat.database.models;
+
+public class LocalOrganization {
+
+ public final boolean canLogin;
+
+ public LocalOrganization(boolean canLogin) {
+ this.canLogin = canLogin;
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalUser.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalUser.java
new file mode 100644
index 00000000..e0040a96
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/models/LocalUser.java
@@ -0,0 +1,15 @@
+package org.openslx.bwlp.sat.database.models;
+
+public class LocalUser {
+
+ public final long lastLogin;
+ public final boolean canLogin;
+ public final boolean isSuperUser;
+
+ public LocalUser(long lastLogin, boolean canLogin, boolean isSuperUser) {
+ this.lastLogin = lastLogin;
+ this.canLogin = canLogin;
+ this.isSuperUser = isSuperUser;
+ }
+
+}
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 51041df9..2ffd281a 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,27 +1,39 @@
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.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 {
- public enum Permission {
+ private static final Logger LOGGER = Logger.getLogger(User.class);
+
+ public static enum Permission {
LINK,
DOWNLOAD,
EDIT,
ADMIN
}
- private static boolean canActionImage(UserInfo ui, Permission checkPerm,
+ private static boolean canActionImage(UserInfo user, Permission checkPerm,
ImagePermissions... imagePermissions) {
for (ImagePermissions perm : imagePermissions) {
if (perm == null)
@@ -35,14 +47,117 @@ public class User {
if (checkPerm == Permission.ADMIN)
return perm.admin;
}
- return isSuperUser(ui);
+ 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;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Check if given user is a local super user.
+ *
+ * @param user
+ * @return
+ */
+ public static boolean isSuperUser(UserInfo user) {
+ LocalUser localData = getLocalUser(user);
+ return localData != null && localData.isSuperUser;
}
- public static boolean isSuperUser(UserInfo ui) {
- // TODO: for superuser override, read from DB
+ /**
+ * Check if given user is allowed to login to this satellite.
+ *
+ * @param user user to check login permission for
+ * @return true if user is allowed to login to this satellite
+ */
+ public static boolean canLogin(UserInfo user) {
+ LocalUser localData = getLocalUser(user);
+ if (localData != null)
+ return localData.canLogin; // User locally known, use user-specific permission
+ LocalOrganization local = getLocalOrganization(user.organizationId);
+ // User unknown, check per-organization login permission
+ if (local == null)
+ return false;
+ if (local.canLogin)
+ return true;
+ // Special case: If user is not allowed to login, check if there are no allowed
+ // organizations yet. If so, automatically allow the organization of this user.
+ try {
+ if (DbOrganization.getLoginAllowedOrganizations().isEmpty()) {
+ DbOrganization.setCanLogin(user.organizationId, true);
+ return true;
+ }
+ } catch (SQLException e) {
+ // Ignore
+ }
return false;
}
-
+
/**
* Check if the given user has the given permission for the image identified
* by the given image base id.
@@ -55,15 +170,21 @@ public class User {
*/
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);
+ return canActionImage(user, permission, localImage.userPermissions, localImage.defaultPermissions)
+ || isSuperUser(user);
}
/**
@@ -121,11 +242,37 @@ public class User {
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: "
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, "Required image permission: "
+ permission.toString());
}
}
+ 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);
+ }
+
+ 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 is allowed to create new images.
*
@@ -142,4 +289,20 @@ public class User {
"No permission to create new image");
}
+ /**
+ * 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 canCreateLectureOrFail(UserInfo user) throws TAuthorizationException {
+ if (!canCreateLecture(user))
+ throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
+ "No permission to create new lecture");
+ }
+
}
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 7e743e14..cab355a7 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,8 +6,10 @@ 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.DbLecture;
import org.openslx.bwlp.sat.database.mappers.DbUser;
import org.openslx.bwlp.sat.fileserv.ActiveUpload;
import org.openslx.bwlp.sat.fileserv.FileServer;
@@ -16,7 +18,9 @@ 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.ImageBaseWrite;
+import org.openslx.bwlp.thrift.iface.ImageDataError;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImagePermissions;
import org.openslx.bwlp.thrift.iface.ImageSummaryRead;
@@ -29,6 +33,7 @@ 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.TAuthorizationException;
+import org.openslx.bwlp.thrift.iface.TImageDataException;
import org.openslx.bwlp.thrift.iface.TInternalServerError;
import org.openslx.bwlp.thrift.iface.TInvalidTokenException;
import org.openslx.bwlp.thrift.iface.TNotFoundException;
@@ -148,48 +153,70 @@ public class ServerHandler implements SatelliteServer.Iface {
}
@Override
- public boolean createImage(String userToken, String imageName) throws TAuthorizationException {
+ public String createImage(String userToken, String imageName) throws TAuthorizationException,
+ TImageDataException, TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
User.canCreateImageOrFail(user);
- // TODO: Create image
- return true;
+ if (!Util.isPrintable(imageName) || Util.isEmptyString(imageName))
+ throw new TImageDataException(ImageDataError.INVALID_DATA, "Invalid or empty name");
+ try {
+ return DbImage.createImage(user, imageName);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
- public boolean updateImageBase(String userToken, String imageBaseId, ImageBaseWrite image)
- throws TAuthorizationException, TInternalServerError, TNotFoundException {
+ public void updateImageBase(String userToken, String imageBaseId, ImageBaseWrite image)
+ throws TAuthorizationException, TInternalServerError, TNotFoundException, TImageDataException {
UserInfo user = SessionManager.getOrFail(userToken);
User.hasImageBasePermissionOrFail(user, imageBaseId, Permission.EDIT);
- // TODO: Permissions cleared; Now update image base data
- return false;
+ if (!Util.isPrintable(image.imageName) || Util.isEmptyString(image.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.
+ try {
+ DbImage.updateImageMetadata(user, imageBaseId, image);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
- public boolean updateImageVersion(String userToken, String imageVersionId, ImageVersionWrite image)
+ public void updateImageVersion(String userToken, String imageVersionId, ImageVersionWrite image)
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;
+ try {
+ DbImage.updateImageVersion(user, imageVersionId, image);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
- public boolean deleteImageVersion(String userToken, String imageVersionId)
- throws TAuthorizationException, TNotFoundException, TInternalServerError {
+ public void deleteImageVersion(String userToken, String imageVersionId) 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;
+ try {
+ DbImage.markForDeletion(imageVersionId);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
- public boolean writeImagePermissions(String userToken, String imageBaseId,
+ public void writeImagePermissions(String userToken, String imageBaseId,
Map<String, ImagePermissions> permissions) throws TAuthorizationException, TNotFoundException,
TInternalServerError {
UserInfo user = SessionManager.getOrFail(userToken);
User.hasImageBasePermissionOrFail(user, imageBaseId, Permission.ADMIN);
- // TODO: Permissions cleared; Now update image base data
- return false;
+ try {
+ DbImagePermissions.writeForImageBase(imageBaseId, permissions);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
@@ -205,16 +232,39 @@ public class ServerHandler implements SatelliteServer.Iface {
}
@Override
- public String createLecture(String userToken, LectureWrite lecture) throws TAuthorizationException {
- // TODO Auto-generated method stub
- return null;
+ 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);
+ try {
+ DbImage.setImageOwner(imageBaseId, newOwnerId);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
- public boolean updateLecture(String userToken, String lectureId, LectureWrite lecture)
- throws TAuthorizationException, TNotFoundException {
- // TODO Auto-generated method stub
- return false;
+ public String createLecture(String userToken, LectureWrite lecture) throws TAuthorizationException,
+ TInternalServerError {
+ UserInfo user = SessionManager.getOrFail(userToken);
+ User.canCreateLectureOrFail(user);
+ try {
+ return DbLecture.create(user, lecture);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
+ }
+
+ @Override
+ public void updateLecture(String userToken, String lectureId, LectureWrite lecture)
+ throws TAuthorizationException, TNotFoundException, TInternalServerError {
+ UserInfo user = SessionManager.getOrFail(userToken);
+ User.hasLecturePermissionOrFail(user, lectureId, Permission.EDIT);
+ try {
+ DbLecture.update(user, lectureId, lecture);
+ } catch (SQLException e) {
+ throw new TInternalServerError();
+ }
}
@Override
@@ -238,17 +288,15 @@ public class ServerHandler implements SatelliteServer.Iface {
}
@Override
- public boolean deleteLecture(String userToken, String lectureId) throws TAuthorizationException,
+ public void deleteLecture(String userToken, String lectureId) throws TAuthorizationException,
TNotFoundException {
// TODO Auto-generated method stub
- return false;
}
@Override
- public boolean writeLecturePermissions(String userToken, String lectureId,
+ public void writeLecturePermissions(String userToken, String lectureId,
Map<String, LecturePermissions> permissions) throws TAuthorizationException, TNotFoundException {
// TODO Auto-generated method stub
- return false;
}
@Override
@@ -259,6 +307,13 @@ public class ServerHandler implements SatelliteServer.Iface {
}
@Override
+ public void setLectureOwner(String userToken, String lectureId, String newOwnerId)
+ throws TAuthorizationException, TNotFoundException, TInternalServerError, TException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
public List<UserInfo> getUserList(String userToken, int page) throws TAuthorizationException,
TInternalServerError {
try {
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 bf444a20..3fdadfb1 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
@@ -1,12 +1,19 @@
package org.openslx.bwlp.sat.thrift;
+import java.sql.SQLException;
+import java.util.Iterator;
import java.util.Map;
+import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
+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.TAuthorizationException;
+import org.openslx.bwlp.thrift.iface.TInvalidTokenException;
import org.openslx.bwlp.thrift.iface.UserInfo;
import org.openslx.thrifthelper.ThriftManager;
@@ -31,10 +38,29 @@ public class SessionManager {
public void touch(long now) {
this.validUntil = now + SESSION_TIMEOUT;
}
+
+ public boolean isTooOld(long now) {
+ return validUntil < now;
+ }
}
// saves the current tokens and the mapped userdata, returning from the server
- private static Map<String, Entry> tokenManager = new ConcurrentHashMap<>();
+ private static final Map<String, Entry> tokenManager = new ConcurrentHashMap<>();
+
+ static {
+ // Clean cached session periodically
+ QuickTimer.scheduleAtFixedDelay(new TimerTask() {
+ @Override
+ public void run() {
+ final long now = System.currentTimeMillis();
+ for (Iterator<Entry> it = tokenManager.values().iterator(); it.hasNext();) {
+ Entry e = it.next();
+ if (e == null || e.isTooOld(now))
+ it.remove();
+ }
+ }
+ }, 60000, 1200600);
+ }
/**
* Get the user corresponding to the given token.
@@ -61,17 +87,16 @@ public class SessionManager {
*/
public static UserInfo get(String token) {
Entry e = tokenManager.get(token);
- if (e != null) {
- // User session already cached
- final long now = System.currentTimeMillis();
- if (e.validUntil < now) {
- tokenManager.remove(token);
- return getRemote(token);
- }
- e.touch(now);
- return e.user;
+ if (e == null)
+ return getRemote(token);
+ // User session already cached
+ final long now = System.currentTimeMillis();
+ if (e.isTooOld(now)) {
+ tokenManager.remove(token);
+ return getRemote(token);
}
- return getRemote(token);
+ e.touch(now);
+ return e.user;
}
/**
@@ -83,19 +108,32 @@ public class SessionManager {
tokenManager.remove(token);
}
+ /**
+ * Get {@link UserInfo} from master server.
+ *
+ * @param token token of user to get
+ * @return
+ */
private static UserInfo getRemote(String token) {
UserInfo ui = null;
try {
ui = ThriftManager.getMasterClient().getUserFromToken(token);
+ } catch (TInvalidTokenException ite) {
+ return null; // Token not known to master server
} catch (Exception e) {
LOGGER.warn("Could not reach master server to query for user token of a client!", e);
}
- if (ui == null)
+ // 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;
+ }
tokenManager.put(token, new Entry(ui));
return ui;
}
- // TODO: Clean map of old entries periodically
-
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Json.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Json.java
new file mode 100644
index 00000000..fe43793a
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Json.java
@@ -0,0 +1,35 @@
+package org.openslx.bwlp.sat.util;
+
+import com.google.gson.Gson;
+
+public class Json {
+
+ /**
+ * Global static instance. The Gson object is thread-safe.
+ */
+ private static final Gson gson = new Gson();
+
+ /**
+ * Deserialize the given json string to an instance of T.
+ * This will deserialize all fields, except transient ones.
+ *
+ * @param data JSON formatted data
+ * @param classOfData class to instantiate
+ * @return instanceof T
+ */
+ public static <T> T deserialize(String data, Class<T> classOfData) {
+ return gson.fromJson(data, classOfData);
+ }
+
+ /**
+ * Serialize the given POJO. All fields except transient ones will be
+ * serialized.
+ *
+ * @param object some object to serialize
+ * @return JSON formatted represenatation of <code>object</code>
+ */
+ public static String serialize(Object object) {
+ return gson.toJson(object);
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Util.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Util.java
index 338ed325..7e3c825a 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Util.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/util/Util.java
@@ -1,6 +1,7 @@
package org.openslx.bwlp.sat.util;
import java.io.Closeable;
+import java.util.regex.Pattern;
public class Util {
@@ -42,4 +43,21 @@ public class Util {
}
}
+ private static Pattern stringChecker = Pattern.compile("[\\p{C}\\p{Zl}\\p{Zp}]");
+ private static Pattern nonSpaceMatcher = Pattern.compile("[^\\p{C}\\p{Z}]");
+
+ /**
+ * Whether the given string contains only printable characters.
+ *
+ * @param string {@link String} to check
+ * @return
+ */
+ public static boolean isPrintable(String string) {
+ return !stringChecker.matcher(string).find();
+ }
+
+ public static boolean isEmptyString(String string) {
+ return !nonSpaceMatcher.matcher(string).find();
+ }
+
}