summaryrefslogtreecommitdiffstats
path: root/dozentenmodulserver/src
diff options
context:
space:
mode:
authorSimon Rettberg2015-06-23 19:10:48 +0200
committerSimon Rettberg2015-06-23 19:10:48 +0200
commit8ad025dd99468f71d2fa5c49e0bcf359b055ec97 (patch)
tree6208ff7d598116e36b21882e5a018a99d2506103 /dozentenmodulserver/src
parentfix bwLehrpool logo not beeing read from the resources (diff)
downloadtutor-module-8ad025dd99468f71d2fa5c49e0bcf359b055ec97.tar.gz
tutor-module-8ad025dd99468f71d2fa5c49e0bcf359b055ec97.tar.xz
tutor-module-8ad025dd99468f71d2fa5c49e0bcf359b055ec97.zip
[server] More methods implemented
Diffstat (limited to 'dozentenmodulserver/src')
-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/mappers/DbImage.java102
-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.java52
-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.java111
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java78
-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/Util.java18
10 files changed, 506 insertions, 44 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/mappers/DbImage.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java
index 51daed49..4dae8039 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;
@@ -169,6 +172,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.executeQuery();
+ 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 +291,23 @@ public class DbImage {
return ShareMode.valueOf(string);
}
+ 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.executeQuery();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbImage.updateImageVersion()", e);
+ throw e;
+ }
+ }
+
}
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..d7cabe47 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,6 +9,7 @@ import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.Database;
import org.openslx.bwlp.sat.database.MysqlConnection;
import org.openslx.bwlp.sat.database.MysqlStatement;
+import org.openslx.bwlp.sat.database.models.LocalUser;
import org.openslx.bwlp.thrift.iface.UserInfo;
public class DbUser {
@@ -46,4 +47,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..fc3241a9 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,8 +1,13 @@
package org.openslx.bwlp.sat.permissions;
import java.sql.SQLException;
+import java.util.Map;
import org.openslx.bwlp.sat.database.mappers.DbImage;
+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;
@@ -11,17 +16,18 @@ 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 {
+ 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 +41,99 @@ public class User {
if (checkPerm == Permission.ADMIN)
return perm.admin;
}
- return isSuperUser(ui);
+ return false;
+ }
+
+ /**
+ * Cache local user data, might be called quite often.
+ */
+ private static final Map<String, LocalUser> localUserCache = new TimeoutHashMap<>(60000);
+
+ private static LocalUser getLocalUser(UserInfo user) {
+ synchronized (localUserCache) {
+ LocalUser local = localUserCache.get(user.userId);
+ if (local != null)
+ return local;
+ }
+ LocalUser localData;
+ try {
+ localData = DbUser.getLocalData(user);
+ } catch (SQLException e) {
+ return null;
+ }
+ if (localData == null)
+ return null;
+ synchronized (localUserCache) {
+ localUserCache.put(user.userId, localData);
+ }
+ return localData;
}
- public static boolean isSuperUser(UserInfo ui) {
- // TODO: for superuser override, read from DB
+ /**
+ * 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;
+ }
+
+ /**
+ * 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 +146,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);
}
/**
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..d4440793 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,6 +6,7 @@ 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;
@@ -16,7 +17,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 +32,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 +152,62 @@ 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;
}
@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;
+ // TODO: Permissions cleared; Now write image permissions
}
@Override
@@ -205,16 +223,27 @@ public class ServerHandler implements SatelliteServer.Iface {
}
@Override
+ 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 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)
+ public void updateLecture(String userToken, String lectureId, LectureWrite lecture)
throws TAuthorizationException, TNotFoundException {
// TODO Auto-generated method stub
- return false;
}
@Override
@@ -238,17 +267,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 +286,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/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();
+ }
+
}