diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java index c9c928677..ad8e9c900 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java @@ -50,8 +50,8 @@ import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey; +import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService; import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService; -import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService; import net.sourceforge.guacamole.protocol.GuacamoleConfiguration; import org.mybatis.guice.transactional.Transactional; @@ -75,10 +75,10 @@ public class ConnectionDirectory implements Directory{ private PermissionCheckService permissionCheckService; /** - * Service for creating and retrieving objects. + * Service managing connections. */ @Inject - private ProviderService providerService; + private ConnectionService connectionService; /** * Service for manipulating connections in the database. @@ -111,7 +111,7 @@ public class ConnectionDirectory implements Directory{ @Override public Connection get(String identifier) throws GuacamoleException { permissionCheckService.verifyConnectionReadAccess(this.user_id, identifier); - return providerService.getExistingMySQLConnection(identifier); + return connectionService.retrieveConnection(identifier); } @Transactional @@ -236,7 +236,9 @@ public class ConnectionDirectory implements Directory{ // Verify permission to delete permissionCheckService.verifyConnectionDeleteAccess(this.user_id, identifier); - MySQLConnection mySQLConnection = providerService.getExistingMySQLConnection(identifier); + // Get connection + MySQLConnection mySQLConnection = + connectionService.retrieveConnection(identifier); // Delete all configuration values ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample(); diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java index c319d56d0..ad7bf9034 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java @@ -55,9 +55,9 @@ import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper; import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties; +import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService; import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService; import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService; -import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService; import net.sourceforge.guacamole.net.auth.mysql.service.SaltService; import net.sourceforge.guacamole.net.auth.mysql.service.SecureRandomSaltService; import net.sourceforge.guacamole.net.auth.mysql.service.Sha256PasswordEncryptionService; @@ -164,7 +164,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider { bind(SaltService.class).to(SecureRandomSaltService.class); bind(PasswordEncryptionService.class).to(Sha256PasswordEncryptionService.class); bind(PermissionCheckService.class); - bind(ProviderService.class); + bind(ConnectionService.class); bind(UserService.class); bind(ActiveConnectionSet.class).toInstance(activeConnectionSet); diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java index e54bc2a7f..901d4d88f 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java @@ -1,3 +1,6 @@ + +package net.sourceforge.guacamole.net.auth.mysql; + /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -33,7 +36,6 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -package net.sourceforge.guacamole.net.auth.mysql; import com.google.inject.Inject; import java.util.ArrayList; @@ -41,14 +43,10 @@ import java.util.Collections; import java.util.List; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.GuacamoleSocket; -import net.sourceforge.guacamole.net.InetGuacamoleSocket; import net.sourceforge.guacamole.net.auth.AbstractConnection; import net.sourceforge.guacamole.net.auth.Connection; import net.sourceforge.guacamole.net.auth.ConnectionRecord; -import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties; -import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService; -import net.sourceforge.guacamole.properties.GuacamoleProperties; -import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket; +import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService; import net.sourceforge.guacamole.protocol.GuacamoleClientInformation; import net.sourceforge.guacamole.protocol.GuacamoleConfiguration; @@ -69,10 +67,10 @@ public class MySQLConnection extends AbstractConnection { private List history = new ArrayList(); /** - * Service for creating and retrieving objects. + * Service for managing connections. */ @Inject - private ProviderService providerService; + private ConnectionService connectionService; /** * Set of all currently active connections. @@ -135,29 +133,7 @@ public class MySQLConnection extends AbstractConnection { @Override public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException { - - // If the current connection is active, and multiple simultaneous connections are not allowed. - if(GuacamoleProperties.getProperty(MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false) - && activeConnectionSet.contains(getConnectionID())) - throw new GuacamoleException("Cannot connect. This connection is in use."); - - // Get guacd connection information - String host = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME); - int port = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_PORT); - - // Get socket - GuacamoleSocket socket = providerService.getMySQLGuacamoleSocket( - new ConfiguredGuacamoleSocket( - new InetGuacamoleSocket(host, port), - getConfiguration() - ), - getConnectionID() - ); - - // Mark this connection as active - activeConnectionSet.add(getConnectionID()); - - return socket; + return connectionService.connect(this, info); } @Override diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java index 499853792..334614f59 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionRecord.java @@ -43,7 +43,7 @@ import net.sourceforge.guacamole.net.auth.Connection; import net.sourceforge.guacamole.net.auth.ConnectionRecord; import net.sourceforge.guacamole.net.auth.User; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory; -import net.sourceforge.guacamole.net.auth.mysql.service.ProviderService; +import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService; import net.sourceforge.guacamole.net.auth.mysql.service.UserService; /** @@ -65,10 +65,10 @@ public class MySQLConnectionRecord implements ConnectionRecord { private UserService userService; /** - * Service for creating and retrieving objects. + * Service for accessing connections. */ @Inject - private ProviderService providerService; + private ConnectionService connectionService; /** * Initialize this MySQLConnectionRecord with the database record it @@ -100,7 +100,7 @@ public class MySQLConnectionRecord implements ConnectionRecord { @Override public Connection getConnection() { - return providerService.getExistingMySQLConnection(connectionHistory.getConnection_id()); + return connectionService.retrieveConnection(connectionHistory.getConnection_id()); } @Override diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ProviderService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java similarity index 53% rename from extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ProviderService.java rename to extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java index a562a1629..02e3c7f05 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ProviderService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java @@ -1,3 +1,6 @@ + +package net.sourceforge.guacamole.net.auth.mysql.service; + /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -33,7 +36,6 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -package net.sourceforge.guacamole.net.auth.mysql.service; import com.google.inject.Inject; import com.google.inject.Provider; @@ -41,84 +43,135 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.auth.Connection; +import net.sourceforge.guacamole.net.GuacamoleSocket; +import net.sourceforge.guacamole.net.InetGuacamoleSocket; +import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionSet; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord; import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket; import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionParameterMapper; +import net.sourceforge.guacamole.net.auth.mysql.model.Connection; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistoryExample; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter; import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample; +import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties; +import net.sourceforge.guacamole.properties.GuacamoleProperties; import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket; +import net.sourceforge.guacamole.protocol.GuacamoleClientInformation; import net.sourceforge.guacamole.protocol.GuacamoleConfiguration; /** - * Provides convenient provider methods for MySQL specific implementations. - * @author James Muehlner + * Service which provides convenience methods for creating, retrieving, and + * manipulating connections. + * + * @author Michael Jumper, James Muehlner */ -public class ProviderService { +public class ConnectionService { + /** + * DAO for accessing connections. + */ @Inject private ConnectionMapper connectionDAO; + /** + * DAO for accessing connection parameters. + */ @Inject private ConnectionParameterMapper connectionParameterDAO; + /** + * DAO for accessing connection history. + */ @Inject private ConnectionHistoryMapper connectionHistoryDAO; + /** + * Provider which creates MySQLConnections. + */ @Inject private Provider mySQLConnectionProvider; + /** + * Provider which creates MySQLConnectionRecords. + */ @Inject private Provider mySQLConnectionRecordProvider; + /** + * Provider which creates MySQLGuacamoleSockets. + */ @Inject private Provider mySQLGuacamoleSocketProvider; /** - * Get the connection based on the connection name of the provided object. - * @param connection - * @return the new Connection object. - * @throws GuacamoleException + * Set of all currently active connections. */ - public MySQLConnection getExistingMySQLConnection(Connection connection) throws GuacamoleException { - return getExistingMySQLConnection(connection.getIdentifier()); - } + @Inject + private ActiveConnectionSet activeConnectionSet; /** - * Get the connection based on the connection name of the provided object. - * @param name - * @return the new Connection object. - * @throws GuacamoleException + * Retrieves the connection having the given name from the database. + * + * @param name The name of the connection to return. + * @return The connection having the given name, or null if no such + * connection could be found. */ - public MySQLConnection getExistingMySQLConnection(String name) throws GuacamoleException { + public MySQLConnection retrieveConnection(String name) { - // Query connection by ID + // Query connection by connection identifier (name) ConnectionExample example = new ConnectionExample(); example.createCriteria().andConnection_nameEqualTo(name); - List connections = + List connections = connectionDAO.selectByExample(example); // If no connection found, return null if(connections.isEmpty()) return null; + // Assert only one connection found + assert connections.size() == 1 : "Multiple connections with same name."; + // Otherwise, return found connection - return getExistingMySQLConnection(connections.get(0)); + return toMySQLConnection(connections.get(0)); } /** - * Get an existing MySQLConnection from a connection database record. - * @param connection - * @return the existing MySQLConnection object. + * Retrieves the connection having the given ID from the database. + * + * @param id The ID of the connection to retrieve. + * @return The connection having the given ID, or null if no such + * connection was found. */ - public MySQLConnection getExistingMySQLConnection(net.sourceforge.guacamole.net.auth.mysql.model.Connection connection) { + public MySQLConnection retrieveConnection(int id) { + + // Query connection by ID + Connection connection = connectionDAO.selectByPrimaryKey(id); + + // If no connection found, return null + if(connection == null) + return null; + + // Otherwise, return found connection + return toMySQLConnection(connection); + + } + + /** + * Convert the given database-retrieved Connection into a MySQLConnection. + * The parameters of the given connection will be read and added to the + * MySQLConnection in the process. + * + * @param connection The connection to convert. + * @return A new MySQLConnection containing all data associated with the + * specified connection. + */ + private MySQLConnection toMySQLConnection(Connection connection) { // Build configuration GuacamoleConfiguration config = new GuacamoleConfiguration(); @@ -151,64 +204,77 @@ public class ProviderService { } /** - * Get an existing MySQLConnection from a connection ID. - * @param id - * @return the existing MySQLConnection object if found, null if not. + * Retrieves the history of the connection having the given ID. + * + * @param connectionID The ID of the connection to retrieve the history of. + * @return A list of MySQLConnectionRecord documenting the history of this + * connection. */ - public MySQLConnection getExistingMySQLConnection(Integer id) { + public List retrieveHistory(int connectionID) { - // Query connection by ID - net.sourceforge.guacamole.net.auth.mysql.model.Connection connection = - connectionDAO.selectByPrimaryKey(id); - - // If no connection found, return null - if(connection == null) - return null; - - // Otherwise, return found connection - return getExistingMySQLConnection(connection); - - } - - /** - * Gets a list of existing MySQLConnectionRecord from the database. These represent - * the history records of the connection. - * @param connectionID - * @return the list of MySQLConnectionRecord related to this connectionID. - */ - public List getExistingMySQLConnectionRecords(Integer connectionID) { + // Retrieve history records relating to given connection ID ConnectionHistoryExample example = new ConnectionHistoryExample(); example.createCriteria().andConnection_idEqualTo(connectionID); - // we want to return the newest records first + + // We want to return the newest records first example.setOrderByClause("start_date DESC"); + + // Retrieve all connection history entries List connectionHistories = connectionHistoryDAO.selectByExample(example); + + // Convert history entries to connection records List connectionRecords = new ArrayList(); for(ConnectionHistory history : connectionHistories) { - connectionRecords.add(getExistingMySQLConnectionRecord(history)); + + // Create connection record from history + MySQLConnectionRecord record = mySQLConnectionRecordProvider.get(); + record.init(history); + connectionRecords.add(record); + } + return connectionRecords; } /** - * Create a MySQLConnectionRecord object around a single ConnectionHistory database record. - * @param history - * @return the new MySQLConnectionRecord object. + * Create a MySQLGuacamoleSocket using the provided connection. + * + * @param connection The connection to use when connecting the socket. + * @param info The information to use when performing the connection + * handshake. + * @return The connected socket. + * @throws GuacamoleException If an error occurs while connecting the + * socket. */ - public MySQLConnectionRecord getExistingMySQLConnectionRecord(ConnectionHistory history) { - MySQLConnectionRecord record = mySQLConnectionRecordProvider.get(); - record.init(history); - return record; + public MySQLGuacamoleSocket connect(MySQLConnection connection, + GuacamoleClientInformation info) + throws GuacamoleException { + + // If the given connection is active, and multiple simultaneous + // connections are not allowed, disallow connection + if(GuacamoleProperties.getProperty( + MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false) + && activeConnectionSet.contains(connection.getConnectionID())) + throw new GuacamoleException("Cannot connect. This connection is in use."); + + // Get guacd connection information + String host = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME); + int port = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_PORT); + + // Get socket + GuacamoleSocket socket = new ConfiguredGuacamoleSocket( + new InetGuacamoleSocket(host, port), + connection.getConfiguration(), info + ); + + // Mark this connection as active + activeConnectionSet.add(connection.getConnectionID()); + + // Return new MySQLGuacamoleSocket + MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get(); + mySQLGuacamoleSocket.init(socket, connection.getConnectionID()); + return mySQLGuacamoleSocket; + } - /** - * Create a MySQLGuacamoleSocket using the provided ConfiguredGuacamoleSocket and connection ID. - * @param socket - * @param connectionID - * @return - */ - public MySQLGuacamoleSocket getMySQLGuacamoleSocket(ConfiguredGuacamoleSocket socket, int connectionID) { - MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get(); - mySQLGuacamoleSocket.init(socket, connectionID); - return mySQLGuacamoleSocket; - } }