You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2016/07/22 02:50:59 UTC
[5/8] incubator-guacamole-client git commit: GUACAMOLE-5: Implement
joining of shared connections via temporary credentials.
GUACAMOLE-5: Implement joining of shared connections via temporary credentials.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/19f80dac
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/19f80dac
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/19f80dac
Branch: refs/heads/master
Commit: 19f80dac9533faa48be9f95c162d158a87965935
Parents: bfa5c38
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Jul 21 14:20:28 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Jul 21 14:25:51 2016 -0700
----------------------------------------------------------------------
.../TrackedActiveConnection.java | 21 +++
.../auth/jdbc/sharing/SharedConnection.java | 13 +-
.../tunnel/AbstractGuacamoleTunnelService.java | 169 +++++++++++++++----
.../jdbc/tunnel/ActiveConnectionRecord.java | 166 ++++++++++++++++--
.../jdbc/tunnel/GuacamoleTunnelService.java | 38 +++++
.../RestrictedGuacamoleTunnelService.java | 18 +-
6 files changed, 362 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/19f80dac/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/activeconnection/TrackedActiveConnection.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/activeconnection/TrackedActiveConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/activeconnection/TrackedActiveConnection.java
index 9b39f2f..6c2e4d5 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/activeconnection/TrackedActiveConnection.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/activeconnection/TrackedActiveConnection.java
@@ -76,6 +76,13 @@ public class TrackedActiveConnection extends RestrictedObject implements ActiveC
private String username;
/**
+ * The connection ID of the connection as determined by guacd, not to be
+ * confused with the connection identifier determined by the database. This
+ * is the ID that must be supplied to guacd if joining this connection.
+ */
+ private String connectionID;
+
+ /**
* The underlying GuacamoleTunnel.
*/
private GuacamoleTunnel tunnel;
@@ -107,6 +114,7 @@ public class TrackedActiveConnection extends RestrictedObject implements ActiveC
// Copy all non-sensitive data from given record
this.connection = activeConnectionRecord.getConnection();
+ this.connectionID = activeConnectionRecord.getConnectionID();
this.sharingProfileIdentifier = activeConnectionRecord.getSharingProfileIdentifier();
this.identifier = activeConnectionRecord.getUUID().toString();
this.startDate = activeConnectionRecord.getStartDate();
@@ -142,6 +150,19 @@ public class TrackedActiveConnection extends RestrictedObject implements ActiveC
return connection;
}
+ /**
+ * Returns the connection ID of the in-progress connection as determined by
+ * guacd, not to be confused with the connection identifier determined by
+ * the database. This is the ID that must be supplied to guacd if joining
+ * this connection.
+ *
+ * @return
+ * The ID of the in-progress connection, as determined by guacd.
+ */
+ public String getConnectionID() {
+ return connectionID;
+ }
+
@Override
public String getConnectionIdentifier() {
return connection.getIdentifier();
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/19f80dac/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/SharedConnection.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/SharedConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/SharedConnection.java
index 984f449..70b8944 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/SharedConnection.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/SharedConnection.java
@@ -19,16 +19,17 @@
package org.apache.guacamole.auth.jdbc.sharing;
+import com.google.inject.Inject;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleUnsupportedException;
import org.apache.guacamole.auth.jdbc.activeconnection.TrackedActiveConnection;
import org.apache.guacamole.auth.jdbc.connectiongroup.RootConnectionGroup;
import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile;
+import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.auth.Connection;
import org.apache.guacamole.net.auth.ConnectionRecord;
@@ -44,6 +45,12 @@ import org.apache.guacamole.protocol.GuacamoleConfiguration;
public class SharedConnection implements Connection {
/**
+ * Service for establishing tunnels to Guacamole connections.
+ */
+ @Inject
+ private GuacamoleTunnelService tunnelService;
+
+ /**
* Randomly-generated unique identifier, guaranteeing this shared connection
* does not duplicate the identifying information of the underlying
* connection being shared.
@@ -130,8 +137,8 @@ public class SharedConnection implements Connection {
@Override
public GuacamoleTunnel connect(GuacamoleClientInformation info)
throws GuacamoleException {
- // STUB
- throw new GuacamoleUnsupportedException("Connecting to shared connections is not yet implemented.");
+ return tunnelService.getGuacamoleTunnel(user, activeConnection,
+ sharingProfile, info);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/19f80dac/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
index 82af02d..2d5e1f8 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java
@@ -38,10 +38,11 @@ import org.apache.guacamole.auth.jdbc.connection.ConnectionRecordMapper;
import org.apache.guacamole.auth.jdbc.connection.ConnectionModel;
import org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel;
import org.apache.guacamole.auth.jdbc.connection.ConnectionParameterModel;
-import org.apache.guacamole.auth.jdbc.user.UserModel;
import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleResourceNotFoundException;
import org.apache.guacamole.GuacamoleSecurityException;
import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
+import org.apache.guacamole.auth.jdbc.activeconnection.TrackedActiveConnection;
import org.apache.guacamole.auth.jdbc.connection.ConnectionMapper;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.net.GuacamoleSocket;
@@ -55,6 +56,11 @@ import org.apache.guacamole.token.StandardTokens;
import org.apache.guacamole.token.TokenFilter;
import org.mybatis.guice.transactional.Transactional;
import org.apache.guacamole.auth.jdbc.connection.ConnectionParameterMapper;
+import org.apache.guacamole.auth.jdbc.sharing.SharedConnectionUser;
+import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile;
+import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileParameterMapper;
+import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileParameterModel;
+import org.apache.guacamole.auth.jdbc.user.RemoteAuthenticatedUser;
/**
@@ -88,7 +94,13 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
* Mapper for accessing connection parameters.
*/
@Inject
- private ConnectionParameterMapper parameterMapper;
+ private ConnectionParameterMapper connectionParameterMapper;
+
+ /**
+ * Mapper for accessing sharing profile parameters.
+ */
+ @Inject
+ private SharingProfileParameterMapper sharingProfileParameterMapper;
/**
* Mapper for accessing connection history.
@@ -141,7 +153,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
* @throws GuacamoleException
* If access is denied to the given user for any reason.
*/
- protected abstract ModeledConnection acquire(AuthenticatedUser user,
+ protected abstract ModeledConnection acquire(RemoteAuthenticatedUser user,
List<ModeledConnection> connections) throws GuacamoleException;
/**
@@ -155,7 +167,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
* @param connection
* The connection being released.
*/
- protected abstract void release(AuthenticatedUser user,
+ protected abstract void release(RemoteAuthenticatedUser user,
ModeledConnection connection);
/**
@@ -172,7 +184,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
* @throws GuacamoleException
* If access is denied to the given user for any reason.
*/
- protected abstract void acquire(AuthenticatedUser user,
+ protected abstract void acquire(RemoteAuthenticatedUser user,
ModeledConnectionGroup connectionGroup) throws GuacamoleException;
/**
@@ -186,7 +198,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
* @param connectionGroup
* The connection group being released.
*/
- protected abstract void release(AuthenticatedUser user,
+ protected abstract void release(RemoteAuthenticatedUser user,
ModeledConnectionGroup connectionGroup);
/**
@@ -206,7 +218,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
* A GuacamoleConfiguration containing the protocol and parameters from
* the given connection.
*/
- private GuacamoleConfiguration getGuacamoleConfiguration(AuthenticatedUser user,
+ private GuacamoleConfiguration getGuacamoleConfiguration(RemoteAuthenticatedUser user,
ModeledConnection connection) {
// Generate configuration from available data
@@ -217,7 +229,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
config.setProtocol(model.getProtocol());
// Set parameters from associated data
- Collection<ConnectionParameterModel> parameters = parameterMapper.select(connection.getIdentifier());
+ Collection<ConnectionParameterModel> parameters = connectionParameterMapper.select(connection.getIdentifier());
for (ConnectionParameterModel parameter : parameters)
config.setParameter(parameter.getName(), parameter.getValue());
@@ -233,6 +245,52 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
}
/**
+ * Returns a guacamole configuration which joins the active connection
+ * having the given ID, using the provided sharing profile to restrict the
+ * access provided to the user accessing the shared connection. If tokens
+ * are used in the connection parameter values of the sharing profile,
+ * credentials from the given user will be substituted appropriately.
+ *
+ * @param user
+ * The user whose credentials should be used if necessary.
+ *
+ * @param sharingProfile
+ * The sharing profile whose associated parameters dictate the level
+ * of access granted to the user joining the connection.
+ *
+ * @param connectionID
+ * The ID of the connection being joined, as provided by guacd when the
+ * original connection was established, or null if a new connection
+ * should be created instead.
+ *
+ * @return
+ * A GuacamoleConfiguration containing the protocol and parameters from
+ * the given connection.
+ */
+ private GuacamoleConfiguration getGuacamoleConfiguration(RemoteAuthenticatedUser user,
+ ModeledSharingProfile sharingProfile, String connectionID) {
+
+ // Generate configuration from available data
+ GuacamoleConfiguration config = new GuacamoleConfiguration();
+ config.setConnectionID(connectionID);
+
+ // Set parameters from associated data
+ Collection<SharingProfileParameterModel> parameters = sharingProfileParameterMapper.select(sharingProfile.getIdentifier());
+ for (SharingProfileParameterModel parameter : parameters)
+ config.setParameter(parameter.getName(), parameter.getValue());
+
+ // Build token filter containing credential tokens
+ TokenFilter tokenFilter = new TokenFilter();
+ StandardTokens.addStandardTokens(tokenFilter, user.getCredentials());
+
+ // Filter the configuration
+ tokenFilter.filterValues(config.getParameters());
+
+ return config;
+
+ }
+
+ /**
* Saves the given ActiveConnectionRecord to the database. The end date of
* the saved record will be populated with the current time.
*
@@ -241,17 +299,15 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
*/
private void saveConnectionRecord(ActiveConnectionRecord record) {
- // Get associated connection
- ModeledConnection connection = record.getConnection();
-
// Get associated models
- AuthenticatedUser user = record.getUser();
ConnectionRecordModel recordModel = new ConnectionRecordModel();
// Copy user information and timestamps into new record
- recordModel.setUsername(user.getIdentifier());
- recordModel.setConnectionIdentifier(connection.getIdentifier());
- recordModel.setConnectionName(connection.getName());
+ recordModel.setUsername(record.getUsername());
+ recordModel.setConnectionIdentifier(record.getConnectionIdentifier());
+ recordModel.setConnectionName(record.getConnectionName());
+ recordModel.setSharingProfileIdentifier(record.getSharingProfileIdentifier());
+ recordModel.setSharingProfileName(record.getSharingProfileName());
recordModel.setStartDate(record.getStartDate());
recordModel.setEndDate(new Date());
@@ -329,19 +385,26 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
if (!hasRun.compareAndSet(false, true))
return;
- // Get original user and connection
- AuthenticatedUser user = activeConnection.getUser();
- ModeledConnection connection = activeConnection.getConnection();
+ // Remove underlying tunnel from list of active tunnels
+ activeTunnels.remove(activeConnection.getUUID().toString());
+
+ // Get original user
+ RemoteAuthenticatedUser user = activeConnection.getUser();
- // Get associated identifiers
- String identifier = connection.getIdentifier();
- String parentIdentifier = connection.getParentIdentifier();
+ // Release the associated connection if this is the primary connection
+ if (activeConnection.isPrimaryConnection()) {
- // Release connection
- activeTunnels.remove(activeConnection.getUUID().toString());
- activeConnections.remove(identifier, activeConnection);
- activeConnectionGroups.remove(parentIdentifier, activeConnection);
- release(user, connection);
+ // Get connection and associated identifiers
+ ModeledConnection connection = activeConnection.getConnection();
+ String identifier = connection.getIdentifier();
+ String parentIdentifier = connection.getParentIdentifier();
+
+ // Release connection
+ activeConnections.remove(identifier, activeConnection);
+ activeConnectionGroups.remove(parentIdentifier, activeConnection);
+ release(user, connection);
+
+ }
// Release any associated group
if (activeConnection.hasBalancingGroup())
@@ -379,25 +442,44 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
* while connection configuration information is being retrieved.
*/
private GuacamoleTunnel assignGuacamoleTunnel(ActiveConnectionRecord activeConnection,
- GuacamoleClientInformation info)
- throws GuacamoleException {
+ GuacamoleClientInformation info) throws GuacamoleException {
- ModeledConnection connection = activeConnection.getConnection();
-
// Record new active connection
Runnable cleanupTask = new ConnectionCleanupTask(activeConnection);
activeTunnels.put(activeConnection.getUUID().toString(), activeConnection);
- activeConnections.put(connection.getIdentifier(), activeConnection);
- activeConnectionGroups.put(connection.getParentIdentifier(), activeConnection);
try {
+ GuacamoleConfiguration config;
+
+ // Pull configuration directly from the connection if we are not
+ // joining an active connection
+ if (activeConnection.isPrimaryConnection()) {
+ ModeledConnection connection = activeConnection.getConnection();
+ activeConnections.put(connection.getIdentifier(), activeConnection);
+ activeConnectionGroups.put(connection.getParentIdentifier(), activeConnection);
+ config = getGuacamoleConfiguration(activeConnection.getUser(), connection);
+ }
+
+ // If we ARE joining an active connection, generate a configuration
+ // which does so
+ else {
+
+ // Verify that the connection ID is known
+ String connectionID = activeConnection.getConnectionID();
+ if (connectionID == null)
+ throw new GuacamoleResourceNotFoundException("No existing connection to be joined.");
+
+ // Build configuration from the sharing profile and the ID of
+ // the connection being joined
+ config = getGuacamoleConfiguration(activeConnection.getUser(),
+ activeConnection.getSharingProfile(), connectionID);
+
+ }
+
// Obtain socket which will automatically run the cleanup task
- GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
- getUnconfiguredGuacamoleSocket(cleanupTask),
- getGuacamoleConfiguration(activeConnection.getUser(), connection),
- info
- );
+ ConfiguredGuacamoleSocket socket = new ConfiguredGuacamoleSocket(
+ getUnconfiguredGuacamoleSocket(cleanupTask), config, info);
// Assign and return new tunnel
return activeConnection.assignGuacamoleTunnel(socket);
@@ -596,4 +678,17 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
}
+ @Override
+ @Transactional
+ public GuacamoleTunnel getGuacamoleTunnel(SharedConnectionUser user,
+ TrackedActiveConnection activeConnection,
+ ModeledSharingProfile sharingProfile,
+ GuacamoleClientInformation info)
+ throws GuacamoleException {
+
+ // Connect to shared connection
+ return assignGuacamoleTunnel(new ActiveConnectionRecord(user, activeConnection, sharingProfile), info);
+
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/19f80dac/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/ActiveConnectionRecord.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/ActiveConnectionRecord.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/ActiveConnectionRecord.java
index a34e339..f768f23 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/ActiveConnectionRecord.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/ActiveConnectionRecord.java
@@ -21,13 +21,16 @@ package org.apache.guacamole.auth.jdbc.tunnel;
import java.util.Date;
import java.util.UUID;
+import org.apache.guacamole.auth.jdbc.activeconnection.TrackedActiveConnection;
import org.apache.guacamole.auth.jdbc.connection.ModeledConnection;
import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
-import org.apache.guacamole.auth.jdbc.user.AuthenticatedUser;
+import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile;
+import org.apache.guacamole.auth.jdbc.user.RemoteAuthenticatedUser;
import org.apache.guacamole.net.AbstractGuacamoleTunnel;
import org.apache.guacamole.net.GuacamoleSocket;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.auth.ConnectionRecord;
+import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
/**
@@ -44,7 +47,7 @@ public class ActiveConnectionRecord implements ConnectionRecord {
* The user that connected to the connection associated with this connection
* record.
*/
- private final AuthenticatedUser user;
+ private final RemoteAuthenticatedUser user;
/**
* The balancing group from which the associated connection was chosen, if
@@ -58,6 +61,13 @@ public class ActiveConnectionRecord implements ConnectionRecord {
private final ModeledConnection connection;
/**
+ * The sharing profile that was used to access the connection associated
+ * with this connection record. If the connection was accessed directly
+ * (without involving a sharing profile), this will be null.
+ */
+ private final ModeledSharingProfile sharingProfile;
+
+ /**
* The time this connection record was created.
*/
private final Date startDate = new Date();
@@ -66,13 +76,54 @@ public class ActiveConnectionRecord implements ConnectionRecord {
* The UUID that will be assigned to the underlying tunnel.
*/
private final UUID uuid = UUID.randomUUID();
+
+ /**
+ * The connection ID of the connection as determined by guacd, not to be
+ * confused with the connection identifier determined by the database. This
+ * is the ID that must be supplied to guacd if joining this connection.
+ */
+ private String connectionID;
/**
* The GuacamoleTunnel used by the connection associated with this
* connection record.
*/
private GuacamoleTunnel tunnel;
-
+
+ /**
+ * Creates a new connection record associated with the given user,
+ * connection, balancing connection group, and sharing profile. The given
+ * balancing connection group MUST be the connection group from which the
+ * given connection was chosen, and the given sharing profile MUST be the
+ * sharing profile that was used to share access to the given connection.
+ * The start date of this connection record will be the time of its
+ * creation.
+ *
+ * @param user
+ * The user that connected to the connection associated with this
+ * connection record.
+ *
+ * @param balancingGroup
+ * The balancing group from which the given connection was chosen, or
+ * null if no balancing group is being used.
+ *
+ * @param connection
+ * The connection to associate with this connection record.
+ *
+ * @param sharingProfile
+ * The sharing profile that was used to share access to the given
+ * connection, or null if no sharing profile was used.
+ */
+ private ActiveConnectionRecord(RemoteAuthenticatedUser user,
+ ModeledConnectionGroup balancingGroup,
+ ModeledConnection connection,
+ ModeledSharingProfile sharingProfile) {
+ this.user = user;
+ this.balancingGroup = balancingGroup;
+ this.connection = connection;
+ this.sharingProfile = sharingProfile;
+ }
+
/**
* Creates a new connection record associated with the given user,
* connection, and balancing connection group. The given balancing
@@ -90,12 +141,10 @@ public class ActiveConnectionRecord implements ConnectionRecord {
* @param connection
* The connection to associate with this connection record.
*/
- public ActiveConnectionRecord(AuthenticatedUser user,
+ public ActiveConnectionRecord(RemoteAuthenticatedUser user,
ModeledConnectionGroup balancingGroup,
ModeledConnection connection) {
- this.user = user;
- this.balancingGroup = balancingGroup;
- this.connection = connection;
+ this(user, balancingGroup, connection, null);
}
/**
@@ -110,12 +159,39 @@ public class ActiveConnectionRecord implements ConnectionRecord {
* @param connection
* The connection to associate with this connection record.
*/
- public ActiveConnectionRecord(AuthenticatedUser user,
+ public ActiveConnectionRecord(RemoteAuthenticatedUser user,
ModeledConnection connection) {
this(user, null, connection);
}
/**
+ * Creates a new connection record associated with the given user, active
+ * connection, and sharing profile. The given sharing profile MUST be the
+ * sharing profile that was used to share access to the given connection.
+ * The start date of this connection record will be the time of its
+ * creation.
+ *
+ * @param user
+ * The user that connected to the connection associated with this
+ * connection record.
+ *
+ * @param activeConnection
+ * The active connection which is being shared to the given user via
+ * the given sharing profile.
+ *
+ * @param sharingProfile
+ * The sharing profile that was used to share access to the given
+ * connection. As a record created in this way always refers to a
+ * shared connection, this value may NOT be null.
+ */
+ public ActiveConnectionRecord(RemoteAuthenticatedUser user,
+ TrackedActiveConnection activeConnection,
+ ModeledSharingProfile sharingProfile) {
+ this(user, null, activeConnection.getConnection(), sharingProfile);
+ this.connectionID = activeConnection.getConnectionID();
+ }
+
+ /**
* Returns the user that connected to the connection associated with this
* connection record.
*
@@ -123,7 +199,7 @@ public class ActiveConnectionRecord implements ConnectionRecord {
* The user that connected to the connection associated with this
* connection record.
*/
- public AuthenticatedUser getUser() {
+ public RemoteAuthenticatedUser getUser() {
return user;
}
@@ -150,6 +226,20 @@ public class ActiveConnectionRecord implements ConnectionRecord {
}
/**
+ * Returns the sharing profile that was used to access the connection
+ * associated with this connection record. If the connection was accessed
+ * directly (without involving a sharing profile), this will be null.
+ *
+ * @return
+ * The sharing profile that was used to access the connection
+ * associated with this connection record, or null if the connection
+ * was accessed directly.
+ */
+ public ModeledSharingProfile getSharingProfile() {
+ return sharingProfile;
+ }
+
+ /**
* Returns whether the connection associated with this connection record
* was chosen from a balancing group.
*
@@ -161,6 +251,21 @@ public class ActiveConnectionRecord implements ConnectionRecord {
return balancingGroup != null;
}
+ /**
+ * Returns whether this connection record is associated with a connection
+ * being used directly, in the absence of a sharing profile. If a connection
+ * is shared, this will continue to return false for the connection being
+ * shared, but will return true for the connections which join that
+ * connection.
+ *
+ * @return
+ * true if the connection associated with this connection record is
+ * being used directly, false otherwise.
+ */
+ public boolean isPrimaryConnection() {
+ return sharingProfile == null;
+ }
+
@Override
public String getConnectionIdentifier() {
return connection.getIdentifier();
@@ -173,12 +278,26 @@ public class ActiveConnectionRecord implements ConnectionRecord {
@Override
public String getSharingProfileIdentifier() {
+
+ // Return sharing profile identifier if known
+ if (sharingProfile != null)
+ return sharingProfile.getIdentifier();
+
+ // No associated sharing profile
return null;
+
}
@Override
public String getSharingProfileName() {
+
+ // Return sharing profile name if known
+ if (sharingProfile != null)
+ return sharingProfile.getName();
+
+ // No associated sharing profile
return null;
+
}
@Override
@@ -201,7 +320,7 @@ public class ActiveConnectionRecord implements ConnectionRecord {
@Override
public String getUsername() {
- return user.getUser().getIdentifier();
+ return user.getIdentifier();
}
@Override
@@ -229,13 +348,13 @@ public class ActiveConnectionRecord implements ConnectionRecord {
* given socket.
*
* @param socket
- * The GuacamoleSocket to use to create the tunnel associated with this
- * connection record.
+ * The ConfiguredGuacamoleSocket to use to create the tunnel associated
+ * with this connection record.
*
* @return
* The newly-created tunnel associated with this connection record.
*/
- public GuacamoleTunnel assignGuacamoleTunnel(final GuacamoleSocket socket) {
+ public GuacamoleTunnel assignGuacamoleTunnel(final ConfiguredGuacamoleSocket socket) {
// Create tunnel with given socket
this.tunnel = new AbstractGuacamoleTunnel() {
@@ -252,6 +371,10 @@ public class ActiveConnectionRecord implements ConnectionRecord {
};
+ // Store connection ID of the primary connection only
+ if (isPrimaryConnection())
+ this.connectionID = socket.getConnectionID();
+
// Return newly-created tunnel
return this.tunnel;
@@ -268,5 +391,20 @@ public class ActiveConnectionRecord implements ConnectionRecord {
public UUID getUUID() {
return uuid;
}
-
+
+ /**
+ * Returns the connection ID of the in-progress connection as determined by
+ * guacd, not to be confused with the connection identifier determined by
+ * the database. This is the ID that must be supplied to guacd if joining
+ * this connection. If the in-progress connection is joining another
+ * connection, this will be the ID of the connection being joined, NOT the
+ * ID of the connection directly represented by this record.
+ *
+ * @return
+ * The ID of the in-progress connection, as determined by guacd.
+ */
+ public String getConnectionID() {
+ return connectionID;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/19f80dac/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
index 554967b..6a00b2e 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/GuacamoleTunnelService.java
@@ -24,6 +24,9 @@ import org.apache.guacamole.auth.jdbc.user.AuthenticatedUser;
import org.apache.guacamole.auth.jdbc.connection.ModeledConnection;
import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.activeconnection.TrackedActiveConnection;
+import org.apache.guacamole.auth.jdbc.sharing.SharedConnectionUser;
+import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.auth.Connection;
import org.apache.guacamole.net.auth.ConnectionGroup;
@@ -145,4 +148,39 @@ public interface GuacamoleTunnelService {
*/
public Collection<ActiveConnectionRecord> getActiveConnections(ConnectionGroup connectionGroup);
+ /**
+ * Creates a socket for the given user which joins the given active
+ * connection. The given client information will be passed to guacd when
+ * the connection is established. This function will apply any concurrent
+ * usage rules in effect, but will NOT test object- or system-level
+ * permissions.
+ *
+ * @param user
+ * The user for whom the connection is being established.
+ *
+ * @param activeConnection
+ * The active connection the user is joining.
+ *
+ * @param sharingProfile
+ * The sharing profile whose associated parameters dictate the level
+ * of access granted to the user joining the connection.
+ *
+ * @param info
+ * Information describing the Guacamole client connecting to the given
+ * connection.
+ *
+ * @return
+ * A new GuacamoleTunnel which is configured and connected to the given
+ * active connection.
+ *
+ * @throws GuacamoleException
+ * If the connection cannot be established due to concurrent usage
+ * rules.
+ */
+ GuacamoleTunnel getGuacamoleTunnel(SharedConnectionUser user,
+ TrackedActiveConnection activeConnection,
+ ModeledSharingProfile sharingProfile,
+ GuacamoleClientInformation info)
+ throws GuacamoleException;
+
}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/19f80dac/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/RestrictedGuacamoleTunnelService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/RestrictedGuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/RestrictedGuacamoleTunnelService.java
index 4163adc..ca92341 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/RestrictedGuacamoleTunnelService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/RestrictedGuacamoleTunnelService.java
@@ -27,12 +27,12 @@ import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.guacamole.GuacamoleClientTooManyException;
-import org.apache.guacamole.auth.jdbc.user.AuthenticatedUser;
import org.apache.guacamole.auth.jdbc.connection.ModeledConnection;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleResourceConflictException;
import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
+import org.apache.guacamole.auth.jdbc.user.RemoteAuthenticatedUser;
/**
@@ -166,7 +166,7 @@ public class RestrictedGuacamoleTunnelService
}
@Override
- protected ModeledConnection acquire(AuthenticatedUser user,
+ protected ModeledConnection acquire(RemoteAuthenticatedUser user,
List<ModeledConnection> connections) throws GuacamoleException {
// Do not acquire connection unless within overall limits
@@ -174,7 +174,7 @@ public class RestrictedGuacamoleTunnelService
throw new GuacamoleResourceConflictException("Cannot connect. Overall maximum connections reached.");
// Get username
- String username = user.getUser().getIdentifier();
+ String username = user.getIdentifier();
// Sort connections in ascending order of usage
ModeledConnection[] sortedConnections = connections.toArray(new ModeledConnection[connections.size()]);
@@ -230,18 +230,18 @@ public class RestrictedGuacamoleTunnelService
}
@Override
- protected void release(AuthenticatedUser user, ModeledConnection connection) {
- activeSeats.remove(new Seat(user.getUser().getIdentifier(), connection.getIdentifier()));
+ protected void release(RemoteAuthenticatedUser user, ModeledConnection connection) {
+ activeSeats.remove(new Seat(user.getIdentifier(), connection.getIdentifier()));
activeConnections.remove(connection.getIdentifier());
totalActiveConnections.decrementAndGet();
}
@Override
- protected void acquire(AuthenticatedUser user,
+ protected void acquire(RemoteAuthenticatedUser user,
ModeledConnectionGroup connectionGroup) throws GuacamoleException {
// Get username
- String username = user.getUser().getIdentifier();
+ String username = user.getIdentifier();
// Attempt to aquire connection group according to per-user limits
Seat seat = new Seat(username, connectionGroup.getIdentifier());
@@ -267,9 +267,9 @@ public class RestrictedGuacamoleTunnelService
}
@Override
- protected void release(AuthenticatedUser user,
+ protected void release(RemoteAuthenticatedUser user,
ModeledConnectionGroup connectionGroup) {
- activeGroupSeats.remove(new Seat(user.getUser().getIdentifier(), connectionGroup.getIdentifier()));
+ activeGroupSeats.remove(new Seat(user.getIdentifier(), connectionGroup.getIdentifier()));
activeGroups.remove(connectionGroup.getIdentifier());
}