summaryrefslogtreecommitdiffstats
path: root/dozentenmodulserver
diff options
context:
space:
mode:
authorSimon Rettberg2015-07-15 17:33:19 +0200
committerSimon Rettberg2015-07-15 17:33:19 +0200
commit2987d0992a0609a3c9eb23048d87df630225b978 (patch)
tree4f9a778563b2da0316bc3e637d2dd31ee5280b70 /dozentenmodulserver
parent[cilent] check if vmdk parsed from vmx is relative or absolute and do proper ... (diff)
downloadtutor-module-2987d0992a0609a3c9eb23048d87df630225b978.tar.gz
tutor-module-2987d0992a0609a3c9eb23048d87df630225b978.tar.xz
tutor-module-2987d0992a0609a3c9eb23048d87df630225b978.zip
Adapt to changed thrift api for improved session validation
Diffstat (limited to 'dozentenmodulserver')
-rw-r--r--dozentenmodulserver/setup/sat-01-schema.sql2
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java1
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbImage.java10
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOsVirt.java61
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java19
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java4
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/ServerHandler.java4
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java77
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/cache/VirtualizerList.java30
9 files changed, 177 insertions, 31 deletions
diff --git a/dozentenmodulserver/setup/sat-01-schema.sql b/dozentenmodulserver/setup/sat-01-schema.sql
index e07156f8..bb4a4e5c 100644
--- a/dozentenmodulserver/setup/sat-01-schema.sql
+++ b/dozentenmodulserver/setup/sat-01-schema.sql
@@ -114,7 +114,7 @@ CREATE TABLE IF NOT EXISTS `imageversion` (
`isvalid` tinyint(1) NOT NULL,
`isprocessed` tinyint(1) NOT NULL,
`mastersha1` binary(20) DEFAULT NULL,
- `virtualizerconfig` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin COMMENT 'Specific configuration of the virtualizer for this image. For vmware, this is basically a dump of the *.vmx.',
+ `virtualizerconfig` text BINARY NULL DEFAULT NULL COMMENT 'Specific configuration of the virtualizer for this image. For vmware, this is basically a dump of the *.vmx.',
PRIMARY KEY (`imageversionid`),
KEY `version_access` (`imagebaseid`,`isenabled`,`isvalid`,`createtime`),
KEY `fk_imageversion_2_idx` (`uploaderid`),
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
index 992d5562..570cf1fa 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
@@ -55,6 +55,7 @@ public class App {
ThriftManager.setMasterServerAddress("bwlp-masterserver.ruf.uni-freiburg.de");
// Load useful things from master server
+ //LOGGER.info(ThriftManager.getMasterClient().getUserFromToken("9ECAC1AFC02FF295292362BD165847AE"));
OrganizationList.get();
OperatingSystemList.get();
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 fc78a5aa..3f392048 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
@@ -70,10 +70,10 @@ public class DbImage {
public static ImageDetailsRead getImageDetails(UserInfo user, String imageBaseId)
throws TNotFoundException, SQLException {
try (MysqlConnection connection = Database.getConnection()) {
- MysqlStatement stmt = connection.prepareStatement("SELECT imagebaseid, currentversionid, latestversionid,"
- + " displayname, description, osid, virtid, createtime, updatetime, ownerid, updaterid,"
- + " sharemode, istemplate,"
- + " canlinkdefault, candownloaddefault, caneditdefault, canadmindefault,"
+ MysqlStatement stmt = connection.prepareStatement("SELECT i.imagebaseid, i.currentversionid, 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)"
@@ -95,7 +95,7 @@ public class DbImage {
toShareMode(rs.getString("sharemode")), rs.getByte("istemplate") != 0, defaultPermissions);
return image;
} catch (SQLException e) {
- LOGGER.error("Query failed in DbImage.getImage()", e);
+ LOGGER.error("Query failed in DbImage.getImageDetails()", e);
throw e;
}
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOsVirt.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOsVirt.java
index e092e944..f49c9065 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOsVirt.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbOsVirt.java
@@ -3,13 +3,16 @@ package org.openslx.bwlp.sat.database.mappers;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.Database;
import org.openslx.bwlp.sat.database.MysqlConnection;
import org.openslx.bwlp.sat.database.MysqlStatement;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
+import org.openslx.bwlp.thrift.iface.Virtualizer;
public class DbOsVirt {
@@ -29,20 +32,22 @@ public class DbOsVirt {
}
connection.commit();
} catch (SQLException e) {
- LOGGER.error("Query failed in DbOsVirt.writeOsList()", e);
+ LOGGER.error("Query failed in DbOsVirt.storeOsList()", e);
throw e;
}
}
public static List<OperatingSystem> getOsList() throws SQLException {
try (MysqlConnection connection = Database.getConnection()) {
+ // Query OSs
MysqlStatement stmt = connection.prepareStatement("SELECT osid, displayname, architecture"
+ " FROM operatingsystem");
ResultSet rs = stmt.executeQuery();
List<OperatingSystem> list = new ArrayList<>();
+ Map<Integer, Map<String, String>> osVirtMappings = getOsVirtMappings(connection);
while (rs.next()) {
- // TODO: virt mapping
- list.add(new OperatingSystem(rs.getInt("osid"), rs.getString("displayname"), null,
+ int osId = rs.getInt("osid");
+ list.add(new OperatingSystem(osId, rs.getString("displayname"), osVirtMappings.get(osId),
rs.getString("architecture")));
}
return list;
@@ -51,5 +56,55 @@ public class DbOsVirt {
throw e;
}
}
+
+ private static Map<Integer, Map<String, String>> getOsVirtMappings(MysqlConnection connection) throws SQLException {
+ MysqlStatement stmt = connection.prepareStatement("SELECT osid, virtid, virtoskeyword FROM os_x_virt");
+ ResultSet rs = stmt.executeQuery();
+ Map<Integer, Map<String, String>> map = new HashMap<>();
+ while (rs.next()) {
+ Integer osId = rs.getInt("osid");
+ Map<String, String> osMap = map.get(osId);
+ if (osMap == null) {
+ osMap = new HashMap<>();
+ map.put(osId, osMap);
+ }
+ osMap.put(rs.getString("virtid"), rs.getString("virtoskeyword"));
+ }
+ return map;
+ }
+
+ public static void storeVirtualizerList(List<Virtualizer> list) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("INSERT INTO virtualizer"
+ + " (virtid, virtname) VALUES"
+ + " (:virtid, :virtname)"
+ + " ON DUPLICATE KEY UPDATE virtname = VALUES(virtname)");
+ for (Virtualizer virt : list) {
+ stmt.setString("virtid", virt.virtId);
+ stmt.setString("displayname", virt.virtName);
+ stmt.executeUpdate();
+ }
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbOsVirt.storeVirtualizerList()", e);
+ throw e;
+ }
+ }
+
+ public static List<Virtualizer> getVirtualizerList() throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT virtid, virtname"
+ + " FROM virtualizer");
+ ResultSet rs = stmt.executeQuery();
+ List<Virtualizer> list = new ArrayList<>();
+ while (rs.next()) {
+ list.add(new Virtualizer(rs.getString("virtid"), rs.getString("virtname")));
+ }
+ return list;
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbOsVirt.getVirtualizerList()", e);
+ throw e;
+ }
+ }
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
index 86660ac1..34fc6cce 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
@@ -41,29 +41,32 @@ public class User {
* 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
+ * @return null if user is allowed, {@link AuthorizationError} otherwise
*/
- public static boolean canLogin(UserInfo user) {
+ public static AuthorizationError canLogin(UserInfo user) {
LocalUser localData = LocalData.getLocalUser(user);
- if (localData != null)
- return localData.canLogin; // User locally known, use user-specific permission
+ if (localData != null) {
+ if (localData.canLogin)
+ return null; // User locally known, use user-specific permission
+ return AuthorizationError.ACCOUNT_SUSPENDED;
+ }
LocalOrganization local = LocalData.getLocalOrganization(user.organizationId);
// User unknown, check per-organization login permission
if (local == null)
- return false;
+ return AuthorizationError.INVALID_ORGANIZATION;
if (local.canLogin)
- return true;
+ return null;
// 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;
+ return null;
}
} catch (SQLException e) {
// Ignore
}
- return false;
+ return AuthorizationError.GENERIC_ERROR;
}
/**
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java
index 70c47edb..3e0159b6 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java
@@ -49,9 +49,9 @@ public class BinaryListener implements Runnable {
final TNonblockingServerTransport serverTransport;
try {
serverTransport = new TNonblockingServerSocket(port);
- log.fatal("Listening on port " + port + " (plain handler)");
+ log.info("Listening on port " + port + " (plain handler)");
} catch (TTransportException e) {
- log.fatal("Could not listen on port " + port + " (plain handler)");
+ log.info("Could not listen on port " + port + " (plain handler)");
throw e;
}
THsHaServer.Args args = new THsHaServer.Args(serverTransport);
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 24a110e5..22a90de7 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
@@ -105,8 +105,8 @@ public class ServerHandler implements SatelliteServer.Iface {
*/
@Override
- public boolean isAuthenticated(String userToken) {
- return SessionManager.get(userToken) != null;
+ public void isAuthenticated(String userToken) throws TAuthorizationException, TInternalServerError {
+ SessionManager.ensureAuthenticated(userToken);
}
@Override
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java
index 1f36adfb..936b7a06 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/SessionManager.java
@@ -12,6 +12,7 @@ import org.openslx.bwlp.sat.permissions.User;
import org.openslx.bwlp.thrift.iface.AuthorizationError;
import org.openslx.bwlp.thrift.iface.Role;
import org.openslx.bwlp.thrift.iface.TAuthorizationException;
+import org.openslx.bwlp.thrift.iface.TInternalServerError;
import org.openslx.bwlp.thrift.iface.TInvalidTokenException;
import org.openslx.bwlp.thrift.iface.UserInfo;
import org.openslx.thrifthelper.ThriftManager;
@@ -80,14 +81,36 @@ public class SessionManager {
}
/**
- * Get the user corresponding to the given token. Returns null if the token
- * is not known, or the session already timed out.
+ * Do nothing if a user belongs to the given token and is authorized to use
+ * this satellite, throw an exception otherwise.
+ *
+ * @param token Token in question
+ * @throws TAuthorizationException
+ * @throws TInternalServerError
+ */
+ public static void ensureAuthenticated(String token) throws TAuthorizationException,
+ TInternalServerError {
+ getInternal(token);
+ }
+
+ /**
+ * Get the user corresponding to the given token. Returns <code>null</code>
+ * if the token is not known, or the session already timed out.
*
* @param token user's token
* @return UserInfo for the matching user
*/
public static UserInfo get(String token) {
+ try {
+ return getInternal(token);
+ } catch (TAuthorizationException | TInternalServerError e) {
+ return null;
+ }
+ }
+
+ private static UserInfo getInternal(String token) throws TAuthorizationException, TInternalServerError {
Entry e = tokenManager.get(token);
+ LOGGER.info("Cache miss for token " + token + ", asking master");
if (e == null)
return getRemote(token);
// User session already cached
@@ -114,25 +137,63 @@ public class SessionManager {
*
* @param token token of user to get
* @return
+ * @throws TAuthorizationException if user is not allowed to use this
+ * satellite, this exception contains the reason
+ * @throws TInternalServerError if something unexpected fails
*/
- private static UserInfo getRemote(String token) {
+ private static UserInfo getRemote(String token) throws TAuthorizationException, TInternalServerError {
UserInfo ui = null;
try {
ui = ThriftManager.getMasterClient().getUserFromToken(token);
} catch (TInvalidTokenException ite) {
- return null; // Token not known to master server
+ LOGGER.warn("Invalid token: " + token, ite);
+ throw new TAuthorizationException(AuthorizationError.INVALID_TOKEN,
+ "Your token is not known to the master server");
} catch (Exception e) {
- LOGGER.warn("Could not reach master server to query for user token of a client!", e);
+ LOGGER.warn("Could not reach master server to query for user token (" + token + ") of a client!",
+ e);
+ throw new TInternalServerError();
}
+ LOGGER.info("Got user " + ui.userId + " for token " + token);
+ // TODO XXX HACK: Remove this once master server supplies role
+ if (ui.role == null)
+ ui.role = Role.TUTOR;
// Valid reply, check if user is allowed to communicate with this satellite server
- if (!User.canLogin(ui))
- return null;
+ AuthorizationError authError = User.canLogin(ui);
+ if (authError != null) {
+ LOGGER.info("User " + ui.userId + " cannot login: " + authError.toString());
+ switch (authError) {
+ case ACCOUNT_SUSPENDED:
+ throw new TAuthorizationException(authError,
+ "Your account is not allowed to log in to this satellite");
+ case BANNED_NETWORK:
+ throw new TAuthorizationException(authError, "Your IP address is banned from this satellite");
+ case INVALID_CREDENTIALS:
+ case INVALID_KEY:
+ case CHALLENGE_FAILED:
+ throw new TAuthorizationException(authError, "Authentication error");
+ case INVALID_ORGANIZATION:
+ throw new TAuthorizationException(authError,
+ "Your organization is not known to this satellite");
+ case ORGANIZATION_SUSPENDED:
+ throw new TAuthorizationException(authError,
+ "Your organization is not allowed to log in to this satellite");
+ case NOT_AUTHENTICATED:
+ case NO_PERMISSION:
+ throw new TAuthorizationException(authError, "No permission");
+ case GENERIC_ERROR:
+ case INVALID_TOKEN:
+ default:
+ throw new TAuthorizationException(authError, "Internal server error");
+ }
+ }
// Is valid, insert/update db record, but ignore students
if (ui.role != Role.STUDENT) {
try {
DbUser.writeUserOnLogin(ui);
} catch (SQLException e) {
- return null;
+ LOGGER.info("User " + ui.userId + " cannot be written to DB - rejecting.");
+ throw new TInternalServerError();
}
}
tokenManager.put(token, new Entry(ui));
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/cache/VirtualizerList.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/cache/VirtualizerList.java
index 87b85186..469096d8 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/cache/VirtualizerList.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/cache/VirtualizerList.java
@@ -1,7 +1,11 @@
package org.openslx.bwlp.sat.thrift.cache;
import java.util.List;
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.sat.database.mappers.DbOsVirt;
+
+import java.sql.SQLException;
import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.Virtualizer;
import org.openslx.thrifthelper.ThriftManager;
@@ -12,6 +16,8 @@ import org.openslx.thrifthelper.ThriftManager;
*/
public class VirtualizerList extends CacheBase<List<Virtualizer>> {
+ private static final Logger LOGGER = Logger.getLogger(VirtualizerList.class);
+
private static final VirtualizerList instance = new VirtualizerList();
public static List<Virtualizer> get() {
@@ -20,8 +26,28 @@ public class VirtualizerList extends CacheBase<List<Virtualizer>> {
@Override
protected List<Virtualizer> getCallback() throws TException {
- return ThriftManager.getMasterClient().getVirtualizers();
- // TODO: Store in DB
+ final List<Virtualizer> list;
+ try {
+ list = ThriftManager.getMasterClient().getVirtualizers();
+ } catch (TException e1) {
+ LOGGER.warn("Could not fetch Virtualizer list from master, using local data...", e1);
+ try {
+ return DbOsVirt.getVirtualizerList();
+ } catch (SQLException e) {
+ LOGGER.warn("Using local Virtualizer list from database also failed.", e);
+ }
+ return null;
+ }
+// QuickTimer.scheduleOnce(new Task() {
+// @Override
+// public void fire() {
+// try {
+// DbOsVirt.storeOsList(list);
+// } catch (SQLException e) {
+// }
+// }
+// });
+ return list;
}
}