mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-360: Refactor TunnelRequestService to handle any Connectable supported by TunnelRequestType.
This commit is contained in:
@@ -21,8 +21,6 @@ package org.apache.guacamole.tunnel;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.guacamole.GuacamoleClientException;
|
import org.apache.guacamole.GuacamoleClientException;
|
||||||
import org.apache.guacamole.GuacamoleClientException;
|
|
||||||
import org.apache.guacamole.GuacamoleException;
|
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,40 +99,6 @@ public abstract class TunnelRequest {
|
|||||||
*/
|
*/
|
||||||
public static final String TIMEZONE_PARAMETER = "GUAC_TIMEZONE";
|
public static final String TIMEZONE_PARAMETER = "GUAC_TIMEZONE";
|
||||||
|
|
||||||
/**
|
|
||||||
* All supported object types that can be used as the destination of a
|
|
||||||
* tunnel.
|
|
||||||
*/
|
|
||||||
public static enum Type {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Guacamole connection.
|
|
||||||
*/
|
|
||||||
CONNECTION("c"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Guacamole connection group.
|
|
||||||
*/
|
|
||||||
CONNECTION_GROUP("g");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parameter value which denotes a destination object of this type.
|
|
||||||
*/
|
|
||||||
final String PARAMETER_VALUE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines a Type having the given corresponding parameter value.
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
* The parameter value which denotes a destination object of this
|
|
||||||
* type.
|
|
||||||
*/
|
|
||||||
Type(String value) {
|
|
||||||
PARAMETER_VALUE = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the parameter having the given name.
|
* Returns the value of the parameter having the given name.
|
||||||
*
|
*
|
||||||
@@ -257,18 +221,11 @@ public abstract class TunnelRequest {
|
|||||||
* If the type was not present in the request, or if the type requested
|
* If the type was not present in the request, or if the type requested
|
||||||
* is in the wrong format.
|
* is in the wrong format.
|
||||||
*/
|
*/
|
||||||
public Type getType() throws GuacamoleException {
|
public TunnelRequestType getType() throws GuacamoleException {
|
||||||
|
|
||||||
String type = getRequiredParameter(TYPE_PARAMETER);
|
TunnelRequestType type = TunnelRequestType.parseType(getRequiredParameter(TYPE_PARAMETER));
|
||||||
|
if (type != null)
|
||||||
// For each possible object type
|
return type;
|
||||||
for (Type possibleType : Type.values()) {
|
|
||||||
|
|
||||||
// Match against defined parameter value
|
|
||||||
if (type.equals(possibleType.PARAMETER_VALUE))
|
|
||||||
return possibleType;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new GuacamoleClientException("Illegal identifier - unknown type.");
|
throw new GuacamoleClientException("Illegal identifier - unknown type.");
|
||||||
|
|
||||||
|
@@ -24,15 +24,13 @@ import com.google.inject.Singleton;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.GuacamoleSecurityException;
|
import org.apache.guacamole.GuacamoleResourceNotFoundException;
|
||||||
import org.apache.guacamole.GuacamoleSession;
|
import org.apache.guacamole.GuacamoleSession;
|
||||||
import org.apache.guacamole.GuacamoleUnauthorizedException;
|
import org.apache.guacamole.GuacamoleUnauthorizedException;
|
||||||
import org.apache.guacamole.net.GuacamoleTunnel;
|
import org.apache.guacamole.net.GuacamoleTunnel;
|
||||||
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
||||||
import org.apache.guacamole.net.auth.Connection;
|
import org.apache.guacamole.net.auth.Connectable;
|
||||||
import org.apache.guacamole.net.auth.ConnectionGroup;
|
|
||||||
import org.apache.guacamole.net.auth.Credentials;
|
import org.apache.guacamole.net.auth.Credentials;
|
||||||
import org.apache.guacamole.net.auth.Directory;
|
|
||||||
import org.apache.guacamole.net.auth.UserContext;
|
import org.apache.guacamole.net.auth.UserContext;
|
||||||
import org.apache.guacamole.net.event.TunnelCloseEvent;
|
import org.apache.guacamole.net.event.TunnelCloseEvent;
|
||||||
import org.apache.guacamole.net.event.TunnelConnectEvent;
|
import org.apache.guacamole.net.event.TunnelConnectEvent;
|
||||||
@@ -204,58 +202,20 @@ public class TunnelRequestService {
|
|||||||
* If an error occurs while creating the tunnel.
|
* If an error occurs while creating the tunnel.
|
||||||
*/
|
*/
|
||||||
protected GuacamoleTunnel createConnectedTunnel(UserContext context,
|
protected GuacamoleTunnel createConnectedTunnel(UserContext context,
|
||||||
final TunnelRequest.Type type, String id,
|
final TunnelRequestType type, String id,
|
||||||
GuacamoleClientInformation info, Map<String, String> tokens)
|
GuacamoleClientInformation info, Map<String, String> tokens)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Create connected tunnel from identifier
|
// Retrieve requested destination object
|
||||||
GuacamoleTunnel tunnel = null;
|
Connectable connectable = type.getConnectable(context, id);
|
||||||
switch (type) {
|
if (connectable == null)
|
||||||
|
throw new GuacamoleResourceNotFoundException("Requested tunnel "
|
||||||
// Connection identifiers
|
+ "destination does not exist.");
|
||||||
case CONNECTION: {
|
|
||||||
|
|
||||||
// Get connection directory
|
|
||||||
Directory<Connection> directory = context.getConnectionDirectory();
|
|
||||||
|
|
||||||
// Get authorized connection
|
|
||||||
Connection connection = directory.get(id);
|
|
||||||
if (connection == null) {
|
|
||||||
logger.info("Connection \"{}\" does not exist for user \"{}\".", id, context.self().getIdentifier());
|
|
||||||
throw new GuacamoleSecurityException("Requested connection is not authorized.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect tunnel
|
|
||||||
tunnel = connection.connect(info, tokens);
|
|
||||||
logger.info("User \"{}\" connected to connection \"{}\".", context.self().getIdentifier(), id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connection group identifiers
|
|
||||||
case CONNECTION_GROUP: {
|
|
||||||
|
|
||||||
// Get connection group directory
|
|
||||||
Directory<ConnectionGroup> directory = context.getConnectionGroupDirectory();
|
|
||||||
|
|
||||||
// Get authorized connection group
|
|
||||||
ConnectionGroup group = directory.get(id);
|
|
||||||
if (group == null) {
|
|
||||||
logger.info("Connection group \"{}\" does not exist for user \"{}\".", id, context.self().getIdentifier());
|
|
||||||
throw new GuacamoleSecurityException("Requested connection group is not authorized.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect tunnel
|
|
||||||
tunnel = group.connect(info, tokens);
|
|
||||||
logger.info("User \"{}\" connected to group \"{}\".", context.self().getIdentifier(), id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type is guaranteed to be one of the above
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Connect tunnel to destination
|
||||||
|
GuacamoleTunnel tunnel = connectable.connect(info, tokens);
|
||||||
|
logger.info("User \"{}\" connected to {} \"{}\".",
|
||||||
|
context.self().getIdentifier(), type.NAME, id);
|
||||||
return tunnel;
|
return tunnel;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -297,7 +257,7 @@ public class TunnelRequestService {
|
|||||||
*/
|
*/
|
||||||
protected GuacamoleTunnel createAssociatedTunnel(final GuacamoleTunnel tunnel,
|
protected GuacamoleTunnel createAssociatedTunnel(final GuacamoleTunnel tunnel,
|
||||||
final String authToken, final GuacamoleSession session,
|
final String authToken, final GuacamoleSession session,
|
||||||
final UserContext context, final TunnelRequest.Type type,
|
final UserContext context, final TunnelRequestType type,
|
||||||
final String id) throws GuacamoleException {
|
final String id) throws GuacamoleException {
|
||||||
|
|
||||||
// Monitor tunnel closure and data
|
// Monitor tunnel closure and data
|
||||||
@@ -320,26 +280,9 @@ public class TunnelRequestService {
|
|||||||
long connectionEndTime = System.currentTimeMillis();
|
long connectionEndTime = System.currentTimeMillis();
|
||||||
long duration = connectionEndTime - connectionStartTime;
|
long duration = connectionEndTime - connectionStartTime;
|
||||||
|
|
||||||
// Log closure
|
logger.info("User \"{}\" disconnected from {} \"{}\". Duration: {} milliseconds",
|
||||||
switch (type) {
|
session.getAuthenticatedUser().getIdentifier(),
|
||||||
|
type.NAME, id, duration);
|
||||||
// Connection identifiers
|
|
||||||
case CONNECTION:
|
|
||||||
logger.info("User \"{}\" disconnected from connection \"{}\". Duration: {} milliseconds",
|
|
||||||
session.getAuthenticatedUser().getIdentifier(), id, duration);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Connection group identifiers
|
|
||||||
case CONNECTION_GROUP:
|
|
||||||
logger.info("User \"{}\" disconnected from connection group \"{}\". Duration: {} milliseconds",
|
|
||||||
session.getAuthenticatedUser().getIdentifier(), id, duration);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Type is guaranteed to be one of the above
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -390,7 +333,7 @@ public class TunnelRequestService {
|
|||||||
// Parse request parameters
|
// Parse request parameters
|
||||||
String authToken = request.getAuthenticationToken();
|
String authToken = request.getAuthenticationToken();
|
||||||
String id = request.getIdentifier();
|
String id = request.getIdentifier();
|
||||||
TunnelRequest.Type type = request.getType();
|
TunnelRequestType type = request.getType();
|
||||||
String authProviderIdentifier = request.getAuthenticationProviderIdentifier();
|
String authProviderIdentifier = request.getAuthenticationProviderIdentifier();
|
||||||
GuacamoleClientInformation info = getClientInformation(request);
|
GuacamoleClientInformation info = getClientInformation(request);
|
||||||
|
|
||||||
|
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.apache.guacamole.GuacamoleException;
|
||||||
|
import org.apache.guacamole.net.auth.Connectable;
|
||||||
|
import org.apache.guacamole.net.auth.Connection;
|
||||||
|
import org.apache.guacamole.net.auth.ConnectionGroup;
|
||||||
|
import org.apache.guacamole.net.auth.UserContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All supported object types that can be used as the destination of a tunnel.
|
||||||
|
*
|
||||||
|
* @see TunnelRequest#TYPE_PARAMETER
|
||||||
|
* @see TunnelRequest#getType()
|
||||||
|
*/
|
||||||
|
public enum TunnelRequestType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Guacamole connection.
|
||||||
|
*/
|
||||||
|
CONNECTION("c", "connection") {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnectable(UserContext userContext,
|
||||||
|
String identifier) throws GuacamoleException {
|
||||||
|
return userContext.getConnectionDirectory().get(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Guacamole connection group.
|
||||||
|
*/
|
||||||
|
CONNECTION_GROUP("g", "connection group") {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionGroup getConnectable(UserContext userContext,
|
||||||
|
String identifier) throws GuacamoleException {
|
||||||
|
return userContext.getConnectionGroupDirectory().get(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter value which denotes a destination object of this type
|
||||||
|
* within a tunnel request.
|
||||||
|
*
|
||||||
|
* @see TunnelRequest#TYPE_PARAMETER
|
||||||
|
* @see TunnelRequest#getType()
|
||||||
|
*/
|
||||||
|
public final String PARAMETER_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A human-readable, descriptive name of the type of destination object.
|
||||||
|
*/
|
||||||
|
public final String NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a tunnel request type having the given corresponding parameter
|
||||||
|
* value and human-readable name.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* The parameter value which denotes a destination object of this
|
||||||
|
* type.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* A human-readable, descriptive name of the type of destination
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
private TunnelRequestType(String value, String name) {
|
||||||
|
PARAMETER_VALUE = value;
|
||||||
|
NAME = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the object having the given identifier from the given
|
||||||
|
* UserContext, where the type of object retrieved is the type of object
|
||||||
|
* represented by this tunnel request type.
|
||||||
|
*
|
||||||
|
* @param userContext
|
||||||
|
* The UserContext to retrieve the object from.
|
||||||
|
*
|
||||||
|
* @param identifier
|
||||||
|
* The identifier of the object to retrieve.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The object having the given identifier, or null if no such object
|
||||||
|
* exists.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs retrieving the requested object, or if permission
|
||||||
|
* to retrieve the object is denied.
|
||||||
|
*/
|
||||||
|
public abstract Connectable getConnectable(UserContext userContext,
|
||||||
|
String identifier) throws GuacamoleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given tunnel request type string, returning the
|
||||||
|
* TunnelRequestType which matches that string, as declared by
|
||||||
|
* {@link #PARAMETER_VALUE}. If no such type exists, null is returned.
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* The type string to parse.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The TunnelRequestType which specifies the given string as its
|
||||||
|
* {@link #PARAMETER_VALUE}, or null if no such type exists.
|
||||||
|
*/
|
||||||
|
public static TunnelRequestType parseType(String type) {
|
||||||
|
|
||||||
|
// Locate type with given parameter value
|
||||||
|
for (TunnelRequestType possibleType : values()) {
|
||||||
|
if (type.equals(possibleType.PARAMETER_VALUE))
|
||||||
|
return possibleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No such type
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user