summaryrefslogtreecommitdiffstats
path: root/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java')
-rw-r--r--src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java116
1 files changed, 99 insertions, 17 deletions
diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java b/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java
index f1ad057..eacb347 100644
--- a/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java
+++ b/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java
@@ -10,8 +10,7 @@ import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
+import java.util.*;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@@ -21,6 +20,10 @@ import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+import org.apache.guacamole.form.Field;
+import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
+import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException;
+import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,6 +34,7 @@ import org.slf4j.LoggerFactory;
*/
public class ConnectionManager {
+
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class);
// TODO: Config
@@ -38,11 +42,16 @@ public class ConnectionManager {
private static final LinkedHashMap<String, AvailableClient> clientPool = new LinkedHashMap<String, AvailableClient>();
+ private static final LinkedHashMap<Integer, JsonLocation> locationPool = new LinkedHashMap<Integer, JsonLocation>();
+
+ public static LinkedHashMap<Integer, JsonLocation> getLocationPool() { return locationPool; }
+
/**
* Pass plain user name, get existing connection (if any), or a fresh one
* @param user (LDAP) user name
*/
- public static WrappedConnection getForUser(String user) {
+ public static WrappedConnection getForUser(String user, int locationid)
+ throws GuacamoleCredentialsException {
if (SOURCE_URL == null) {
LOGGER.warn("Don't have a source URL for client machines!");
return null;
@@ -51,17 +60,35 @@ public class ConnectionManager {
updateList();
// Find existing/free client
AvailableClient freeClient;
- for (;;) {
+ for (; ; ) {
freeClient = null;
synchronized (clientPool) {
- for (AvailableClient ac : clientPool.values()) {
+ Collection<AvailableClient> clients;
+ if (locationid == 0) {
+ clients = new HashSet<AvailableClient>();
+ for (JsonLocation loc : locationPool.values()) {
+ if (!loc.hasPassword()) clients.addAll(loc.clientList);
+ }
+ } else {
+ JsonLocation location = locationPool.get(locationid);
+ if (location == null) {
+ // Request the user to select a location
+ throw new GuacamoleInsufficientCredentialsException(
+ "Select Location", new CredentialsInfo(
+ Collections.<Field>singletonList(new LocationField())
+ ));
+ }
+ clients = location.clientList;
+ }
+
+ for (AvailableClient ac : clients) {
if (ac.isInUseBy(user)) {
freeClient = ac;
break;
}
}
if (freeClient == null) {
- for (AvailableClient ac : clientPool.values()) {
+ for (AvailableClient ac : clients) {
if (ac.claim(user)) {
freeClient = ac;
break;
@@ -69,8 +96,13 @@ public class ConnectionManager {
}
}
}
- if (freeClient == null)
- return null; // TODO: No more clients available -- how to handle?
+ if (freeClient == null) {
+ // Request the user to select another location
+ throw new GuacamoleCredentialsException(
+ "No free client. Select another location.", new CredentialsInfo(
+ Collections.<Field>singletonList(new LocationField())
+ ));
+ }
// Found free or existing client, check if connection is (still) possible
if (freeClient.checkConnection(0)) {
LOGGER.info("Establishing mapping for user " + user + " to " + freeClient);
@@ -79,6 +111,8 @@ public class ConnectionManager {
// Connection check failed - release and loop again
freeClient.releaseConnection(user);
}
+ } catch (GuacamoleCredentialsException e) {
+ throw e;
} catch (Exception e) {
LOGGER.warn("KACKE AM DAMPFEN", e);
return null;
@@ -91,7 +125,7 @@ public class ConnectionManager {
* Fetch fresh client list from satellite server.
* Cache for 15 seconds.
*/
- private static synchronized void updateList() {
+ public static synchronized void updateList() {
long now = System.currentTimeMillis();
if (now < lastUpdate) {
lastUpdate = now;
@@ -139,23 +173,68 @@ public class ConnectionManager {
LOGGER.warn("Not updating local list");
return;
}
- list = root.clients;
- if (list == null) {
- LOGGER.info("Client list null");
+
+
+ if (root.locations == null) {
+ LOGGER.info("Location list null");
}
- if (root.locations != null) {
- for (JsonLocation l : root.locations) {
- LOGGER.info("Location " + l.name + " with pw " + l.password);
+ synchronized (locationPool) {
+ for (JsonLocation lnew : root.locations) {
+ JsonLocation existing = locationPool.get(lnew.id);
+ boolean redoClientMapping = false;
+ if (existing == null) {
+ locationPool.put(lnew.id, lnew);
+ existing = lnew;
+ redoClientMapping = true;
+ } else {
+ if (existing.locationids != lnew.locationids) redoClientMapping = true;
+ existing.locationids = lnew.locationids;
+ existing.name = lnew.name;
+ existing.password = lnew.password;
+ }
+ if (redoClientMapping) {
+ existing.clientList = new ArrayList<AvailableClient>();
+ for (AvailableClient client : clientPool.values()) {
+ int locationid = client.getLocationid();
+ for (int id : existing.locationids) {
+ if (id == locationid) {
+ existing.clientList.add(client);
+ break;
+ }
+ }
+ }
+ }
+ existing.checked = true;
+ LOGGER.info("Location " + lnew.name + " with pw " + lnew.password);
}
+ for (JsonLocation loc : locationPool.values()) {
+ if (loc.checked) loc.checked = false;
+ else locationPool.remove(loc.id);
+ }
+ }
+
+ if (root.clients == null) {
+ LOGGER.info("Client list null");
}
synchronized (clientPool) {
- for (JsonClient cnew : list) {
+ for (JsonClient cnew : root.clients) {
if (cnew.password == null || cnew.clientip == null)
continue; // Invalid
AvailableClient existing = clientPool.get(cnew.clientip);
if (existing == null) {
// New client
- clientPool.put(cnew.clientip, new AvailableClient(cnew));
+ AvailableClient newClient = new AvailableClient(cnew);
+ clientPool.put(cnew.clientip, newClient);
+
+ for (JsonLocation loc : locationPool.values()) {
+ for (int id : loc.locationids) {
+ if (id == cnew.locationid) {
+ loc.clientList.add(newClient);
+ newClient.locationList.add(loc);
+ break;
+ }
+ }
+ }
LOGGER.info("New client " + cnew.clientip);
} else {
existing.update(cnew);
@@ -166,6 +245,9 @@ public class ConnectionManager {
AvailableClient c = it.next();
if (c.isTimeout(NOW)) {
LOGGER.info("Removing client " + c + " from list");
+ for (JsonLocation loc : c.locationList) {
+ loc.clientList.remove(c);
+ }
it.remove();
}