mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-586: Use data source when connecting to connections or groups. Remove deprecated getUserContext() from GuacamoleSession and related classes. Use identifiers which embed the data source for client URLs.
This commit is contained in:
@@ -115,40 +115,6 @@ public class GuacamoleSession {
|
|||||||
this.authenticatedUser = authenticatedUser;
|
this.authenticatedUser = authenticatedUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the UserContext associated with this session.
|
|
||||||
*
|
|
||||||
* @return The UserContext associated with this session.
|
|
||||||
*/
|
|
||||||
public UserContext getUserContext() {
|
|
||||||
|
|
||||||
// Warn of deprecation
|
|
||||||
logger.debug(
|
|
||||||
"\n****************************************************************"
|
|
||||||
+ "\n"
|
|
||||||
+ "\n !!!! PLEASE DO NOT USE getUserContext() !!!!"
|
|
||||||
+ "\n"
|
|
||||||
+ "\n getUserContext() has been replaced by getUserContexts(), which"
|
|
||||||
+ "\n properly handles multiple authentication providers. All use of"
|
|
||||||
+ "\n the old getUserContext() must be removed before GUAC-586 can"
|
|
||||||
+ "\n be considered complete."
|
|
||||||
+ "\n"
|
|
||||||
+ "\n****************************************************************"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Return the UserContext associated with the AuthenticationProvider
|
|
||||||
// that authenticated the current user.
|
|
||||||
String authProviderIdentifier = authenticatedUser.getAuthenticationProvider().getIdentifier();
|
|
||||||
for (UserContext userContext : userContexts) {
|
|
||||||
if (userContext.getAuthenticationProvider().getIdentifier().equals(authProviderIdentifier))
|
|
||||||
return userContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not found, return null
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all UserContexts associated with this session. Each
|
* Returns a list of all UserContexts associated with this session. Each
|
||||||
* AuthenticationProvider currently loaded by Guacamole may provide its own
|
* AuthenticationProvider currently loaded by Guacamole may provide its own
|
||||||
|
@@ -31,7 +31,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
*
|
*
|
||||||
* @author Michael Jumper
|
* @author Michael Jumper
|
||||||
*/
|
*/
|
||||||
public class HTTPTunnelRequest implements TunnelRequest {
|
public class HTTPTunnelRequest extends TunnelRequest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The wrapped HttpServletRequest.
|
* The wrapped HttpServletRequest.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Glyptodon LLC
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,88 +23,331 @@
|
|||||||
package org.glyptodon.guacamole.net.basic;
|
package org.glyptodon.guacamole.net.basic;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request interface which provides only the functions absolutely required
|
* A request object which provides only the functions absolutely required to
|
||||||
* to retrieve and connect to a tunnel.
|
* retrieve and connect to a tunnel.
|
||||||
*
|
*
|
||||||
* @author Michael Jumper
|
* @author Michael Jumper
|
||||||
*/
|
*/
|
||||||
public interface TunnelRequest {
|
public abstract class TunnelRequest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All supported identifier types.
|
* The name of the request parameter containing the user's authentication
|
||||||
|
* token.
|
||||||
*/
|
*/
|
||||||
public static enum IdentifierType {
|
public static final String AUTH_TOKEN_PARAMETER = "token";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter containing the identifier of the
|
||||||
|
* AuthenticationProvider associated with the UserContext containing the
|
||||||
|
* object to which a tunnel is being requested.
|
||||||
|
*/
|
||||||
|
public static final String AUTH_PROVIDER_IDENTIFIER_PARAMETER = "GUAC_DATA_SOURCE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter specifying the type of object to which a
|
||||||
|
* tunnel is being requested. Currently, this may be "c" for a Guacamole
|
||||||
|
* connection, or "g" for a Guacamole connection group.
|
||||||
|
*/
|
||||||
|
public static final String TYPE_PARAMETER = "GUAC_TYPE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter containing the unique identifier of the object
|
||||||
|
* to which a tunnel is being requested.
|
||||||
|
*/
|
||||||
|
public static final String IDENTIFIER_PARAMETER = "GUAC_ID";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter containing the desired display width, in
|
||||||
|
* pixels.
|
||||||
|
*/
|
||||||
|
public static final String WIDTH_PARAMETER = "GUAC_WIDTH";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter containing the desired display height, in
|
||||||
|
* pixels.
|
||||||
|
*/
|
||||||
|
public static final String HEIGHT_PARAMETER = "GUAC_HEIGHT";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter containing the desired display resolution, in
|
||||||
|
* DPI.
|
||||||
|
*/
|
||||||
|
public static final String DPI_PARAMETER = "GUAC_DPI";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter specifying one supported audio mimetype. This
|
||||||
|
* will normally appear multiple times within a single tunnel request -
|
||||||
|
* once for each mimetype.
|
||||||
|
*/
|
||||||
|
public static final String AUDIO_PARAMETER = "GUAC_AUDIO";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the parameter specifying one supported video mimetype. This
|
||||||
|
* will normally appear multiple times within a single tunnel request -
|
||||||
|
* once for each mimetype.
|
||||||
|
*/
|
||||||
|
public static final String VIDEO_PARAMETER = "GUAC_VIDEO";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All supported object types that can be used as the destination of a
|
||||||
|
* tunnel.
|
||||||
|
*/
|
||||||
|
public static enum Type {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique identifier of a connection.
|
* A Guacamole connection.
|
||||||
*/
|
*/
|
||||||
CONNECTION("c/"),
|
CONNECTION("c"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique identifier of a connection group.
|
* A Guacamole connection group.
|
||||||
*/
|
*/
|
||||||
CONNECTION_GROUP("g/");
|
CONNECTION_GROUP("g");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter value which denotes a destination object of this type.
|
||||||
|
*/
|
||||||
|
final String PARAMETER_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The prefix which precedes an identifier of this type.
|
* Defines a Type having the given corresponding parameter value.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* The parameter value which denotes a destination object of this
|
||||||
|
* type.
|
||||||
*/
|
*/
|
||||||
final String PREFIX;
|
Type(String value) {
|
||||||
|
PARAMETER_VALUE = value;
|
||||||
/**
|
|
||||||
* Defines an IdentifierType having the given prefix.
|
|
||||||
* @param prefix The prefix which will precede any identifier of this
|
|
||||||
* type, thus differentiating it from other identifier
|
|
||||||
* types.
|
|
||||||
*/
|
|
||||||
IdentifierType(String prefix) {
|
|
||||||
PREFIX = prefix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Given an identifier, determines the corresponding identifier type.
|
|
||||||
*
|
|
||||||
* @param identifier The identifier whose type should be identified.
|
|
||||||
* @return The identified identifier type.
|
|
||||||
*/
|
|
||||||
static IdentifierType getType(String identifier) {
|
|
||||||
|
|
||||||
// If null, no known identifier
|
|
||||||
if (identifier == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Connection identifiers
|
|
||||||
if (identifier.startsWith(CONNECTION.PREFIX))
|
|
||||||
return CONNECTION;
|
|
||||||
|
|
||||||
// Connection group identifiers
|
|
||||||
if (identifier.startsWith(CONNECTION_GROUP.PREFIX))
|
|
||||||
return CONNECTION_GROUP;
|
|
||||||
|
|
||||||
// Otherwise, unknown
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the parameter having the given name.
|
* Returns the value of the parameter having the given name.
|
||||||
*
|
*
|
||||||
* @param name The name of the parameter to return.
|
* @param name
|
||||||
* @return The value of the parameter having the given name, or null
|
* The name of the parameter to return.
|
||||||
* if no such parameter was specified.
|
*
|
||||||
|
* @return
|
||||||
|
* The value of the parameter having the given name, or null if no such
|
||||||
|
* parameter was specified.
|
||||||
*/
|
*/
|
||||||
public String getParameter(String name);
|
public abstract String getParameter(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all values specified for the given parameter.
|
* Returns a list of all values specified for the given parameter.
|
||||||
*
|
*
|
||||||
* @param name The name of the parameter to return.
|
* @param name
|
||||||
* @return All values of the parameter having the given name , or null
|
* The name of the parameter to return.
|
||||||
* if no such parameter was specified.
|
*
|
||||||
|
* @return
|
||||||
|
* All values of the parameter having the given name , or null if no
|
||||||
|
* such parameter was specified.
|
||||||
*/
|
*/
|
||||||
public List<String> getParameterValues(String name);
|
public abstract List<String> getParameterValues(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the parameter having the given name, throwing an
|
||||||
|
* exception if the parameter is missing.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* The name of the parameter to return.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The value of the parameter having the given name.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the parameter is not present in the request.
|
||||||
|
*/
|
||||||
|
public String getRequiredParameter(String name) throws GuacamoleException {
|
||||||
|
|
||||||
|
// Pull requested parameter, aborting if absent
|
||||||
|
String value = getParameter(name);
|
||||||
|
if (value == null)
|
||||||
|
throw new GuacamoleClientException("Parameter \"" + name + "\" is required.");
|
||||||
|
|
||||||
|
return value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the integer value of the parameter having the given name,
|
||||||
|
* throwing an exception if the parameter cannot be parsed.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* The name of the parameter to return.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The integer value of the parameter having the given name, or null if
|
||||||
|
* the parameter is missing.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the parameter is not a valid integer.
|
||||||
|
*/
|
||||||
|
public Integer getIntegerParameter(String name) throws GuacamoleException {
|
||||||
|
|
||||||
|
// Pull requested parameter
|
||||||
|
String value = getParameter(name);
|
||||||
|
if (value == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Attempt to parse as an integer
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rethrow any parsing error as a GuacamoleClientException
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
throw new GuacamoleClientException("Parameter \"" + name + "\" must be a valid integer.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the authentication token associated with this tunnel request.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The authentication token associated with this tunnel request, or
|
||||||
|
* null if no authentication token is present.
|
||||||
|
*/
|
||||||
|
public String getAuthenticationToken() {
|
||||||
|
return getParameter(AUTH_TOKEN_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identifier of the AuthenticationProvider associated with the
|
||||||
|
* UserContext from which the connection or connection group is to be
|
||||||
|
* retrieved when the tunnel is created. In the context of the REST API and
|
||||||
|
* the JavaScript side of the web application, this is referred to as the
|
||||||
|
* data source identifier.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The identifier of the AuthenticationProvider associated with the
|
||||||
|
* UserContext from which the connection or connection group is to be
|
||||||
|
* retrieved when the tunnel is created.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the identifier was not present in the request.
|
||||||
|
*/
|
||||||
|
public String getAuthenticationProviderIdentifier()
|
||||||
|
throws GuacamoleException {
|
||||||
|
return getRequiredParameter(AUTH_PROVIDER_IDENTIFIER_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type of object for which the tunnel is being requested.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The type of object for which the tunnel is being requested.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the type was not present in the request, or if the type requested
|
||||||
|
* is in the wrong format.
|
||||||
|
*/
|
||||||
|
public Type getType() throws GuacamoleException {
|
||||||
|
|
||||||
|
String type = getRequiredParameter(TYPE_PARAMETER);
|
||||||
|
|
||||||
|
// For each possible object 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.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the identifier of the destination of the tunnel being requested.
|
||||||
|
* As there are multiple types of destination objects available, and within
|
||||||
|
* multiple data sources, the associated object type and data source are
|
||||||
|
* also necessary to determine what this identifier refers to.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The identifier of the destination of the tunnel being requested.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the identifier was not present in the request.
|
||||||
|
*/
|
||||||
|
public String getIdentifier() throws GuacamoleException {
|
||||||
|
return getRequiredParameter(IDENTIFIER_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the display width desired for the Guacamole session over the
|
||||||
|
* tunnel being requested.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The display width desired for the Guacamole session over the tunnel
|
||||||
|
* being requested, or null if no width was given.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the width specified was not a valid integer.
|
||||||
|
*/
|
||||||
|
public Integer getWidth() throws GuacamoleException {
|
||||||
|
return getIntegerParameter(WIDTH_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the display height desired for the Guacamole session over the
|
||||||
|
* tunnel being requested.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The display height desired for the Guacamole session over the tunnel
|
||||||
|
* being requested, or null if no width was given.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the height specified was not a valid integer.
|
||||||
|
*/
|
||||||
|
public Integer getHeight() throws GuacamoleException {
|
||||||
|
return getIntegerParameter(HEIGHT_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the display resolution desired for the Guacamole session over
|
||||||
|
* the tunnel being requested, in DPI.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The display resolution desired for the Guacamole session over the
|
||||||
|
* tunnel being requested, or null if no resolution was given.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the resolution specified was not a valid integer.
|
||||||
|
*/
|
||||||
|
public Integer getDPI() throws GuacamoleException {
|
||||||
|
return getIntegerParameter(DPI_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all audio mimetypes declared as supported within the
|
||||||
|
* tunnel request.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A list of all audio mimetypes declared as supported within the
|
||||||
|
* tunnel request, or null if no mimetypes were specified.
|
||||||
|
*/
|
||||||
|
public List<String> getAudioMimetypes() {
|
||||||
|
return getParameterValues(AUDIO_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all video mimetypes declared as supported within the
|
||||||
|
* tunnel request.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A list of all video mimetypes declared as supported within the
|
||||||
|
* tunnel request, or null if no mimetypes were specified.
|
||||||
|
*/
|
||||||
|
public List<String> getVideoMimetypes() {
|
||||||
|
return getParameterValues(VIDEO_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -25,16 +25,15 @@ package org.glyptodon.guacamole.net.basic;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
|
||||||
import org.glyptodon.guacamole.GuacamoleException;
|
import org.glyptodon.guacamole.GuacamoleException;
|
||||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||||
import org.glyptodon.guacamole.environment.Environment;
|
|
||||||
import org.glyptodon.guacamole.net.DelegatingGuacamoleTunnel;
|
import org.glyptodon.guacamole.net.DelegatingGuacamoleTunnel;
|
||||||
import org.glyptodon.guacamole.net.GuacamoleTunnel;
|
import org.glyptodon.guacamole.net.GuacamoleTunnel;
|
||||||
import org.glyptodon.guacamole.net.auth.Connection;
|
import org.glyptodon.guacamole.net.auth.Connection;
|
||||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||||
import org.glyptodon.guacamole.net.auth.Directory;
|
import org.glyptodon.guacamole.net.auth.Directory;
|
||||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||||
|
import org.glyptodon.guacamole.net.basic.rest.ObjectRetrievalService;
|
||||||
import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService;
|
import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService;
|
||||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -53,12 +52,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class TunnelRequestService {
|
public class TunnelRequestService {
|
||||||
|
|
||||||
/**
|
|
||||||
* The Guacamole server environment.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
private Environment environment;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger for this class.
|
* Logger for this class.
|
||||||
*/
|
*/
|
||||||
@@ -70,6 +63,12 @@ public class TunnelRequestService {
|
|||||||
@Inject
|
@Inject
|
||||||
private AuthenticationService authenticationService;
|
private AuthenticationService authenticationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for convenient retrieval of objects.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private ObjectRetrievalService retrievalService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads and returns the client information provided within the given
|
* Reads and returns the client information provided within the given
|
||||||
* request.
|
* request.
|
||||||
@@ -80,35 +79,40 @@ public class TunnelRequestService {
|
|||||||
* @return GuacamoleClientInformation
|
* @return GuacamoleClientInformation
|
||||||
* An object containing information about the client sending the tunnel
|
* An object containing information about the client sending the tunnel
|
||||||
* request.
|
* request.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If the parameters of the tunnel request are invalid.
|
||||||
*/
|
*/
|
||||||
protected GuacamoleClientInformation getClientInformation(TunnelRequest request) {
|
protected GuacamoleClientInformation getClientInformation(TunnelRequest request)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Get client information
|
// Get client information
|
||||||
GuacamoleClientInformation info = new GuacamoleClientInformation();
|
GuacamoleClientInformation info = new GuacamoleClientInformation();
|
||||||
|
|
||||||
// Set width if provided
|
// Set width if provided
|
||||||
String width = request.getParameter("width");
|
Integer width = request.getWidth();
|
||||||
if (width != null)
|
if (width != null)
|
||||||
info.setOptimalScreenWidth(Integer.parseInt(width));
|
info.setOptimalScreenWidth(width);
|
||||||
|
|
||||||
// Set height if provided
|
// Set height if provided
|
||||||
String height = request.getParameter("height");
|
Integer height = request.getHeight();
|
||||||
if (height != null)
|
if (height != null)
|
||||||
info.setOptimalScreenHeight(Integer.parseInt(height));
|
info.setOptimalScreenHeight(height);
|
||||||
|
|
||||||
// Set resolution if provided
|
// Set resolution if provided
|
||||||
String dpi = request.getParameter("dpi");
|
Integer dpi = request.getDPI();
|
||||||
if (dpi != null)
|
if (dpi != null)
|
||||||
info.setOptimalResolution(Integer.parseInt(dpi));
|
info.setOptimalResolution(dpi);
|
||||||
|
|
||||||
// Add audio mimetypes
|
// Add audio mimetypes
|
||||||
List<String> audio_mimetypes = request.getParameterValues("audio");
|
List<String> audioMimetypes = request.getAudioMimetypes();
|
||||||
if (audio_mimetypes != null)
|
if (audioMimetypes != null)
|
||||||
info.getAudioMimetypes().addAll(audio_mimetypes);
|
info.getAudioMimetypes().addAll(audioMimetypes);
|
||||||
|
|
||||||
// Add video mimetypes
|
// Add video mimetypes
|
||||||
List<String> video_mimetypes = request.getParameterValues("video");
|
List<String> videoMimetypes = request.getVideoMimetypes();
|
||||||
if (video_mimetypes != null)
|
if (videoMimetypes != null)
|
||||||
info.getVideoMimetypes().addAll(video_mimetypes);
|
info.getVideoMimetypes().addAll(videoMimetypes);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@@ -122,7 +126,7 @@ public class TunnelRequestService {
|
|||||||
* The UserContext associated with the user for whom the tunnel is
|
* The UserContext associated with the user for whom the tunnel is
|
||||||
* being created.
|
* being created.
|
||||||
*
|
*
|
||||||
* @param idType
|
* @param type
|
||||||
* The type of object being connected to (connection or group).
|
* The type of object being connected to (connection or group).
|
||||||
*
|
*
|
||||||
* @param id
|
* @param id
|
||||||
@@ -138,13 +142,13 @@ 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.IdentifierType idType, String id,
|
final TunnelRequest.Type type, String id,
|
||||||
GuacamoleClientInformation info)
|
GuacamoleClientInformation info)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Create connected tunnel from identifier
|
// Create connected tunnel from identifier
|
||||||
GuacamoleTunnel tunnel = null;
|
GuacamoleTunnel tunnel = null;
|
||||||
switch (idType) {
|
switch (type) {
|
||||||
|
|
||||||
// Connection identifiers
|
// Connection identifiers
|
||||||
case CONNECTION: {
|
case CONNECTION: {
|
||||||
@@ -205,7 +209,7 @@ public class TunnelRequestService {
|
|||||||
* @param session
|
* @param session
|
||||||
* The Guacamole session to associate the tunnel with.
|
* The Guacamole session to associate the tunnel with.
|
||||||
*
|
*
|
||||||
* @param idType
|
* @param type
|
||||||
* The type of object being connected to (connection or group).
|
* The type of object being connected to (connection or group).
|
||||||
*
|
*
|
||||||
* @param id
|
* @param id
|
||||||
@@ -220,7 +224,7 @@ public class TunnelRequestService {
|
|||||||
* If an error occurs while obtaining the tunnel.
|
* If an error occurs while obtaining the tunnel.
|
||||||
*/
|
*/
|
||||||
protected GuacamoleTunnel createAssociatedTunnel(final GuacamoleSession session,
|
protected GuacamoleTunnel createAssociatedTunnel(final GuacamoleSession session,
|
||||||
GuacamoleTunnel tunnel, final TunnelRequest.IdentifierType idType,
|
GuacamoleTunnel tunnel, final TunnelRequest.Type type,
|
||||||
final String id) throws GuacamoleException {
|
final String id) throws GuacamoleException {
|
||||||
|
|
||||||
// Monitor tunnel closure and data
|
// Monitor tunnel closure and data
|
||||||
@@ -239,7 +243,7 @@ public class TunnelRequestService {
|
|||||||
long duration = connectionEndTime - connectionStartTime;
|
long duration = connectionEndTime - connectionStartTime;
|
||||||
|
|
||||||
// Log closure
|
// Log closure
|
||||||
switch (idType) {
|
switch (type) {
|
||||||
|
|
||||||
// Connection identifiers
|
// Connection identifiers
|
||||||
case CONNECTION:
|
case CONNECTION:
|
||||||
@@ -289,27 +293,20 @@ public class TunnelRequestService {
|
|||||||
public GuacamoleTunnel createTunnel(TunnelRequest request)
|
public GuacamoleTunnel createTunnel(TunnelRequest request)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Get auth token and session
|
// Parse request parameters
|
||||||
final String authToken = request.getParameter("authToken");
|
String authToken = request.getAuthenticationToken();
|
||||||
final GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
|
String id = request.getIdentifier();
|
||||||
|
TunnelRequest.Type type = request.getType();
|
||||||
// Get client information and connection ID from request
|
String authProviderIdentifier = request.getAuthenticationProviderIdentifier();
|
||||||
String id = request.getParameter("id");
|
GuacamoleClientInformation info = getClientInformation(request);
|
||||||
final GuacamoleClientInformation info = getClientInformation(request);
|
|
||||||
|
|
||||||
// Determine ID type
|
|
||||||
TunnelRequest.IdentifierType idType = TunnelRequest.IdentifierType.getType(id);
|
|
||||||
if (idType == null)
|
|
||||||
throw new GuacamoleClientException("Illegal identifier - unknown type.");
|
|
||||||
|
|
||||||
// Remove prefix
|
|
||||||
id = id.substring(idType.PREFIX.length());
|
|
||||||
|
|
||||||
// Create connected tunnel using provided connection ID and client information
|
// Create connected tunnel using provided connection ID and client information
|
||||||
final GuacamoleTunnel tunnel = createConnectedTunnel(session.getUserContext(), idType, id, info);
|
GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
|
||||||
|
UserContext userContext = retrievalService.retrieveUserContext(session, authProviderIdentifier);
|
||||||
|
GuacamoleTunnel tunnel = createConnectedTunnel(userContext, type, id, info);
|
||||||
|
|
||||||
// Associate tunnel with session
|
// Associate tunnel with session
|
||||||
return createAssociatedTunnel(session, tunnel, idType, id);
|
return createAssociatedTunnel(session, tunnel, type, id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -66,19 +66,6 @@ public class AuthenticationService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the UserContext for a given auth token, if the auth token represents
|
|
||||||
* a currently logged in user. Throws an unauthorized error otherwise.
|
|
||||||
*
|
|
||||||
* @param authToken The auth token to check against the map of logged in users.
|
|
||||||
* @return The user context that corresponds to the provided auth token.
|
|
||||||
* @throws GuacamoleException If the auth token does not correspond to any
|
|
||||||
* logged in user.
|
|
||||||
*/
|
|
||||||
public UserContext getUserContext(String authToken) throws GuacamoleException {
|
|
||||||
return getGuacamoleSession(authToken).getUserContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all UserContexts associated with a given auth token, if the auth
|
* Returns all UserContexts associated with a given auth token, if the auth
|
||||||
* token represents a currently logged in user. Throws an unauthorized
|
* token represents a currently logged in user. Throws an unauthorized
|
||||||
|
@@ -32,7 +32,7 @@ import org.glyptodon.guacamole.net.basic.TunnelRequest;
|
|||||||
*
|
*
|
||||||
* @author Michael Jumper
|
* @author Michael Jumper
|
||||||
*/
|
*/
|
||||||
public class WebSocketTunnelRequest implements TunnelRequest {
|
public class WebSocketTunnelRequest extends TunnelRequest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All parameters passed via HTTP to the WebSocket handshake.
|
* All parameters passed via HTTP to the WebSocket handshake.
|
||||||
|
@@ -33,7 +33,7 @@ import org.glyptodon.guacamole.net.basic.TunnelRequest;
|
|||||||
*
|
*
|
||||||
* @author Michael Jumper
|
* @author Michael Jumper
|
||||||
*/
|
*/
|
||||||
public class WebSocketTunnelRequest implements TunnelRequest {
|
public class WebSocketTunnelRequest extends TunnelRequest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All parameters passed via HTTP to the WebSocket handshake.
|
* All parameters passed via HTTP to the WebSocket handshake.
|
||||||
|
@@ -158,7 +158,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
var RECONNECT_ACTION = {
|
var RECONNECT_ACTION = {
|
||||||
name : "CLIENT.ACTION_RECONNECT",
|
name : "CLIENT.ACTION_RECONNECT",
|
||||||
callback : function reconnectCallback() {
|
callback : function reconnectCallback() {
|
||||||
$scope.client = guacClientManager.replaceManagedClient(uniqueId, $routeParams.params);
|
$scope.client = guacClientManager.replaceManagedClient($routeParams.id, $routeParams.params);
|
||||||
guacNotification.showStatus(false);
|
guacNotification.showStatus(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -219,13 +219,13 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
$scope.$on('guacClientClipboard', function clientClipboardListener(event, client, mimetype, clipboardData) {
|
$scope.$on('guacClientClipboard', function clientClipboardListener(event, client, mimetype, clipboardData) {
|
||||||
$scope.clipboardData = clipboardData;
|
$scope.clipboardData = clipboardData;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Parse the type, name, and id out of the url paramteres,
|
* The client which should be attached to the client UI.
|
||||||
* as well as any extra parameters if set.
|
*
|
||||||
|
* @type ManagedClient
|
||||||
*/
|
*/
|
||||||
var uniqueId = $routeParams.type + '/' + $routeParams.id;
|
$scope.client = guacClientManager.getManagedClient($routeParams.id, $routeParams.params);
|
||||||
$scope.client = guacClientManager.getManagedClient(uniqueId, $routeParams.params);
|
|
||||||
|
|
||||||
var keysCurrentlyPressed = {};
|
var keysCurrentlyPressed = {};
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
|
|
||||||
// Required types
|
// Required types
|
||||||
var ClientProperties = $injector.get('ClientProperties');
|
var ClientProperties = $injector.get('ClientProperties');
|
||||||
|
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||||
var ManagedClientState = $injector.get('ManagedClientState');
|
var ManagedClientState = $injector.get('ManagedClientState');
|
||||||
var ManagedDisplay = $injector.get('ManagedDisplay');
|
var ManagedDisplay = $injector.get('ManagedDisplay');
|
||||||
var ManagedFileDownload = $injector.get('ManagedFileDownload');
|
var ManagedFileDownload = $injector.get('ManagedFileDownload');
|
||||||
@@ -153,8 +154,8 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
* desired connection ID, display resolution, and supported audio/video
|
* desired connection ID, display resolution, and supported audio/video
|
||||||
* codecs.
|
* codecs.
|
||||||
*
|
*
|
||||||
* @param {String} id
|
* @param {ClientIdentifier} identifier
|
||||||
* The ID of the connection or group to connect to.
|
* The identifier representing the connection or group to connect to.
|
||||||
*
|
*
|
||||||
* @param {String} [connectionParameters]
|
* @param {String} [connectionParameters]
|
||||||
* Any additional HTTP parameters to pass while connecting.
|
* Any additional HTTP parameters to pass while connecting.
|
||||||
@@ -163,7 +164,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
* The string of connection parameters to be passed to the Guacamole
|
* The string of connection parameters to be passed to the Guacamole
|
||||||
* client.
|
* client.
|
||||||
*/
|
*/
|
||||||
var getConnectString = function getConnectString(id, connectionParameters) {
|
var getConnectString = function getConnectString(identifier, connectionParameters) {
|
||||||
|
|
||||||
// Calculate optimal width/height for display
|
// Calculate optimal width/height for display
|
||||||
var pixel_density = $window.devicePixelRatio || 1;
|
var pixel_density = $window.devicePixelRatio || 1;
|
||||||
@@ -173,21 +174,23 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
|
|
||||||
// Build base connect string
|
// Build base connect string
|
||||||
var connectString =
|
var connectString =
|
||||||
"id=" + encodeURIComponent(id)
|
"token=" + encodeURIComponent(authenticationService.getCurrentToken())
|
||||||
+ "&authToken=" + encodeURIComponent(authenticationService.getCurrentToken())
|
+ "&GUAC_DATA_SOURCE=" + encodeURIComponent(identifier.dataSource)
|
||||||
+ "&width=" + Math.floor(optimal_width)
|
+ "&GUAC_ID=" + encodeURIComponent(identifier.id)
|
||||||
+ "&height=" + Math.floor(optimal_height)
|
+ "&GUAC_TYPE=" + encodeURIComponent(identifier.type)
|
||||||
+ "&dpi=" + Math.floor(optimal_dpi)
|
+ "&GUAC_WIDTH=" + Math.floor(optimal_width)
|
||||||
|
+ "&GUAC_HEIGHT=" + Math.floor(optimal_height)
|
||||||
|
+ "&GUAC_DPI=" + Math.floor(optimal_dpi)
|
||||||
+ (connectionParameters ? '&' + connectionParameters : '');
|
+ (connectionParameters ? '&' + connectionParameters : '');
|
||||||
|
|
||||||
// Add audio mimetypes to connect_string
|
// Add audio mimetypes to connect_string
|
||||||
guacAudio.supported.forEach(function(mimetype) {
|
guacAudio.supported.forEach(function(mimetype) {
|
||||||
connectString += "&audio=" + encodeURIComponent(mimetype);
|
connectString += "&GUAC_AUDIO=" + encodeURIComponent(mimetype);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add video mimetypes to connect_string
|
// Add video mimetypes to connect_string
|
||||||
guacVideo.supported.forEach(function(mimetype) {
|
guacVideo.supported.forEach(function(mimetype) {
|
||||||
connectString += "&video=" + encodeURIComponent(mimetype);
|
connectString += "&GUAC_VIDEO=" + encodeURIComponent(mimetype);
|
||||||
});
|
});
|
||||||
|
|
||||||
return connectString;
|
return connectString;
|
||||||
@@ -238,7 +241,9 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
* or group.
|
* or group.
|
||||||
*
|
*
|
||||||
* @param {String} id
|
* @param {String} id
|
||||||
* The ID of the connection or group to connect to.
|
* The ID of the connection or group to connect to. This String must be
|
||||||
|
* a valid ClientIdentifier string, as would be generated by
|
||||||
|
* ClientIdentifier.toString().
|
||||||
*
|
*
|
||||||
* @param {String} [connectionParameters]
|
* @param {String} [connectionParameters]
|
||||||
* Any additional HTTP parameters to pass while connecting.
|
* Any additional HTTP parameters to pass while connecting.
|
||||||
@@ -402,23 +407,23 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector',
|
|||||||
// Manage the client display
|
// Manage the client display
|
||||||
managedClient.managedDisplay = ManagedDisplay.getInstance(client.getDisplay());
|
managedClient.managedDisplay = ManagedDisplay.getInstance(client.getDisplay());
|
||||||
|
|
||||||
// Connect the Guacamole client
|
// Parse connection details from ID
|
||||||
client.connect(getConnectString(id, connectionParameters));
|
var clientIdentifier = ClientIdentifier.fromString(id);
|
||||||
|
|
||||||
// Determine type of connection
|
// Connect the Guacamole client
|
||||||
var typePrefix = id.substring(0, 2);
|
client.connect(getConnectString(clientIdentifier, connectionParameters));
|
||||||
|
|
||||||
// If using a connection, pull connection name
|
// If using a connection, pull connection name
|
||||||
if (typePrefix === 'c/') {
|
if (clientIdentifier.type === ClientIdentifier.Types.CONNECTION) {
|
||||||
connectionService.getConnection(id.substring(2))
|
connectionService.getConnection(clientIdentifier.dataSource, clientIdentifier.id)
|
||||||
.success(function connectionRetrieved(connection) {
|
.success(function connectionRetrieved(connection) {
|
||||||
managedClient.name = connection.name;
|
managedClient.name = connection.name;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// If using a connection group, pull connection name
|
// If using a connection group, pull connection name
|
||||||
else if (typePrefix === 'g/') {
|
else if (clientIdentifier.type === ClientIdentifier.Types.CONNECTION_GROUP) {
|
||||||
connectionGroupService.getConnectionGroup(id.substring(2))
|
connectionGroupService.getConnectionGroup(clientIdentifier.dataSource, clientIdentifier.id)
|
||||||
.success(function connectionGroupRetrieved(group) {
|
.success(function connectionGroupRetrieved(group) {
|
||||||
managedClient.name = group.name;
|
managedClient.name = group.name;
|
||||||
});
|
});
|
||||||
|
@@ -27,7 +27,8 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
|||||||
function homeController($scope, $injector) {
|
function homeController($scope, $injector) {
|
||||||
|
|
||||||
// Get required types
|
// Get required types
|
||||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||||
|
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||||
|
|
||||||
// Get required services
|
// Get required services
|
||||||
var authenticationService = $injector.get('authenticationService');
|
var authenticationService = $injector.get('authenticationService');
|
||||||
@@ -56,6 +57,51 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object passed to the guacGroupList directive, providing context-specific
|
||||||
|
* functions or data.
|
||||||
|
*/
|
||||||
|
$scope.context = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unique string identifier which must be used when
|
||||||
|
* connecting to a connection or connection group represented by the
|
||||||
|
* given GroupListItem.
|
||||||
|
*
|
||||||
|
* @param {GroupListItem} item
|
||||||
|
* The GroupListItem to determine the client identifier of.
|
||||||
|
*
|
||||||
|
* @returns {String}
|
||||||
|
* The client identifier associated with the connection or
|
||||||
|
* connection group represented by the given GroupListItem, or null
|
||||||
|
* if the GroupListItem cannot have an associated client
|
||||||
|
* identifier.
|
||||||
|
*/
|
||||||
|
getClientIdentifier : function getClientIdentifier(item) {
|
||||||
|
|
||||||
|
// If the item is a connection, generate a connection identifier
|
||||||
|
if (item.isConnection)
|
||||||
|
return ClientIdentifier.toString({
|
||||||
|
dataSource : item.dataSource,
|
||||||
|
type : ClientIdentifier.Types.CONNECTION,
|
||||||
|
id : item.identifier
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the item is a connection, generate a connection group identifier
|
||||||
|
if (item.isConnectionGroup)
|
||||||
|
return ClientIdentifier.toString({
|
||||||
|
dataSource : item.dataSource,
|
||||||
|
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
||||||
|
id : item.identifier
|
||||||
|
});
|
||||||
|
|
||||||
|
// Otherwise, no such identifier can exist
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Retrieve root groups and all descendants
|
// Retrieve root groups and all descendants
|
||||||
dataSourceService.apply(
|
dataSourceService.apply(
|
||||||
connectionGroupService.getConnectionGroupTree,
|
connectionGroupService.getConnectionGroupTree,
|
||||||
|
@@ -48,6 +48,7 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
|
|||||||
|
|
||||||
// Required types
|
// Required types
|
||||||
var ActiveConnection = $injector.get('ActiveConnection');
|
var ActiveConnection = $injector.get('ActiveConnection');
|
||||||
|
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||||
var RecentConnection = $injector.get('RecentConnection');
|
var RecentConnection = $injector.get('RecentConnection');
|
||||||
|
|
||||||
// Required services
|
// Required services
|
||||||
@@ -104,7 +105,11 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
|
|||||||
var addVisibleConnection = function addVisibleConnection(dataSource, connection) {
|
var addVisibleConnection = function addVisibleConnection(dataSource, connection) {
|
||||||
|
|
||||||
// Add given connection to set of visible objects
|
// Add given connection to set of visible objects
|
||||||
visibleObjects['c/' + connection.identifier] = connection;
|
visibleObjects[ClientIdentifier.toString({
|
||||||
|
dataSource : dataSource,
|
||||||
|
type : ClientIdentifier.Types.CONNECTION,
|
||||||
|
id : connection.identifier
|
||||||
|
})] = connection;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,7 +128,11 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
|
|||||||
var addVisibleConnectionGroup = function addVisibleConnectionGroup(dataSource, connectionGroup) {
|
var addVisibleConnectionGroup = function addVisibleConnectionGroup(dataSource, connectionGroup) {
|
||||||
|
|
||||||
// Add given connection group to set of visible objects
|
// Add given connection group to set of visible objects
|
||||||
visibleObjects['g/' + connectionGroup.identifier] = connectionGroup;
|
visibleObjects[ClientIdentifier.toString({
|
||||||
|
dataSource : dataSource,
|
||||||
|
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
||||||
|
id : connectionGroup.identifier
|
||||||
|
})] = connectionGroup;
|
||||||
|
|
||||||
// Add all child connections
|
// Add all child connections
|
||||||
if (connectionGroup.childConnections)
|
if (connectionGroup.childConnections)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<a ng-href="#/client/c/{{item.identifier}}">
|
<a ng-href="#/client/{{context.getClientIdentifier(item)}}">
|
||||||
<!--
|
<!--
|
||||||
Copyright (C) 2014 Glyptodon LLC
|
Copyright (C) 2014 Glyptodon LLC
|
||||||
|
|
||||||
|
@@ -21,6 +21,6 @@
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<a ng-show="item.isBalancing" ng-href="#/client/g/{{item.identifier}}">{{item.name}}</a>
|
<a ng-show="item.isBalancing" ng-href="#/client/{{context.getClientIdentifier(item)}}">{{item.name}}</a>
|
||||||
<span ng-show="!item.isBalancing">{{item.name}}</span>
|
<span ng-show="!item.isBalancing">{{item.name}}</span>
|
||||||
</span>
|
</span>
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
<h2 class="header">{{'HOME.SECTION_HEADER_ALL_CONNECTIONS' | translate}}</h2>
|
<h2 class="header">{{'HOME.SECTION_HEADER_ALL_CONNECTIONS' | translate}}</h2>
|
||||||
<div class="all-connections">
|
<div class="all-connections">
|
||||||
<guac-group-list
|
<guac-group-list
|
||||||
|
context="context"
|
||||||
connection-groups="rootConnectionGroups"
|
connection-groups="rootConnectionGroups"
|
||||||
connection-template="'app/home/templates/connection.html'"
|
connection-template="'app/home/templates/connection.html'"
|
||||||
connection-group-template="'app/home/templates/connectionGroup.html'"
|
connection-group-template="'app/home/templates/connectionGroup.html'"
|
||||||
|
@@ -159,7 +159,7 @@ angular.module('index').config(['$routeProvider', '$locationProvider',
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Client view
|
// Client view
|
||||||
.when('/client/:type/:id/:params?', {
|
.when('/client/:id/:params?', {
|
||||||
bodyClassName : 'client',
|
bodyClassName : 'client',
|
||||||
templateUrl : 'app/client/templates/client.html',
|
templateUrl : 'app/client/templates/client.html',
|
||||||
controller : 'clientController',
|
controller : 'clientController',
|
||||||
|
@@ -23,4 +23,8 @@
|
|||||||
/**
|
/**
|
||||||
* Module for generating and implementing user navigation options.
|
* Module for generating and implementing user navigation options.
|
||||||
*/
|
*/
|
||||||
angular.module('navigation', ['notification', 'rest']);
|
angular.module('navigation', [
|
||||||
|
'auth',
|
||||||
|
'notification',
|
||||||
|
'rest'
|
||||||
|
]);
|
||||||
|
@@ -27,9 +27,10 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
|||||||
function userPageService($injector) {
|
function userPageService($injector) {
|
||||||
|
|
||||||
// Get required types
|
// Get required types
|
||||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
var ClientIdentifier = $injector.get('ClientIdentifier');
|
||||||
var PageDefinition = $injector.get('PageDefinition');
|
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||||
var PermissionSet = $injector.get('PermissionSet');
|
var PageDefinition = $injector.get('PageDefinition');
|
||||||
|
var PermissionSet = $injector.get('PermissionSet');
|
||||||
|
|
||||||
// Get required services
|
// Get required services
|
||||||
var $q = $injector.get('$q');
|
var $q = $injector.get('$q');
|
||||||
@@ -102,7 +103,11 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
|||||||
if (connection) {
|
if (connection) {
|
||||||
homePage = new PageDefinition(
|
homePage = new PageDefinition(
|
||||||
connection.name,
|
connection.name,
|
||||||
'/client/c/' + encodeURIComponent(connection.identifier)
|
'/client/' + ClientIdentifier.toString({
|
||||||
|
dataSource : dataSource,
|
||||||
|
type : ClientIdentifier.Types.CONNECTION,
|
||||||
|
id : connection.identifier
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +118,11 @@ angular.module('navigation').factory('userPageService', ['$injector',
|
|||||||
&& _.isEmpty(connectionGroup.childConnectionGroups)) {
|
&& _.isEmpty(connectionGroup.childConnectionGroups)) {
|
||||||
homePage = new PageDefinition(
|
homePage = new PageDefinition(
|
||||||
connectionGroup.name,
|
connectionGroup.name,
|
||||||
'/client/g/' + encodeURIComponent(connectionGroup.identifier)
|
'/client/' + ClientIdentifier.toString({
|
||||||
|
dataSource : dataSource,
|
||||||
|
type : ClientIdentifier.Types.CONNECTION_GROUP,
|
||||||
|
id : connectionGroup.identifier
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ClientIdentifier class definition.
|
||||||
|
*/
|
||||||
|
angular.module('client').factory('ClientIdentifier', ['$injector',
|
||||||
|
function defineClientIdentifier($injector) {
|
||||||
|
|
||||||
|
// Required services
|
||||||
|
var authenticationService = $injector.get('authenticationService');
|
||||||
|
var $window = $injector.get('$window');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object which uniquely identifies a particular connection or connection
|
||||||
|
* group within Guacamole. This object can be converted to/from a string to
|
||||||
|
* generate a guaranteed-unique, deterministic identifier for client URLs.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {ClientIdentifier|Object} [template={}]
|
||||||
|
* The object whose properties should be copied within the new
|
||||||
|
* ClientIdentifier.
|
||||||
|
*/
|
||||||
|
var ClientIdentifier = function ClientIdentifier(template) {
|
||||||
|
|
||||||
|
// Use empty object by default
|
||||||
|
template = template || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of the data source associated with the object to
|
||||||
|
* which the client will connect. This identifier will be the
|
||||||
|
* identifier of an AuthenticationProvider within the Guacamole web
|
||||||
|
* application.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
this.dataSource = template.dataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of object to which the client will connect. Possible values
|
||||||
|
* are defined within ClientIdentifier.Types.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
this.type = template.type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique identifier of the object to which the client will
|
||||||
|
* connect.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
this.id = template.id;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All possible ClientIdentifier types.
|
||||||
|
*
|
||||||
|
* @type Object.<String, String>
|
||||||
|
*/
|
||||||
|
ClientIdentifier.Types = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type string for a Guacamole connection.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
CONNECTION : 'c',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type string for a Guacamole connection group.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
CONNECTION_GROUP : 'g'
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given ClientIdentifier or ClientIdentifier-like object to
|
||||||
|
* a String representation. Any object having the same properties as
|
||||||
|
* ClientIdentifier may be used, but only those properties will be taken
|
||||||
|
* into account when producing the resulting String.
|
||||||
|
*
|
||||||
|
* @param {ClientIdentifier|Object} id
|
||||||
|
* The ClientIdentifier or ClientIdentifier-like object to convert to
|
||||||
|
* a String representation.
|
||||||
|
*
|
||||||
|
* @returns {String}
|
||||||
|
* A deterministic String representation of the given ClientIdentifier
|
||||||
|
* or ClientIdentifier-like object.
|
||||||
|
*/
|
||||||
|
ClientIdentifier.toString = function toString(id) {
|
||||||
|
return $window.btoa([
|
||||||
|
id.id,
|
||||||
|
id.type,
|
||||||
|
id.dataSource
|
||||||
|
].join('\0'));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given String into the corresponding ClientIdentifier. If
|
||||||
|
* the provided String is not a valid identifier, it will be interpreted
|
||||||
|
* as the identifier of a connection within the data source that
|
||||||
|
* authenticated the current user.
|
||||||
|
*
|
||||||
|
* @param {String} str
|
||||||
|
* The String to convert to a ClientIdentifier.
|
||||||
|
*
|
||||||
|
* @returns {ClientIdentifier}
|
||||||
|
* The ClientIdentifier represented by the given String.
|
||||||
|
*/
|
||||||
|
ClientIdentifier.fromString = function fromString(str) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
var values = $window.atob(str).split('\0');
|
||||||
|
return new ClientIdentifier({
|
||||||
|
id : values[0],
|
||||||
|
type : values[1],
|
||||||
|
dataSource : values[2]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the provided string is invalid, transform into a reasonable guess
|
||||||
|
catch (e) {
|
||||||
|
return new ClientIdentifier({
|
||||||
|
id : str,
|
||||||
|
type : ClientIdentifier.Types.CONNECTION,
|
||||||
|
dataSource : authenticationService.getDataSource() || 'default'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return ClientIdentifier;
|
||||||
|
|
||||||
|
}]);
|
Reference in New Issue
Block a user