diff --git a/extensions/guacamole-auth-mysql/pom.xml b/extensions/guacamole-auth-mysql/pom.xml
index e4a4f6544..912908484 100644
--- a/extensions/guacamole-auth-mysql/pom.xml
+++ b/extensions/guacamole-auth-mysql/pom.xml
@@ -48,32 +48,6 @@
-
-
- org.mybatis.generator
- mybatis-generator-maven-plugin
- 1.3.2
-
-
-
- Generate MyBatis Artifacts
-
- generate
-
-
-
-
-
-
-
- mysql
- mysql-connector-java
- 5.1.23
-
-
-
-
-
@@ -104,22 +78,31 @@
org.mybatismybatis
- 3.1.1
+ 3.2.8org.mybatismybatis-guice
- 3.2
+ 3.6
-
+
+
+
+ com.google.inject
+ guice
+ 3.0
+
+
+
com.google.collectionsgoogle-collections1.0
+
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ActiveConnectionMap.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ActiveConnectionMap.java
deleted file mode 100644
index 272434aa9..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ActiveConnectionMap.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql;
-
-
-import com.google.inject.Inject;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import org.glyptodon.guacamole.GuacamoleException;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
-import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
-
-/**
- * Represents the map of currently active Connections to the count of the number
- * of current users. Whenever a socket is opened, the connection count should be
- * incremented, and whenever a socket is closed, the connection count should be
- * decremented.
- *
- * @author James Muehlner
- */
-public class ActiveConnectionMap {
-
- /**
- * Represents the count of users currently using a MySQL connection.
- */
- public class Connection {
-
- /**
- * The ID of the MySQL connection that this Connection represents.
- */
- private int connectionID;
-
- /**
- * The number of users currently using this connection.
- */
- private int currentUserCount;
-
- /**
- * Returns the ID of the MySQL connection that this Connection
- * represents.
- *
- * @return the ID of the MySQL connection that this Connection
- * represents.
- */
- public int getConnectionID() {
- return connectionID;
- }
-
- /**
- * Returns the number of users currently using this connection.
- *
- * @return the number of users currently using this connection.
- */
- public int getCurrentUserCount() {
- return currentUserCount;
- }
-
- /**
- * Set the current user count for this connection.
- *
- * @param currentUserCount The new user count for this Connection.
- */
- public void setCurrentUserCount(int currentUserCount) {
- this.currentUserCount = currentUserCount;
- }
-
- /**
- * Create a new Connection for the given connectionID with a zero
- * current user count.
- *
- * @param connectionID The ID of the MySQL connection that this
- * Connection represents.
- */
- public Connection(int connectionID) {
- this.connectionID = connectionID;
- this.currentUserCount = 0;
- }
- }
-
- /*
- * Represents a user connected to a connection or BALANCING connection group.
- */
- public class ConnectionUser {
- /**
- * The ID of the connection or connection group that this ConnectionUser refers to.
- */
- private int identifier;
-
- /**
- * The user that this ConnectionUser refers to.
- */
- private int userID;
-
- /**
- * Returns ID of the connection or connection group that this ConnectionUser refers to.
- * @return ID of the connection or connection group that this ConnectionUser refers to.
- */
- public int getIdentifier() {
- return identifier;
- }
-
- /**
- * Returns the user ID that this ConnectionUser refers to.
- * @return the user ID that this ConnectionUser refers to.
- */
- public int getUserID() {
- return userID;
- }
-
- /**
- * Create a ConnectionUser with the given connection or connection group
- * ID and user ID.
- *
- * @param identifier The connection or connection group ID that this
- * ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- */
- public ConnectionUser(int identifier, int userID) {
- this.identifier = identifier;
- this.userID = userID;
- }
-
- @Override
- public boolean equals(Object other) {
-
- // Only another ConnectionUser can equal this ConnectionUser
- if(!(other instanceof ConnectionUser))
- return false;
-
- ConnectionUser otherConnectionGroupUser =
- (ConnectionUser)other;
-
- /*
- * Two ConnectionGroupUsers are equal iff they represent the exact
- * same pairing of connection or connection group and user.
- */
- return this.identifier == otherConnectionGroupUser.identifier
- && this.userID == otherConnectionGroupUser.userID;
- }
-
- @Override
- public int hashCode() {
- int hash = 3;
- hash = 23 * hash + this.identifier;
- hash = 23 * hash + this.userID;
- return hash;
- }
- }
-
- /**
- * DAO for accessing connection history.
- */
- @Inject
- private ConnectionHistoryMapper connectionHistoryDAO;
-
- /**
- * Map of all the connections that are currently active to the
- * count of current users.
- */
- private Map activeConnectionMap =
- new HashMap();
-
- /**
- * Map of all the connection group users to the count of current usages.
- */
- private Map activeConnectionGroupUserMap =
- new HashMap();
-
- /**
- * Map of all the connection users to the count of current usages.
- */
- private Map activeConnectionUserMap =
- new HashMap();
-
- /**
- * Returns the number of connections opened by the given user using
- * the given ConnectionGroup.
- *
- * @param connectionGroupID The connection group ID that this
- * ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- *
- * @return The number of connections opened by the given user to the given
- * ConnectionGroup.
- */
- public int getConnectionGroupUserCount(int connectionGroupID, int userID) {
- Integer count = activeConnectionGroupUserMap.get
- (new ConnectionUser(connectionGroupID, userID));
-
- // No ConnectionUser found means this combination was never used
- if(count == null)
- return 0;
-
- return count;
- }
-
- /**
- * Checks if the given user is currently connected to the given BALANCING
- * connection group.
- *
- * @param connectionGroupID The connection group ID that this
- * ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- *
- * @return True if the given user is currently connected to the given
- * BALANCING connection group, false otherwise.
- */
- public boolean isConnectionGroupUserActive(int connectionGroupID, int userID) {
- Integer count = activeConnectionGroupUserMap.get
- (new ConnectionUser(connectionGroupID, userID));
-
- // The connection group is in use if the ConnectionUser count > 0
- return count != null && count > 0;
- }
-
- /**
- * Increment the count of the number of connections opened by the given user
- * to the given ConnectionGroup.
- *
- * @param connectionGroupID The connection group ID that this
- * ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- */
- private void incrementConnectionGroupUserCount(int connectionGroupID, int userID) {
- int currentCount = getConnectionGroupUserCount(connectionGroupID, userID);
-
- activeConnectionGroupUserMap.put
- (new ConnectionUser(connectionGroupID, userID), currentCount + 1);
- }
-
- /**
- * Decrement the count of the number of connections opened by the given user
- * to the given ConnectionGroup.
- *
- * @param connectionGroupID The connection group ID that this
- * ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- */
- private void decrementConnectionGroupUserCount(int connectionGroupID, int userID) {
- int currentCount = getConnectionGroupUserCount(connectionGroupID, userID);
-
- activeConnectionGroupUserMap.put
- (new ConnectionUser(connectionGroupID, userID), currentCount - 1);
- }
-
- /**
- * Returns the number of connections opened by the given user using
- * the given Connection.
- *
- * @param connectionID The connection ID that this ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- *
- * @return The number of connections opened by the given user to the given
- * connection.
- */
- public int getConnectionUserCount(int connectionID, int userID) {
- Integer count = activeConnectionUserMap.get
- (new ConnectionUser(connectionID, userID));
-
- // No ConnectionUser found means this combination was never used
- if(count == null)
- return 0;
-
- return count;
- }
-
- /**
- * Checks if the given user is currently connected to the given connection.
- *
- * @param connectionID The connection ID that this ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- *
- * @return True if the given user is currently connected to the given
- * connection, false otherwise.
- */
- public boolean isConnectionUserActive(int connectionID, int userID) {
- Integer count = activeConnectionUserMap.get
- (new ConnectionUser(connectionID, userID));
-
- // The connection is in use if the ConnectionUser count > 0
- return count != null && count > 0;
- }
-
- /**
- * Increment the count of the number of connections opened by the given user
- * to the given Connection.
- *
- * @param connectionID The connection ID that this ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- */
- private void incrementConnectionUserCount(int connectionID, int userID) {
- int currentCount = getConnectionUserCount(connectionID, userID);
-
- activeConnectionUserMap.put
- (new ConnectionUser(connectionID, userID), currentCount + 1);
- }
-
- /**
- * Decrement the count of the number of connections opened by the given user
- * to the given Connection.
- *
- * @param connectionID The connection ID that this ConnectionUser refers to.
- * @param userID The user ID that this ConnectionUser refers to.
- */
- private void decrementConnectionUserCount(int connectionID, int userID) {
- int currentCount = getConnectionUserCount(connectionID, userID);
-
- activeConnectionUserMap.put
- (new ConnectionUser(connectionID, userID), currentCount - 1);
- }
-
- /**
- * Returns the ID of the connection with the lowest number of current
- * active users, if found.
- *
- * @param connectionIDs The subset of connection IDs to find the least
- * used connection within.
- *
- * @return The ID of the connection with the lowest number of current
- * active users, if found.
- */
- public Integer getLeastUsedConnection(Collection connectionIDs) {
-
- if(connectionIDs.isEmpty())
- return null;
-
- int minUserCount = Integer.MAX_VALUE;
- Integer minConnectionID = null;
-
- for(Integer connectionID : connectionIDs) {
- Connection connection = activeConnectionMap.get(connectionID);
-
- /*
- * If the connection is not found in the map, it has not been used,
- * and therefore will be count 0.
- */
- if(connection == null) {
- minUserCount = 0;
- minConnectionID = connectionID;
- }
- // If this is the least active connection
- else if(connection.getCurrentUserCount() < minUserCount) {
- minUserCount = connection.getCurrentUserCount();
- minConnectionID = connection.getConnectionID();
- }
- }
-
- return minConnectionID;
- }
-
- /**
- * Returns the count of currently active users for the given connectionID.
- * @return the count of currently active users for the given connectionID.
- */
- public int getCurrentUserCount(int connectionID) {
- Connection connection = activeConnectionMap.get(connectionID);
-
- if(connection == null)
- return 0;
-
- return connection.getCurrentUserCount();
- }
-
- /**
- * Decrement the current user count for this Connection.
- *
- * @param connectionID The ID of the MySQL connection that this
- * Connection represents.
- *
- * @throws GuacamoleException If the connection is not found.
- */
- private void decrementUserCount(int connectionID)
- throws GuacamoleException {
- Connection connection = activeConnectionMap.get(connectionID);
-
- if(connection == null)
- throw new GuacamoleResourceNotFoundException
- ("Connection to decrement does not exist.");
-
- // Decrement the current user count
- connection.setCurrentUserCount(connection.getCurrentUserCount() - 1);
- }
-
- /**
- * Increment the current user count for this Connection.
- *
- * @param connectionID The ID of the MySQL connection that this
- * Connection represents.
- *
- * @throws GuacamoleException If the connection is not found.
- */
- private void incrementUserCount(int connectionID) {
- Connection connection = activeConnectionMap.get(connectionID);
-
- // If the Connection does not exist, it should be created
- if(connection == null) {
- connection = new Connection(connectionID);
- activeConnectionMap.put(connectionID, connection);
- }
-
- // Increment the current user count
- connection.setCurrentUserCount(connection.getCurrentUserCount() + 1);
- }
-
- /**
- * Check if a connection is currently in use.
- * @param connectionID The connection to check the status of.
- * @return true if the connection is currently in use.
- */
- public boolean isActive(int connectionID) {
- return getCurrentUserCount(connectionID) > 0;
- }
-
- /**
- * Set a connection as open.
- * @param connectionID The ID of the connection that is being opened.
- * @param userID The ID of the user who is opening the connection.
- * @param connectionGroupID The ID of the BALANCING connection group that is
- * being connected to; null if not used.
- * @return The ID of the history record created for this open connection.
- */
- public int openConnection(int connectionID, int userID, Integer connectionGroupID) {
-
- // Create the connection history record
- ConnectionHistory connectionHistory = new ConnectionHistory();
- connectionHistory.setConnection_id(connectionID);
- connectionHistory.setUser_id(userID);
- connectionHistory.setStart_date(new Date());
- connectionHistoryDAO.insert(connectionHistory);
-
- // Increment the user count
- incrementUserCount(connectionID);
-
- // Increment the connection user count
- incrementConnectionUserCount(connectionID, userID);
-
- // If this is a connection to a BALANCING ConnectionGroup, increment the count
- if(connectionGroupID != null)
- incrementConnectionGroupUserCount(connectionGroupID, userID);
-
- return connectionHistory.getHistory_id();
- }
-
- /**
- * Set a connection as closed.
- * @param historyID The ID of the history record about the open connection.
- * @param connectionGroupID The ID of the BALANCING connection group that is
- * being connected to; null if not used.
- * @throws GuacamoleException If the open connection history is not found.
- */
- public void closeConnection(int historyID, Integer connectionGroupID)
- throws GuacamoleException {
-
- // Get the existing history record
- ConnectionHistory connectionHistory =
- connectionHistoryDAO.selectByPrimaryKey(historyID);
-
- if(connectionHistory == null)
- throw new GuacamoleResourceNotFoundException("History record not found.");
-
- // Get the connection and user IDs
- int connectionID = connectionHistory.getConnection_id();
- int userID = connectionHistory.getUser_id();
-
- // Update the connection history record to mark that it is now closed
- connectionHistory.setEnd_date(new Date());
- connectionHistoryDAO.updateByPrimaryKey(connectionHistory);
-
- // Decrement the user count.
- decrementUserCount(connectionID);
-
- // Decrement the connection user count
- decrementConnectionUserCount(connectionID, userID);
-
- // If this is a connection to a BALANCING ConnectionGroup, decrement the count
- if(connectionGroupID != null)
- decrementConnectionGroupUserCount(connectionGroupID, userID);
- }
-}
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
deleted file mode 100644
index e9fde29dc..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql;
-
-
-import com.google.inject.Inject;
-import java.util.Set;
-import org.glyptodon.guacamole.GuacamoleClientException;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.auth.Connection;
-import org.glyptodon.guacamole.net.auth.Directory;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionParameterMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
-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.ConnectionPermissionKey;
-import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
-import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
-import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
-import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
-import org.glyptodon.guacamole.GuacamoleUnsupportedException;
-import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
-import org.mybatis.guice.transactional.Transactional;
-
-/**
- * A MySQL-based implementation of the connection directory.
- *
- * @author James Muehlner
- */
-public class ConnectionDirectory implements Directory{
-
- /**
- * The user who this connection directory belongs to. Access is based on
- * his/her permission settings.
- */
- private AuthenticatedUser currentUser;
-
- /**
- * The ID of the parent connection group.
- */
- private Integer parentID;
-
- /**
- * Service for checking permissions.
- */
- @Inject
- private PermissionCheckService permissionCheckService;
-
- /**
- * Service managing connections.
- */
- @Inject
- private ConnectionService connectionService;
-
- /**
- * Service managing connection groups.
- */
- @Inject
- private ConnectionGroupService connectionGroupService;
-
- /**
- * Service for manipulating connection permissions in the database.
- */
- @Inject
- private ConnectionPermissionMapper connectionPermissionDAO;
-
- /**
- * Service for manipulating connection parameters in the database.
- */
- @Inject
- private ConnectionParameterMapper connectionParameterDAO;
-
- /**
- * Set the user and parentID for this directory.
- *
- * @param currentUser
- * The user owning this connection directory.
- *
- * @param parentID
- * The ID of the parent connection group.
- */
- public void init(AuthenticatedUser currentUser, Integer parentID) {
- this.currentUser = currentUser;
- this.parentID = parentID;
- }
-
- @Transactional
- @Override
- public Connection get(String identifier) throws GuacamoleException {
-
- // Get connection
- MySQLConnection connection =
- connectionService.retrieveConnection(identifier, currentUser);
-
- if(connection == null)
- return null;
-
- // Verify permission to use the parent connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (connection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify access is granted
- permissionCheckService.verifyConnectionAccess(
- currentUser,
- connection.getConnectionID(),
- MySQLConstants.CONNECTION_READ);
-
- // Return connection
- return connection;
-
- }
-
- @Transactional
- @Override
- public Set getIdentifiers() throws GuacamoleException {
-
- // Verify permission to use the connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- return permissionCheckService.retrieveConnectionIdentifiers(currentUser,
- parentID, MySQLConstants.CONNECTION_READ);
- }
-
- @Transactional
- @Override
- public void add(Connection object) throws GuacamoleException {
-
- String name = object.getName().trim();
- if(name.isEmpty())
- throw new GuacamoleClientException("The connection name cannot be blank.");
-
- // Verify permission to create
- permissionCheckService.verifySystemAccess(currentUser,
- MySQLConstants.SYSTEM_CONNECTION_CREATE);
-
- // Verify permission to edit the connection group
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- this.parentID, MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Verify permission to use the connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify that no connection already exists with this name.
- MySQLConnection previousConnection =
- connectionService.retrieveConnection(name, parentID, currentUser);
- if(previousConnection != null)
- throw new GuacamoleClientException("That connection name is already in use.");
-
- // Create connection
- MySQLConnection connection = connectionService.createConnection(
- name, object.getConfiguration().getProtocol(), currentUser, parentID);
-
- // Set the connection ID
- object.setIdentifier(connection.getIdentifier());
-
- // Add connection parameters
- createConfigurationValues(connection.getConnectionID(),
- object.getConfiguration());
-
- // Finally, give the current user full access to the newly created
- // connection.
- ConnectionPermissionKey newConnectionPermission = new ConnectionPermissionKey();
- newConnectionPermission.setUser_id(currentUser.getUserID());
- newConnectionPermission.setConnection_id(connection.getConnectionID());
-
- // Read permission
- newConnectionPermission.setPermission(MySQLConstants.CONNECTION_READ);
- connectionPermissionDAO.insert(newConnectionPermission);
-
- // Update permission
- newConnectionPermission.setPermission(MySQLConstants.CONNECTION_UPDATE);
- connectionPermissionDAO.insert(newConnectionPermission);
-
- // Delete permission
- newConnectionPermission.setPermission(MySQLConstants.CONNECTION_DELETE);
- connectionPermissionDAO.insert(newConnectionPermission);
-
- // Administer permission
- newConnectionPermission.setPermission(MySQLConstants.CONNECTION_ADMINISTER);
- connectionPermissionDAO.insert(newConnectionPermission);
-
- }
-
- /**
- * Inserts all parameter values from the given configuration into the
- * database, associating them with the connection having the givenID.
- *
- * @param connection_id The ID of the connection to associate all
- * parameters with.
- * @param config The GuacamoleConfiguration to read parameters from.
- */
- private void createConfigurationValues(int connection_id,
- GuacamoleConfiguration config) {
-
- // Insert new parameters for each parameter in the config
- for (String name : config.getParameterNames()) {
-
- // Create a ConnectionParameter based on the current parameter
- ConnectionParameter parameter = new ConnectionParameter();
- parameter.setConnection_id(connection_id);
- parameter.setParameter_name(name);
- parameter.setParameter_value(config.getParameter(name));
-
- // Insert connection parameter
- connectionParameterDAO.insert(parameter);
- }
-
- }
-
- @Transactional
- @Override
- public void update(Connection object) throws GuacamoleException {
-
- // If connection not actually from this auth provider, we can't handle
- // the update
- if (!(object instanceof MySQLConnection))
- throw new GuacamoleUnsupportedException("Connection not from database.");
-
- MySQLConnection mySQLConnection = (MySQLConnection) object;
-
- // Verify permission to update
- permissionCheckService.verifyConnectionAccess(currentUser,
- mySQLConnection.getConnectionID(),
- MySQLConstants.CONNECTION_UPDATE);
-
- // Perform update
- connectionService.updateConnection(mySQLConnection);
-
- // Delete old connection parameters
- ConnectionParameterExample parameterExample = new ConnectionParameterExample();
- parameterExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
- connectionParameterDAO.deleteByExample(parameterExample);
-
- // Add connection parameters
- createConfigurationValues(mySQLConnection.getConnectionID(),
- object.getConfiguration());
-
- }
-
- @Transactional
- @Override
- public void remove(String identifier) throws GuacamoleException {
-
- // Get connection
- MySQLConnection mySQLConnection =
- connectionService.retrieveConnection(identifier, currentUser);
-
- if(mySQLConnection == null)
- throw new GuacamoleResourceNotFoundException("Connection not found.");
-
- // Verify permission to use the parent connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (mySQLConnection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify permission to delete
- permissionCheckService.verifyConnectionAccess(currentUser,
- mySQLConnection.getConnectionID(),
- MySQLConstants.CONNECTION_DELETE);
-
- // Delete the connection itself
- connectionService.deleteConnection(mySQLConnection.getConnectionID());
-
- }
-
- @Override
- public void move(String identifier, Directory directory)
- throws GuacamoleException {
-
- if(!(directory instanceof ConnectionDirectory))
- throw new GuacamoleUnsupportedException("Directory not from database");
-
- Integer toConnectionGroupID = ((ConnectionDirectory)directory).parentID;
-
- // Get connection
- MySQLConnection mySQLConnection =
- connectionService.retrieveConnection(identifier, currentUser);
-
- if(mySQLConnection == null)
- throw new GuacamoleResourceNotFoundException("Connection not found.");
-
- // Verify permission to update the connection
- permissionCheckService.verifyConnectionAccess(currentUser,
- mySQLConnection.getConnectionID(),
- MySQLConstants.CONNECTION_UPDATE);
-
- // Verify permission to use the from connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (mySQLConnection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify permission to update the from connection group
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- mySQLConnection.getParentID(), MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Verify permission to use the to connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (toConnectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify permission to update the to connection group
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- toConnectionGroupID, MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Verify that no connection already exists with this name.
- MySQLConnection previousConnection =
- connectionService.retrieveConnection(mySQLConnection.getName(),
- toConnectionGroupID, currentUser);
- if(previousConnection != null)
- throw new GuacamoleClientException("That connection name is already in use.");
-
- // Update the connection
- mySQLConnection.setParentID(toConnectionGroupID);
- connectionService.updateConnection(mySQLConnection);
- }
-
-}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionGroupDirectory.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionGroupDirectory.java
deleted file mode 100644
index 0064b7708..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionGroupDirectory.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql;
-
-
-import com.google.inject.Inject;
-import java.util.Set;
-import org.glyptodon.guacamole.GuacamoleClientException;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.auth.ConnectionGroup;
-import org.glyptodon.guacamole.net.auth.ConnectionGroup.Type;
-import org.glyptodon.guacamole.net.auth.Directory;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionKey;
-import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
-import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
-import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
-import org.glyptodon.guacamole.GuacamoleUnsupportedException;
-import org.mybatis.guice.transactional.Transactional;
-
-/**
- * A MySQL-based implementation of the connection group directory.
- *
- * @author James Muehlner
- */
-public class ConnectionGroupDirectory implements Directory{
-
- /**
- * The user who this connection directory belongs to. Access is based on
- * his/her permission settings.
- */
- private AuthenticatedUser currentUser;
-
- /**
- * The ID of the parent connection group.
- */
- private Integer parentID;
-
- /**
- * Service for checking permissions.
- */
- @Inject
- private PermissionCheckService permissionCheckService;
-
- /**
- * Service managing connection groups.
- */
- @Inject
- private ConnectionGroupService connectionGroupService;
-
- /**
- * Service for manipulating connection group permissions in the database.
- */
- @Inject
- private ConnectionGroupPermissionMapper connectionGroupPermissionDAO;
-
- /**
- * Set the user and parentID for this directory.
- *
- * @param currentUser
- * The user owning this connection group directory.
- *
- * @param parentID
- * The ID of the parent connection group.
- */
- public void init(AuthenticatedUser currentUser, Integer parentID) {
- this.parentID = parentID;
- this.currentUser = currentUser;
- }
-
- @Transactional
- @Override
- public ConnectionGroup get(String identifier) throws GuacamoleException {
-
- // Get connection
- MySQLConnectionGroup connectionGroup =
- connectionGroupService.retrieveConnectionGroup(identifier, currentUser);
-
- if(connectionGroup == null)
- return null;
-
- // Verify permission to use the parent connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (connectionGroup.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify access is granted
- permissionCheckService.verifyConnectionGroupAccess(
- currentUser,
- connectionGroup.getConnectionGroupID(),
- MySQLConstants.CONNECTION_GROUP_READ);
-
- // Return connection group
- return connectionGroup;
-
- }
-
- @Transactional
- @Override
- public Set getIdentifiers() throws GuacamoleException {
-
- // Verify permission to use the connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- return permissionCheckService.retrieveConnectionGroupIdentifiers(currentUser,
- parentID, MySQLConstants.CONNECTION_GROUP_READ);
- }
-
- @Transactional
- @Override
- public void add(ConnectionGroup object) throws GuacamoleException {
-
- String name = object.getName().trim();
- if(name.isEmpty())
- throw new GuacamoleClientException("The connection group name cannot be blank.");
-
- Type type = object.getType();
-
- String mySQLType = MySQLConstants.getConnectionGroupTypeConstant(type);
-
- // Verify permission to create
- permissionCheckService.verifySystemAccess(currentUser,
- MySQLConstants.SYSTEM_CONNECTION_GROUP_CREATE);
-
- // Verify permission to edit the parent connection group
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- this.parentID, MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Verify permission to use the parent connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify that no connection already exists with this name.
- MySQLConnectionGroup previousConnectionGroup =
- connectionGroupService.retrieveConnectionGroup(name, parentID, currentUser);
- if(previousConnectionGroup != null)
- throw new GuacamoleClientException("That connection group name is already in use.");
-
- // Create connection group
- MySQLConnectionGroup connectionGroup = connectionGroupService
- .createConnectionGroup(name, currentUser, parentID, mySQLType);
-
- // Set the connection group ID
- object.setIdentifier(connectionGroup.getIdentifier());
-
- // Finally, give the current user full access to the newly created
- // connection group.
- ConnectionGroupPermissionKey newConnectionGroupPermission = new ConnectionGroupPermissionKey();
- newConnectionGroupPermission.setUser_id(currentUser.getUserID());
- newConnectionGroupPermission.setConnection_group_id(connectionGroup.getConnectionGroupID());
-
- // Read permission
- newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_READ);
- connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
-
- // Update permission
- newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_UPDATE);
- connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
-
- // Delete permission
- newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_DELETE);
- connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
-
- // Administer permission
- newConnectionGroupPermission.setPermission(MySQLConstants.CONNECTION_GROUP_ADMINISTER);
- connectionGroupPermissionDAO.insert(newConnectionGroupPermission);
-
- }
-
- @Transactional
- @Override
- public void update(ConnectionGroup object) throws GuacamoleException {
-
- // If connection not actually from this auth provider, we can't handle
- // the update
- if (!(object instanceof MySQLConnectionGroup))
- throw new GuacamoleUnsupportedException("Connection not from database.");
-
- MySQLConnectionGroup mySQLConnectionGroup = (MySQLConnectionGroup) object;
-
- // Verify permission to update
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- mySQLConnectionGroup.getConnectionGroupID(),
- MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Perform update
- connectionGroupService.updateConnectionGroup(mySQLConnectionGroup);
- }
-
- @Transactional
- @Override
- public void remove(String identifier) throws GuacamoleException {
-
- // Get connection
- MySQLConnectionGroup mySQLConnectionGroup =
- connectionGroupService.retrieveConnectionGroup(identifier, currentUser);
-
- if(mySQLConnectionGroup == null)
- throw new GuacamoleResourceNotFoundException("Connection group not found.");
-
- // Verify permission to use the parent connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (mySQLConnectionGroup.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify permission to delete
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- mySQLConnectionGroup.getConnectionGroupID(),
- MySQLConstants.CONNECTION_GROUP_DELETE);
-
- // Delete the connection group itself
- connectionGroupService.deleteConnectionGroup
- (mySQLConnectionGroup.getConnectionGroupID());
-
- }
-
- @Override
- public void move(String identifier, Directory directory)
- throws GuacamoleException {
-
- if(MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER.equals(identifier))
- throw new GuacamoleUnsupportedException("The root connection group cannot be moved.");
-
- if(!(directory instanceof ConnectionGroupDirectory))
- throw new GuacamoleUnsupportedException("Directory not from database");
-
- Integer toConnectionGroupID = ((ConnectionGroupDirectory)directory).parentID;
-
- // Get connection group
- MySQLConnectionGroup mySQLConnectionGroup =
- connectionGroupService.retrieveConnectionGroup(identifier, currentUser);
-
- if(mySQLConnectionGroup == null)
- throw new GuacamoleResourceNotFoundException("Connection group not found.");
-
- // Verify permission to update the connection group
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- mySQLConnectionGroup.getConnectionGroupID(),
- MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Verify permission to use the from connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (mySQLConnectionGroup.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify permission to update the from connection group
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- mySQLConnectionGroup.getParentID(), MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Verify permission to use the to connection group for organizational purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (toConnectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
-
- // Verify permission to update the to connection group
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- toConnectionGroupID, MySQLConstants.CONNECTION_GROUP_UPDATE);
-
- // Verify that no connection already exists with this name.
- MySQLConnectionGroup previousConnectionGroup =
- connectionGroupService.retrieveConnectionGroup(mySQLConnectionGroup.getName(),
- toConnectionGroupID, currentUser);
- if(previousConnectionGroup != null)
- throw new GuacamoleClientException("That connection group name is already in use.");
-
- // Verify that moving this connectionGroup would not cause a cycle
- Integer relativeParentID = toConnectionGroupID;
- while(relativeParentID != null) {
- if(relativeParentID == mySQLConnectionGroup.getConnectionGroupID())
- throw new GuacamoleUnsupportedException("Connection group cycle detected.");
-
- MySQLConnectionGroup relativeParentGroup = connectionGroupService.
- retrieveConnectionGroup(relativeParentID, currentUser);
-
- relativeParentID = relativeParentGroup.getParentID();
- }
-
- // Update the connection
- mySQLConnectionGroup.setParentID(toConnectionGroupID);
- connectionGroupService.updateConnectionGroup(mySQLConnectionGroup);
- }
-
-}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/DirectoryObject.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/DirectoryObject.java
new file mode 100644
index 000000000..cae34ea43
--- /dev/null
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/DirectoryObject.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+package net.sourceforge.guacamole.net.auth.mysql;
+
+/**
+ * Common interface for objects that will ultimately be made available through
+ * the Directory class. All such objects will need the same base set of queries
+ * to fulfill the needs of the Directory class.
+ *
+ * @author Michael Jumper
+ * @param
+ * The type of object contained within the directory whose objects are
+ * mapped by this mapper.
+ */
+public interface DirectoryObject {
+
+ /**
+ * Returns the backing model object. Changes to the model object will
+ * affect this object, and changes to this object will affect the model
+ * object.
+ *
+ * @return
+ * The user model object backing this MySQLUser.
+ */
+ public ModelType getModel();
+
+ /**
+ * Sets the backing model object. This will effectively replace all data
+ * contained within this object.
+ *
+ * @param model
+ * The backing model object.
+ */
+ public void setModel(ModelType model);
+
+}
\ No newline at end of file
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 2a0080325..ece180551 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
@@ -33,20 +33,9 @@ import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
import org.glyptodon.guacamole.net.auth.Credentials;
import org.glyptodon.guacamole.net.auth.UserContext;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
-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.dao.ConnectionPermissionMapper;
-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.ConnectionGroupService;
-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.SHA256PasswordEncryptionService;
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
import net.sourceforge.guacamole.net.auth.mysql.service.SecureRandomSaltService;
@@ -65,16 +54,11 @@ import org.mybatis.guice.datasource.helper.JdbcHelper;
*/
public class MySQLAuthenticationProvider implements AuthenticationProvider {
- /**
- * Set of all active connections.
- */
- private ActiveConnectionMap activeConnectionMap = new ActiveConnectionMap();
-
/**
* Injector which will manage the object graph of this authentication
* provider.
*/
- private Injector injector;
+ private final Injector injector;
@Override
public UserContext getUserContext(Credentials credentials) throws GuacamoleException {
@@ -83,10 +67,10 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
UserService userService = injector.getInstance(UserService.class);
// Get user
- MySQLUser authenticatedUser = userService.retrieveUser(credentials);
- if (authenticatedUser != null) {
+ MySQLUser user = userService.retrieveUser(credentials);
+ if (user != null) {
MySQLUserContext context = injector.getInstance(MySQLUserContext.class);
- context.init(new AuthenticatedUser(authenticatedUser.getUserID(), credentials));
+ context.init(user);
return context;
}
@@ -145,27 +129,15 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
bindTransactionFactoryType(JdbcTransactionFactory.class);
// Add MyBatis mappers
- addMapperClass(ConnectionHistoryMapper.class);
- addMapperClass(ConnectionMapper.class);
- addMapperClass(ConnectionGroupMapper.class);
- addMapperClass(ConnectionGroupPermissionMapper.class);
- addMapperClass(ConnectionParameterMapper.class);
- addMapperClass(ConnectionPermissionMapper.class);
- addMapperClass(SystemPermissionMapper.class);
addMapperClass(UserMapper.class);
- addMapperClass(UserPermissionMapper.class);
// Bind interfaces
- bind(MySQLUserContext.class);
- bind(UserDirectory.class);
bind(MySQLUser.class);
- bind(SaltService.class).to(SecureRandomSaltService.class);
+ bind(MySQLUserContext.class);
bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);
- bind(PermissionCheckService.class);
- bind(ConnectionService.class);
- bind(ConnectionGroupService.class);
+ bind(SaltService.class).to(SecureRandomSaltService.class);
+ bind(UserDirectory.class);
bind(UserService.class);
- bind(ActiveConnectionMap.class).toInstance(activeConnectionMap);
}
} // end of mybatis module
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
deleted file mode 100644
index c685f7eaa..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnection.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql;
-
-
-import com.google.inject.Inject;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.GuacamoleSocket;
-import org.glyptodon.guacamole.net.auth.AbstractConnection;
-import org.glyptodon.guacamole.net.auth.ConnectionRecord;
-import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
-import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
-import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
-
-/**
- * A MySQL based implementation of the Connection object.
- * @author James Muehlner
- */
-public class MySQLConnection extends AbstractConnection {
-
- /**
- * The ID associated with this connection in the database.
- */
- private Integer connectionID;
-
- /**
- * The ID of the parent connection group for this connection.
- */
- private Integer parentID;
-
- /**
- * The user who queried or created this connection.
- */
- private AuthenticatedUser currentUser;
-
- /**
- * History of this connection.
- */
- private List history = new ArrayList();
-
- /**
- * Service for managing connections.
- */
- @Inject
- private ConnectionService connectionService;
-
- /**
- * Create a default, empty connection.
- */
- public MySQLConnection() {
- }
-
- /**
- * Get the ID of the corresponding connection record.
- * @return The ID of the corresponding connection, if any.
- */
- public Integer getConnectionID() {
- return connectionID;
- }
-
- /**
- * Sets the ID of the corresponding connection record.
- * @param connectionID The ID to assign to this connection.
- */
- public void setConnectionID(Integer connectionID) {
- this.connectionID = connectionID;
- }
-
- /**
- * Get the ID of the parent connection group for this connection, if any.
- * @return The ID of the parent connection group for this connection, if any.
- */
- public Integer getParentID() {
- return parentID;
- }
-
- /**
- * Sets the ID of the parent connection group for this connection.
- * @param parentID The ID of the parent connection group for this connection.
- */
- public void setParentID(Integer parentID) {
- this.parentID = parentID;
-
- // Translate to string identifier
- if (parentID != null)
- this.setParentIdentifier(String.valueOf(parentID));
- else
- this.setParentIdentifier(MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER);
-
- }
-
- /**
- * Initialize from explicit values.
- *
- * @param connectionID
- * The ID of the associated database record, if any.
- *
- * @param parentID
- * The ID of the parent connection group for this connection, if any.
- *
- * @param name
- * The human-readable name associated with this connection.
- *
- * @param identifier
- * The unique identifier associated with this connection.
- *
- * @param config
- * The GuacamoleConfiguration associated with this connection.
- *
- * @param history
- * All ConnectionRecords associated with this connection.
- *
- * @param currentUser
- * The user who queried this connection.
- */
- public void init(Integer connectionID, Integer parentID, String name,
- String identifier, GuacamoleConfiguration config,
- List extends ConnectionRecord> history,
- AuthenticatedUser currentUser) {
-
- this.connectionID = connectionID;
- this.setParentID(parentID);
- setName(name);
- setIdentifier(identifier);
- setConfiguration(config);
- this.history.addAll(history);
- this.currentUser = currentUser;
-
- }
-
- @Override
- public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
- return connectionService.connect(this, info, currentUser, null);
- }
-
- @Override
- public List extends ConnectionRecord> getHistory() throws GuacamoleException {
- return Collections.unmodifiableList(history);
- }
-
-}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionGroup.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionGroup.java
deleted file mode 100644
index 53380bb5c..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionGroup.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql;
-
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.GuacamoleSocket;
-import org.glyptodon.guacamole.net.auth.AbstractConnectionGroup;
-import org.glyptodon.guacamole.net.auth.Connection;
-import org.glyptodon.guacamole.net.auth.ConnectionGroup;
-import org.glyptodon.guacamole.net.auth.Directory;
-import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
-import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
-import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
-
-/**
- * A MySQL based implementation of the ConnectionGroup object.
- * @author James Muehlner
- */
-public class MySQLConnectionGroup extends AbstractConnectionGroup {
-
- /**
- * The ID associated with this connection group in the database.
- */
- private Integer connectionGroupID;
-
- /**
- * The ID of the parent connection group for this connection group.
- */
- private Integer parentID;
-
- /**
- * The user who queried or created this connection group.
- */
- private AuthenticatedUser currentUser;
-
- /**
- * A Directory of connections that have this connection group as a parent.
- */
- private ConnectionDirectory connectionDirectory = null;
-
- /**
- * A Directory of connection groups that have this connection group as a parent.
- */
- private ConnectionGroupDirectory connectionGroupDirectory = null;
-
- /**
- * Service managing connection groups.
- */
- @Inject
- private ConnectionGroupService connectionGroupService;
-
- /**
- * Service for checking permissions.
- */
- @Inject
- private PermissionCheckService permissionCheckService;
-
- /**
- * Service for creating new ConnectionDirectory objects.
- */
- @Inject Provider connectionDirectoryProvider;
-
- /**
- * Service for creating new ConnectionGroupDirectory objects.
- */
- @Inject Provider connectionGroupDirectoryProvider;
-
- /**
- * Create a default, empty connection group.
- */
- public MySQLConnectionGroup() {
- }
-
- /**
- * Get the ID of the corresponding connection group record.
- * @return The ID of the corresponding connection group, if any.
- */
- public Integer getConnectionGroupID() {
- return connectionGroupID;
- }
-
- /**
- * Sets the ID of the corresponding connection group record.
- * @param connectionGroupID The ID to assign to this connection group.
- */
- public void setConnectionID(Integer connectionGroupID) {
- this.connectionGroupID = connectionGroupID;
- }
-
- /**
- * Get the ID of the parent connection group for this connection group, if any.
- * @return The ID of the parent connection group for this connection group, if any.
- */
- public Integer getParentID() {
- return parentID;
- }
-
- /**
- * Sets the ID of the parent connection group for this connection group.
- * @param parentID The ID of the parent connection group for this connection group.
- */
- public void setParentID(Integer parentID) {
- this.parentID = parentID;
-
- // Translate to string identifier
- if (parentID != null)
- this.setParentIdentifier(String.valueOf(parentID));
- else
- this.setParentIdentifier(MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER);
-
- }
-
- /**
- * Initialize from explicit values.
- *
- * @param connectionGroupID
- * The ID of the associated database record, if any.
- *
- * @param parentID
- * The ID of the parent connection group for this connection group, if
- * any.
- *
- * @param name
- * The name of this connection group.
- *
- * @param identifier
- * The unique identifier associated with this connection group.
- *
- * @param type
- * The type of this connection group.
- *
- * @param currentUser
- * The user who queried this connection.
- */
- public void init(Integer connectionGroupID, Integer parentID, String name,
- String identifier, ConnectionGroup.Type type, AuthenticatedUser currentUser) {
- this.connectionGroupID = connectionGroupID;
- this.setParentID(parentID);
- setName(name);
- setIdentifier(identifier);
- setType(type);
- this.currentUser = currentUser;
-
- connectionDirectory = connectionDirectoryProvider.get();
- connectionDirectory.init(currentUser, connectionGroupID);
-
- connectionGroupDirectory = connectionGroupDirectoryProvider.get();
- connectionGroupDirectory.init(currentUser, connectionGroupID);
- }
-
- @Override
- public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
-
- // Verify permission to use the connection group for balancing purposes
- permissionCheckService.verifyConnectionGroupUsageAccess
- (this.connectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_BALANCING);
-
- // Verify permission to delete
- permissionCheckService.verifyConnectionGroupAccess(currentUser,
- this.connectionGroupID,
- MySQLConstants.CONNECTION_GROUP_READ);
-
- return connectionGroupService.connect(this, info, currentUser);
- }
-
- @Override
- public Directory getConnectionDirectory() throws GuacamoleException {
- return connectionDirectory;
- }
-
- @Override
- public Directory getConnectionGroupDirectory() throws GuacamoleException {
- return connectionGroupDirectory;
- }
-
-}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java
index 4200bfe5d..86c72b2e8 100644
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java
@@ -23,7 +23,6 @@
package net.sourceforge.guacamole.net.auth.mysql;
-import com.google.inject.Inject;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.io.GuacamoleReader;
import org.glyptodon.guacamole.io.GuacamoleWriter;
@@ -35,12 +34,6 @@ import org.glyptodon.guacamole.net.GuacamoleSocket;
*/
public class MySQLGuacamoleSocket implements GuacamoleSocket {
- /**
- * Injected ActiveConnectionMap which will contain all active connections.
- */
- @Inject
- private ActiveConnectionMap activeConnectionMap;
-
/**
* The wrapped socket.
*/
@@ -86,18 +79,7 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket {
@Override
public void close() throws GuacamoleException {
-
- // Mark this connection as inactive
- synchronized (activeConnectionMap) {
-
- if (isOpen())
- activeConnectionMap.closeConnection(historyID, connectionGroupID);
-
- // Close socket
- socket.close();
-
- }
-
+ socket.close();
}
@Override
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java
index 25b07f123..36d159afe 100644
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java
@@ -22,40 +22,50 @@
package net.sourceforge.guacamole.net.auth.mysql;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import com.google.inject.Inject;
+import net.sourceforge.guacamole.net.auth.mysql.model.UserModel;
+import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService;
+import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.auth.AbstractUser;
import org.glyptodon.guacamole.net.auth.User;
-import org.glyptodon.guacamole.net.auth.permission.Permission;
+import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
+import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
+import org.glyptodon.guacamole.net.auth.simple.SimpleObjectPermissionSet;
+import org.glyptodon.guacamole.net.auth.simple.SimpleSystemPermissionSet;
/**
* A MySQL based implementation of the User object.
* @author James Muehlner
*/
-public class MySQLUser extends AbstractUser {
+public class MySQLUser implements User, DirectoryObject {
/**
- * The ID of this user in the database, if any.
+ * Service for hashing passwords.
*/
- private Integer userID;
+ @Inject
+ private PasswordEncryptionService encryptionService;
/**
- * The set of current permissions a user has.
+ * Service for providing secure, random salts.
*/
- private Set permissions = new HashSet();
+ @Inject
+ private SaltService saltService;
+
+ /**
+ * The internal model object containing the values which represent this
+ * user in the database.
+ */
+ private UserModel userModel;
/**
- * Any newly added permissions that have yet to be committed.
+ * The plaintext password previously set by a call to setPassword(), if
+ * any. The password of a user cannot be retrieved once saved into the
+ * database, so this serves to ensure getPassword() returns a reasonable
+ * value if setPassword() is called. If no password has been set, or the
+ * user was retrieved from the database, this will be null.
*/
- private Set newPermissions = new HashSet();
-
- /**
- * Any newly deleted permissions that have yet to be deleted.
- */
- private Set removedPermissions = new HashSet();
-
+ private String password = null;
+
/**
* Creates a new, empty MySQLUser.
*/
@@ -63,118 +73,85 @@ public class MySQLUser extends AbstractUser {
}
/**
- * Initializes a new MySQLUser having the given username.
- *
- * @param name The name to assign to this MySQLUser.
+ * Creates a new MySQLUser backed by the given user model object. Changes
+ * to this model object will affect the new MySQLUser even after creation,
+ * and changes to the new MySQLUser will affect this model object.
+ *
+ * @param userModel
+ * The user model object to use to back this MySQLUser.
*/
- public void init(String name) {
- init(null, name, null, Collections.EMPTY_SET);
- }
-
- /**
- * Initializes a new MySQLUser, copying all data from the given user
- * object.
- *
- * @param user The user object to copy.
- * @throws GuacamoleException If an error occurs while reading the user
- * data in the given object.
- */
- public void init(User user) throws GuacamoleException {
- init(null, user.getUsername(), user.getPassword(), user.getPermissions());
- }
-
- /**
- * Initializes a new MySQLUser initialized from the given data from the
- * database.
- *
- * @param userID The ID of the user in the database, if any.
- * @param username The username of this user.
- * @param password The password to assign to this user.
- * @param permissions The permissions to assign to this user, as
- * retrieved from the database.
- */
- public void init(Integer userID, String username, String password,
- Set permissions) {
- this.userID = userID;
- setUsername(username);
- setPassword(password);
- this.permissions.addAll(permissions);
- }
-
- /**
- * Get the current set of permissions this user has.
- * @return the current set of permissions.
- */
- public Set getCurrentPermissions() {
- return permissions;
- }
-
- /**
- * Get any new permissions that have yet to be inserted.
- * @return the new set of permissions.
- */
- public Set getNewPermissions() {
- return newPermissions;
- }
-
- /**
- * Get any permissions that have not yet been deleted.
- * @return the permissions that need to be deleted.
- */
- public Set getRemovedPermissions() {
- return removedPermissions;
- }
-
- /**
- * Reset the new and removed permission sets after they are
- * no longer needed.
- */
- public void resetPermissions() {
- newPermissions.clear();
- removedPermissions.clear();
- }
-
- /**
- * Returns the ID of this user in the database, if it exists.
- *
- * @return The ID of this user in the database, or null if this user
- * was not retrieved from the database.
- */
- public Integer getUserID() {
- return userID;
- }
-
- /**
- * Sets the ID of this user to the given value.
- *
- * @param userID The ID to assign to this user.
- */
- public void setUserID(Integer userID) {
- this.userID = userID;
+ public MySQLUser(UserModel userModel) {
+ this.userModel = userModel;
}
@Override
- public Set getPermissions() throws GuacamoleException {
- return Collections.unmodifiableSet(permissions);
+ public UserModel getModel() {
+ return userModel;
}
@Override
- public boolean hasPermission(Permission permission) throws GuacamoleException {
- return permissions.contains(permission);
+ public void setModel(UserModel userModel) {
+ this.userModel = userModel;
+ this.password = null;
}
@Override
- public void addPermission(Permission permission) throws GuacamoleException {
- permissions.add(permission);
- newPermissions.add(permission);
- removedPermissions.remove(permission);
+ public String getUsername() {
+ return userModel.getUsername();
}
@Override
- public void removePermission(Permission permission) throws GuacamoleException {
- permissions.remove(permission);
- newPermissions.remove(permission);
- removedPermissions.add(permission);
+ public void setUsername(String username) {
+ userModel.setUsername(username);
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public void setPassword(String password) {
+
+ // Store plaintext password internally
+ this.password = password;
+
+ // Generate new salt and hash given password using newly-generated salt
+ byte[] salt = saltService.generateSalt();
+ byte[] hash = encryptionService.createPasswordHash(password, salt);
+
+ // Set stored salt and hash
+ userModel.setPasswordSalt(salt);
+ userModel.setPasswordHash(hash);
+
+ }
+
+ @Override
+ public SystemPermissionSet getSystemPermissions()
+ throws GuacamoleException {
+ // STUB
+ return new SimpleSystemPermissionSet();
+ }
+
+ @Override
+ public ObjectPermissionSet getConnectionPermissions()
+ throws GuacamoleException {
+ // STUB
+ return new SimpleObjectPermissionSet();
+ }
+
+ @Override
+ public ObjectPermissionSet getConnectionGroupPermissions()
+ throws GuacamoleException {
+ // STUB
+ return new SimpleObjectPermissionSet();
+ }
+
+ @Override
+ public ObjectPermissionSet getUserPermissions()
+ throws GuacamoleException {
+ // STUB
+ return new SimpleObjectPermissionSet();
}
}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java
index 43f0728bb..55766260d 100644
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java
@@ -24,13 +24,15 @@ package net.sourceforge.guacamole.net.auth.mysql;
import com.google.inject.Inject;
+import java.util.Collections;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
import org.glyptodon.guacamole.net.auth.Directory;
import org.glyptodon.guacamole.net.auth.User;
import org.glyptodon.guacamole.net.auth.UserContext;
-import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
-import org.glyptodon.guacamole.net.auth.Credentials;
+import org.glyptodon.guacamole.net.auth.simple.SimpleConnectionDirectory;
+import org.glyptodon.guacamole.net.auth.simple.SimpleConnectionGroup;
+import org.glyptodon.guacamole.net.auth.simple.SimpleConnectionGroupDirectory;
/**
* The MySQL representation of a UserContext.
@@ -39,10 +41,9 @@ import org.glyptodon.guacamole.net.auth.Credentials;
public class MySQLUserContext implements UserContext {
/**
- * The the user owning this context. The permissions of this user dictate
- * the access given via the user and connection directories.
+ * The the user owning this context.
*/
- private AuthenticatedUser currentUser;
+ private MySQLUser currentUser;
/**
* User directory restricted by the permissions of the user associated
@@ -51,36 +52,19 @@ public class MySQLUserContext implements UserContext {
@Inject
private UserDirectory userDirectory;
- /**
- * The root connection group.
- */
- @Inject
- private MySQLConnectionGroup rootConnectionGroup;
-
- /**
- * Service for accessing users.
- */
- @Inject
- private UserService userService;
-
/**
* Initializes the user and directories associated with this context.
*
* @param currentUser
* The user owning this context.
*/
- public void init(AuthenticatedUser currentUser) {
+ public void init(MySQLUser currentUser) {
this.currentUser = currentUser;
- userDirectory.init(currentUser);
- rootConnectionGroup.init(null, null,
- MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
- MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
- ConnectionGroup.Type.ORGANIZATIONAL, currentUser);
}
@Override
public User self() {
- return userService.retrieveUser(currentUser.getUserID());
+ return currentUser;
}
@Override
@@ -90,7 +74,11 @@ public class MySQLUserContext implements UserContext {
@Override
public ConnectionGroup getRootConnectionGroup() throws GuacamoleException {
- return rootConnectionGroup;
+ /* STUB */
+ return new SimpleConnectionGroup("ROOT", "ROOT",
+ new SimpleConnectionDirectory(Collections.EMPTY_MAP),
+ new SimpleConnectionGroupDirectory(Collections.EMPTY_LIST)
+ );
}
}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java
index 66a1a16df..9014c7238 100644
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java
@@ -23,686 +23,76 @@
package net.sourceforge.guacamole.net.auth.mysql;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
import com.google.inject.Inject;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.Collections;
import java.util.Set;
-import org.glyptodon.guacamole.GuacamoleClientException;
+import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.GuacamoleSecurityException;
import org.glyptodon.guacamole.net.auth.Directory;
import org.glyptodon.guacamole.net.auth.User;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionKey;
-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.model.SystemPermissionExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
-import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionKey;
-import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionGroupService;
-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.UserService;
-import org.glyptodon.guacamole.GuacamoleUnsupportedException;
-import org.glyptodon.guacamole.net.auth.permission.ConnectionGroupPermission;
-import org.glyptodon.guacamole.net.auth.permission.ConnectionPermission;
-import org.glyptodon.guacamole.net.auth.permission.Permission;
-import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
-import org.glyptodon.guacamole.net.auth.permission.UserPermission;
import org.mybatis.guice.transactional.Transactional;
/**
* A MySQL based implementation of the User Directory.
+ *
* @author James Muehlner
+ * @author Michael Jumper
*/
public class UserDirectory implements Directory {
/**
- * The user this user directory belongs to. Access is based on his/her
- * permission settings.
- */
- private AuthenticatedUser currentUser;
-
- /**
- * Service for accessing users.
+ * Service for managing user objects.
*/
@Inject
private UserService userService;
- /**
- * Service for accessing connections.
- */
- @Inject
- private ConnectionService connectionService;
-
- /**
- * Service for accessing connection groups.
- */
- @Inject
- private ConnectionGroupService connectionGroupService;
-
- /**
- * DAO for accessing user permissions, which will be injected.
- */
- @Inject
- private UserPermissionMapper userPermissionDAO;
-
- /**
- * DAO for accessing connection permissions, which will be injected.
- */
- @Inject
- private ConnectionPermissionMapper connectionPermissionDAO;
-
- /**
- * DAO for accessing connection group permissions, which will be injected.
- */
- @Inject
- private ConnectionGroupPermissionMapper connectionGroupPermissionDAO;
-
- /**
- * DAO for accessing system permissions, which will be injected.
- */
- @Inject
- private SystemPermissionMapper systemPermissionDAO;
-
- /**
- * Service for checking various permissions, which will be injected.
- */
- @Inject
- private PermissionCheckService permissionCheckService;
-
- /**
- * Set the user for this directory.
- *
- * @param currentUser
- * The user whose permissions define the visibility of other users in
- * this directory.
- */
- public void init(AuthenticatedUser currentUser) {
- this.currentUser = currentUser;
- }
-
- @Transactional
- @Override
- public org.glyptodon.guacamole.net.auth.User get(String identifier)
- throws GuacamoleException {
-
- // Get user
- MySQLUser user = userService.retrieveUser(identifier);
-
- if(user == null)
- return null;
-
- // Verify access is granted
- permissionCheckService.verifyUserAccess(currentUser,
- user.getUserID(),
- MySQLConstants.USER_READ);
-
- // Return user
- return user;
-
- }
-
- @Transactional
- @Override
- public Set getIdentifiers() throws GuacamoleException {
- return permissionCheckService.retrieveUsernames(currentUser,
- MySQLConstants.USER_READ);
- }
-
- @Override
- @Transactional
- public void add(org.glyptodon.guacamole.net.auth.User object)
- throws GuacamoleException {
-
- String username = object.getUsername().trim();
- if(username.isEmpty())
- throw new GuacamoleClientException("The username cannot be blank.");
-
- // Verify current user has permission to create users
- permissionCheckService.verifySystemAccess(currentUser,
- MySQLConstants.SYSTEM_USER_CREATE);
- Preconditions.checkNotNull(object);
-
- // Verify that no user already exists with this username.
- MySQLUser previousUser = userService.retrieveUser(username);
- if(previousUser != null)
- throw new GuacamoleClientException("That username is already in use.");
-
- // Create new user
- MySQLUser user = userService.createUser(username, object.getPassword());
-
- // Create permissions of new user in database
- createPermissions(user.getUserID(), object.getPermissions());
-
- // Give the current user full access to the newly created user.
- UserPermissionKey newUserPermission = new UserPermissionKey();
- newUserPermission.setUser_id(currentUser.getUserID());
- newUserPermission.setAffected_user_id(user.getUserID());
-
- // READ permission on new user
- newUserPermission.setPermission(MySQLConstants.USER_READ);
- userPermissionDAO.insert(newUserPermission);
-
- // UPDATE permission on new user
- newUserPermission.setPermission(MySQLConstants.USER_UPDATE);
- userPermissionDAO.insert(newUserPermission);
-
- // DELETE permission on new user
- newUserPermission.setPermission(MySQLConstants.USER_DELETE);
- userPermissionDAO.insert(newUserPermission);
-
- // ADMINISTER permission on new user
- newUserPermission.setPermission(MySQLConstants.USER_ADMINISTER);
- userPermissionDAO.insert(newUserPermission);
-
- }
-
- /**
- * Add the given permissions to the given user.
- *
- * @param user_id The ID of the user whose permissions should be updated.
- * @param permissions The permissions to add.
- * @throws GuacamoleException If an error occurs while updating the
- * permissions of the given user.
- */
- private void createPermissions(int user_id, Set permissions) throws GuacamoleException {
-
- // Partition given permissions by permission type
- List newUserPermissions = new ArrayList();
- List newConnectionPermissions = new ArrayList();
- List newConnectionGroupPermissions = new ArrayList();
- List newSystemPermissions = new ArrayList();
-
- for (Permission permission : permissions) {
-
- if (permission instanceof UserPermission)
- newUserPermissions.add((UserPermission) permission);
-
- else if (permission instanceof ConnectionPermission)
- newConnectionPermissions.add((ConnectionPermission) permission);
-
- else if (permission instanceof ConnectionGroupPermission)
- newConnectionGroupPermissions.add((ConnectionGroupPermission) permission);
-
- else if (permission instanceof SystemPermission)
- newSystemPermissions.add((SystemPermission) permission);
- }
-
- // Create the new permissions
- createUserPermissions(user_id, newUserPermissions);
- createConnectionPermissions(user_id, newConnectionPermissions);
- createConnectionGroupPermissions(user_id, newConnectionGroupPermissions);
- createSystemPermissions(user_id, newSystemPermissions);
-
- }
-
- /**
- * Remove the given permissions from the given user.
- *
- * @param user_id The ID of the user whose permissions should be updated.
- * @param permissions The permissions to remove.
- * @throws GuacamoleException If an error occurs while updating the
- * permissions of the given user.
- */
- private void removePermissions(int user_id, Set permissions)
- throws GuacamoleException {
-
- // Partition given permissions by permission type
- List removedUserPermissions = new ArrayList();
- List removedConnectionPermissions = new ArrayList();
- List removedConnectionGroupPermissions = new ArrayList();
- List removedSystemPermissions = new ArrayList();
-
- for (Permission permission : permissions) {
-
- if (permission instanceof UserPermission)
- removedUserPermissions.add((UserPermission) permission);
-
- else if (permission instanceof ConnectionPermission)
- removedConnectionPermissions.add((ConnectionPermission) permission);
-
- else if (permission instanceof ConnectionGroupPermission)
- removedConnectionGroupPermissions.add((ConnectionGroupPermission) permission);
-
- else if (permission instanceof SystemPermission)
- removedSystemPermissions.add((SystemPermission) permission);
- }
-
- // Delete the removed permissions.
- deleteUserPermissions(user_id, removedUserPermissions);
- deleteConnectionPermissions(user_id, removedConnectionPermissions);
- deleteConnectionGroupPermissions(user_id, removedConnectionGroupPermissions);
- deleteSystemPermissions(user_id, removedSystemPermissions);
-
- }
-
- /**
- * Create the given user permissions for the given user.
- *
- * @param user_id The ID of the user to change the permissions of.
- * @param permissions The new permissions the given user should have when
- * this operation completes.
- * @throws GuacamoleException If permission to alter the access permissions
- * of affected objects is denied.
- */
- private void createUserPermissions(int user_id,
- Collection permissions)
- throws GuacamoleException {
-
- // If no permissions given, stop now
- if(permissions.isEmpty())
- return;
-
- // Get list of administerable user IDs
- List administerableUserIDs =
- permissionCheckService.retrieveUserIDs(currentUser,
- MySQLConstants.USER_ADMINISTER);
-
- // Get set of usernames corresponding to administerable users
- Map administerableUsers =
- userService.translateUsernames(administerableUserIDs);
-
- // Insert all given permissions
- for (UserPermission permission : permissions) {
-
- // Get original ID
- Integer affected_id =
- administerableUsers.get(permission.getObjectIdentifier());
-
- // Verify that the user actually has permission to administrate
- // every one of these users
- if (affected_id == null)
- throw new GuacamoleSecurityException(
- "User #" + currentUser.getUserID()
- + " does not have permission to administrate user "
- + permission.getObjectIdentifier());
-
- // Create new permission
- UserPermissionKey newPermission = new UserPermissionKey();
- newPermission.setUser_id(currentUser.getUserID());
- newPermission.setPermission(MySQLConstants.getUserConstant(permission.getType()));
- newPermission.setAffected_user_id(affected_id);
- userPermissionDAO.insert(newPermission);
-
- }
-
- }
-
- /**
- * Delete permissions having to do with users for a given user.
- *
- * @param user_id The ID of the user to change the permissions of.
- * @param permissions The permissions the given user should no longer have
- * when this operation completes.
- * @throws GuacamoleException If permission to alter the access permissions
- * of affected objects is denied.
- */
- private void deleteUserPermissions(int user_id,
- Collection permissions)
- throws GuacamoleException {
-
- // If no permissions given, stop now
- if(permissions.isEmpty())
- return;
-
- // Get list of administerable user IDs
- List administerableUserIDs =
- permissionCheckService.retrieveUserIDs(currentUser,
- MySQLConstants.USER_ADMINISTER);
-
- // Get set of usernames corresponding to administerable users
- Map administerableUsers =
- userService.translateUsernames(administerableUserIDs);
-
- // Delete requested permissions
- for (UserPermission permission : permissions) {
-
- // Get original ID
- Integer affected_id =
- administerableUsers.get(permission.getObjectIdentifier());
-
- // Verify that the user actually has permission to administrate
- // every one of these users
- if (affected_id == null)
- throw new GuacamoleSecurityException(
- "User #" + currentUser.getUserID()
- + " does not have permission to administrate user "
- + permission.getObjectIdentifier());
-
- // Delete requested permission
- UserPermissionExample userPermissionExample = new UserPermissionExample();
- userPermissionExample.createCriteria()
- .andUser_idEqualTo(user_id)
- .andPermissionEqualTo(MySQLConstants.getUserConstant(permission.getType()))
- .andAffected_user_idEqualTo(affected_id);
- userPermissionDAO.deleteByExample(userPermissionExample);
-
- }
-
- }
-
- /**
- * Create any new permissions having to do with connections for a given
- * user.
- *
- * @param user_id The ID of the user to assign or remove permissions from.
- * @param permissions The new permissions the user should have after this
- * operation completes.
- * @throws GuacamoleException If permission to alter the access permissions
- * of affected objects is deniedD
- */
- private void createConnectionPermissions(int user_id,
- Collection permissions)
- throws GuacamoleException {
-
- // If no permissions given, stop now
- if(permissions.isEmpty())
- return;
-
- // Get list of administerable connection IDs
- Set administerableConnectionIDs = Sets.newHashSet(
- permissionCheckService.retrieveConnectionIDs(currentUser,
- MySQLConstants.CONNECTION_ADMINISTER));
-
- // Insert all given permissions
- for (ConnectionPermission permission : permissions) {
-
- // Get original ID
- Integer connection_id = Integer.valueOf(permission.getObjectIdentifier());
-
- // Throw exception if permission to administer this connection
- // is not granted
- if (!administerableConnectionIDs.contains(connection_id))
- throw new GuacamoleSecurityException(
- "User #" + currentUser.getUserID()
- + " does not have permission to administrate connection "
- + permission.getObjectIdentifier());
-
- // Create new permission
- ConnectionPermissionKey newPermission = new ConnectionPermissionKey();
- newPermission.setUser_id(user_id);
- newPermission.setPermission(MySQLConstants.getConnectionConstant(permission.getType()));
- newPermission.setConnection_id(connection_id);
- connectionPermissionDAO.insert(newPermission);
-
- }
- }
-
- /**
- * Create any new permissions having to do with connection groups
- * for a given user.
- *
- * @param user_id The ID of the user to assign or remove permissions from.
- * @param permissions The new permissions the user should have after this
- * operation completes.
- * @throws GuacamoleException If permission to alter the access permissions
- * of affected objects is deniedD
- */
- private void createConnectionGroupPermissions(int user_id,
- Collection permissions)
- throws GuacamoleException {
-
- // If no permissions given, stop now
- if(permissions.isEmpty())
- return;
-
- // Get list of administerable connection group IDs
- Set administerableConnectionGroupIDs = Sets.newHashSet(
- permissionCheckService.retrieveConnectionGroupIDs(currentUser,
- MySQLConstants.CONNECTION_GROUP_ADMINISTER));
-
- // Insert all given permissions
- for (ConnectionGroupPermission permission : permissions) {
-
- // Get original ID
- Integer connection_group_id = Integer.valueOf(permission.getObjectIdentifier());
-
- // Throw exception if permission to administer this connection group
- // is not granted
- if (!administerableConnectionGroupIDs.contains(connection_group_id))
- throw new GuacamoleSecurityException(
- "User #" + currentUser.getUserID()
- + " does not have permission to administrate connection group"
- + permission.getObjectIdentifier());
-
- // Create new permission
- ConnectionGroupPermissionKey newPermission = new ConnectionGroupPermissionKey();
- newPermission.setUser_id(user_id);
- newPermission.setPermission(MySQLConstants.getConnectionGroupConstant(permission.getType()));
- newPermission.setConnection_group_id(connection_group_id);
- connectionGroupPermissionDAO.insert(newPermission);
-
- }
- }
-
- /**
- * Delete permissions having to do with connections for a given user.
- *
- * @param user_id The ID of the user to change the permissions of.
- * @param permissions The permissions the given user should no longer have
- * when this operation completes.
- * @throws GuacamoleException If permission to alter the access permissions
- * of affected objects is denied.
- */
- private void deleteConnectionPermissions(int user_id,
- Collection permissions)
- throws GuacamoleException {
-
- // If no permissions given, stop now
- if(permissions.isEmpty())
- return;
-
- // Get list of administerable connection IDs
- Set administerableConnectionIDs = Sets.newHashSet(
- permissionCheckService.retrieveConnectionIDs(currentUser,
- MySQLConstants.CONNECTION_ADMINISTER));
-
- // Delete requested permissions
- for (ConnectionPermission permission : permissions) {
-
- // Get original ID
- Integer connection_id = Integer.valueOf(permission.getObjectIdentifier());
-
- // Verify that the user actually has permission to administrate
- // every one of these connections
- if (!administerableConnectionIDs.contains(connection_id))
- throw new GuacamoleSecurityException(
- "User #" + currentUser.getUserID()
- + " does not have permission to administrate connection "
- + permission.getObjectIdentifier());
-
- ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
- connectionPermissionExample.createCriteria()
- .andUser_idEqualTo(user_id)
- .andPermissionEqualTo(MySQLConstants.getConnectionConstant(permission.getType()))
- .andConnection_idEqualTo(connection_id);
- connectionPermissionDAO.deleteByExample(connectionPermissionExample);
-
- }
-
- }
-
- /**
- * Delete permissions having to do with connection groups for a given user.
- *
- * @param user_id The ID of the user to change the permissions of.
- * @param permissions The permissions the given user should no longer have
- * when this operation completes.
- * @throws GuacamoleException If permission to alter the access permissions
- * of affected objects is denied.
- */
- private void deleteConnectionGroupPermissions(int user_id,
- Collection permissions)
- throws GuacamoleException {
-
- // If no permissions given, stop now
- if(permissions.isEmpty())
- return;
-
- // Get list of administerable connection group IDs
- Set administerableConnectionGroupIDs = Sets.newHashSet(
- permissionCheckService.retrieveConnectionGroupIDs(currentUser,
- MySQLConstants.CONNECTION_GROUP_ADMINISTER));
-
- // Delete requested permissions
- for (ConnectionGroupPermission permission : permissions) {
-
- // Get original ID
- Integer connection_group_id = Integer.valueOf(permission.getObjectIdentifier());
-
- // Verify that the user actually has permission to administrate
- // every one of these connection groups
- if (!administerableConnectionGroupIDs.contains(connection_group_id))
- throw new GuacamoleSecurityException(
- "User #" + currentUser.getUserID()
- + " does not have permission to administrate connection group"
- + permission.getObjectIdentifier());
-
- ConnectionGroupPermissionExample connectionGroupPermissionExample = new ConnectionGroupPermissionExample();
- connectionGroupPermissionExample.createCriteria()
- .andUser_idEqualTo(user_id)
- .andPermissionEqualTo(MySQLConstants.getConnectionGroupConstant(permission.getType()))
- .andConnection_group_idEqualTo(connection_group_id);
- connectionGroupPermissionDAO.deleteByExample(connectionGroupPermissionExample);
-
- }
-
- }
-
- /**
- * Create any new system permissions for a given user. All permissions in
- * the given list will be inserted.
- *
- * @param user_id The ID of the user whose permissions should be updated.
- * @param permissions The new system permissions that the given user should
- * have when this operation completes.
- * @throws GuacamoleException If permission to administer system permissions
- * is denied.
- */
- private void createSystemPermissions(int user_id,
- Collection permissions) throws GuacamoleException {
-
- // If no permissions given, stop now
- if(permissions.isEmpty())
- return;
-
- // Only a system administrator can add system permissions.
- permissionCheckService.verifySystemAccess(
- currentUser, SystemPermission.Type.ADMINISTER.name());
-
- // Insert all requested permissions
- for (SystemPermission permission : permissions) {
-
- // Insert permission
- SystemPermissionKey newSystemPermission = new SystemPermissionKey();
- newSystemPermission.setUser_id(user_id);
- newSystemPermission.setPermission(MySQLConstants.getSystemConstant(permission.getType()));
- systemPermissionDAO.insert(newSystemPermission);
-
- }
-
- }
-
- /**
- * Delete system permissions for a given user. All permissions in
- * the given list will be removed from the user.
- *
- * @param user_id The ID of the user whose permissions should be updated.
- * @param permissions The permissions the given user should no longer have
- * when this operation completes.
- * @throws GuacamoleException If the permissions specified could not be
- * removed due to system restrictions.
- */
- private void deleteSystemPermissions(int user_id,
- Collection permissions)
- throws GuacamoleException {
-
- // If no permissions given, stop now
- if (permissions.isEmpty())
- return;
-
- // Prevent self-de-adminifying
- if (user_id == currentUser.getUserID())
- throw new GuacamoleUnsupportedException("Removing your own administrative permissions is not allowed.");
-
- // Build list of requested system permissions
- List systemPermissionTypes = new ArrayList();
- for (SystemPermission permission : permissions)
- systemPermissionTypes.add(MySQLConstants.getSystemConstant(permission.getType()));
-
- // Delete the requested system permissions for this user
- SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
- systemPermissionExample.createCriteria().andUser_idEqualTo(user_id)
- .andPermissionIn(systemPermissionTypes);
- systemPermissionDAO.deleteByExample(systemPermissionExample);
-
- }
-
- @Override
- @Transactional
- public void update(org.glyptodon.guacamole.net.auth.User object)
- throws GuacamoleException {
-
- // If user not actually from this auth provider, we can't handle updated
- // permissions.
- if (!(object instanceof MySQLUser))
- throw new GuacamoleUnsupportedException("User not from database.");
-
- MySQLUser mySQLUser = (MySQLUser) object;
-
- // Validate permission to update this user is granted
- permissionCheckService.verifyUserAccess(currentUser,
- mySQLUser.getUserID(),
- MySQLConstants.USER_UPDATE);
-
- // Update the user in the database
- userService.updateUser(mySQLUser);
-
- // Update permissions in database
- createPermissions(mySQLUser.getUserID(), mySQLUser.getNewPermissions());
- removePermissions(mySQLUser.getUserID(), mySQLUser.getRemovedPermissions());
-
- // The appropriate permissions have been inserted and deleted, so
- // reset the new and removed permission sets.
- mySQLUser.resetPermissions();
-
- }
-
- @Override
- @Transactional
- public void remove(String identifier) throws GuacamoleException {
-
- // Get user pending deletion
- MySQLUser user = userService.retrieveUser(identifier);
-
- // Prevent self-deletion
- if (user.getUserID() == currentUser.getUserID())
- throw new GuacamoleUnsupportedException("Deleting your own user is not allowed.");
-
- // Validate current user has permission to remove the specified user
- permissionCheckService.verifyUserAccess(currentUser,
- user.getUserID(),
- MySQLConstants.USER_DELETE);
-
- // Delete specified user
- userService.deleteUser(user.getUserID());
-
- }
-
@Override
public void move(String identifier, Directory groupIdentifier)
throws GuacamoleException {
throw new GuacamoleSecurityException("Permission denied.");
}
+ @Override
+ public User get(String identifier) throws GuacamoleException {
+ return userService.retrieveObject(identifier);
+ }
+
+ @Override
+ @Transactional
+ public Collection getAll(Collection identifiers) throws GuacamoleException {
+ return Collections.unmodifiableCollection(userService.retrieveObjects(identifiers));
+ }
+
+ @Override
+ @Transactional
+ public Set getIdentifiers() throws GuacamoleException {
+ // STUB
+ return userService.getIdentifiers();
+ }
+
+ @Override
+ @Transactional
+ public void add(User object) throws GuacamoleException {
+ // STUB
+ MySQLUser user = (MySQLUser) object;
+ userService.createObject(user);
+ }
+
+ @Override
+ @Transactional
+ public void update(User object) throws GuacamoleException {
+ // STUB
+ MySQLUser user = (MySQLUser) object;
+ userService.updateObject(user);
+ }
+
+ @Override
+ @Transactional
+ public void remove(String identifier) throws GuacamoleException {
+ // STUB
+ userService.deleteObject(identifier);
+ }
+
}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/DirectoryObjectMapper.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/DirectoryObjectMapper.java
new file mode 100644
index 000000000..3687b95c3
--- /dev/null
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/DirectoryObjectMapper.java
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+package net.sourceforge.guacamole.net.auth.mysql.dao;
+
+import java.util.Collection;
+import java.util.Set;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * Common interface for objects that will ultimately be made available through
+ * the Directory class. All such objects will need the same base set of queries
+ * to fulfill the needs of the Directory class.
+ *
+ * @author Michael Jumper
+ * @param
+ * The type of object contained within the directory whose objects are
+ * mapped by this mapper.
+ */
+public interface DirectoryObjectMapper {
+
+ /**
+ * Selects the identifiers of all objects.
+ *
+ * @return
+ * A Set containing all identifiers of all objects.
+ */
+ Set selectIdentifiers();
+
+ /**
+ * Selects all objects which have the given identifiers. If an identifier
+ * has no corresponding object, it will be ignored.
+ *
+ * @param identifiers
+ * The identifiers of the objects to return.
+ *
+ * @return
+ * A Collection of all objects having the given identifiers.
+ */
+ Collection select(@Param("identifiers") Collection identifiers);
+
+ /**
+ * Inserts the given object into the database. If the object already
+ * exists, this will result in an error.
+ *
+ * @param object
+ * The object to insert.
+ *
+ * @return
+ * The number of rows inserted.
+ */
+ int insert(@Param("object") T object);
+
+ /**
+ * Deletes the given object into the database. If the object does not
+ * exist, this operation has no effect.
+ *
+ * @param identifier
+ * The identifier of the object to delete.
+ *
+ * @return
+ * The number of rows deleted.
+ */
+ int delete(@Param("identifier") String identifier);
+
+ /**
+ * Updates the given existing object in the database. If the object does
+ * not actually exist, this operation has no effect.
+ *
+ * @param object
+ * The object to update.
+ *
+ * @return
+ * The number of rows updated.
+ */
+ int update(@Param("object") T object);
+
+}
\ No newline at end of file
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/UserMapper.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/UserMapper.java
new file mode 100644
index 000000000..048d61207
--- /dev/null
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/UserMapper.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+package net.sourceforge.guacamole.net.auth.mysql.dao;
+
+import net.sourceforge.guacamole.net.auth.mysql.model.UserModel;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * Mapper for user objects.
+ *
+ * @author Michael Jumper
+ */
+public interface UserMapper extends DirectoryObjectMapper {
+
+ /**
+ * Returns the user having the given username and password, if any. If no
+ * such user exists, null is returned.
+ *
+ * @param username
+ * The username of the user to return.
+ *
+ * @param password
+ * The password of the user to return.
+ *
+ * @return
+ * The user having the given username and password, or null if no such
+ * user exists.
+ */
+ UserModel selectByCredentials(@Param("username") String username,
+ @Param("password") String password);
+
+}
\ No newline at end of file
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/model/UserModel.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/model/UserModel.java
new file mode 100644
index 000000000..4130b6033
--- /dev/null
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/model/UserModel.java
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+package net.sourceforge.guacamole.net.auth.mysql.model;
+
+/**
+ * Object representation of a Guacamole user, as represented in the database.
+ *
+ * @author Michael Jumper
+ */
+public class UserModel {
+
+ /**
+ * The ID of this user in the database, if any.
+ */
+ private Integer userID;
+
+ /**
+ * The unique username which identifies this user.
+ */
+ private String username;
+
+ /**
+ * The SHA-256 hash of the password and salt.
+ */
+ private byte[] passwordHash;
+
+ /**
+ * The 32-byte random binary password salt that was appended to the
+ * password prior to hashing.
+ */
+ private byte[] passwordSalt;
+
+ /**
+ * Creates a new, empty user.
+ */
+ public UserModel() {
+ }
+
+ /**
+ * Returns the username that uniquely identifies this user.
+ *
+ * @return
+ * The username that uniquely identifies this user.
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * Sets the username that uniquely identifies this user.
+ *
+ * @param username
+ * The username that uniquely identifies this user.
+ */
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ /**
+ * Returns the ID of this user in the database, if it exists.
+ *
+ * @return
+ * The ID of this user in the database, or null if this user was not
+ * retrieved from the database.
+ */
+ public Integer getUserID() {
+ return userID;
+ }
+
+ /**
+ * Sets the ID of this user to the given value.
+ *
+ * @param userID
+ * The ID to assign to this user.
+ */
+ public void setUserID(Integer userID) {
+ this.userID = userID;
+ }
+
+ /**
+ * Returns the hash of this user's password and password salt. This may be
+ * null if the user was not retrieved from the database, and setPassword()
+ * has not yet been called.
+ *
+ * @return
+ * The hash of this user's password and password salt.
+ */
+ public byte[] getPasswordHash() {
+ return passwordHash;
+ }
+
+ /**
+ * Sets the hash of this user's password and password salt. This is
+ * normally only set upon retrieval from the database, or through a call
+ * to the higher-level setPassword() function.
+ *
+ * @param passwordHash
+ * The hash of this user's password and password salt.
+ */
+ public void setPasswordHash(byte[] passwordHash) {
+ this.passwordHash = passwordHash;
+ }
+
+ /**
+ * Returns the random salt that was used when generating this user's
+ * password hash. This may be null if the user was not retrieved from the
+ * database, and setPassword() has not yet been called.
+ *
+ * @return
+ * The random salt that was used when generating this user's password
+ * hash.
+ */
+ public byte[] getPasswordSalt() {
+ return passwordSalt;
+ }
+
+ /**
+ * Sets the random salt that was used when generating this user's password
+ * hash. This is normally only set upon retrieval from the database, or
+ * through a call to the higher-level setPassword() function.
+ *
+ * @param passwordSalt
+ * The random salt used when generating this user's password hash.
+ */
+ public void setPasswordSalt(byte[] passwordSalt) {
+ this.passwordSalt = passwordSalt;
+ }
+
+}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java
deleted file mode 100644
index 4c21ee548..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql.service;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.GuacamoleSocket;
-import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap;
-import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
-import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
-import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup;
-import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupMapper;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroup;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupExample.Criteria;
-import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
-import org.glyptodon.guacamole.GuacamoleClientTooManyException;
-import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
-import org.glyptodon.guacamole.GuacamoleServerBusyException;
-import org.glyptodon.guacamole.properties.GuacamoleProperties;
-import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
-
-/**
- * Service which provides convenience methods for creating, retrieving, and
- * manipulating connection groups.
- *
- * @author James Muehlner
- */
-public class ConnectionGroupService {
-
- /**
- * Service for managing connections.
- */
- @Inject
- private ConnectionService connectionService;
-
- /**
- * DAO for accessing connection groups.
- */
- @Inject
- private ConnectionGroupMapper connectionGroupDAO;
-
- /**
- * Provider which creates MySQLConnectionGroups.
- */
- @Inject
- private Provider mysqlConnectionGroupProvider;
-
- /**
- * The map of all active connections.
- */
- @Inject
- private ActiveConnectionMap activeConnectionMap;
-
-
- /**
- * Retrieves the connection group having the given
- * name from the database.
- *
- * @param name
- * The name of the connection to return.
- *
- * @param parentID
- * The ID of the parent connection group.
- *
- * @param currentUser
- * The user who queried this connection group.
- *
- * @return
- * The connection having the given name, or null if no such connection
- * group could be found.
- */
- public MySQLConnectionGroup retrieveConnectionGroup(String name, Integer parentID,
- AuthenticatedUser currentUser) {
-
- // Create criteria
- ConnectionGroupExample example = new ConnectionGroupExample();
- Criteria criteria = example.createCriteria().andConnection_group_nameEqualTo(name);
- if(parentID != null)
- criteria.andParent_idEqualTo(parentID);
- else
- criteria.andParent_idIsNull();
-
- // Query connection group by name and parentID
- List connectionGroups =
- connectionGroupDAO.selectByExample(example);
-
- // If no connection group found, return null
- if(connectionGroups.isEmpty())
- return null;
-
- // Otherwise, return found connection
- return toMySQLConnectionGroup(connectionGroups.get(0), currentUser);
-
- }
-
- /**
- * Retrieves the connection group having the given unique identifier
- * from the database.
- *
- * @param uniqueIdentifier
- * The unique identifier of the connection group to retrieve.
- *
- * @param currentUser
- * The user who queried this connection group.
- *
- * @return
- * The connection group having the given unique identifier, or null if
- * no such connection group was found.
- *
- * @throws GuacamoleException
- * If an error occurs while retrieving the connection group.
- */
- public MySQLConnectionGroup retrieveConnectionGroup(String uniqueIdentifier,
- AuthenticatedUser currentUser) throws GuacamoleException {
-
- // The unique identifier for a MySQLConnectionGroup is the database ID
- Integer connectionGroupID = null;
-
- // Try to parse the connectionID if it's not the root group
- if(!MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER.equals(uniqueIdentifier)) {
- try {
- connectionGroupID = Integer.parseInt(uniqueIdentifier);
- } catch(NumberFormatException e) {
- throw new GuacamoleResourceNotFoundException("Invalid connection group ID.");
- }
- }
-
- return retrieveConnectionGroup(connectionGroupID, currentUser);
- }
-
- /**
- * Retrieves the connection group having the given ID from the database.
- *
- * @param id
- * The ID of the connection group to retrieve.
- *
- * @param currentUser
- * The user who queried this connection.
- *
- * @return
- * The connection group having the given ID, or null if no such
- * connection was found.
- */
- public MySQLConnectionGroup retrieveConnectionGroup(Integer id, AuthenticatedUser currentUser) {
-
- // This is the root connection group, so just create it here
- if(id == null) {
- MySQLConnectionGroup connectionGroup = mysqlConnectionGroupProvider.get();
- connectionGroup.init(null, null,
- MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
- MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER,
- org.glyptodon.guacamole.net.auth.ConnectionGroup.Type.ORGANIZATIONAL,
- currentUser);
-
- return connectionGroup;
- }
-
- // Query connection by ID
- ConnectionGroup connectionGroup = connectionGroupDAO.selectByPrimaryKey(id);
-
- // If no connection found, return null
- if(connectionGroup == null)
- return null;
-
- // Otherwise, return found connection
- return toMySQLConnectionGroup(connectionGroup, currentUser);
- }
-
- /**
- * Connect to the connection within the given group with the lowest number
- * of currently active users.
- *
- * @param group
- * The group to load balance across.
- *
- * @param info
- * The information to use when performing the connection handshake.
- *
- * @param currentUser
- * The user who is connecting to the socket.
- *
- * @return
- * The connected socket.
- *
- * @throws GuacamoleException
- * If an error occurs while connecting the socket.
- */
- public GuacamoleSocket connect(MySQLConnectionGroup group,
- GuacamoleClientInformation info, AuthenticatedUser currentUser)
- throws GuacamoleException {
-
- // Get all connections in the group.
- List connectionIDs = connectionService.getAllConnectionIDs
- (group.getConnectionGroupID());
-
- synchronized (activeConnectionMap) {
-
- // Get the least used connection.
- Integer leastUsedConnectionID =
- activeConnectionMap.getLeastUsedConnection(connectionIDs);
-
- if(leastUsedConnectionID == null)
- throw new GuacamoleResourceNotFoundException("No connections found in group.");
-
- if(GuacamoleProperties.getProperty(
- MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
- && activeConnectionMap.isActive(leastUsedConnectionID))
- throw new GuacamoleServerBusyException
- ("Cannot connect. All connections are in use.");
-
- if(GuacamoleProperties.getProperty(
- MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true)
- && activeConnectionMap.isConnectionGroupUserActive(group.getConnectionGroupID(), currentUser.getUserID()))
- throw new GuacamoleClientTooManyException
- ("Cannot connect. Connection group already in use by this user.");
-
- // Get the connection
- MySQLConnection connection = connectionService
- .retrieveConnection(leastUsedConnectionID, currentUser);
-
- // Connect to the connection
- return connectionService.connect(connection, info, currentUser, group.getConnectionGroupID());
-
- }
-
- }
-
- /**
- * Returns a list of the IDs of all connection groups with a given parent ID.
- * @param parentID The ID of the parent for all the queried connection groups.
- * @return a list of the IDs of all connection groups with a given parent ID.
- */
- public List getAllConnectionGroupIDs(Integer parentID) {
-
- // Create criteria
- ConnectionGroupExample example = new ConnectionGroupExample();
- Criteria criteria = example.createCriteria();
-
- if(parentID != null)
- criteria.andParent_idEqualTo(parentID);
- else
- criteria.andParent_idIsNull();
-
- // Query the connections
- List connectionGroups = connectionGroupDAO.selectByExample(example);
-
- // List of IDs of connections with the given parent
- List connectionGroupIDs = new ArrayList();
-
- for(ConnectionGroup connectionGroup : connectionGroups) {
- connectionGroupIDs.add(connectionGroup.getConnection_group_id());
- }
-
- return connectionGroupIDs;
- }
-
- /**
- * Get the identifiers of all the connection groups defined in the system
- * with a certain parentID.
- *
- * @return A Set of identifiers of all the connection groups defined
- * in the system with the given parentID.
- */
- public Set getAllConnectionGroupIdentifiers(Integer parentID) {
-
- // Set of all present connection identifiers
- Set identifiers = new HashSet();
-
- // Set up Criteria
- ConnectionGroupExample example = new ConnectionGroupExample();
- Criteria criteria = example.createCriteria();
- if(parentID != null)
- criteria.andParent_idEqualTo(parentID);
- else
- criteria.andParent_idIsNull();
-
- // Query connection identifiers
- List connectionGroups =
- connectionGroupDAO.selectByExample(example);
- for (ConnectionGroup connectionGroup : connectionGroups)
- identifiers.add(String.valueOf(connectionGroup.getConnection_group_id()));
-
- return identifiers;
-
- }
-
- /**
- * 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.
- *
- * @param currentUser
- * The user who queried this connection.
- *
- * @return
- * A new MySQLConnection containing all data associated with the
- * specified connection.
- */
- private MySQLConnectionGroup toMySQLConnectionGroup(ConnectionGroup connectionGroup,
- AuthenticatedUser currentUser) {
-
- // Create new MySQLConnection from retrieved data
- MySQLConnectionGroup mySQLConnectionGroup = mysqlConnectionGroupProvider.get();
-
- String mySqlType = connectionGroup.getType();
- org.glyptodon.guacamole.net.auth.ConnectionGroup.Type authType;
-
- if(mySqlType.equals(MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL))
- authType = org.glyptodon.guacamole.net.auth.ConnectionGroup.Type.ORGANIZATIONAL;
- else
- authType = org.glyptodon.guacamole.net.auth.ConnectionGroup.Type.BALANCING;
-
- mySQLConnectionGroup.init(
- connectionGroup.getConnection_group_id(),
- connectionGroup.getParent_id(),
- connectionGroup.getConnection_group_name(),
- Integer.toString(connectionGroup.getConnection_group_id()),
- authType,
- currentUser
- );
-
- return mySQLConnectionGroup;
-
- }
-
- /**
- * Get the connection group IDs of all the connection groups defined in the system.
- *
- * @return A list of connection group IDs of all the connection groups defined in the system.
- */
- public List getAllConnectionGroupIDs() {
-
- // Set of all present connection group IDs
- List connectionGroupIDs = new ArrayList();
-
- // Query all connection IDs
- List connections =
- connectionGroupDAO.selectByExample(new ConnectionGroupExample());
- for (ConnectionGroup connection : connections)
- connectionGroupIDs.add(connection.getConnection_group_id());
-
- return connectionGroupIDs;
-
- }
-
- /**
- * Creates a new connection group having the given name and type.
- *
- * @param name
- * The name to assign to the new connection group.
- *
- * @param currentUser
- * The user who created this connection group.
- *
- * @param parentID
- * The ID of the parent of the new connection group, if any.
- *
- * @param type
- * The type of the new connection group.
- *
- * @return A new MySQLConnectionGroup containing the data of the newly created
- * connection group.
- */
- public MySQLConnectionGroup createConnectionGroup(String name, AuthenticatedUser currentUser,
- Integer parentID, String type) {
-
- // Initialize database connection
- ConnectionGroup connectionGroup = new ConnectionGroup();
- connectionGroup.setConnection_group_name(name);
- connectionGroup.setParent_id(parentID);
- connectionGroup.setType(type);
-
- // Create connection
- connectionGroupDAO.insert(connectionGroup);
- return toMySQLConnectionGroup(connectionGroup, currentUser);
-
- }
-
- /**
- * Updates the connection group in the database corresponding to the given
- * MySQLConnectionGroup.
- *
- * @param mySQLConnectionGroup The MySQLConnectionGroup to update (save)
- * to the database.
- * This connection must already exist.
- */
- public void updateConnectionGroup(MySQLConnectionGroup mySQLConnectionGroup) {
-
- // Populate connection
- ConnectionGroup connectionGroup = new ConnectionGroup();
- connectionGroup.setConnection_group_id(mySQLConnectionGroup.getConnectionGroupID());
- connectionGroup.setParent_id(mySQLConnectionGroup.getParentID());
- connectionGroup.setConnection_group_name(mySQLConnectionGroup.getName());
-
- switch(mySQLConnectionGroup.getType()) {
- case BALANCING :
- connectionGroup.setType(MySQLConstants.CONNECTION_GROUP_BALANCING);
- break;
- case ORGANIZATIONAL:
- connectionGroup.setType(MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL);
- break;
- }
-
- // Update the connection group in the database
- connectionGroupDAO.updateByPrimaryKey(connectionGroup);
-
- }
-
- /**
- * Deletes the connection group having the given ID from the database.
- * @param id The ID of the connection group to delete.
- */
- public void deleteConnectionGroup(int id) {
- connectionGroupDAO.deleteByPrimaryKey(id);
- }
-}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java
deleted file mode 100644
index 63126eb76..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql.service;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.GuacamoleSocket;
-import org.glyptodon.guacamole.net.InetGuacamoleSocket;
-import org.glyptodon.guacamole.net.SSLGuacamoleSocket;
-import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap;
-import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
-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.ConnectionExample.Criteria;
-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 org.glyptodon.guacamole.properties.GuacamoleProperties;
-import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket;
-import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
-import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
-import org.apache.ibatis.session.RowBounds;
-import org.glyptodon.guacamole.GuacamoleClientTooManyException;
-import org.glyptodon.guacamole.GuacamoleResourceConflictException;
-import org.glyptodon.guacamole.token.StandardTokens;
-import org.glyptodon.guacamole.token.TokenFilter;
-
-/**
- * Service which provides convenience methods for creating, retrieving, and
- * manipulating connections.
- *
- * @author Michael Jumper, James Muehlner
- */
-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 MySQLGuacamoleSockets.
- */
- @Inject
- private Provider mySQLGuacamoleSocketProvider;
-
- /**
- * Map of all currently active connections.
- */
- @Inject
- private ActiveConnectionMap activeConnectionMap;
-
- /**
- * Service managing users.
- */
- @Inject
- private UserService userService;
-
- /**
- * Retrieves the connection having the given name from the database.
- *
- * @param name
- * The name of the connection to return.
- *
- * @param parentID
- * The ID of the parent connection group.
- *
- * @param currentUser
- * The user who queried this connection.
- *
- * @return
- * The connection having the given name, or null if no such
- * connection could be found.
- */
- public MySQLConnection retrieveConnection(String name, Integer parentID,
- AuthenticatedUser currentUser) {
-
- // Create criteria
- ConnectionExample example = new ConnectionExample();
- Criteria criteria = example.createCriteria().andConnection_nameEqualTo(name);
- if(parentID != null)
- criteria.andParent_idEqualTo(parentID);
- else
- criteria.andParent_idIsNull();
-
- // Query connection by name and parentID
- List connections =
- connectionDAO.selectByExample(example);
-
- // If no connection found, return null
- if(connections.isEmpty())
- return null;
-
- // Otherwise, return found connection
- return toMySQLConnection(connections.get(0), currentUser);
-
- }
-
- /**
- * Retrieves the connection having the given unique identifier
- * from the database.
- *
- * @param uniqueIdentifier
- * The unique identifier of the connection to retrieve.
- *
- * @param currentUser
- * The user who queried this connection.
- *
- * @return
- * The connection having the given unique identifier, or null if no
- * such connection was found.
- */
- public MySQLConnection retrieveConnection(String uniqueIdentifier, AuthenticatedUser currentUser) {
-
- // The unique identifier for a MySQLConnection is the database ID
- int connectionID;
- try {
- connectionID = Integer.parseInt(uniqueIdentifier);
- } catch(NumberFormatException e) {
- // Invalid number means it can't be a DB record; not found
- return null;
- }
-
- return retrieveConnection(connectionID, currentUser);
- }
-
- /**
- * Retrieves the connection having the given ID from the database.
- *
- * @param id
- * The ID of the connection to retrieve.
- *
- * @param currentUser
- * The user who queried this connection.
- *
- * @return
- * The connection having the given ID, or null if no such connection
- * was found.
- */
- public MySQLConnection retrieveConnection(int id, AuthenticatedUser currentUser) {
-
- // 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, currentUser);
- }
-
- /**
- * Returns a list of the IDs of all connections with a given parent ID.
- * @param parentID The ID of the parent for all the queried connections.
- * @return a list of the IDs of all connections with a given parent ID.
- */
- public List getAllConnectionIDs(Integer parentID) {
-
- // Create criteria
- ConnectionExample example = new ConnectionExample();
- Criteria criteria = example.createCriteria();
-
- if(parentID != null)
- criteria.andParent_idEqualTo(parentID);
- else
- criteria.andParent_idIsNull();
-
- // Query the connections
- List connections = connectionDAO.selectByExample(example);
-
- // List of IDs of connections with the given parent
- List connectionIDs = new ArrayList();
-
- for(Connection connection : connections) {
- connectionIDs.add(connection.getConnection_id());
- }
-
- return connectionIDs;
- }
-
- /**
- * 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.
- *
- * @param currentUser
- * The user who queried this connection.
- *
- * @return A new MySQLConnection containing all data associated with the
- * specified connection.
- */
- private MySQLConnection toMySQLConnection(Connection connection, AuthenticatedUser currentUser) {
-
- // Build configuration
- GuacamoleConfiguration config = new GuacamoleConfiguration();
-
- // Query parameters for configuration
- ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample();
- connectionParameterExample.createCriteria().andConnection_idEqualTo(connection.getConnection_id());
- List connectionParameters =
- connectionParameterDAO.selectByExample(connectionParameterExample);
-
- // Set protocol
- config.setProtocol(connection.getProtocol());
-
- // Set all values for all parameters
- for (ConnectionParameter parameter : connectionParameters)
- config.setParameter(parameter.getParameter_name(),
- parameter.getParameter_value());
-
- // Create new MySQLConnection from retrieved data
- MySQLConnection mySQLConnection = mySQLConnectionProvider.get();
- mySQLConnection.init(
- connection.getConnection_id(),
- connection.getParent_id(),
- connection.getConnection_name(),
- Integer.toString(connection.getConnection_id()),
- config,
- retrieveHistory(connection.getConnection_id()),
- currentUser
- );
-
- return mySQLConnection;
-
- }
-
- /**
- * 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 List retrieveHistory(int 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
- example.setOrderByClause("start_date DESC");
-
- // Set the maximum number of history records returned to 100
- RowBounds rowBounds = new RowBounds(0, 100);
-
- // Retrieve all connection history entries
- List connectionHistories =
- connectionHistoryDAO.selectByExampleWithRowbounds(example, rowBounds);
-
- // Convert history entries to connection records
- List connectionRecords = new ArrayList();
- Set userIDSet = new HashSet();
- for(ConnectionHistory history : connectionHistories) {
- userIDSet.add(history.getUser_id());
- }
-
- // Determine whether connection is currently active
- int user_count = activeConnectionMap.getCurrentUserCount(connectionID);
-
- // Get all the usernames for the users who are in the history
- Map usernameMap = userService.retrieveUsernames(userIDSet);
-
- // Create the new ConnectionRecords
- for(ConnectionHistory history : connectionHistories) {
-
- Date startDate = history.getStart_date();
- Date endDate = history.getEnd_date();
- String username = usernameMap.get(history.getUser_id());
-
- // If there are active users, list the top N not-ended connections
- // as active (best guess)
- MySQLConnectionRecord connectionRecord;
- if (user_count > 0 && endDate == null) {
- connectionRecord = new MySQLConnectionRecord(startDate, endDate, username, true);
- user_count--;
- }
-
- // If no active users, or end date is recorded, connection is not
- // active.
- else
- connectionRecord = new MySQLConnectionRecord(startDate, endDate, username, false);
-
- connectionRecords.add(connectionRecord);
-
- }
-
- return connectionRecords;
- }
-
-
-
- /**
- * 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.
- *
- * @param currentUser
- * The user who is connecting to the socket.
- *
- * @param connectionGroupID
- * The ID of the balancing connection group that is being connected to;
- * null if not used.
- *
- * @return
- * The connected socket.
- *
- * @throws GuacamoleException
- * If an error occurs while connecting the socket.
- */
- public MySQLGuacamoleSocket connect(MySQLConnection connection,
- GuacamoleClientInformation info, AuthenticatedUser currentUser,
- Integer connectionGroupID)
- throws GuacamoleException {
-
- synchronized (activeConnectionMap) {
-
- // If the given connection is active, and multiple simultaneous
- // connections are not allowed, disallow connection
- if(GuacamoleProperties.getProperty(
- MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
- && activeConnectionMap.isActive(connection.getConnectionID()))
- throw new GuacamoleResourceConflictException("Cannot connect. This connection is in use.");
-
- if(GuacamoleProperties.getProperty(
- MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true)
- && activeConnectionMap.isConnectionUserActive(connection.getConnectionID(), currentUser.getUserID()))
- throw new GuacamoleClientTooManyException
- ("Cannot connect. Connection already in use by this user.");
-
- // Get guacd connection information
- String host = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_HOSTNAME);
- int port = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_PORT);
-
- // Build token filter containing credential tokens
- TokenFilter tokenFilter = new TokenFilter();
- StandardTokens.addStandardTokens(tokenFilter, currentUser.getCredentials());
-
- // Filter the configuration
- GuacamoleConfiguration config = new GuacamoleConfiguration(connection.getConfiguration());
- tokenFilter.filterValues(config.getParameters());
-
- // Get socket
- GuacamoleSocket socket;
- if (GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_SSL, false))
- socket = new ConfiguredGuacamoleSocket(
- new SSLGuacamoleSocket(host, port),
- config, info
- );
- else
- socket = new ConfiguredGuacamoleSocket(
- new InetGuacamoleSocket(host, port),
- config, info
- );
-
- // Mark this connection as active
- int historyID = activeConnectionMap.openConnection(connection.getConnectionID(),
- currentUser.getUserID(), connectionGroupID);
-
- // Return new MySQLGuacamoleSocket
- MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
- mySQLGuacamoleSocket.init(socket, historyID, connectionGroupID);
-
- return mySQLGuacamoleSocket;
-
- }
-
- }
-
- /**
- * Creates a new connection having the given name and protocol.
- *
- * @param name
- * The name to assign to the new connection.
- *
- * @param protocol
- * The protocol to assign to the new connection.
- *
- * @param currentUser
- * The user who created this connection.
- *
- * @param parentID
- * The ID of the parent connection group.
- *
- * @return
- * A new MySQLConnection containing the data of the newly created
- * connection.
- */
- public MySQLConnection createConnection(String name, String protocol,
- AuthenticatedUser currentUser, Integer parentID) {
-
- // Initialize database connection
- Connection connection = new Connection();
- connection.setConnection_name(name);
- connection.setProtocol(protocol);
- connection.setParent_id(parentID);
-
- // Create connection
- connectionDAO.insert(connection);
- return toMySQLConnection(connection, currentUser);
-
- }
-
- /**
- * Deletes the connection having the given ID from the database.
- * @param id The ID of the connection to delete.
- */
- public void deleteConnection(int id) {
- connectionDAO.deleteByPrimaryKey(id);
- }
-
- /**
- * Updates the connection in the database corresponding to the given
- * MySQLConnection.
- *
- * @param mySQLConnection The MySQLConnection to update (save) to the
- * database. This connection must already exist.
- */
- public void updateConnection(MySQLConnection mySQLConnection) {
-
- // Populate connection
- Connection connection = new Connection();
- connection.setConnection_id(mySQLConnection.getConnectionID());
- connection.setParent_id(mySQLConnection.getParentID());
- connection.setConnection_name(mySQLConnection.getName());
- connection.setProtocol(mySQLConnection.getConfiguration().getProtocol());
-
- // Update the connection in the database
- connectionDAO.updateByPrimaryKey(connection);
-
- }
-
- /**
- * Get the identifiers of all the connections defined in the system
- * with a certain parentID.
- *
- * @return A Set of identifiers of all the connections defined in the system
- * with the given parentID.
- */
- public Set getAllConnectionIdentifiers(Integer parentID) {
-
- // Set of all present connection identifiers
- Set identifiers = new HashSet();
-
- // Set up Criteria
- ConnectionExample example = new ConnectionExample();
- Criteria criteria = example.createCriteria();
- if(parentID != null)
- criteria.andParent_idEqualTo(parentID);
- else
- criteria.andParent_idIsNull();
-
- // Query connection identifiers
- List connections =
- connectionDAO.selectByExample(example);
- for (Connection connection : connections)
- identifiers.add(String.valueOf(connection.getConnection_id()));
-
- return identifiers;
-
- }
-
- /**
- * Get the connection IDs of all the connections defined in the system
- * with a certain parent connection group.
- *
- * @return A list of connection IDs of all the connections defined in the system.
- */
- public List getAllConnectionIDs() {
-
- // Set of all present connection IDs
- List connectionIDs = new ArrayList();
-
- // Create the criteria
- ConnectionExample example = new ConnectionExample();
-
- // Query the connections
- List connections =
- connectionDAO.selectByExample(example);
- for (Connection connection : connections)
- connectionIDs.add(connection.getConnection_id());
-
- return connectionIDs;
-
- }
-
-}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/DirectoryObjectService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/DirectoryObjectService.java
new file mode 100644
index 000000000..f33744d25
--- /dev/null
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/DirectoryObjectService.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package net.sourceforge.guacamole.net.auth.mysql.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import net.sourceforge.guacamole.net.auth.mysql.DirectoryObject;
+import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper;
+
+/**
+ * Service which provides convenience methods for creating, retrieving, and
+ * manipulating users.
+ *
+ * @author Michael Jumper
+ * @param
+ * The type of object this service provides access to.
+ *
+ * @param
+ * The underlying model object used to represent ObjectType in the
+ * database.
+ */
+public abstract class DirectoryObjectService, ModelType> {
+
+ /**
+ * Returns an instance of a mapper for the type of object used by this
+ * service.
+ *
+ * @return
+ * A mapper which provides access to the model objects associated with
+ * the objects used by this service.
+ */
+ protected abstract DirectoryObjectMapper getObjectMapper();
+
+ /**
+ * Returns an instance of an object which is backed by the given model
+ * object.
+ *
+ * @param model
+ * The model object to use to back the returned object.
+ *
+ * @return
+ * An object which is backed by the given model object.
+ */
+ protected abstract ObjectType getObjectInstance(ModelType model);
+
+ /**
+ * Returns a collection of objects which are backed by the models in the
+ * given collection.
+ *
+ * @param models
+ * The model objects to use to back the objects within the returned
+ * collection.
+ *
+ * @return
+ * A collection of objects which are backed by the models in the given
+ * collection.
+ */
+ protected Collection getObjectInstances(Collection models) {
+
+ // Create new collection of objects by manually converting each model
+ Collection objects = new ArrayList(models.size());
+ for (ModelType model : models)
+ objects.add(getObjectInstance(model));
+
+ return objects;
+
+ }
+
+ /**
+ * Retrieves the single object that has the given identifier, if it exists.
+ *
+ * @param identifier
+ * The identifier of the object to retrieve.
+ *
+ * @return
+ * The object having the given identifier, or null if no such object
+ * exists.
+ */
+ public ObjectType retrieveObject(String identifier) {
+
+ // Pull objects having given identifier
+ Collection objects = retrieveObjects(Collections.singleton(identifier));
+
+ // If no such object, return null
+ if (objects.isEmpty())
+ return null;
+
+ // The object collection will have exactly one element unless the
+ // database has seriously lost integrity
+ assert(objects.size() == 1);
+
+ // Return first and only object
+ return objects.iterator().next();
+
+ }
+
+ /**
+ * Retrieves all objects that have the identifiers in the given collection.
+ *
+ * @param identifiers
+ * The identifiers of the objects to retrieve.
+ *
+ * @return
+ * The objects having the given identifiers.
+ */
+ public Collection retrieveObjects(Collection identifiers) {
+
+ // Do not query if no identifiers given
+ if (identifiers.isEmpty())
+ return Collections.EMPTY_LIST;
+
+ // Return collection of requested objects
+ return getObjectInstances(getObjectMapper().select(identifiers));
+
+ }
+
+ /**
+ * Creates the given object within the database. If the object already
+ * exists, an error will be thrown. The internal model object will be
+ * updated appropriately to contain the new database ID.
+ *
+ * @param object
+ * The object to create.
+ */
+ public void createObject(ObjectType object) {
+ getObjectMapper().insert(object.getModel());
+ }
+
+ /**
+ * Deletes the object having the given identifier. If no such object
+ * exists, this function has no effect.
+ *
+ * @param identifier
+ * The identifier of the object to delete.
+ */
+ public void deleteObject(String identifier) {
+ getObjectMapper().delete(identifier);
+ }
+
+ /**
+ * Updates the given object in the database, applying any changes that have
+ * been made. If no such object exists, this function has no effect.
+ *
+ * @param object
+ * The object to update.
+ */
+ public void updateObject(ObjectType object) {
+ getObjectMapper().update(object.getModel());
+ }
+
+ /**
+ * Returns the set of all identifiers for all objects in the database.
+ *
+ * @return
+ * The set of all identifiers for all objects in the database.
+ */
+ public Set getIdentifiers() {
+ return getObjectMapper().selectIdentifiers();
+ }
+
+}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PasswordEncryptionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PasswordEncryptionService.java
index 67ea8bab0..5d21eeb3e 100644
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PasswordEncryptionService.java
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PasswordEncryptionService.java
@@ -22,27 +22,12 @@
package net.sourceforge.guacamole.net.auth.mysql.service;
-
/**
* A service to perform password encryption and checking.
* @author James Muehlner
*/
public interface PasswordEncryptionService {
- /**
- * Checks whether the provided, unhashed password matches the given
- * hash/salt pair.
- *
- * @param password The unhashed password to validate.
- * @param hashedPassword The hashed password to compare the given password
- * against.
- * @param salt The salt used when the hashed password given was created.
- * @return true if the provided credentials match the values given, false
- * otherwise.
- */
- public boolean checkPassword(String password, byte[] hashedPassword,
- byte[] salt);
-
/**
* Creates a password hash based on the provided username, password, and
* salt.
@@ -52,4 +37,5 @@ public interface PasswordEncryptionService {
* @return The generated password hash.
*/
public byte[] createPasswordHash(String password, byte[] salt);
+
}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionCheckService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionCheckService.java
deleted file mode 100644
index a6a8d2326..000000000
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionCheckService.java
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-package net.sourceforge.guacamole.net.auth.mysql.service;
-
-import com.google.inject.Inject;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
-import org.glyptodon.guacamole.GuacamoleSecurityException;
-import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup;
-import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionGroupPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionGroupPermissionKey;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample.Criteria;
-import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
-import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
-import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionKey;
-import org.glyptodon.guacamole.net.auth.permission.ConnectionGroupPermission;
-import org.glyptodon.guacamole.net.auth.permission.ConnectionPermission;
-import org.glyptodon.guacamole.net.auth.permission.Permission;
-import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
-import org.glyptodon.guacamole.net.auth.permission.UserPermission;
-
-/**
- * A service to retrieve information about what objects a user has permission to.
- * @author James Muehlner
- */
-public class PermissionCheckService {
-
- /**
- * Service for accessing users.
- */
- @Inject
- private UserService userService;
-
- /**
- * Service for accessing connections.
- */
- @Inject
- private ConnectionService connectionService;
-
- /**
- * Service for accessing connection groups.
- */
- @Inject
- private ConnectionGroupService connectionGroupService;
-
- /**
- * DAO for accessing permissions related to users.
- */
- @Inject
- private UserPermissionMapper userPermissionDAO;
-
- /**
- * DAO for accessing permissions related to connections.
- */
- @Inject
- private ConnectionPermissionMapper connectionPermissionDAO;
-
- /**
- * DAO for accessing permissions related to connection groups.
- */
- @Inject
- private ConnectionGroupPermissionMapper connectionGroupPermissionDAO;
-
- /**
- * DAO for accessing permissions related to the system as a whole.
- */
- @Inject
- private SystemPermissionMapper systemPermissionDAO;
-
- /**
- * Verifies that the user has the specified access to the given other
- * user. If permission is denied, a GuacamoleSecurityException is thrown.
- *
- * @param currentUser
- * The user to check.
- *
- * @param affectedUserID
- * The user that would be affected by the operation if permission is
- * granted.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @throws GuacamoleSecurityException
- * If the specified permission is not granted.
- */
- public void verifyUserAccess(AuthenticatedUser currentUser, int affectedUserID,
- String permissionType) throws GuacamoleSecurityException {
-
- // If permission does not exist, throw exception
- if(!checkUserAccess(currentUser, affectedUserID, permissionType))
- throw new GuacamoleSecurityException("Permission denied.");
-
- }
-
- /**
- * Verifies that the user has the specified access to the given connection.
- * If permission is denied, a GuacamoleSecurityException is thrown.
- *
- * @param currentUser
- * The user to check.
- *
- * @param affectedConnectionID
- * The connection that would be affected by the operation if permission
- * is granted.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @throws GuacamoleSecurityException
- * If the specified permission is not granted.
- */
- public void verifyConnectionAccess(AuthenticatedUser currentUser,
- int affectedConnectionID, String permissionType) throws GuacamoleSecurityException {
-
- // If permission does not exist, throw exception
- if(!checkConnectionAccess(currentUser, affectedConnectionID, permissionType))
- throw new GuacamoleSecurityException("Permission denied.");
-
- }
-
- /**
- * Verifies that the user has the specified access to the given connection group.
- * If permission is denied, a GuacamoleSecurityException is thrown.
- *
- * @param currentUser
- * The user to check.
- *
- * @param affectedConnectionGroupID
- * The connection group that would be affected by the operation if
- * permission is granted.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @throws GuacamoleSecurityException
- * If the specified permission is not granted.
- */
- public void verifyConnectionGroupAccess(AuthenticatedUser currentUser,
- Integer affectedConnectionGroupID, String permissionType) throws GuacamoleSecurityException {
-
- // If permission does not exist, throw exception
- if(!checkConnectionGroupAccess(currentUser, affectedConnectionGroupID, permissionType))
- throw new GuacamoleSecurityException("Permission denied.");
-
- }
-
- /**
- * Verifies that the user has the specified access to the system. If
- * permission is denied, a GuacamoleSecurityException is thrown.
- *
- * @param currentUser
- * The user to check.
- *
- * @param systemPermissionType
- * The type of permission to check for.
- *
- * @throws GuacamoleSecurityException
- * If the specified permission is not granted.
- */
- public void verifySystemAccess(AuthenticatedUser currentUser, String systemPermissionType)
- throws GuacamoleSecurityException {
-
- // If permission does not exist, throw exception
- if(!checkSystemAccess(currentUser, systemPermissionType))
- throw new GuacamoleSecurityException("Permission denied.");
-
- }
-
- /**
- * Checks whether a user has the specified type of access to the affected
- * user.
- *
- * @param currentUser
- * The user to check.
- *
- * @param affectedUserID
- * The user that would be affected by the operation if permission is
- * granted.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * true if the specified permission is granted, false otherwise.
- */
- public boolean checkUserAccess(AuthenticatedUser currentUser,
- Integer affectedUserID, String permissionType) {
-
- // A system administrator has full access to everything.
- if(checkSystemAdministratorAccess(currentUser))
- return true;
-
- // Check existence of requested permission
- UserPermissionExample example = new UserPermissionExample();
- example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andAffected_user_idEqualTo(affectedUserID).andPermissionEqualTo(permissionType);
- return userPermissionDAO.countByExample(example) > 0;
-
- }
-
- /**
- * Checks whether a user has the specified type of access to the affected
- * connection.
- *
- * @param currentUser
- * The user to check.
- *
- * @param affectedConnectionID
- * The connection that would be affected by the operation if permission
- * is granted.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * true if the specified permission is granted, false otherwise.
- */
- public boolean checkConnectionAccess(AuthenticatedUser currentUser,
- Integer affectedConnectionID, String permissionType) {
-
- // A system administrator has full access to everything.
- if(checkSystemAdministratorAccess(currentUser))
- return true;
-
- // Check existence of requested permission
- ConnectionPermissionExample example = new ConnectionPermissionExample();
- example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andConnection_idEqualTo(affectedConnectionID).andPermissionEqualTo(permissionType);
- return connectionPermissionDAO.countByExample(example) > 0;
-
- }
-
- /**
- * Checks whether a user has the specified type of access to the affected
- * connection group.
- *
- * @param currentUser
- * The user to check.
- *
- * @param affectedConnectionGroupID
- * The connection group that would be affected by the operation if
- * permission is granted.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * true if the specified permission is granted, false otherwise.
- */
- public boolean checkConnectionGroupAccess(AuthenticatedUser currentUser,
- Integer affectedConnectionGroupID, String permissionType) {
-
- // All users have implicit permission to read and update the root connection group
- if(affectedConnectionGroupID == null &&
- MySQLConstants.CONNECTION_GROUP_READ.equals(permissionType) ||
- MySQLConstants.CONNECTION_GROUP_UPDATE.equals(permissionType))
- return true;
-
- // A system administrator has full access to everything.
- if(checkSystemAdministratorAccess(currentUser))
- return true;
-
- // Check existence of requested permission
- ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample();
- example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andConnection_group_idEqualTo(affectedConnectionGroupID).andPermissionEqualTo(permissionType);
- return connectionGroupPermissionDAO.countByExample(example) > 0;
-
- }
-
- /**
- * Checks whether a user has the specified type of access to the system.
- *
- * @param currentUser
- * The user to check.
- *
- * @param systemPermissionType
- * The type of permission to check for.
- *
- * @return
- * true if the specified permission is granted, false otherwise.
- */
- private boolean checkSystemAccess(AuthenticatedUser currentUser, String systemPermissionType) {
-
- // A system administrator has full access to everything.
- if(checkSystemAdministratorAccess(currentUser))
- return true;
-
- // Check existence of requested permission
- SystemPermissionExample example = new SystemPermissionExample();
- example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andPermissionEqualTo(systemPermissionType);
- return systemPermissionDAO.countByExample(example) > 0;
-
- }
-
- /**
- * Checks whether a user has system administrator access to the system.
- *
- * @param currentUser
- * The user to check.
- *
- * @return
- * true if the system administrator access exists, false otherwise.
- */
- private boolean checkSystemAdministratorAccess(AuthenticatedUser currentUser) {
-
- // Check existence of system administrator permission
- SystemPermissionExample example = new SystemPermissionExample();
- example.createCriteria().andUser_idEqualTo(currentUser.getUserID())
- .andPermissionEqualTo(MySQLConstants.SYSTEM_ADMINISTER);
- return systemPermissionDAO.countByExample(example) > 0;
- }
-
- /**
- * Verifies that the specified group can be used for organization
- * by the given user.
- *
- * @param connectionGroupID
- * The ID of the affected ConnectionGroup.
- *
- * @param currentUser
- * The user to check.
- *
- * @param type
- * The desired usage.
- *
- * @throws GuacamoleSecurityException
- * If the connection group cannot be used for organization.
- */
- public void verifyConnectionGroupUsageAccess(Integer connectionGroupID,
- AuthenticatedUser currentUser, String type) throws GuacamoleSecurityException {
-
- // If permission does not exist, throw exception
- if(!checkConnectionGroupUsageAccess(connectionGroupID, currentUser, type))
- throw new GuacamoleSecurityException("Permission denied.");
-
- }
-
- /**
- * Check whether a user can use connectionGroup for the given usage.
- *
- * @param connectionGroupID
- * The ID of the affected connection group.
- *
- * @param currentUser
- * The user to check.
- *
- * @param usage
- * The desired usage.
- *
- * @return
- * true if the user can use the connection group for the given usage.
- */
- private boolean checkConnectionGroupUsageAccess(
- Integer connectionGroupID, AuthenticatedUser currentUser, String usage) {
-
- // The root level connection group can only be used for organization
- if(connectionGroupID == null)
- return MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL.equals(usage);
-
- // A system administrator has full access to everything.
- if(checkSystemAdministratorAccess(currentUser))
- return true;
-
- // A connection group administrator can use the group either way.
- if(checkConnectionGroupAccess(currentUser, connectionGroupID,
- MySQLConstants.CONNECTION_GROUP_ADMINISTER))
- return true;
-
- // Query the connection group
- MySQLConnectionGroup connectionGroup = connectionGroupService.
- retrieveConnectionGroup(connectionGroupID, currentUser);
-
- // If the connection group is not found, it cannot be used.
- if(connectionGroup == null)
- return false;
-
- // Verify that the desired usage matches the type.
- return MySQLConstants.getConnectionGroupTypeConstant(
- connectionGroup.getType()).equals(usage);
-
- }
-
- /**
- * Find the list of the IDs of all users a user has permission to.
- * The access type is defined by permissionType.
- *
- * @param currentUser
- * The user to check.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * A list of all user IDs this user has the specified access to.
- */
- public List retrieveUserIDs(AuthenticatedUser currentUser, String permissionType) {
-
- // A system administrator has access to all users.
- if(checkSystemAdministratorAccess(currentUser))
- return userService.getAllUserIDs();
-
- // Query all user permissions for the given user and permission type
- UserPermissionExample example = new UserPermissionExample();
- example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andPermissionEqualTo(permissionType);
- example.setDistinct(true);
- List userPermissions =
- userPermissionDAO.selectByExample(example);
-
- // Convert result into list of IDs
- List currentUsers = new ArrayList(userPermissions.size());
- for(UserPermissionKey permission : userPermissions)
- currentUsers.add(permission.getAffected_user_id());
-
- return currentUsers;
-
- }
-
- /**
- * Find the list of the IDs of all connections a user has permission to.
- * The access type is defined by permissionType.
- *
- * @param currentUser
- * The user to check.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * A list of all connection IDs this user has the specified access to.
- */
- public List retrieveConnectionIDs(AuthenticatedUser currentUser,
- String permissionType) {
-
- return retrieveConnectionIDs(currentUser, null, permissionType, false);
-
- }
-
- /**
- * Find the list of the IDs of all connections a user has permission to.
- * The access type is defined by permissionType.
- *
- * @param currentUser
- * The user to check.
- *
- * @param parentID
- * The parent connection group.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * A list of all connection IDs this user has the specified access to.
- */
- public List retrieveConnectionIDs(AuthenticatedUser currentUser, Integer parentID,
- String permissionType) {
-
- return retrieveConnectionIDs(currentUser, parentID, permissionType, true);
-
- }
-
- /**
- * Find the list of the IDs of all connections a user has permission to.
- * The access type is defined by permissionType.
- *
- * @param currentUser
- * The user to check.
- *
- * @param parentID
- * The parent connection group.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @param checkParentID
- * Whether the parentID should be checked or not.
- *
- * @return
- * A list of all connection IDs this user has the specified access to.
- */
- private List retrieveConnectionIDs(AuthenticatedUser currentUser, Integer parentID,
- String permissionType, boolean checkParentID) {
-
- // A system administrator has access to all connections.
- if(checkSystemAdministratorAccess(currentUser)) {
- if(checkParentID)
- return connectionService.getAllConnectionIDs(parentID);
- else
- return connectionService.getAllConnectionIDs();
- }
-
- // Query all connection permissions for the given user and permission type
- ConnectionPermissionExample example = new ConnectionPermissionExample();
- Criteria criteria = example.createCriteria().andUser_idEqualTo(currentUser.getUserID())
- .andPermissionEqualTo(permissionType);
-
- // Ensure that the connections are all under the parent ID, if needed
- if(checkParentID) {
- // Get the IDs of all connections in the connection group
- List allConnectionIDs = connectionService.getAllConnectionIDs(parentID);
-
- if(allConnectionIDs.isEmpty())
- return Collections.EMPTY_LIST;
-
- criteria.andConnection_idIn(allConnectionIDs);
- }
-
- example.setDistinct(true);
- List connectionPermissions =
- connectionPermissionDAO.selectByExample(example);
-
- // Convert result into list of IDs
- List connectionIDs = new ArrayList(connectionPermissions.size());
- for(ConnectionPermissionKey permission : connectionPermissions)
- connectionIDs.add(permission.getConnection_id());
-
- return connectionIDs;
-
- }
-
- /**
- * Find the list of the IDs of all connection groups a user has permission to.
- * The access type is defined by permissionType.
- *
- * @param currentUser
- * The user to check.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * A list of all connection group IDs this user has the specified
- * access to.
- */
- public List retrieveConnectionGroupIDs(AuthenticatedUser currentUser,
- String permissionType) {
-
- return retrieveConnectionGroupIDs(currentUser, null, permissionType, false);
-
- }
-
- /**
- * Find the list of the IDs of all connection groups a user has permission to.
- * The access type is defined by permissionType.
- *
- * @param currentUser
- * The user to check.
- *
- * @param parentID
- * The parent connection group.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @return
- * A list of all connection group IDs this user has the specified
- * access to.
- */
- public List retrieveConnectionGroupIDs(AuthenticatedUser currentUser, Integer parentID,
- String permissionType) {
-
- return retrieveConnectionGroupIDs(currentUser, parentID, permissionType, true);
-
- }
-
- /**
- * Find the list of the IDs of all connection groups a user has permission to.
- * The access type is defined by permissionType.
- *
- * @param currentUser
- * The user to check.
- *
- * @param parentID
- * The parent connection group.
- *
- * @param permissionType
- * The type of permission to check for.
- *
- * @param checkParentID
- * Whether the parentID should be checked or not.
- *
- * @return
- * A list of all connection group IDs this user has the specified
- * access to.
- */
- private List retrieveConnectionGroupIDs(AuthenticatedUser currentUser, Integer parentID,
- String permissionType, boolean checkParentID) {
-
- // A system administrator has access to all connectionGroups .
- if(checkSystemAdministratorAccess(currentUser)) {
- if(checkParentID)
- return connectionGroupService.getAllConnectionGroupIDs(parentID);
- else
- return connectionGroupService.getAllConnectionGroupIDs();
- }
-
- // Query all connection permissions for the given user and permission type
- ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample();
- ConnectionGroupPermissionExample.Criteria criteria =
- example.createCriteria().andUser_idEqualTo(currentUser.getUserID())
- .andPermissionEqualTo(permissionType);
-
- // Ensure that the connection groups are all under the parent ID, if needed
- if(checkParentID) {
- // Get the IDs of all connection groups in the connection group
- List allConnectionGroupIDs = connectionGroupService
- .getAllConnectionGroupIDs(parentID);
-
- if(allConnectionGroupIDs.isEmpty())
- return Collections.EMPTY_LIST;
-
- criteria.andConnection_group_idIn(allConnectionGroupIDs);
- }
-
- example.setDistinct(true);
- List connectionGroupPermissions =
- connectionGroupPermissionDAO.selectByExample(example);
-
- // Convert result into list of IDs
- List connectionGroupIDs = new ArrayList(connectionGroupPermissions.size());
- for(ConnectionGroupPermissionKey permission : connectionGroupPermissions)
- connectionGroupIDs.add(permission.getConnection_group_id());
-
- // All users have implicit access to read and update the root group
- if(MySQLConstants.CONNECTION_GROUP_READ.equals(permissionType)
- && MySQLConstants.CONNECTION_GROUP_UPDATE.equals(permissionType)
- && !checkParentID)
- connectionGroupIDs.add(null);
-
- return connectionGroupIDs;
-
- }
-
- /**
- * Retrieve all existing usernames that the given user has permission to
- * perform the given operation upon.
- *
- * @param currentUser
- * The user whose permissions should be checked.
- *
- * @param permissionType
- * The permission to check.
- *
- * @return
- * A set of all usernames for which the given user has the given
- * permission.
- */
- public Set retrieveUsernames(AuthenticatedUser currentUser, String permissionType) {
-
- // A system administrator has access to all users.
- if(checkSystemAdministratorAccess(currentUser))
- return userService.getAllUsernames();
-
- // List of all user IDs for which this user has read access
- List currentUsers =
- retrieveUserIDs(currentUser, MySQLConstants.USER_READ);
-
- // Query all associated users
- return userService.translateUsernames(currentUsers).keySet();
-
- }
-
- /**
- * Retrieve all existing connection identifiers that the given user has
- * permission to perform the given operation upon.
- *
- * @param currentUser
- * The user whose permissions should be checked.
- *
- * @param permissionType
- * The permission to check.
- *
- * @param parentID
- * The parent connection group.
- *
- * @return
- * A set of all connection identifiers for which the given user has the
- * given permission.
- */
- public Set retrieveConnectionIdentifiers(AuthenticatedUser currentUser, Integer parentID,
- String permissionType) {
-
- // A system administrator has access to all connections.
- if(checkSystemAdministratorAccess(currentUser))
- return connectionService.getAllConnectionIdentifiers(parentID);
-
- // List of all connection IDs for which this user has access
- List connectionIDs =
- retrieveConnectionIDs(currentUser, parentID, permissionType);
-
- // Unique Identifiers for MySQLConnections are the database IDs
- Set connectionIdentifiers = new HashSet();
-
- for(Integer connectionID : connectionIDs)
- connectionIdentifiers.add(Integer.toString(connectionID));
-
- return connectionIdentifiers;
- }
-
- /**
- * Retrieve all existing connection group identifiers that the given user
- * has permission to perform the given operation upon.
- *
- * @param currentUser
- * The user whose permissions should be checked.
- *
- * @param permissionType
- * The permission to check.
- *
- * @param parentID
- * The parent connection group.
- *
- * @return
- * A set of all connection group identifiers for which the given user
- * has the given permission.
- */
- public Set retrieveConnectionGroupIdentifiers(AuthenticatedUser currentUser, Integer parentID,
- String permissionType) {
-
- // A system administrator has access to all connections.
- if(checkSystemAdministratorAccess(currentUser))
- return connectionGroupService.getAllConnectionGroupIdentifiers(parentID);
-
- // List of all connection group IDs for which this user has access
- List connectionGroupIDs =
- retrieveConnectionGroupIDs(currentUser, parentID, permissionType);
-
- // Unique Identifiers for MySQLConnectionGroups are the database IDs
- Set connectionGroupIdentifiers = new HashSet();
-
- for(Integer connectionGroupID : connectionGroupIDs)
- connectionGroupIdentifiers.add(Integer.toString(connectionGroupID));
-
- return connectionGroupIdentifiers;
- }
-
- /**
- * Retrieves all user permissions granted to the user having the given ID.
- *
- * @param userID The ID of the user to retrieve permissions of.
- * @return A set of all user permissions granted to the user having the
- * given ID.
- */
- public Set retrieveUserPermissions(int userID) {
-
- // Set of all permissions
- Set permissions = new HashSet();
-
- // Query all user permissions
- UserPermissionExample userPermissionExample = new UserPermissionExample();
- userPermissionExample.createCriteria().andUser_idEqualTo(userID);
- List userPermissions =
- userPermissionDAO.selectByExample(userPermissionExample);
-
- // Get list of affected user IDs
- List affectedUserIDs = new ArrayList();
- for(UserPermissionKey userPermission : userPermissions)
- affectedUserIDs.add(userPermission.getAffected_user_id());
-
- // Get corresponding usernames
- Map affectedUsers =
- userService.retrieveUsernames(affectedUserIDs);
-
- // Add user permissions
- for(UserPermissionKey userPermission : userPermissions) {
-
- // Construct permission from data
- UserPermission permission = new UserPermission(
- UserPermission.Type.valueOf(userPermission.getPermission()),
- affectedUsers.get(userPermission.getAffected_user_id())
- );
-
- // Add to set
- permissions.add(permission);
-
- }
-
- return permissions;
-
- }
-
- /**
- * Retrieves all connection permissions granted to the user having the
- * given ID.
- *
- * @param userID The ID of the user to retrieve permissions of.
- * @return A set of all connection permissions granted to the user having
- * the given ID.
- */
- public Set retrieveConnectionPermissions(int userID) {
-
- // Set of all permissions
- Set permissions = new HashSet();
-
- // Query all connection permissions
- ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
- connectionPermissionExample.createCriteria().andUser_idEqualTo(userID);
- List connectionPermissions =
- connectionPermissionDAO.selectByExample(connectionPermissionExample);
-
- // Add connection permissions
- for(ConnectionPermissionKey connectionPermission : connectionPermissions) {
-
- // Construct permission from data
- ConnectionPermission permission = new ConnectionPermission(
- ConnectionPermission.Type.valueOf(connectionPermission.getPermission()),
- String.valueOf(connectionPermission.getConnection_id())
- );
-
- // Add to set
- permissions.add(permission);
-
- }
-
- return permissions;
-
- }
-
- /**
- * Retrieves all connection group permissions granted to the user having the
- * given ID.
- *
- * @param userID The ID of the user to retrieve permissions of.
- * @return A set of all connection group permissions granted to the user having
- * the given ID.
- */
- public Set retrieveConnectionGroupPermissions(int userID) {
-
- // Set of all permissions
- Set permissions = new HashSet();
-
- // Query all connection permissions
- ConnectionGroupPermissionExample connectionGroupPermissionExample = new ConnectionGroupPermissionExample();
- connectionGroupPermissionExample.createCriteria().andUser_idEqualTo(userID);
- List connectionGroupPermissions =
- connectionGroupPermissionDAO.selectByExample(connectionGroupPermissionExample);
-
- // Add connection permissions
- for(ConnectionGroupPermissionKey connectionGroupPermission : connectionGroupPermissions) {
-
- // Construct permission from data
- ConnectionGroupPermission permission = new ConnectionGroupPermission(
- ConnectionGroupPermission.Type.valueOf(connectionGroupPermission.getPermission()),
- String.valueOf(connectionGroupPermission.getConnection_group_id())
- );
-
- // Add to set
- permissions.add(permission);
-
- }
-
- // All users have implict access to read the root connection group
- permissions.add(new ConnectionGroupPermission(
- ConnectionGroupPermission.Type.READ,
- MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER
- ));
-
- // All users have implict access to update the root connection group
- permissions.add(new ConnectionGroupPermission(
- ConnectionGroupPermission.Type.UPDATE,
- MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER
- ));
-
- return permissions;
-
- }
-
- /**
- * Retrieves all system permissions granted to the user having the
- * given ID.
- *
- * @param userID The ID of the user to retrieve permissions of.
- * @return A set of all system permissions granted to the user having the
- * given ID.
- */
- public Set retrieveSystemPermissions(int userID) {
-
- // Set of all permissions
- Set permissions = new HashSet();
-
- // And finally, system permissions
- SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
- systemPermissionExample.createCriteria().andUser_idEqualTo(userID);
- List systemPermissions =
- systemPermissionDAO.selectByExample(systemPermissionExample);
- for(SystemPermissionKey systemPermission : systemPermissions) {
-
- // User creation permission
- if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_USER_CREATE))
- permissions.add(new SystemPermission(SystemPermission.Type.CREATE_USER));
-
- // System creation permission
- else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_CONNECTION_CREATE))
- permissions.add(new SystemPermission(SystemPermission.Type.CREATE_CONNECTION));
-
- // System creation permission
- else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_CONNECTION_GROUP_CREATE))
- permissions.add(new SystemPermission(SystemPermission.Type.CREATE_CONNECTION_GROUP));
-
- // System administration permission
- else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_ADMINISTER))
- permissions.add(new SystemPermission(SystemPermission.Type.ADMINISTER));
-
- }
-
- return permissions;
-
- }
-
- /**
- * Retrieves all permissions granted to the user having the given ID.
- *
- * @param userID The ID of the user to retrieve permissions of.
- * @return A set of all permissions granted to the user having the given
- * ID.
- */
- public Set retrieveAllPermissions(int userID) {
-
- // Set which will contain all permissions
- Set allPermissions = new HashSet();
-
- // Add user permissions
- allPermissions.addAll(retrieveUserPermissions(userID));
-
- // Add connection permissions
- allPermissions.addAll(retrieveConnectionPermissions(userID));
-
- // add connection group permissions
- allPermissions.addAll(retrieveConnectionGroupPermissions(userID));
-
- // Add system permissions
- allPermissions.addAll(retrieveSystemPermissions(userID));
-
- return allPermissions;
- }
-
-}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/SHA256PasswordEncryptionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/SHA256PasswordEncryptionService.java
index aa3043805..78f0cef65 100644
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/SHA256PasswordEncryptionService.java
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/SHA256PasswordEncryptionService.java
@@ -25,7 +25,6 @@ package net.sourceforge.guacamole.net.auth.mysql.service;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
import javax.xml.bind.DatatypeConverter;
/**
@@ -34,16 +33,6 @@ import javax.xml.bind.DatatypeConverter;
*/
public class SHA256PasswordEncryptionService implements PasswordEncryptionService {
- @Override
- public boolean checkPassword(String password, byte[] hashedPassword,
- byte[] salt) {
-
- // Compare bytes of password in credentials against hashed password
- byte[] passwordBytes = createPasswordHash(password, salt);
- return Arrays.equals(passwordBytes, hashedPassword);
-
- }
-
@Override
public byte[] createPasswordHash(String password, byte[] salt) {
@@ -72,4 +61,5 @@ public class SHA256PasswordEncryptionService implements PasswordEncryptionServic
}
}
+
}
diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java
index 9338fbdcb..453a4c6e2 100644
--- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java
+++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java
@@ -22,24 +22,13 @@
package net.sourceforge.guacamole.net.auth.mysql.service;
-import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Provider;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.Credentials;
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
+import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper;
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
-import net.sourceforge.guacamole.net.auth.mysql.model.User;
-import net.sourceforge.guacamole.net.auth.mysql.model.UserExample;
-import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
+import net.sourceforge.guacamole.net.auth.mysql.model.UserModel;
/**
* Service which provides convenience methods for creating, retrieving, and
@@ -47,13 +36,13 @@ import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
*
* @author Michael Jumper, James Muehlner
*/
-public class UserService {
+public class UserService extends DirectoryObjectService {
/**
- * DAO for accessing users.
+ * Mapper for accessing users.
*/
@Inject
- private UserMapper userDAO;
+ private UserMapper userMapper;
/**
* Provider for creating users.
@@ -61,106 +50,16 @@ public class UserService {
@Inject
private Provider mySQLUserProvider;
- /**
- * Service for checking permissions.
- */
- @Inject
- private PermissionCheckService permissionCheckService;
-
- /**
- * Service for encrypting passwords.
- */
- @Inject
- private PasswordEncryptionService passwordService;
-
- /**
- * Service for generating random salts.
- */
- @Inject
- private SaltService saltService;
-
- /**
- * Create a new MySQLUser based on the provided User.
- *
- * @param user The User to use when populating the data of the given
- * MySQLUser.
- * @return A new MySQLUser object, populated with the data of the given
- * user.
- *
- * @throws GuacamoleException If an error occurs while reading the data
- * of the provided User.
- */
- public MySQLUser toMySQLUser(org.glyptodon.guacamole.net.auth.User user) throws GuacamoleException {
- MySQLUser mySQLUser = mySQLUserProvider.get();
- mySQLUser.init(user);
- return mySQLUser;
+ @Override
+ protected DirectoryObjectMapper getObjectMapper() {
+ return userMapper;
}
- /**
- * Create a new MySQLUser based on the provided database record.
- *
- * @param user The database record describing the user.
- * @return A new MySQLUser object, populated with the data of the given
- * database record.
- */
- private MySQLUser toMySQLUser(UserWithBLOBs user) {
-
- // Retrieve user from provider
- MySQLUser mySQLUser = mySQLUserProvider.get();
-
- // Init with data from given database user
- mySQLUser.init(
- user.getUser_id(),
- user.getUsername(),
- null,
- permissionCheckService.retrieveAllPermissions(user.getUser_id())
- );
-
- // Return new user
- return mySQLUser;
-
- }
-
- /**
- * Retrieves the user having the given ID from the database.
- *
- * @param id The ID of the user to retrieve.
- * @return The existing MySQLUser object if found, null otherwise.
- */
- public MySQLUser retrieveUser(int id) {
-
- // Query user by ID
- UserWithBLOBs user = userDAO.selectByPrimaryKey(id);
-
- // If no user found, return null
- if(user == null)
- return null;
-
- // Otherwise, return found user
- return toMySQLUser(user);
-
- }
-
- /**
- * Retrieves the user having the given username from the database.
- *
- * @param name The username of the user to retrieve.
- * @return The existing MySQLUser object if found, null otherwise.
- */
- public MySQLUser retrieveUser(String name) {
-
- // Query user by ID
- UserExample example = new UserExample();
- example.createCriteria().andUsernameEqualTo(name);
- List users = userDAO.selectByExampleWithBLOBs(example);
-
- // If no user found, return null
- if(users.isEmpty())
- return null;
-
- // Otherwise, return found user
- return toMySQLUser(users.get(0));
-
+ @Override
+ protected MySQLUser getObjectInstance(UserModel model) {
+ MySQLUser user = mySQLUserProvider.get();
+ user.setModel(model);
+ return user;
}
/**
@@ -173,194 +72,18 @@ public class UserService {
*/
public MySQLUser retrieveUser(Credentials credentials) {
- // No null users in database
- if (credentials.getUsername() == null)
+ // Get username and password
+ String username = credentials.getUsername();
+ String password = credentials.getPassword();
+
+ // Retrieve user model, if the user exists
+ UserModel userModel = userMapper.selectByCredentials(username, password);
+ if (userModel == null)
return null;
- // Query user
- UserExample userExample = new UserExample();
- userExample.createCriteria().andUsernameEqualTo(credentials.getUsername());
- List users = userDAO.selectByExampleWithBLOBs(userExample);
-
- // Check that a user was found
- if (users.isEmpty())
- return null;
-
- // Assert only one user found
- assert users.size() == 1 : "Multiple users with same username.";
-
- // Get first (and only) user
- UserWithBLOBs user = users.get(0);
-
- // Check password, if invalid return null
- if (!passwordService.checkPassword(credentials.getPassword(),
- user.getPassword_hash(), user.getPassword_salt()))
- return null;
-
- // Return found user
- return toMySQLUser(user);
-
- }
-
- /**
- * Retrieves a translation map of usernames to their corresponding IDs.
- *
- * @param ids The IDs of the users to retrieve the usernames of.
- * @return A map containing the names of all users and their corresponding
- * IDs.
- */
- public Map translateUsernames(List ids) {
-
- // If no IDs given, just return empty map
- if (ids.isEmpty())
- return Collections.EMPTY_MAP;
-
- // Map of all names onto their corresponding IDs
- Map names = new HashMap();
-
- // Get all users having the given IDs
- UserExample example = new UserExample();
- example.createCriteria().andUser_idIn(ids);
- List users =
- userDAO.selectByExample(example);
-
- // Produce set of names
- for (User user : users)
- names.put(user.getUsername(), user.getUser_id());
-
- return names;
-
- }
-
- /**
- * Retrieves a map of all usernames for the given IDs.
- *
- * @param ids The IDs of the users to retrieve the usernames of.
- * @return A map containing the names of all users and their corresponding
- * IDs.
- */
- public Map retrieveUsernames(Collection ids) {
-
- // If no IDs given, just return empty map
- if (ids.isEmpty())
- return Collections.EMPTY_MAP;
-
- // Map of all names onto their corresponding IDs
- Map names = new HashMap();
-
- // Get all users having the given IDs
- UserExample example = new UserExample();
- example.createCriteria().andUser_idIn(Lists.newArrayList(ids));
- List users =
- userDAO.selectByExample(example);
-
- // Produce set of names
- for (User user : users)
- names.put(user.getUser_id(), user.getUsername());
-
- return names;
-
- }
-
- /**
- * Creates a new user having the given username and password.
- *
- * @param username The username to assign to the new user.
- * @param password The password to assign to the new user.
- * @return A new MySQLUser containing the data of the newly created
- * user.
- */
- public MySQLUser createUser(String username, String password) {
-
- // Initialize database user
- UserWithBLOBs user = new UserWithBLOBs();
- user.setUsername(username);
-
- // Set password if specified
- if (password != null) {
- byte[] salt = saltService.generateSalt();
- user.setPassword_salt(salt);
- user.setPassword_hash(
- passwordService.createPasswordHash(password, salt));
- }
-
- // Create user
- userDAO.insert(user);
- return toMySQLUser(user);
-
- }
-
- /**
- * Deletes the user having the given ID from the database.
- * @param user_id The ID of the user to delete.
- */
- public void deleteUser(int user_id) {
- userDAO.deleteByPrimaryKey(user_id);
- }
-
- /**
- * Updates the user in the database corresponding to the given MySQLUser.
- *
- * @param mySQLUser The MySQLUser to update (save) to the database. This
- * user must already exist.
- */
- public void updateUser(MySQLUser mySQLUser) {
-
- UserWithBLOBs user = new UserWithBLOBs();
- user.setUser_id(mySQLUser.getUserID());
- user.setUsername(mySQLUser.getUsername());
-
- // Set password if specified
- if (mySQLUser.getPassword() != null) {
- byte[] salt = saltService.generateSalt();
- user.setPassword_salt(salt);
- user.setPassword_hash(
- passwordService.createPasswordHash(mySQLUser.getPassword(), salt));
- }
-
- // Update the user in the database
- userDAO.updateByPrimaryKeySelective(user);
-
- }
-
- /**
- * Get the usernames of all the users defined in the system.
- *
- * @return A Set of usernames of all the users defined in the system.
- */
- public Set getAllUsernames() {
-
- // Set of all present usernames
- Set usernames = new HashSet();
-
- // Query all usernames
- List users =
- userDAO.selectByExample(new UserExample());
- for (User user : users)
- usernames.add(user.getUsername());
-
- return usernames;
-
- }
-
- /**
- * Get the user IDs of all the users defined in the system.
- *
- * @return A list of user IDs of all the users defined in the system.
- */
- public List getAllUserIDs() {
-
- // Set of all present user IDs
- List userIDs = new ArrayList();
-
- // Query all user IDs
- List users =
- userDAO.selectByExample(new UserExample());
- for (User user : users)
- userIDs.add(user.getUser_id());
-
- return userIDs;
-
+ // Return corresponding user
+ return getObjectInstance(userModel);
+
}
}
diff --git a/extensions/guacamole-auth-mysql/src/main/resources/generatorConfig.xml b/extensions/guacamole-auth-mysql/src/main/resources/generatorConfig.xml
deleted file mode 100644
index fca4e00d6..000000000
--- a/extensions/guacamole-auth-mysql/src/main/resources/generatorConfig.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-