GUACAMOLE-38: Code cleanup - remove unneeded code, debugging, etc. Provide proper documentation.

This commit is contained in:
Nick Couchman
2017-07-21 12:53:31 -04:00
parent ed8ca17a95
commit 7aaca96f10
9 changed files with 115 additions and 220 deletions

View File

@@ -37,6 +37,11 @@ import org.apache.guacamole.token.TokenFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class providing the necessary hooks into the Guacamole Client authentication
* process so that the QuickConnect functionality can be initialized and be used
* throughout the web client.
*/
public class QuickConnectAuthenticationProvider extends SimpleAuthenticationProvider {
/**
@@ -44,17 +49,16 @@ public class QuickConnectAuthenticationProvider extends SimpleAuthenticationProv
*/
private final Logger logger = LoggerFactory.getLogger(QuickConnectAuthenticationProvider.class);
private UserContext userContext = null;
@Inject
private Provider<QuickConnectUserContext> userContextProvider;
/**
* userContext for this authentication provider.
*/
private UserContext userContext;
@Override
public String getIdentifier() {
return "quickconnect";
}
/**
* For QuickConnect, authenticateUser simply returns null because this
* extension is designed to provide only a connection directory to users
@@ -71,14 +75,10 @@ public class QuickConnectAuthenticationProvider extends SimpleAuthenticationProv
public AuthenticatedUser authenticateUser(Credentials credentials)
throws GuacamoleException {
logger.debug(">>>QuickConnect<<< authenticateUser running for user {}.", credentials.getUsername());
String username = credentials.getUsername();
if(username == null || username.isEmpty())
if (username == null || username.isEmpty())
throw new GuacamoleInvalidCredentialsException("You must login.", CredentialsInfo.USERNAME_PASSWORD);
userContext = new QuickConnectUserContext(this, credentials.getUsername());
return null;
}
@@ -88,67 +88,14 @@ public class QuickConnectAuthenticationProvider extends SimpleAuthenticationProv
getAuthorizedConfigurations(Credentials credentials)
throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Retrieving configurations for user {}", credentials.getUsername());
if(userContext == null)
userContext = new QuickConnectUserContext(this, credentials.getUsername());
return Collections.<String, GuacamoleConfiguration>emptyMap();
}
private Map<String, GuacamoleConfiguration>
getFilteredAuthorizedConfigurations(Credentials credentials)
throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Filtering configurations.");
// Get configurations
Map<String, GuacamoleConfiguration> configs =
getAuthorizedConfigurations(credentials);
// Return as unauthorized if not authorized to retrieve configs
if (configs == null)
return null;
// Build credential TokenFilter
TokenFilter tokenFilter = new TokenFilter();
StandardTokens.addStandardTokens(tokenFilter, credentials);
// Filter each configuration
for (GuacamoleConfiguration config : configs.values())
tokenFilter.filterValues(config.getParameters());
return configs;
}
private Map<String, GuacamoleConfiguration>
getFilteredAuthorizedConfigurations(AuthenticatedUser authenticatedUser)
throws GuacamoleException {
// Pull using credentials
return getFilteredAuthorizedConfigurations(authenticatedUser.getCredentials());
}
@Override
public UserContext getUserContext(AuthenticatedUser authenticatedUser)
throws GuacamoleException {
logger.debug(">>>QuickConnect<<< getUserContext for {}", authenticatedUser.getCredentials().getUsername());
// Get configurations
// Map<String, GuacamoleConfiguration> configs =
// getFilteredAuthorizedConfigurations(authenticatedUser);
// Return as unauthorized if not authorized to retrieve configs
// if (configs == null)
// return null;
// Return user context restricted to authorized configs
// return new QuickConnectUserContext(this, authenticatedUser.getIdentifier(), configs);
return new QuickConnectUserContext(this, authenticatedUser.getIdentifier());
}

View File

@@ -71,8 +71,10 @@ public class QuickConnectAuthenticationProviderModule extends AbstractModule {
bind(Environment.class).toInstance(environment);
// Bind QuickConnect-specific classes;
bind(QuickConnectConnectionGroup.class);
bind(QuickConnectDirectory.class);
bind(QuickConnectUserContext.class);
bind(QuickConnection.class);
}

View File

@@ -31,6 +31,11 @@ import org.apache.guacamole.net.auth.AbstractConnectionGroup;
import org.apache.guacamole.net.auth.ConnectionGroup;
import org.apache.guacamole.protocol.GuacamoleClientInformation;
/**
* Provides a very simple, single-level connection group used
* for temporarily storing the QuickConnections created by
* users.
*/
class QuickConnectConnectionGroup extends AbstractConnectionGroup {
/**
@@ -38,6 +43,15 @@ class QuickConnectConnectionGroup extends AbstractConnectionGroup {
*/
private Set<String> connectionIdentifiers;
/**
* Set up a QuickConnectConnectionGroup with a name and identifier, and
* an empty set of child connections.
*
* @param name
* The name of the QuickConnectConnectionGroup.
* @param identifier
* The identifier of the QuickConnectConnectionGroup.
*/
public QuickConnectConnectionGroup(String name, String identifier) {
setName(name);
@@ -48,15 +62,20 @@ class QuickConnectConnectionGroup extends AbstractConnectionGroup {
}
public QuickConnectConnectionGroup(String name, String identifier,
Collection<String> connectionIdentifiers) {
setName(name);
setIdentifier(identifier);
setType(ConnectionGroup.Type.ORGANIZATIONAL);
this.connectionIdentifiers = new HashSet<String>(connectionIdentifiers);
/**
* Add a connection identifier to this connection group, and
* return the identifier if the add succeeds, else return null.
*
* @param identifier
* The identifier of the connection to add to the group.
* @return
* The String identifier of the connection if the add
* operation was successful; otherwise null.
*/
public String addConnectionIdentifier(String identifier) {
if (connectionIdentifiers.add(identifier))
return identifier;
return null;
}
@Override
@@ -90,10 +109,4 @@ class QuickConnectConnectionGroup extends AbstractConnectionGroup {
throw new GuacamoleSecurityException("Permission denied.");
}
public String addConnectionIdentifier(String identifier) {
if (connectionIdentifiers.add(identifier))
return identifier;
return null;
}
}

View File

@@ -68,35 +68,38 @@ public class QuickConnectDirectory extends SimpleConnectionDirectory {
public QuickConnectDirectory(Collection<Connection> connections, ConnectionGroup rootGroup) {
super(connections);
this.rootGroup = (QuickConnectConnectionGroup)rootGroup;
logger.debug(">>>QuickConnect<<< Created new directory.");
}
/**
* Returns the current counter and then increments it.
*
* @returns
* An Integer representing the next available connection
* ID to get used when adding connections.
*/
private Integer getNextConnectionID() {
return CONNECTION_ID++;
}
@Override
public void add(Connection object) throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Adding connection object.");
// Get the next connection ID.
String connectionId = getNextConnectionID().toString();
// Set up identifier and parent on original object.
object.setIdentifier(connectionId);
object.setParentIdentifier(ROOT_IDENTIFIER);
/*
SimpleConnection newConn = new SimpleConnection(
object.getName(),
connectionId,
object.getConfiguration()
);
newConn.setParentIdentifier(ROOT_IDENTIFIER);
*/
// Add connection to the directory
putConnection(new QuickConnection(object));
// Add connection to the tree
this.rootGroup.addConnectionIdentifier(connectionId);
}
@Override
public void update(Connection object) throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Updating connection object.");
putConnection(object);
}

View File

@@ -47,9 +47,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An extremely simple UserContext implementation which provides access to
* a defined and restricted set of GuacamoleConfigurations. Access to
* querying or modifying either users or permissions is denied.
* A simple implementation of UserContext to support the QuickConnect
* extension, primarily used for storing connections the user has
* created using the QuickConnect bar in the webapp.
*/
public class QuickConnectUserContext implements UserContext {
@@ -98,107 +98,41 @@ public class QuickConnectUserContext implements UserContext {
private final ConnectionGroup rootGroup;
/**
* Creates a new SimpleUserContext which provides access to only those
* configurations within the given Map. The username is assigned
* arbitrarily.
* Construct a QuickConnectUserContext using the authProvider and
* the username.
*
* @param authProvider
* The AuthenticationProvider creating this UserContext.
*
* @param configs
* A Map of all configurations for which the user associated with this
* UserContext has read access.
*/
public QuickConnectUserContext(AuthenticationProvider authProvider,
Map<String, GuacamoleConfiguration> configs) {
this(authProvider, UUID.randomUUID().toString(), configs);
logger.debug(">>>QuickConnect<<< Constructor with authProvider and configs.");
}
/**
* Creates a new SimpleUserContext for the user with the given username
* which provides access to only those configurations within the given Map.
*
* @param authProvider
* The AuthenticationProvider creating this UserContext.
*
* The authentication provider module instantiating this
* this class.
* @param username
* The username of the user associated with this UserContext.
*
* @param configs
* A Map of all configurations for which the user associated with
* this UserContext has read access.
* The name of the user logging in and using this class.
*/
public QuickConnectUserContext(AuthenticationProvider authProvider,
String username, Map<String, GuacamoleConfiguration> configs) {
Collection<String> connectionIdentifiers = new ArrayList<String>(configs.size());
Collection<String> connectionGroupIdentifiers = Collections.singleton(ROOT_IDENTIFIER);
// Produce collection of connections from given configs
Collection<Connection> connections = new ArrayList<Connection>(configs.size());
for (Map.Entry<String, GuacamoleConfiguration> configEntry : configs.entrySet()) {
// Get connection identifier and configuration
String identifier = configEntry.getKey();
GuacamoleConfiguration config = configEntry.getValue();
// Add as simple connection
Connection connection = new SimpleConnection(identifier, identifier, config);
connection.setParentIdentifier(ROOT_IDENTIFIER);
connections.add(connection);
// Add identifier to overall set of identifiers
connectionIdentifiers.add(identifier);
}
// Add root group that contains only the given configurations
this.rootGroup = new QuickConnectConnectionGroup(
ROOT_IDENTIFIER, ROOT_IDENTIFIER,
connectionIdentifiers
);
// Build new user from credentials
this.self = new SimpleUser(username, connectionIdentifiers,
connectionGroupIdentifiers);
// Create directories for new user
this.userDirectory = new SimpleUserDirectory(self);
this.connectionDirectory = new QuickConnectDirectory(connections,this.rootGroup);
this.connectionGroupDirectory = new SimpleConnectionGroupDirectory(Collections.singleton(this.rootGroup));
// Associate provided AuthenticationProvider
this.authProvider = authProvider;
}
public QuickConnectUserContext(AuthenticationProvider authProvider,
String username) {
// Initialize the rootGroup to a basic connection group with a
// single root identifier.
this.rootGroup = new QuickConnectConnectionGroup(
ROOT_IDENTIFIER, ROOT_IDENTIFIER
);
// Initialize the user to a SimpleUser with the username, no
// preexisting connections, and the single root group.
this.self = new SimpleUser(username,
Collections.<String>emptyList(),
Collections.singleton(ROOT_IDENTIFIER)
);
// Initialize each of the directories associated with the userContext.
this.userDirectory = new SimpleUserDirectory(self);
this.connectionDirectory = new QuickConnectDirectory(Collections.<Connection>emptyList(), this.rootGroup);
this.connectionGroupDirectory = new SimpleConnectionGroupDirectory(Collections.singleton(this.rootGroup));
// Set the authProvider to the calling authProvider object.
this.authProvider = authProvider;
}
public void setConfigs(Map<String, GuacamoleConfiguration> configs) {
return;
}
@Override
public User self() {
return self;
@@ -217,35 +151,23 @@ public class QuickConnectUserContext implements UserContext {
@Override
public Directory<User> getUserDirectory()
throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Returning the entire user directory: {}", userDirectory.getIdentifiers());
return userDirectory;
}
@Override
public Directory<Connection> getConnectionDirectory()
throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Returning the entire connection directory: {}", connectionDirectory.getIdentifiers());
return connectionDirectory;
}
@Override
public Directory<ConnectionGroup> getConnectionGroupDirectory()
throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Returning the entire group directory: {}", connectionGroupDirectory.getIdentifiers());
return connectionGroupDirectory;
}
@Override
public ConnectionGroup getRootConnectionGroup() throws GuacamoleException {
logger.debug(">>>QuickConnect<<< Returning the entire root Connection Group: {}", rootGroup);
return rootGroup;
}

View File

@@ -39,6 +39,9 @@ import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
import org.apache.guacamole.protocol.GuacamoleClientInformation;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
/**
* A type of Connection specific to this authentication extension.
*/
public class QuickConnection extends AbstractConnection {
/**
@@ -51,10 +54,26 @@ public class QuickConnection extends AbstractConnection {
*/
private int activeConnections;
/**
* Empty connection constructor.
*/
public QuickConnection() {
}
/**
* Constructor that takes a name, identifier, and GuacamoleConfiguration
* and builds a QuickConnection from it.
*
* @param name
* The name of the connection.
* @param identifier
* The unique identifier of this connection within this
* authentication module.
* @param config
* The GuacamoleConfiguration object to store in this
* QuickConnection.
*/
public QuickConnection(String name, String identifier,
GuacamoleConfiguration config) {
@@ -69,6 +88,14 @@ public class QuickConnection extends AbstractConnection {
}
/**
* Constructs a QuickConnection from a generic Connection
* object, copying over the relevant data and initializing
* the rest.
*
* @param object
* The generic Connection object to be copied.
*/
public QuickConnection(Connection object) {
setName(object.getName());

View File

@@ -23,8 +23,6 @@
angular.module('guacQuickConnect').controller('quickconnectController', ['$scope', '$injector', '$log',
function manageConnectionController($scope, $injector, $log) {
$log.debug('In quickconnectController...');
// Required types
var ClientIdentifier = $injector.get('ClientIdentifier');
var Connection = $injector.get('Connection');
@@ -58,8 +56,6 @@ angular.module('guacQuickConnect').controller('quickconnectController', ['$scope
*/
$scope.quickConnect = function quickConnect() {
$log.debug('Got saveConnection() call.');
// Construct parameters from URI...
/**
* Parse URL into the following components:
@@ -75,14 +71,10 @@ angular.module('guacQuickConnect').controller('quickconnectController', ['$scope
* [17] - JS Route
*/
var regexURL = /^(((rdp|ssh|telnet|vnc)?):\/)?\/?((.*?)(:(.*?)|)@)?([^:\/\s]+)(:([^\/]*))?((\/\w+\/)*)([-\w.\/]+[^#?\s]*)?(\?([^#]*))?(#(.*))?$/g;
$log.debug(regexURL);
var urlArray = regexURL.exec($scope.uri);
$log.debug($scope.uri);
$log.debug(urlArray);
var gettingProtocols = schemaService.getProtocols('quickconnect');
gettingProtocols.success(function checkProtocol(supportedProtocols) {
$log.debug(supportedProtocols);
if (!(urlArray[3] in supportedProtocols)) {
guacNotification.showStatus({
'className' : 'error',
@@ -94,6 +86,8 @@ angular.module('guacQuickConnect').controller('quickconnectController', ['$scope
}
var port = 0;
var urlParams = Array();
// Default port assignments for various protocols.
switch(urlArray[3]) {
case 'rdp':
port = 3389;
@@ -111,23 +105,29 @@ angular.module('guacQuickConnect').controller('quickconnectController', ['$scope
port = 0;
}
// If the port is explicitly set, overwrite the default
if (!isNaN(urlArray[10]))
port = parseInt(urlArray[10]);
// Parse out any additional URI parameters on the connection string into an array.
if (!(typeof urlArray[15] === 'undefined'))
urlParams = JSON.parse('{"' + decodeURI(urlArray[15]).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}');
console.log(urlParams);
var connParams = {};
// If hostname is undefined, assume localhost
if (!(typeof urlArray[8] === 'undefined'))
connParams['hostname'] = urlArray[8];
else
connParams['hostname'] = 'localhost';
// Username and password
if (!(typeof urlArray[5] === 'undefined'))
connParams['username'] = urlArray[5];
if (!(typeof urlArray[7] === 'undefined'))
connParams['password'] = urlArray[7];
// Additional connection parameters
connParams['port'] = port;
connParams['read-only'] = 'read-only' in urlParams ? urlParams['read-only'] : '';
connParams['swap-red-blue'] = 'swap-red-blue' in urlParams ? urlParams['swap-red-blue'] : '';
@@ -145,21 +145,23 @@ angular.module('guacQuickConnect').controller('quickconnectController', ['$scope
connParams['private-key'] = 'private-key' in urlParams ? urlParams['private-key'] : '';
connParams['passphrase'] = 'passphrase' in urlParams ? urlParams['passphrase'] : '';
// Set up the name of the connection based on various parts of the URI
var connName = urlArray[3] + '://';
if(!(typeof connParams['username'] === 'undefined'))
connName += connParams['username'] + '@';
connName += connParams['hostname'] + ':' + connParams['port'];
// Create the new connection
$scope.connection = new Connection({
name : connName,
protocol : urlArray[3],
parameters: connParams
});
console.log($scope.connection);
// Save the new connection into the QuickConnect datasource.
connectionService.saveConnection($scope.selectedDataSource, $scope.connection)
.success(function runConnection(newConnection) {
$log.debug('Connection saved - we should run it, now: ' + newConnection.identifier);
// If the save succeeds, launch the new connection.
$location.url('/client/' + ClientIdentifier.toString({
dataSource : $scope.selectedDataSource,
type : ClientIdentifier.Types.CONNECTION,
@@ -177,31 +179,8 @@ angular.module('guacQuickConnect').controller('quickconnectController', ['$scope
});
return;
/*
$scope.connection.parameters = $scope.parameters;
// Save the connection
connectionService.saveConnection($scope.selectedDataSource, $scope.connection)
.success(function savedConnection(newConnection) {
$log.debug('Connection saved successfully: ' + newConnection);
// $location.url('/settings/' + encodeURIComponent($scope.selectedDataSource) + '/connections');
})
// Notify of any errors
.error(function connectionSaveFailed(error) {
guacNotification.showStatus({
'className' : 'error',
'title' : 'MANAGE_CONNECTION.DIALOG_HEADER_ERROR',
'text' : error.translatableMessage,
'actions' : [ ACKNOWLEDGE_ACTION ]
});
});
*/
};
}]);

View File

@@ -18,7 +18,7 @@
*/
/**
* Module which provides Adhoc connection capability
* Module which provides QuickConnect capability
*/
angular.module('guacQuickConnect', [
'form'

View File

@@ -1,7 +1,9 @@
<meta name="before" content=".recent-connections" />
<div class="header" ng-controller="quickconnectController">
<div class="quickconnect-container">
<input type=text class="quickconnect-field" placeholder="Enter Connection URI" ng-model="uri" />
<form action="#" ng-submit="quickConnect()">
<input type=text class="quickconnect-field" placeholder="Enter Connection URI" ng-model="uri" />
</form>
</div>
<button class="quickconnect-button" ng-click="quickConnect()">Connect</button>
</div>