Ticket #269: Move all use of ConnectionMapper to ConnectionService.

This commit is contained in:
Michael Jumper
2013-02-28 01:41:20 -08:00
parent a854b8f124
commit cde665346b
5 changed files with 170 additions and 121 deletions

View File

@@ -43,7 +43,6 @@ import java.util.Set;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.auth.Connection;
import net.sourceforge.guacamole.net.auth.Directory;
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.model.ConnectionParameter;
@@ -80,12 +79,6 @@ public class ConnectionDirectory implements Directory<String, Connection>{
@Inject
private ConnectionService connectionService;
/**
* Service for manipulating connections in the database.
*/
@Inject
private ConnectionMapper connectionDAO;
/**
* Service for manipulating connection permissions in the database.
*/
@@ -132,23 +125,19 @@ public class ConnectionDirectory implements Directory<String, Connection>{
// Verify permission to create
permissionCheckService.verifyCreateConnectionPermission(this.user_id);
// Create database object for insert
net.sourceforge.guacamole.net.auth.mysql.model.Connection connection =
new net.sourceforge.guacamole.net.auth.mysql.model.Connection();
connection.setConnection_name(object.getIdentifier());
connection.setProtocol(object.getConfiguration().getProtocol());
connectionDAO.insert(connection);
// Create connection
MySQLConnection connection = connectionService.createConnection(
object.getIdentifier(), object.getConfiguration().getProtocol());
// Add connection parameters
createConfigurationValues(connection.getConnection_id(),
createConfigurationValues(connection.getConnectionID(),
object.getConfiguration());
// Finally, give the current user full access to the newly created
// connection.
ConnectionPermissionKey newConnectionPermission = new ConnectionPermissionKey();
newConnectionPermission.setUser_id(this.user_id);
newConnectionPermission.setConnection_id(connection.getConnection_id());
newConnectionPermission.setConnection_id(connection.getConnectionID());
// Read permission
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_READ);
@@ -208,23 +197,15 @@ public class ConnectionDirectory implements Directory<String, Connection>{
permissionCheckService.verifyConnectionUpdateAccess(this.user_id, object.getIdentifier());
MySQLConnection mySQLConnection = (MySQLConnection) object;
// Create database object for insert
net.sourceforge.guacamole.net.auth.mysql.model.Connection connection =
new net.sourceforge.guacamole.net.auth.mysql.model.Connection();
connection.setConnection_id(mySQLConnection.getConnectionID());
connection.setConnection_name(object.getIdentifier());
connection.setProtocol(object.getConfiguration().getProtocol());
connectionDAO.updateByPrimaryKey(connection);
connectionService.updateConnection(mySQLConnection);
// Delete old connection parameters
ConnectionParameterExample parameterExample = new ConnectionParameterExample();
parameterExample.createCriteria().andConnection_idEqualTo(connection.getConnection_id());
parameterExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
connectionParameterDAO.deleteByExample(parameterExample);
// Add connection parameters
createConfigurationValues(connection.getConnection_id(),
createConfigurationValues(mySQLConnection.getConnectionID(),
object.getConfiguration());
}
@@ -251,7 +232,7 @@ public class ConnectionDirectory implements Directory<String, Connection>{
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
// Delete the connection itself
connectionDAO.deleteByPrimaryKey(mySQLConnection.getConnectionID());
connectionService.deleteConnection(mySQLConnection.getConnectionID());
}

View File

@@ -60,7 +60,7 @@ import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionServic
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
import net.sourceforge.guacamole.net.auth.mysql.service.SecureRandomSaltService;
import net.sourceforge.guacamole.net.auth.mysql.service.Sha256PasswordEncryptionService;
import net.sourceforge.guacamole.net.auth.mysql.service.SHA256PasswordEncryptionService;
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
import net.sourceforge.guacamole.properties.GuacamoleProperties;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
@@ -162,7 +162,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
bind(UserDirectory.class);
bind(MySQLUser.class);
bind(SaltService.class).to(SecureRandomSaltService.class);
bind(PasswordEncryptionService.class).to(Sha256PasswordEncryptionService.class);
bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);
bind(PermissionCheckService.class);
bind(ConnectionService.class);
bind(UserService.class);

View File

@@ -49,18 +49,16 @@ import java.util.Set;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.GuacamoleSecurityException;
import net.sourceforge.guacamole.net.auth.Directory;
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
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.Connection;
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
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.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.SaltService;
@@ -90,10 +88,10 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
private UserService userService;
/**
* DAO for accessing connections, which will be injected.
* Service for accessing connections.
*/
@Inject
private ConnectionMapper connectionDAO;
private ConnectionService connectionService;
/**
* DAO for accessing user permissions, which will be injected.
@@ -424,38 +422,35 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
connectionNames.add(permission.getObjectIdentifier());
// Find all the connections by connection name
ConnectionExample connectionExample = new ConnectionExample();
connectionExample.createCriteria().andConnection_nameIn(connectionNames);
List<Connection> dbConnections = connectionDAO.selectByExample(connectionExample);
List<MySQLConnection> connections = connectionService.retrieveConnectionsByName(connectionNames);
// Build map of found connections, indexed by name
Map<String, Connection> dbConnectionMap = new HashMap<String, Connection>();
for (Connection dbConnection : dbConnections) {
dbConnectionMap.put(dbConnection.getConnection_name(), dbConnection);
}
Map<String, MySQLConnection> connectionMap = new HashMap<String, MySQLConnection>();
for (MySQLConnection connection : connections)
connectionMap.put(connection.getIdentifier(), connection);
// Finally, insert the new permissions
for (ConnectionPermission permission : permissions) {
// Get permission
Connection dbConnection = dbConnectionMap.get(permission.getObjectIdentifier());
if (dbConnection == null)
MySQLConnection connection = connectionMap.get(permission.getObjectIdentifier());
if (connection == null)
throw new GuacamoleException(
"Connection '" + permission.getObjectIdentifier()
+ "' not found.");
// Throw exception if permission to administer this connection
// is not granted
if (!administerableConnections.contains(dbConnection.getConnection_id()))
if (!administerableConnections.contains(connection.getConnectionID()))
throw new GuacamoleSecurityException(
"User #" + this.user_id
+ " does not have permission to administrate connection "
+ dbConnection.getConnection_id());
+ connection.getIdentifier());
// Insert previously-non-existent connection permission
ConnectionPermissionKey newPermission = new ConnectionPermissionKey();
newPermission.setConnection_id(dbConnection.getConnection_id());
newPermission.setConnection_id(connection.getConnectionID());
newPermission.setPermission(permission.getType().name());
newPermission.setUser_id(user_id);
connectionPermissionDAO.insert(newPermission);
@@ -488,35 +483,33 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
identifiers.add(permission.getObjectIdentifier());
// Find all the connections by identifiers
ConnectionExample connectionExample = new ConnectionExample();
connectionExample.createCriteria().andConnection_nameIn(identifiers);
List<Connection> dbConnections = connectionDAO.selectByExample(connectionExample);
List<MySQLConnection> connections = connectionService.retrieveConnectionsByName(identifiers);
List<Integer> connectionIDs = new ArrayList<Integer>();
// Build map of found connections, indexed by identifier
Map<String, Connection> dbConnectionMap = new HashMap<String, Connection>();
for (Connection dbConnection : dbConnections) {
dbConnectionMap.put(dbConnection.getConnection_name(), dbConnection);
connectionIDs.add(dbConnection.getConnection_id());
Map<String, MySQLConnection> connectionMap = new HashMap<String, MySQLConnection>();
for (MySQLConnection connection : connections) {
connectionMap.put(connection.getIdentifier(), connection);
connectionIDs.add(connection.getConnectionID());
}
// Verify we have permission to delete each connection permission.
for (ConnectionPermission permission : permissions) {
// Get user
Connection dbConnection = dbConnectionMap.get(permission.getObjectIdentifier());
if (dbConnection == null)
MySQLConnection connection = connectionMap.get(permission.getObjectIdentifier());
if (connection == null)
throw new GuacamoleException(
"User '" + permission.getObjectIdentifier()
+ "' not found.");
// Verify that the user actually has permission to administrate
// every one of these connections
if (!administerableConnections.contains(dbConnection.getConnection_id()))
if (!administerableConnections.contains(connection.getConnectionID()))
throw new GuacamoleSecurityException(
"User #" + this.user_id
+ " does not have permission to administrate connection "
+ dbConnection.getConnection_id());
+ connection.getIdentifier());
}
if(!connectionIDs.isEmpty()) {

View File

@@ -162,6 +162,60 @@ public class ConnectionService {
}
/**
* Retrieves the connections having the given IDs from the database.
*
* @param ids The IDs of the connections to retrieve.
* @return A list of existing MySQLConnection objects.
*/
public List<MySQLConnection> retrieveConnectionsByID(List<Integer> ids) {
// If no IDs given, just return empty list
if (ids.isEmpty())
return Collections.EMPTY_LIST;
// Query connections by ID
ConnectionExample example = new ConnectionExample();
example.createCriteria().andConnection_idIn(ids);
List<Connection> connections = connectionDAO.selectByExample(example);
// Convert to MySQLConnection list
List<MySQLConnection> mySQLConnections = new ArrayList<MySQLConnection>(connections.size());
for (Connection connection : connections)
mySQLConnections.add(toMySQLConnection(connection));
// Return found connections
return mySQLConnections;
}
/**
* Retrieves the connections having the given names from the database.
*
* @param names The names of the connections to retrieve.
* @return A list of existing MySQLConnection objects.
*/
public List<MySQLConnection> retrieveConnectionsByName(List<String> names) {
// If no names given, just return empty list
if (names.isEmpty())
return Collections.EMPTY_LIST;
// Query connections by ID
ConnectionExample example = new ConnectionExample();
example.createCriteria().andConnection_nameIn(names);
List<Connection> connections = connectionDAO.selectByExample(example);
// Convert to MySQLConnection list
List<MySQLConnection> mySQLConnections = new ArrayList<MySQLConnection>(connections.size());
for (Connection connection : connections)
mySQLConnections.add(toMySQLConnection(connection));
// Return found connections
return mySQLConnections;
}
/**
* Convert the given database-retrieved Connection into a MySQLConnection.
* The parameters of the given connection will be read and added to the
@@ -277,4 +331,69 @@ public class ConnectionService {
}
/**
* 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.
* @return A new MySQLConnection containing the data of the newly created
* connection.
*/
public MySQLConnection createConnection(String name, String protocol) {
// Initialize database connection
Connection connection = new Connection();
connection.setConnection_name(name);
connection.setProtocol(protocol);
// Create connection
connectionDAO.insert(connection);
return toMySQLConnection(connection);
}
/**
* Deletes the connection having the given name from the database.
* @param name The name of the connection to delete.
*/
public void deleteConnection(String name) {
// Get specified connection
MySQLConnection mySQLConnection = retrieveConnection(name);
int connection_id = mySQLConnection.getConnectionID();
// Delete the connection in the database
deleteConnection(connection_id);
}
/**
* 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.setConnection_name(mySQLConnection.getIdentifier());
connection.setProtocol(mySQLConnection.getConfiguration().getProtocol());
// Update the connection in the database
connectionDAO.updateByPrimaryKeySelective(connection);
}
}

View File

@@ -37,7 +37,6 @@ 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.Collections;
import java.util.HashMap;
@@ -49,12 +48,9 @@ import net.sourceforge.guacamole.GuacamoleSecurityException;
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
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.Connection;
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
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;
@@ -65,7 +61,6 @@ import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
import net.sourceforge.guacamole.net.auth.permission.Permission;
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
import net.sourceforge.guacamole.net.auth.permission.UserPermission;
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
/**
* A service to retrieve information about what objects a user has permission to.
@@ -73,11 +68,17 @@ import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
*/
public class PermissionCheckService {
/**
* Service for accessing users.
*/
@Inject
private UserService userService;
/**
* Service for accessing connections.
*/
@Inject
private ConnectionMapper connectionDAO;
private ConnectionService connectionService;
@Inject
private UserPermissionMapper userPermissionDAO;
@@ -88,12 +89,6 @@ public class PermissionCheckService {
@Inject
private SystemPermissionMapper systemPermissionDAO;
@Inject
private Provider<MySQLUser> mySQLUserProvider;
@Inject
private Provider<MySQLConnection> mySQLConnectionProvider;
/**
* Verifies that the user has read access to the given user. If not, throws a GuacamoleSecurityException.
* @param userID
@@ -581,9 +576,9 @@ public class PermissionCheckService {
* @return
*/
private boolean checkConnectionAccess(int userID, String affectedConnectionName, String permissionType) {
Connection connection = getConnection(affectedConnectionName);
MySQLConnection connection = connectionService.retrieveConnection(affectedConnectionName);
if(connection != null)
return checkConnectionAccess(userID, connection.getConnection_id(), permissionType);
return checkConnectionAccess(userID, connection.getConnectionID(), permissionType);
return false;
}
@@ -684,33 +679,9 @@ public class PermissionCheckService {
@Deprecated /* FIXME: Totally useless (we only ever need identifiers, and querying ALL CONNECTION DATA will take ages) */
private Set<MySQLConnection> getConnections(int userID, String permissionType) {
// If connections available, query them
Set<Integer> affectedConnectionIDs = getConnectionIDs(userID, permissionType);
if (!affectedConnectionIDs.isEmpty()) {
// Query available connections
ConnectionExample example = new ConnectionExample();
example.createCriteria().andConnection_idIn(Lists.newArrayList(affectedConnectionIDs));
List<Connection> connectionDBOjects = connectionDAO.selectByExample(example);
// Add connections to final set
Set<MySQLConnection> affectedConnections = new HashSet<MySQLConnection>();
for(Connection affectedConnection : connectionDBOjects) {
MySQLConnection mySQLConnection = mySQLConnectionProvider.get();
mySQLConnection.init(
affectedConnection.getConnection_id(),
affectedConnection.getConnection_name(),
new GuacamoleConfiguration(),
Collections.EMPTY_LIST
);
affectedConnections.add(mySQLConnection);
}
return affectedConnections;
}
// Otherwise, no connections available
return Collections.EMPTY_SET;
return new HashSet<MySQLConnection>(
connectionService.retrieveConnectionsByID(Lists.newArrayList(affectedConnectionIDs)));
}
@@ -773,21 +744,6 @@ public class PermissionCheckService {
return count > 0;
}
/**
* Get a connection object by name.
* @param name
* @return
*/
private Connection getConnection(String name) {
ConnectionExample example = new ConnectionExample();
example.createCriteria().andConnection_nameEqualTo(name);
List<Connection> connections = connectionDAO.selectByExample(example);
if(connections.isEmpty())
return null;
return connections.get(0);
}
/**
* Get all permissions a given user has.
* @param userID
@@ -843,19 +799,19 @@ public class PermissionCheckService {
affectedConnectionIDs.add(connectionPermission.getConnection_id());
// Query connections, store in map indexed by connection ID
ConnectionExample connectionExample = new ConnectionExample();
connectionExample.createCriteria().andConnection_idIn(affectedConnectionIDs);
List<Connection> connections = connectionDAO.selectByExample(connectionExample);
Map<Integer, Connection> connectionMap = new HashMap<Integer, Connection>();
for(Connection connection : connections)
connectionMap.put(connection.getConnection_id(), connection);
List<MySQLConnection> connections =
connectionService.retrieveConnectionsByID(affectedConnectionIDs);
Map<Integer, MySQLConnection> connectionMap = new HashMap<Integer, MySQLConnection>();
for(MySQLConnection connection : connections)
connectionMap.put(connection.getConnectionID(), connection);
// Add connection permissions
for(ConnectionPermissionKey connectionPermission : connectionPermissions) {
Connection affectedConnection = connectionMap.get(connectionPermission.getConnection_id());
MySQLConnection affectedConnection =
connectionMap.get(connectionPermission.getConnection_id());
ConnectionPermission newPermission = new ConnectionPermission(
ConnectionPermission.Type.valueOf(connectionPermission.getPermission()),
affectedConnection.getConnection_name()
affectedConnection.getIdentifier()
);
allPermissions.add(newPermission);
}