GUACAMOLE-5: Associate the UserContext with any created tunnel.

This commit is contained in:
Michael Jumper
2016-07-15 21:17:57 -07:00
parent c231f4eb57
commit e4fe1a3a65
5 changed files with 140 additions and 16 deletions

View File

@@ -28,7 +28,7 @@ import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.net.auth.UserContext;
import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
import org.apache.guacamole.tunnel.UserTunnel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -59,8 +59,8 @@ public class GuacamoleSession {
/**
* All currently-active tunnels, indexed by tunnel UUID.
*/
private final Map<String, StreamInterceptingTunnel> tunnels =
new ConcurrentHashMap<String, StreamInterceptingTunnel>();
private final Map<String, UserTunnel> tunnels =
new ConcurrentHashMap<String, UserTunnel>();
/**
* The last time this session was accessed.
@@ -196,7 +196,7 @@ public class GuacamoleSession {
*
* @return A map of all active tunnels associated with this session.
*/
public Map<String, StreamInterceptingTunnel> getTunnels() {
public Map<String, UserTunnel> getTunnels() {
return tunnels;
}
@@ -206,7 +206,7 @@ public class GuacamoleSession {
*
* @param tunnel The tunnel to associate with this session.
*/
public void addTunnel(StreamInterceptingTunnel tunnel) {
public void addTunnel(UserTunnel tunnel) {
tunnels.put(tunnel.getUUID().toString(), tunnel);
}

View File

@@ -30,7 +30,7 @@ import javax.ws.rs.core.MediaType;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleResourceNotFoundException;
import org.apache.guacamole.GuacamoleSession;
import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
import org.apache.guacamole.tunnel.UserTunnel;
/**
* A REST resource which exposes the active tunnels of a Guacamole session.
@@ -89,10 +89,10 @@ public class TunnelCollectionResource {
public TunnelResource getTunnel(@PathParam("tunnel") String tunnelUUID)
throws GuacamoleException {
Map<String, StreamInterceptingTunnel> tunnels = session.getTunnels();
Map<String, UserTunnel> tunnels = session.getTunnels();
// Pull tunnel with given UUID
final StreamInterceptingTunnel tunnel = tunnels.get(tunnelUUID);
final UserTunnel tunnel = tunnels.get(tunnelUUID);
if (tunnel == null)
throw new GuacamoleResourceNotFoundException("No such tunnel.");

View File

@@ -27,7 +27,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.tunnel.StreamInterceptingTunnel;
import org.apache.guacamole.tunnel.UserTunnel;
/**
* A REST resource which abstracts the operations available for an individual
@@ -48,7 +48,7 @@ public class TunnelResource {
/**
* The tunnel that this TunnelResource represents.
*/
private final StreamInterceptingTunnel tunnel;
private final UserTunnel tunnel;
/**
* Creates a new TunnelResource which exposes the operations and
@@ -57,7 +57,7 @@ public class TunnelResource {
* @param tunnel
* The tunnel that this TunnelResource should represent.
*/
public TunnelResource(StreamInterceptingTunnel tunnel) {
public TunnelResource(UserTunnel tunnel) {
this.tunnel = tunnel;
}

View File

@@ -211,6 +211,10 @@ public class TunnelRequestService {
* @param session
* The Guacamole session to associate the tunnel with.
*
* @param context
* The UserContext associated with the user for whom the tunnel is
* being created.
*
* @param type
* The type of object being connected to (connection or group).
*
@@ -227,11 +231,11 @@ public class TunnelRequestService {
*/
protected GuacamoleTunnel createAssociatedTunnel(GuacamoleTunnel tunnel,
final String authToken, final GuacamoleSession session,
final TunnelRequest.Type type, final String id)
throws GuacamoleException {
final UserContext context, final TunnelRequest.Type type,
final String id) throws GuacamoleException {
// Monitor tunnel closure and data
StreamInterceptingTunnel monitoredTunnel = new StreamInterceptingTunnel(tunnel) {
UserTunnel monitoredTunnel = new UserTunnel(context, tunnel) {
/**
* The time the connection began, measured in milliseconds since
@@ -328,7 +332,7 @@ public class TunnelRequestService {
GuacamoleTunnel tunnel = createConnectedTunnel(userContext, type, id, info);
// Associate tunnel with session
return createAssociatedTunnel(tunnel, authToken, session, type, id);
return createAssociatedTunnel(tunnel, authToken, session, userContext, type, id);
}

View File

@@ -0,0 +1,120 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.guacamole.tunnel;
import java.util.Collection;
import java.util.UUID;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.auth.ActiveConnection;
import org.apache.guacamole.net.auth.Directory;
import org.apache.guacamole.net.auth.UserContext;
/**
* Tunnel implementation which associates a given tunnel with the UserContext of
* the user that created it.
*
* @author Michael Jumper
*/
public class UserTunnel extends StreamInterceptingTunnel {
/**
* The UserContext associated with the user for whom this tunnel was
* created. This UserContext MUST be from the AuthenticationProvider that
* created this tunnel.
*/
private final UserContext userContext;
/**
* Creates a new UserTunnel which wraps the given tunnel, associating it
* with the given UserContext. The UserContext MUST be from the
* AuthenticationProvider that created this tunnel, and MUST be associated
* with the user for whom this tunnel was created.
*
* @param userContext
* The UserContext associated with the user for whom this tunnel was
* created. This UserContext MUST be from the AuthenticationProvider
* that created this tunnel.
*
* @param tunnel
* The tunnel whose stream-related instruction should be intercepted if
* interceptStream() is invoked.
*/
public UserTunnel(UserContext userContext, GuacamoleTunnel tunnel) {
super(tunnel);
this.userContext = userContext;
}
/**
* Returns the UserContext of the user for whom this tunnel was created.
* This UserContext will be the UserContext from the AuthenticationProvider
* that created this tunnel.
*
* @return
* The UserContext of the user for whom this tunnel was created.
*/
public UserContext getUserContext() {
return userContext;
}
/**
* Returns the ActiveConnection object associated with this tunnel within
* the AuthenticationProvider and UserContext which created the tunnel. If
* the AuthenticationProvider is not tracking active connections, or this
* tunnel is no longer active, this will be null.
*
* @return
* The ActiveConnection object associated with this tunnel, or null if
* this tunnel is no longer active or the AuthenticationProvider which
* created the tunnel is not tracking active connections.
*
* @throws GuacamoleException
* If an error occurs which prevents retrieval of the user's current
* active connections.
*/
public ActiveConnection getActiveConnection() throws GuacamoleException {
// Pull the UUID of the current tunnel
UUID uuid = getUUID();
// Get the directory of active connections
Directory<ActiveConnection> activeConnectionDirectory = userContext.getActiveConnectionDirectory();
Collection<String> activeConnectionIdentifiers = activeConnectionDirectory.getIdentifiers();
// Search all connections for a tunnel which matches this tunnel
for (ActiveConnection activeConnection : activeConnectionDirectory.getAll(activeConnectionIdentifiers)) {
// If we lack access, continue with next tunnel
GuacamoleTunnel tunnel = activeConnection.getTunnel();
if (tunnel == null)
continue;
// Tunnels are equivalent if they have the same UUID
if (uuid.equals(tunnel.getUUID()))
return activeConnection;
}
// No active connection associated with this tunnel
return null;
}
}