Ticket #269: Connection implementation completed. Testing and styling remain.

This commit is contained in:
James Muehlner
2013-02-21 22:56:43 -08:00
parent 253636bb4f
commit 4bbe2c9863
12 changed files with 405 additions and 255 deletions

View File

@@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
package net.sourceforge.guacamole.net.auth.mysql;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
@@ -51,6 +51,7 @@ 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.ConnectionPermissionExample;
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
import net.sourceforge.guacamole.net.auth.mysql.utility.PermissionCheckUtility;
import net.sourceforge.guacamole.net.auth.mysql.utility.ProviderUtility;
@@ -68,30 +69,30 @@ public class ConnectionDirectory implements Directory<String, Connection>{
* Access is based on his/her permission settings.
*/
private MySQLUser user;
@Inject
PermissionCheckUtility permissionCheckUtility;
@Inject
ProviderUtility providerUtility;
@Inject
ConnectionMapper connectionDAO;
@Inject
ConnectionPermissionMapper connectionPermissionDAO;
@Inject
ConnectionParameterMapper connectionParameterDAO;
/**
* Set the user for this directory.
* @param user
* @param user
*/
void init(MySQLUser user) {
this.user = user;
}
@Transactional
@Override
public Connection get(String identifier) throws GuacamoleException {
@@ -113,14 +114,13 @@ public class ConnectionDirectory implements Directory<String, Connection>{
@Transactional
@Override
public void add(Connection object) throws GuacamoleException {
Preconditions.checkNotNull(object);
permissionCheckUtility.verifyCreateConnectionPermission(this.user.getUserID());
MySQLConnection mySQLConnection = providerUtility.getNewMySQLConnection(object);
connectionDAO.insert(mySQLConnection.getConnection());
updateConfigurationValues(mySQLConnection);
//finally, give the current user full access to the newly created connection.
ConnectionPermissionKey newConnectionPermission = new ConnectionPermissionKey();
newConnectionPermission.setUser_id(this.user.getUserID());
@@ -134,39 +134,104 @@ public class ConnectionDirectory implements Directory<String, Connection>{
newConnectionPermission.setPermission(MySQLConstants.USER_ADMINISTER);
connectionPermissionDAO.insert(newConnectionPermission);
}
/**
* Saves the values of the configuration to the database
* @param connection
* @param connection
*/
private void updateConfigurationValues(MySQLConnection mySQLConnection) {
GuacamoleConfiguration configuration = mySQLConnection.getConfiguration();
Map<String, String> existingConfiguration = new HashMap<String, String>();
ConnectionParameterExample example = new ConnectionParameterExample();
example.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
List<ConnectionParameter> connectionParameters = connectionParameterDAO.selectByExample(example);
for(ConnectionParameter parameter : connectionParameters)
existingConfiguration.put(parameter.getParameter_name(), parameter.getParameter_value());
List<ConnectionParameter> parametersToInsert = new ArrayList<ConnectionParameter>();
List<ConnectionParameter> parametersToUpdate = new ArrayList<ConnectionParameter>();
Set<String> parameterNames = configuration.getParameterNames();
for(String parameterName : parameterNames) {
String parameterValue = configuration.getParameter(parameterName);
if(existingConfiguration.containsKey(parameterName)) {
String existingValue = existingConfiguration.get(parameterName);
// the value is different; we'll have to update this one in the database
if(!parameterValue.equals(existingValue)) {
ConnectionParameter parameterToUpdate = new ConnectionParameter();
parameterToUpdate.setConnection_id(mySQLConnection.getConnectionID());
parameterToUpdate.setParameter_name(parameterName);
parameterToUpdate.setParameter_value(parameterValue);
parametersToUpdate.add(parameterToUpdate);
}
} else {
// the value is new, we need to insert it
ConnectionParameter parameterToInsert = new ConnectionParameter();
parameterToInsert.setConnection_id(mySQLConnection.getConnectionID());
parameterToInsert.setParameter_name(parameterName);
parameterToInsert.setParameter_value(parameterValue);
parametersToInsert.add(parameterToInsert);
}
}
// First, delete all parameters that are not in the new configuration.
example.clear();
example.createCriteria().
andConnection_idEqualTo(mySQLConnection.getConnectionID()).
andParameter_nameNotIn(Lists.newArrayList(existingConfiguration.keySet()));
//Second, update all the parameters that need to be modified.
for(ConnectionParameter parameter : parametersToUpdate) {
example.clear();
example.createCriteria().
andConnection_idEqualTo(mySQLConnection.getConnectionID()).
andParameter_nameEqualTo(parameter.getParameter_name());
connectionParameterDAO.updateByExample(parameter, example);
}
//Finally, insert any new parameters.
for(ConnectionParameter parameter : parametersToInsert) {
example.clear();
example.createCriteria().
andConnection_idEqualTo(mySQLConnection.getConnectionID()).
andParameter_nameEqualTo(parameter.getParameter_name());
connectionParameterDAO.insert(parameter);
}
}
@Transactional
@Override
public void update(Connection object) throws GuacamoleException {
throw new UnsupportedOperationException("Not supported yet.");
permissionCheckUtility.verifyConnectionUpdateAccess(this.user.getUserID(), object.getIdentifier());
MySQLConnection mySQLConnection = providerUtility.getExistingMySQLConnection(object);
connectionDAO.updateByPrimaryKey(mySQLConnection.getConnection());
updateConfigurationValues(mySQLConnection);
}
@Transactional
@Override
public void remove(String identifier) throws GuacamoleException {
throw new UnsupportedOperationException("Not supported yet.");
permissionCheckUtility.verifyConnectionDeleteAccess(this.user.getUserID(), identifier);
MySQLConnection mySQLConnection = providerUtility.getExistingMySQLConnection(identifier);
// delete all configuration values
ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample();
connectionParameterExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
connectionParameterDAO.deleteByExample(connectionParameterExample);
// delete all permissions that refer to this connection
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
connectionPermissionExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
// delete the connection itself
connectionDAO.deleteByPrimaryKey(mySQLConnection.getConnectionID());
}
}

View File

@@ -74,5 +74,5 @@ public class GuacamolePermissionException extends GuacamoleException {
super(cause);
}
}

View File

@@ -52,6 +52,7 @@ 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.utility.ConfigurationTranslationUtility;
import net.sourceforge.guacamole.net.auth.mysql.utility.PasswordEncryptionUtility;
import net.sourceforge.guacamole.net.auth.mysql.utility.PermissionCheckUtility;
import net.sourceforge.guacamole.net.auth.mysql.utility.ProviderUtility;
@@ -73,18 +74,21 @@ import org.slf4j.LoggerFactory;
public class MySQLAuthenticationProvider implements AuthenticationProvider {
private Logger logger = LoggerFactory.getLogger(MySQLUserContext.class);
private ActiveConnectionSet activeConnectionSet = new ActiveConnectionSet();
private Injector injector;
@Override
public UserContext getUserContext(Credentials credentials) throws GuacamoleException {
MySQLUserContext context = injector.getInstance(MySQLUserContext.class);
context.init(credentials);
return context;
}
public MySQLAuthenticationProvider() throws GuacamoleException {
final Properties myBatisProperties = new Properties();
//set the mysql properties for MyBatis.
myBatisProperties.setProperty("mybatis.environment.id", "guacamole");
myBatisProperties.setProperty("JDBC.host", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_HOSTNAME));
myBatisProperties.setProperty("JDBC.port", String.valueOf(GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_PORT)));
@@ -93,6 +97,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
myBatisProperties.setProperty("JDBC.password", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_PASSWORD));
myBatisProperties.setProperty("JDBC.autoCommit", "false");
// Set up Guice injector.
injector = Guice.createInjector(
JdbcHelper.MySQL,
new Module() {
@@ -117,6 +122,8 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
bind(PasswordEncryptionUtility.class).to(Sha256PasswordEncryptionUtility.class);
bind(PermissionCheckUtility.class);
bind(ProviderUtility.class);
bind(ConfigurationTranslationUtility.class);
bind(ActiveConnectionSet.class).toInstance(activeConnectionSet);
}
}
);

View File

@@ -39,11 +39,19 @@ import com.google.inject.Inject;
import java.util.List;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.GuacamoleSocket;
import net.sourceforge.guacamole.net.InetGuacamoleSocket;
import net.sourceforge.guacamole.net.auth.Connection;
import net.sourceforge.guacamole.net.auth.ConnectionRecord;
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.ConnectionExample;
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter;
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample;
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
import net.sourceforge.guacamole.net.auth.mysql.utility.ConfigurationTranslationUtility;
import net.sourceforge.guacamole.net.auth.mysql.utility.ProviderUtility;
import net.sourceforge.guacamole.properties.GuacamoleProperties;
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
@@ -52,24 +60,34 @@ import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
* @author James Muehlner
*/
public class MySQLConnection implements Connection {
@Inject
ConnectionMapper connectionDAO;
@Inject
ConnectionParameterMapper connectionParameterDAO;
@Inject
ProviderUtility providerUtility;
@Inject
ActiveConnectionSet activeConnectionSet;
@Inject
ConfigurationTranslationUtility configurationTranslationUtility;
private net.sourceforge.guacamole.net.auth.mysql.model.Connection connection;
private GuacamoleConfiguration configuration;
/**
* Create a default, empty connection.
*/
MySQLConnection() {
connection = new net.sourceforge.guacamole.net.auth.mysql.model.Connection();
configuration = new GuacamoleConfiguration();
}
/**
* Get the ID of the underlying connection record.
* @return the ID of the underlying connection
@@ -77,7 +95,7 @@ public class MySQLConnection implements Connection {
public int getConnectionID() {
return connection.getConnection_id();
}
/**
* Get the underlying connection database record.
* @return the underlying connection record.
@@ -85,19 +103,31 @@ public class MySQLConnection implements Connection {
public net.sourceforge.guacamole.net.auth.mysql.model.Connection getConnection() {
return connection;
}
/**
* Create a new MySQLConnection from this new connection. This is a connection that has not yet been inserted.
* @param connection
* @param connection
*/
public void initNew(Connection connection) {
this.connection.setConnection_name(connection.getIdentifier());
this.configuration = connection.getConfiguration();
}
/**
* Initializes the GuacamoleConfiguration based on the ConnectionParameter values in the database.
*/
private void initConfiguration() {
ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample();
connectionParameterExample.createCriteria().andConnection_idEqualTo(connection.getConnection_id());
List<ConnectionParameter> connectionParameters = connectionParameterDAO.selectByExample(connectionParameterExample);
configuration = configurationTranslationUtility.getConfiguration(connection.getProtocol(), connectionParameters);
}
/**
* Load an existing connection by name.
* @param connectionName
* @param connectionName
*/
public void initExisting(String connectionName) throws GuacamoleException {
ConnectionExample example = new ConnectionExample();
@@ -108,16 +138,19 @@ public class MySQLConnection implements Connection {
throw new GuacamoleException("Multiple connections found named '" + connectionName + "'.");
else if(connections.isEmpty())
throw new GuacamoleException("No connection found named '" + connectionName + "'.");
connection = connections.get(0);
initConfiguration();
}
/**
* Initialize from a database record.
* @param connection
* Initialize from a database record. This also initializes the configuration values.
* @param connection
*/
public void init(net.sourceforge.guacamole.net.auth.mysql.model.Connection connection) {
this.connection = connection;
initConfiguration();
}
@Override
@@ -138,13 +171,30 @@ public class MySQLConnection implements Connection {
@Override
public void setConfiguration(GuacamoleConfiguration config) {
this.configuration = config;
}
@Override
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
throw new UnsupportedOperationException("Not supported yet.");
// If the current connection is active, and multiple simultaneous connections are not allowed.
if(GuacamoleProperties.getProperty(MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
&& activeConnectionSet.contains(getConnectionID()))
throw new GuacamoleException("Cannot connect. This connection is in use.");
String host = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME);
int port = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_PORT);
InetGuacamoleSocket inetSocket = new InetGuacamoleSocket(host, port);
ConfiguredGuacamoleSocket configuredSocket = new ConfiguredGuacamoleSocket(inetSocket, configuration);
MySQLGuacamoleSocket mySQLSocket = providerUtility.getMySQLGuacamoleSocket(configuredSocket, getConnectionID());
// mark this connection as active
activeConnectionSet.add(getConnectionID());
return mySQLSocket;
}
@Override
public boolean equals(Object other) {
if(!(other instanceof MySQLConnection))
@@ -163,7 +213,7 @@ public class MySQLConnection implements Connection {
hash = 73 * hash + getIdentifier().hashCode();
return hash;
}
@Override
public List<? extends ConnectionRecord> getHistory() throws GuacamoleException {
return providerUtility.getExistingMySQLConnectionRecords(connection.getConnection_id());

View File

@@ -55,24 +55,24 @@ public class MySQLConnectionRecord implements ConnectionRecord {
* The database record that this ConnectionRecord represents.
*/
private ConnectionHistory connectionHistory;
@Inject
UserMapper userDAO;
@Inject
ConnectionMapper connectionDAO;
@Inject
ProviderUtility providerUtility;
/**
* Initialize this MySQLConnectionRecord with the database record it represents.
* @param connectionHistory
* @param connectionHistory
*/
public void init(ConnectionHistory connectionHistory) {
this.connectionHistory = connectionHistory;
}
@Override
public Date getStartDate() {
return connectionHistory.getStart_date();
@@ -98,5 +98,5 @@ public class MySQLConnectionRecord implements ConnectionRecord {
// if the end date hasn't been stored yet, the connection is still open.
return connectionHistory.getEnd_date() == null;
}
}

View File

@@ -58,21 +58,21 @@ import net.sourceforge.guacamole.net.auth.permission.Permission;
public class MySQLUser implements User {
private UserWithBLOBs user;
@Inject
UserMapper userDAO;
@Inject
PasswordEncryptionUtility passwordUtility;
@Inject
SaltUtility saltUtility;
@Inject
PermissionCheckUtility permissionCheckUtility;
Set<Permission> permissions;
/**
* Create a default, empty user.
*/
@@ -80,11 +80,11 @@ public class MySQLUser implements User {
user = new UserWithBLOBs();
permissions = new HashSet<Permission>();
}
/**
* Create the user, throwing an exception if the credentials do not match what's in the database.
* @param credentials
* @throws GuacamoleException
* @throws GuacamoleException
*/
void init (Credentials credentials) throws GuacamoleException {
UserExample userExample = new UserExample();
@@ -98,25 +98,25 @@ public class MySQLUser implements User {
// check password
if(!passwordUtility.checkCredentials(credentials, user.getPassword_hash(), user.getUsername(), user.getPassword_salt()))
throw new GuacamoleException("No user found with the supplied credentials");
this.permissions = permissionCheckUtility.getAllPermissions(user.getUser_id());
}
/**
* Create a new user from the provided information. This represents a user that has not yet been inserted.
* @param user
* @throws GuacamoleException
* @throws GuacamoleException
*/
public void initNew (User user) throws GuacamoleException {
this.setPassword(user.getPassword());
this.setUsername(user.getUsername());
this.permissions = user.getPermissions();
}
/**
* Loads a user by username.
* @param userName
* @throws GuacamoleException
* @throws GuacamoleException
*/
public void initExisting (String username) throws GuacamoleException {
UserExample example = new UserExample();
@@ -126,36 +126,36 @@ public class MySQLUser implements User {
throw new GuacamoleException("Multiple users found with username '" + username + "'.");
if(userList.isEmpty())
throw new GuacamoleException("No user found with username '" + username + "'.");
this.user = userList.get(0);
this.permissions = permissionCheckUtility.getAllPermissions(user.getUser_id());
}
/**
* Initialize from a database record.
* @param user
* @param user
*/
public void init(UserWithBLOBs user) {
this.user = user;
this.permissions = permissionCheckUtility.getAllPermissions(user.getUser_id());
}
/**
* Get the user id.
* @return
* @return
*/
public int getUserID() {
return user.getUser_id();
}
/**
* Return the database record held by this object.
* @return
* @return
*/
public UserWithBLOBs getUser() {
return user;
}
@Override
public String getUsername() {
return user.getUsername();
@@ -202,7 +202,7 @@ public class MySQLUser implements User {
public void removePermission(Permission permission) throws GuacamoleException {
permissions.remove(permission);
}
@Override
public boolean equals(Object other) {
if(!(other instanceof MySQLUser))

View File

@@ -50,18 +50,18 @@ import org.slf4j.LoggerFactory;
* @author James Muehlner
*/
public class MySQLUserContext implements UserContext {
private Logger logger = LoggerFactory.getLogger(MySQLUserContext.class);
@Inject
private MySQLUser user;
@Inject
private UserDirectory userDirectory;
@Inject
private ConnectionDirectory connectionDirectory;
void init(Credentials credentials) throws GuacamoleException {
user.init(credentials);
userDirectory.init(user);
@@ -82,5 +82,5 @@ public class MySQLUserContext implements UserContext {
public Directory<String, Connection> getConnectionDirectory() throws GuacamoleException {
return connectionDirectory;
}
}

View File

@@ -74,42 +74,42 @@ import org.mybatis.guice.transactional.Transactional;
* @author James Muehlner
*/
public class UserDirectory implements Directory<String, User> {
/**
* The user who this user directory belongs to.
* Access is based on his/her permission settings.
*/
private MySQLUser user;
@Inject
UserMapper userDAO;
@Inject
ConnectionMapper connectionDAO;
@Inject
UserPermissionMapper userPermissionDAO;
@Inject
ConnectionPermissionMapper connectionPermissionDAO;
@Inject
SystemPermissionMapper systemPermissionDAO;
@Inject
PermissionCheckUtility permissionCheckUtility;
@Inject
ProviderUtility providerUtility;
/**
* Set the user for this directory.
* @param user
* @param user
*/
void init(MySQLUser user) {
this.user = user;
}
@Transactional
@Override
public User get(String identifier) throws GuacamoleException {
@@ -133,14 +133,14 @@ public class UserDirectory implements Directory<String, User> {
public void add(User object) throws GuacamoleException {
permissionCheckUtility.verifyCreateUserPermission(this.user.getUserID());
Preconditions.checkNotNull(object);
//create user in database
MySQLUser mySQLUser = providerUtility.getNewMySQLUser(object);
userDAO.insert(mySQLUser.getUser());
//create permissions in database
updatePermissions(mySQLUser);
//finally, give the current user full access to the newly created user.
UserPermissionKey newUserPermission = new UserPermissionKey();
newUserPermission.setUser_id(this.user.getUserID());
@@ -154,24 +154,24 @@ public class UserDirectory implements Directory<String, User> {
newUserPermission.setPermission(MySQLConstants.USER_ADMINISTER);
userPermissionDAO.insert(newUserPermission);
}
/**
* Update all the permissions for a given user to be only those specified in the user object.
* Delete any permissions not in the list, and create any in the list that do not exist
* in the database.
* @param user
* @throws GuacamoleException
* @throws GuacamoleException
*/
private void updatePermissions(MySQLUser user) throws GuacamoleException {
List<UserPermission> userPermissions = new ArrayList<UserPermission>();
List<ConnectionPermission> connectionPermissions = new ArrayList<ConnectionPermission>();
List<SystemPermission> systemPermissions = new ArrayList<SystemPermission>();
// Get the list of all the users and connections that the user performing the user save action has.
// Need to make sure the user saving this user has permission to administrate all the objects in the permission list.
Set<Integer> administerableUsers = permissionCheckUtility.getAdministerableUserIDs(this.user.getUserID());
Set<Integer> administerableConnections = permissionCheckUtility.getAdministerableConnectionIDs(this.user.getUserID());
for(Permission permission : user.getPermissions()) {
if(permission instanceof UserPermission)
userPermissions.add((UserPermission)permission);
@@ -180,36 +180,36 @@ public class UserDirectory implements Directory<String, User> {
else if(permission instanceof SystemPermission)
systemPermissions.add((SystemPermission)permission);
}
updateUserPermissions(userPermissions, user, administerableUsers);
updateConnectionPermissions(connectionPermissions, user, administerableConnections);
updateSystemPermissions(systemPermissions, user);
}
/**
* Update all the permissions having to do with users for a given user.
* @param permissions
* @param user
* @param user
*/
private void updateUserPermissions(Iterable<UserPermission> permissions, MySQLUser user, Set<Integer> administerableUsers) throws GuacamoleException {
List<String> usernames = new ArrayList<String>();
for(UserPermission permission : permissions) {
usernames.add(permission.getObjectIdentifier());
}
// find all the users by username
UserExample userExample = new UserExample();
userExample.createCriteria().andUsernameIn(usernames);
List<net.sourceforge.guacamole.net.auth.mysql.model.User> dbUsers = userDAO.selectByExample(userExample);
List<Integer> userIDs = new ArrayList<Integer>();
Map<String, net.sourceforge.guacamole.net.auth.mysql.model.User> dbUserMap = new HashMap<String, net.sourceforge.guacamole.net.auth.mysql.model.User>();
for(net.sourceforge.guacamole.net.auth.mysql.model.User dbUser : dbUsers) {
dbUserMap.put(dbUser.getUsername(), dbUser);
userIDs.add(dbUser.getUser_id());
}
// find any user permissions that may already exist
UserPermissionExample userPermissionExample = new UserPermissionExample();
userPermissionExample.createCriteria().andAffected_user_idIn(userIDs);
@@ -218,35 +218,35 @@ public class UserDirectory implements Directory<String, User> {
for(UserPermissionKey userPermission : existingPermissions) {
existingUserIDs.add(userPermission.getAffected_user_id());
}
// delete any permissions that are not in the provided list
userPermissionExample.clear();
userPermissionExample.createCriteria().andAffected_user_idNotIn(userIDs);
List<UserPermissionKey> permissionsToDelete = userPermissionDAO.selectByExample(userPermissionExample);
// verify that the user actually has permission to administrate every one of these users
for(UserPermissionKey permissionToDelete : permissionsToDelete) {
if(!administerableUsers.contains(permissionToDelete.getAffected_user_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate user " + permissionToDelete.getAffected_user_id());
}
userPermissionDAO.deleteByExample(userPermissionExample);
// finally, insert the new permissions
for(UserPermission permission : permissions) {
net.sourceforge.guacamole.net.auth.mysql.model.User dbAffectedUser = dbUserMap.get(permission.getObjectIdentifier());
if(dbAffectedUser == null)
throw new GuacamoleException("User '" + permission.getObjectIdentifier() + "' not found.");
// the permission for this user already exists, we don't need to create it again
if(existingUserIDs.contains(dbAffectedUser.getUser_id()))
continue;
// verify that the user actually has permission to administrate every one of these users
if(!administerableUsers.contains(dbAffectedUser.getUser_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate user " + dbAffectedUser.getUser_id());
UserPermissionKey newPermission = new UserPermissionKey();
newPermission.setAffected_user_id(dbAffectedUser.getUser_id());
newPermission.setPermission(permission.getType().name());
@@ -254,31 +254,31 @@ public class UserDirectory implements Directory<String, User> {
userPermissionDAO.insert(newPermission);
}
}
/**
* Update all the permissions having to do with connections for a given user.
* @param permissions
* @param user
* @param user
*/
private void updateConnectionPermissions(Iterable<ConnectionPermission> permissions, MySQLUser user, Set<Integer> administerableConnections) throws GuacamoleException {
List<String> connectionnames = new ArrayList<String>();
for(ConnectionPermission permission : permissions) {
connectionnames.add(permission.getObjectIdentifier());
}
// find all the connections by connectionname
ConnectionExample connectionExample = new ConnectionExample();
connectionExample.createCriteria().andConnection_nameIn(connectionnames);
List<net.sourceforge.guacamole.net.auth.mysql.model.Connection> dbConnections = connectionDAO.selectByExample(connectionExample);
List<Integer> connectionIDs = new ArrayList<Integer>();
Map<String, net.sourceforge.guacamole.net.auth.mysql.model.Connection> dbConnectionMap = new HashMap<String, net.sourceforge.guacamole.net.auth.mysql.model.Connection>();
for(net.sourceforge.guacamole.net.auth.mysql.model.Connection dbConnection : dbConnections) {
dbConnectionMap.put(dbConnection.getConnection_name(), dbConnection);
connectionIDs.add(dbConnection.getConnection_id());
}
// find any connection permissions that may already exist
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
connectionPermissionExample.createCriteria().andConnection_idIn(connectionIDs);
@@ -287,35 +287,35 @@ public class UserDirectory implements Directory<String, User> {
for(ConnectionPermissionKey connectionPermission : existingPermissions) {
existingConnectionIDs.add(connectionPermission.getConnection_id());
}
// delete any permissions that are not in the provided list
connectionPermissionExample.clear();
connectionPermissionExample.createCriteria().andConnection_idNotIn(connectionIDs);
//make sure the user has permission to administrate each of these connections
List<ConnectionPermissionKey> connectionPermissionsToDelete = connectionPermissionDAO.selectByExample(connectionPermissionExample);
for(ConnectionPermissionKey connectionPermissionToDelete : connectionPermissionsToDelete) {
if(!administerableConnections.contains(connectionPermissionToDelete.getConnection_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate connection " + connectionPermissionToDelete.getConnection_id());
}
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
// finally, insert the new permissions
for(ConnectionPermission permission : permissions) {
net.sourceforge.guacamole.net.auth.mysql.model.Connection dbConnection = dbConnectionMap.get(permission.getObjectIdentifier());
if(dbConnection == null)
throw new GuacamoleException("Connection '" + permission.getObjectIdentifier() + "' not found.");
// the permission for this connection already exists, we don't need to create it again
if(existingConnectionIDs.contains(dbConnection.getConnection_id()))
continue;
if(!administerableConnections.contains(dbConnection.getConnection_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate connection " + dbConnection.getConnection_id());
ConnectionPermissionKey newPermission = new ConnectionPermissionKey();
newPermission.setConnection_id(dbConnection.getConnection_id());
newPermission.setPermission(permission.getType().name());
@@ -323,11 +323,11 @@ public class UserDirectory implements Directory<String, User> {
connectionPermissionDAO.insert(newPermission);
}
}
/**
* Update all system permissions for a given user.
* @param permissions
* @param user
* @param user
*/
private void updateSystemPermissions(Iterable<SystemPermission> permissions, MySQLUser user) {
List<String> systemPermissionTypes = new ArrayList<String>();
@@ -338,12 +338,12 @@ public class UserDirectory implements Directory<String, User> {
else if(permission instanceof UserDirectoryPermission)
systemPermissionTypes.add(operation + "_USER");
}
//delete all system permissions not in the list
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
systemPermissionExample.createCriteria().andUser_idEqualTo(user.getUserID()).andPermissionNotIn(systemPermissionTypes);
systemPermissionDAO.deleteByExample(systemPermissionExample);
// find all existing system permissions
systemPermissionExample.clear();
systemPermissionExample.createCriteria().andUser_idEqualTo(user.getUserID()).andPermissionIn(systemPermissionTypes);
@@ -352,13 +352,13 @@ public class UserDirectory implements Directory<String, User> {
for(SystemPermissionKey existingPermission : existingPermissions) {
existingPermissionTypes.add(existingPermission.getPermission());
}
// finally, insert any new system permissions for this user
for(String systemPermissionType : systemPermissionTypes) {
//do not insert the permission if it already exists
//do not insert the permission if it already exists
if(existingPermissionTypes.contains(systemPermissionType))
continue;
SystemPermissionKey newSystemPermission = new SystemPermissionKey();
newSystemPermission.setUser_id(user.getUserID());
newSystemPermission.setPermission(systemPermissionType);
@@ -373,7 +373,7 @@ public class UserDirectory implements Directory<String, User> {
//update the user in the database
MySQLUser mySQLUser = providerUtility.getExistingMySQLUser(object);
userDAO.updateByPrimaryKey(mySQLUser.getUser());
//update permissions in database
updatePermissions(mySQLUser);
}
@@ -382,34 +382,39 @@ public class UserDirectory implements Directory<String, User> {
@Transactional
public void remove(String identifier) throws GuacamoleException {
permissionCheckUtility.verifyUserDeleteAccess(this.user.getUserID(), identifier);
MySQLUser mySQLUser = providerUtility.getExistingMySQLUser(identifier);
//delete all the user permissions in the database
deleteAllPermissions(mySQLUser);
//delete the user in the database
userDAO.deleteByPrimaryKey(mySQLUser.getUserID());
}
/**
* Delete all permissions associated with the provided user. This is only used when deleting a user.
* @param user
* @param user
*/
private void deleteAllPermissions(MySQLUser user) throws GuacamolePermissionException {
//delete all user permissions
UserPermissionExample userPermissionExample = new UserPermissionExample();
userPermissionExample.createCriteria().andUser_idEqualTo(user.getUserID());
userPermissionDAO.deleteByExample(userPermissionExample);
//delete all connection permissions
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
connectionPermissionExample.createCriteria().andUser_idEqualTo(user.getUserID());
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
//delete all system permissions
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
systemPermissionExample.createCriteria().andUser_idEqualTo(user.getUserID());
systemPermissionDAO.deleteByExample(systemPermissionExample);
//delete all permissions that refer to this user
userPermissionExample.createCriteria();
userPermissionExample.createCriteria().andAffected_user_idEqualTo(user.getUserID());
userPermissionDAO.deleteByExample(userPermissionExample);
}
}

View File

@@ -35,6 +35,7 @@
* ***** END LICENSE BLOCK ***** */
package net.sourceforge.guacamole.net.auth.mysql.properties;
import net.sourceforge.guacamole.properties.BooleanGuacamoleProperty;
import net.sourceforge.guacamole.properties.IntegerGuacamoleProperty;
import net.sourceforge.guacamole.properties.StringGuacamoleProperty;
@@ -43,12 +44,12 @@ import net.sourceforge.guacamole.properties.StringGuacamoleProperty;
* @author James Muehlner
*/
public class MySQLGuacamoleProperties {
/**
* This class should not be instantiated.
*/
private MySQLGuacamoleProperties() {}
/**
* The URL of the MySQL server hosting the guacamole authentication tables.
*/
@@ -58,7 +59,7 @@ public class MySQLGuacamoleProperties {
public String getName() { return "mysql-hostname"; }
};
/**
* The port of the MySQL server hosting the guacamole authentication tables.
*/
@@ -68,7 +69,7 @@ public class MySQLGuacamoleProperties {
public String getName() { return "mysql-port"; }
};
/**
* The name of the MySQL database containing the guacamole authentication tables.
*/
@@ -78,7 +79,7 @@ public class MySQLGuacamoleProperties {
public String getName() { return "mysql-database"; }
};
/**
* The username used to authenticate to the MySQL database containing the guacamole authentication tables.
*/
@@ -88,7 +89,7 @@ public class MySQLGuacamoleProperties {
public String getName() { return "mysql-username"; }
};
/**
* The password used to authenticate to the MySQL database containing the guacamole authentication tables.
*/
@@ -98,4 +99,14 @@ public class MySQLGuacamoleProperties {
public String getName() { return "mysql-password"; }
};
/**
* Whether or not multiple users accessing the same connection at the same time should be disallowed.
*/
public static final BooleanGuacamoleProperty MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS = new BooleanGuacamoleProperty() {
@Override
public String getName() { return "mysql-disallow-simultaneous-connections"; }
};
}

View File

@@ -76,28 +76,28 @@ import net.sourceforge.guacamole.net.auth.permission.UserPermission;
* @author James Muehlner
*/
public class PermissionCheckUtility {
@Inject
UserMapper userDAO;
@Inject
ConnectionMapper connectionDAO;
@Inject
UserPermissionMapper userPermissionDAO;
@Inject
ConnectionPermissionMapper connectionPermissionDAO;
@Inject
SystemPermissionMapper systemPermissionDAO;
@Inject
Provider<MySQLUser> mySQLUserProvider;
@Inject
Provider<MySQLConnection> mySQLConnectionProvider;
/**
* Verifies that the user has read access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -108,7 +108,7 @@ public class PermissionCheckUtility {
if(!checkUserReadAccess(userID, affectedUserID))
throw new GuacamolePermissionException("User " + userID + " does not have read access to user " + affectedUserID);
}
/**
* Verifies that the user has update access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -119,7 +119,7 @@ public class PermissionCheckUtility {
if(!checkUserUpdateAccess(userID, affectedUserID))
throw new GuacamolePermissionException("User " + userID + " does not have update access to user " + affectedUserID);
}
/**
* Verifies that the user has delete access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -130,7 +130,7 @@ public class PermissionCheckUtility {
if(!checkUserDeleteAccess(userID, affectedUserID))
throw new GuacamolePermissionException("User " + userID + " does not have delete access to user " + affectedUserID);
}
/**
* Verifies that the user has administer access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -141,7 +141,7 @@ public class PermissionCheckUtility {
if(!checkUserAdministerAccess(userID, affectedUserID))
throw new GuacamolePermissionException("User " + userID + " does not have administer access to user " + affectedUserID);
}
/**
* Verifies that the user has read access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -152,7 +152,7 @@ public class PermissionCheckUtility {
if(!checkUserReadAccess(userID, affectedUsername))
throw new GuacamolePermissionException("User " + userID + " does not have read access to user '" + affectedUsername + "'");
}
/**
* Verifies that the user has update access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -163,7 +163,7 @@ public class PermissionCheckUtility {
if(!checkUserUpdateAccess(userID, affectedUsername))
throw new GuacamolePermissionException("User " + userID + " does not have update access to user '" + affectedUsername + "'");
}
/**
* Verifies that the user has delete access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -174,7 +174,7 @@ public class PermissionCheckUtility {
if(!checkUserDeleteAccess(userID, affectedUsername))
throw new GuacamolePermissionException("User " + userID + " does not have delete access to user '" + affectedUsername + "'");
}
/**
* Verifies that the user has administer access to the given user. If not, throws a GuacamolePermissionException.
* @param userID
@@ -185,7 +185,7 @@ public class PermissionCheckUtility {
if(!checkUserAdministerAccess(userID, affectedUsername))
throw new GuacamolePermissionException("User " + userID + " does not have administer access to user '" + affectedUsername + "'");
}
/**
* Checks if the user has read access to the given user.
* @param userID
@@ -195,7 +195,7 @@ public class PermissionCheckUtility {
public boolean checkUserReadAccess(int userID, int affectedUserID) {
return checkUserAccess(userID, affectedUserID, MySQLConstants.USER_READ);
}
/**
* Checks if the user has update access to the given user.
* @param userID
@@ -205,7 +205,7 @@ public class PermissionCheckUtility {
public boolean checkUserUpdateAccess(int userID, int affectedUserID) {
return checkUserAccess(userID, affectedUserID, MySQLConstants.USER_UPDATE);
}
/**
* Checks if the user has delete access to the given user.
* @param userID
@@ -215,7 +215,7 @@ public class PermissionCheckUtility {
public boolean checkUserDeleteAccess(int userID, int affectedUserID) {
return checkUserAccess(userID, affectedUserID, MySQLConstants.USER_DELETE);
}
/**
* Checks if the user has administer access to the given user.
* @param userID
@@ -225,7 +225,7 @@ public class PermissionCheckUtility {
public boolean checkUserAdministerAccess(int userID, int affectedUserID) {
return checkUserAccess(userID, affectedUserID, MySQLConstants.USER_ADMINISTER);
}
/**
* Checks if the user has read access to the given user.
* @param userID
@@ -235,7 +235,7 @@ public class PermissionCheckUtility {
public boolean checkUserReadAccess(int userID, String affectedUsername) {
return checkUserAccess(userID, affectedUsername, MySQLConstants.USER_READ);
}
/**
* Checks if the user has update access to the given user.
* @param userID
@@ -245,7 +245,7 @@ public class PermissionCheckUtility {
public boolean checkUserUpdateAccess(int userID, String affectedUsername) {
return checkUserAccess(userID, affectedUsername, MySQLConstants.USER_UPDATE);
}
/**
* Checks if the user has delete access to the given user.
* @param userID
@@ -255,7 +255,7 @@ public class PermissionCheckUtility {
public boolean checkUserDeleteAccess(int userID, String affectedUsername) {
return checkUserAccess(userID, affectedUsername, MySQLConstants.USER_DELETE);
}
/**
* Checks if the user has administer access to the given user.
* @param userID
@@ -265,28 +265,28 @@ public class PermissionCheckUtility {
public boolean checkUserAdministerAccess(int userID, String affectedUsername) {
return checkUserAccess(userID, affectedUsername, MySQLConstants.USER_ADMINISTER);
}
/**
* Check if the user has the selected type of access to the affected user.
* @param userID
* @param affectedUsername
* @param permissionType
* @return
* @return
*/
private boolean checkUserAccess(int userID, String affectedUsername, String permissionType) {
User affectedUser = getUser(affectedUsername);
if(affectedUser != null)
return checkUserAccess(userID, affectedUser.getUser_id(), permissionType);
return false;
}
/**
* Check if the user has the selected type of access to the affected user.
* @param userID
* @param affectedUserID
* @param permissionType
* @return
* @return
*/
private boolean checkUserAccess(int userID, Integer affectedUserID, String permissionType) {
UserPermissionExample example = new UserPermissionExample();
@@ -294,7 +294,7 @@ public class PermissionCheckUtility {
int count = userPermissionDAO.countByExample(example);
return count > 0;
}
/**
* Find the list of all user IDs a user has permission to administer.
* @param userID
@@ -303,7 +303,7 @@ public class PermissionCheckUtility {
public Set<Integer> getAdministerableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_ADMINISTER);
}
/**
* Find the list of all user IDs a user has permission to delete.
* @param userID
@@ -312,7 +312,7 @@ public class PermissionCheckUtility {
public Set<Integer> getDeletableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_DELETE);
}
/**
* Find the list of all user IDs a user has permission to write.
* @param userID
@@ -321,7 +321,7 @@ public class PermissionCheckUtility {
public Set<Integer> getUpdateableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_UPDATE);
}
/**
* Find the list of all user IDs a user has permission to read.
* @param userID
@@ -330,7 +330,7 @@ public class PermissionCheckUtility {
public Set<Integer> getReadableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_READ);
}
/**
* Find the list of all users a user has permission to administer.
* @param userID
@@ -339,7 +339,7 @@ public class PermissionCheckUtility {
public Set<MySQLUser> getAdministerableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_ADMINISTER);
}
/**
* Find the list of all users a user has permission to delete.
* @param userID
@@ -348,7 +348,7 @@ public class PermissionCheckUtility {
public Set<MySQLUser> getDeletableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_DELETE);
}
/**
* Find the list of all users a user has permission to write.
* @param userID
@@ -357,7 +357,7 @@ public class PermissionCheckUtility {
public Set<MySQLUser> getUpdateableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_UPDATE);
}
/**
* Find the list of all users a user has permission to read.
* @param userID
@@ -366,7 +366,7 @@ public class PermissionCheckUtility {
public Set<MySQLUser> getReadableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_READ);
}
/**
* Find the list of all users a user has permission to.
* The access type is defined by permissionType.
@@ -385,10 +385,10 @@ public class PermissionCheckUtility {
mySQLUser.init(affectedUser);
affectedUsers.add(mySQLUser);
}
return affectedUsers;
}
/**
* Find the list of the IDs of all users a user has permission to.
* The access type is defined by permissionType.
@@ -403,10 +403,10 @@ public class PermissionCheckUtility {
List<UserPermissionKey> userPermissions = userPermissionDAO.selectByExample(example);
for(UserPermissionKey permission : userPermissions)
userIDs.add(permission.getAffected_user_id());
return userIDs;
}
/**
* Verifies that the user has read access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -417,7 +417,7 @@ public class PermissionCheckUtility {
if(!checkConnectionReadAccess(userID, affectedConnectionID))
throw new GuacamolePermissionException("User " + userID + " does not have read access to connection " + affectedConnectionID);
}
/**
* Verifies that the user has update access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -428,7 +428,7 @@ public class PermissionCheckUtility {
if(!checkConnectionUpdateAccess(userID, affectedConnectionID))
throw new GuacamolePermissionException("User " + userID + " does not have update access to connection " + affectedConnectionID);
}
/**
* Verifies that the user has delete access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -439,7 +439,7 @@ public class PermissionCheckUtility {
if(!checkConnectionDeleteAccess(userID, affectedConnectionID))
throw new GuacamolePermissionException("User " + userID + " does not have delete access to connection " + affectedConnectionID);
}
/**
* Verifies that the user has administer access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -450,7 +450,7 @@ public class PermissionCheckUtility {
if(!checkConnectionAdministerAccess(userID, affectedConnectionID))
throw new GuacamolePermissionException("User " + userID + " does not have administer access to connection " + affectedConnectionID);
}
/**
* Verifies that the user has read access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -461,7 +461,7 @@ public class PermissionCheckUtility {
if(!checkConnectionReadAccess(userID, affectedConnectionName))
throw new GuacamolePermissionException("User " + userID + " does not have read access to connection '" + affectedConnectionName + "'");
}
/**
* Verifies that the user has update access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -472,7 +472,7 @@ public class PermissionCheckUtility {
if(!checkConnectionUpdateAccess(userID, affectedConnectionName))
throw new GuacamolePermissionException("User " + userID + " does not have update access to connection '" + affectedConnectionName + "'");
}
/**
* Verifies that the user has delete access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -483,7 +483,7 @@ public class PermissionCheckUtility {
if(!checkConnectionDeleteAccess(userID, affectedConnectionName))
throw new GuacamolePermissionException("User " + userID + " does not have delete access to connection '" + affectedConnectionName + "'");
}
/**
* Verifies that the user has administer access to the given connection. If not, throws a GuacamolePermissionException.
* @param userID
@@ -494,7 +494,7 @@ public class PermissionCheckUtility {
if(!checkConnectionAdministerAccess(userID, affectedConnectionName))
throw new GuacamolePermissionException("User " + userID + " does not have administer access to connection '" + affectedConnectionName + "'");
}
/**
* Checks if the user has read access to the given connection.
* @param userID
@@ -504,7 +504,7 @@ public class PermissionCheckUtility {
public boolean checkConnectionReadAccess(int userID, int affectedConnectionID) {
return checkConnectionAccess(userID, affectedConnectionID, MySQLConstants.CONNECTION_READ);
}
/**
* Checks if the user has update access to the given connection.
* @param userID
@@ -514,7 +514,7 @@ public class PermissionCheckUtility {
public boolean checkConnectionUpdateAccess(int userID, int affectedConnectionID) {
return checkConnectionAccess(userID, affectedConnectionID, MySQLConstants.CONNECTION_UPDATE);
}
/**
* Checks if the user has delete access to the given connection.
* @param userID
@@ -524,7 +524,7 @@ public class PermissionCheckUtility {
public boolean checkConnectionDeleteAccess(int userID, int affectedConnectionID) {
return checkConnectionAccess(userID, affectedConnectionID, MySQLConstants.CONNECTION_DELETE);
}
/**
* Checks if the user has administer access to the given connection.
* @param userID
@@ -534,7 +534,7 @@ public class PermissionCheckUtility {
public boolean checkConnectionAdministerAccess(int userID, int affectedConnectionID) {
return checkConnectionAccess(userID, affectedConnectionID, MySQLConstants.CONNECTION_ADMINISTER);
}
/**
* Checks if the user has read access to the given connection.
* @param userID
@@ -544,7 +544,7 @@ public class PermissionCheckUtility {
public boolean checkConnectionReadAccess(int userID, String affectedConnectionName) {
return checkConnectionAccess(userID, affectedConnectionName, MySQLConstants.CONNECTION_READ);
}
/**
* Checks if the user has update access to the given connection.
* @param userID
@@ -554,7 +554,7 @@ public class PermissionCheckUtility {
public boolean checkConnectionUpdateAccess(int userID, String affectedConnectionName) {
return checkConnectionAccess(userID, affectedConnectionName, MySQLConstants.CONNECTION_UPDATE);
}
/**
* Checks if the user has delete access to the given connection.
* @param userID
@@ -564,7 +564,7 @@ public class PermissionCheckUtility {
public boolean checkConnectionDeleteAccess(int userID, String affectedConnectionname) {
return checkConnectionAccess(userID, affectedConnectionname, MySQLConstants.CONNECTION_DELETE);
}
/**
* Checks if the user has administer access to the given connection.
* @param userID
@@ -574,28 +574,28 @@ public class PermissionCheckUtility {
public boolean checkConnectionAdministerAccess(int userID, String affectedConnectionName) {
return checkConnectionAccess(userID, affectedConnectionName, MySQLConstants.CONNECTION_ADMINISTER);
}
/**
* Check if the user has the selected type of access to the affected connection.
* @param connectionID
* @param affectedConnectionname
* @param permissionType
* @return
* @return
*/
private boolean checkConnectionAccess(int userID, String affectedConnectionName, String permissionType) {
Connection connection = getConnection(affectedConnectionName);
if(connection != null)
return checkConnectionAccess(userID, connection.getConnection_id(), permissionType);
return false;
}
/**
* Check if the user has the selected type of access to the affected connection.
* @param connectionID
* @param affectedConnectionID
* @param permissionType
* @return
* @return
*/
private boolean checkConnectionAccess(int userID, Integer affectedConnectionID, String permissionType) {
ConnectionPermissionExample example = new ConnectionPermissionExample();
@@ -603,7 +603,7 @@ public class PermissionCheckUtility {
int count = connectionPermissionDAO.countByExample(example);
return count > 0;
}
/**
* Find the list of all connection IDs a user has permission to administer.
* @param userID
@@ -612,7 +612,7 @@ public class PermissionCheckUtility {
public Set<Integer> getAdministerableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_ADMINISTER);
}
/**
* Find the list of all connection IDs a user has permission to delete.
* @param userID
@@ -621,7 +621,7 @@ public class PermissionCheckUtility {
public Set<Integer> getDeletableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_DELETE);
}
/**
* Find the list of all connection IDs a user has permission to write.
* @param userID
@@ -630,7 +630,7 @@ public class PermissionCheckUtility {
public Set<Integer> getUpdateableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_UPDATE);
}
/**
* Find the list of all connection IDs a user has permission to read.
* @param userID
@@ -639,7 +639,7 @@ public class PermissionCheckUtility {
public Set<Integer> getReadableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_READ);
}
/**
* Find the list of all connections a user has permission to administer.
* @param userID
@@ -648,7 +648,7 @@ public class PermissionCheckUtility {
public Set<MySQLConnection> getAdministerableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_ADMINISTER);
}
/**
* Find the list of all connections a user has permission to delete.
* @param userID
@@ -657,7 +657,7 @@ public class PermissionCheckUtility {
public Set<MySQLConnection> getDeletableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_DELETE);
}
/**
* Find the list of all connections a user has permission to write.
* @param userID
@@ -666,7 +666,7 @@ public class PermissionCheckUtility {
public Set<MySQLConnection> getUpdateableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_UPDATE);
}
/**
* Find the list of all connections a user has permission to read.
* @param userID
@@ -675,7 +675,7 @@ public class PermissionCheckUtility {
public Set<MySQLConnection> getReadableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_READ);
}
/**
* Find the list of all connections a user has permission to.
* The access type is defined by permissionType.
@@ -694,10 +694,10 @@ public class PermissionCheckUtility {
mySQLConnection.init(affectedConnection);
affectedConnections.add(mySQLConnection);
}
return affectedConnections;
}
/**
* Find the list of the IDs of all connections a user has permission to.
* The access type is defined by permissionType.
@@ -712,43 +712,43 @@ public class PermissionCheckUtility {
List<ConnectionPermissionKey> connectionPermissions = connectionPermissionDAO.selectByExample(example);
for(ConnectionPermissionKey permission : connectionPermissions)
connectionIDs.add(permission.getConnection_id());
return connectionIDs;
}
public void verifyCreateUserPermission(int userID) throws GuacamolePermissionException {
if(!checkCreateUserPermission(userID))
throw new GuacamolePermissionException("User " + userID + " does not have permission to create users.");
}
public void verifyCreateConnectionPermission(int userID) throws GuacamolePermissionException {
if(!checkCreateConnectionPermission(userID))
throw new GuacamolePermissionException("User " + userID + " does not have permission to create connections.");
}
/**
* Check if the user has the permission to create users.
* @param userID
* @return
* @return
*/
public boolean checkCreateUserPermission(int userID) {
return checkSystemPermission(userID, MySQLConstants.SYSTEM_USER_CREATE);
}
/**
* Check if the user has the permission to create connections.
* @param userID
* @return
* @return
*/
public boolean checkCreateConnectionPermission(int userID) {
return checkSystemPermission(userID, MySQLConstants.SYSTEM_CONNECTION_CREATE);
}
/**
* Check if the user has the selected system permission.
* @param userID
* @param systemPermissionType
* @return
* @param systemPermissionType
* @return
*/
private boolean checkSystemPermission(int userID, String systemPermissionType) {
SystemPermissionExample example = new SystemPermissionExample();
@@ -756,11 +756,11 @@ public class PermissionCheckUtility {
int count = systemPermissionDAO.countByExample(example);
return count > 0;
}
/**
* Get a connection object by name.
* @param name
* @return
* @return
*/
private Connection getConnection(String name) {
ConnectionExample example = new ConnectionExample();
@@ -768,14 +768,14 @@ public class PermissionCheckUtility {
List<Connection> connections = connectionDAO.selectByExample(example);
if(connections.isEmpty())
return null;
return connections.get(0);
}
/**
* Get a user object by username.
* @param userName
* @return
* @return
*/
private User getUser(String username) {
UserExample example = new UserExample();
@@ -783,18 +783,18 @@ public class PermissionCheckUtility {
List<User> users = userDAO.selectByExample(example);
if(users.isEmpty())
return null;
return users.get(0);
}
/**
* Get all permissions a given user has.
* @param userID
* @return all permissions a user has.
* @return all permissions a user has.
*/
public Set<Permission> getAllPermissions(int userID) {
Set<Permission> allPermissions = new HashSet<Permission>();
// first, user permissions
UserPermissionExample userPermissionExample = new UserPermissionExample();
userPermissionExample.createCriteria().andUser_idEqualTo(userID);
@@ -803,7 +803,7 @@ public class PermissionCheckUtility {
for(UserPermissionKey userPermission : userPermissions) {
affectedUserIDs.add(userPermission.getAffected_user_id());
}
UserExample userExample = new UserExample();
userExample.createCriteria().andUser_idIn(affectedUserIDs);
List<User> users = userDAO.selectByExample(userExample);
@@ -811,7 +811,7 @@ public class PermissionCheckUtility {
for(User user : users) {
userMap.put(user.getUser_id(), user);
}
for(UserPermissionKey userPermission : userPermissions) {
User affectedUser = userMap.get(userPermission.getAffected_user_id());
UserPermission newPermission = new UserPermission(
@@ -820,7 +820,7 @@ public class PermissionCheckUtility {
);
allPermissions.add(newPermission);
}
//secondly, connection permissions
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
connectionPermissionExample.createCriteria().andUser_idEqualTo(userID);
@@ -829,7 +829,7 @@ public class PermissionCheckUtility {
for(ConnectionPermissionKey connectionPermission : connectionPermissions) {
affectedConnectionIDs.add(connectionPermission.getConnection_id());
}
ConnectionExample connectionExample = new ConnectionExample();
connectionExample.createCriteria().andConnection_idIn(affectedConnectionIDs);
List<Connection> connections = connectionDAO.selectByExample(connectionExample);
@@ -837,7 +837,7 @@ public class PermissionCheckUtility {
for(Connection connection : connections) {
connectionMap.put(connection.getConnection_id(), connection);
}
for(ConnectionPermissionKey connectionPermission : connectionPermissions) {
Connection affectedConnection = connectionMap.get(connectionPermission.getConnection_id());
ConnectionPermission newPermission = new ConnectionPermission(
@@ -846,7 +846,7 @@ public class PermissionCheckUtility {
);
allPermissions.add(newPermission);
}
//and finally, system permissions
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
systemPermissionExample.createCriteria().andUser_idEqualTo(userID);
@@ -857,11 +857,11 @@ public class PermissionCheckUtility {
newPermission = new UserDirectoryPermission(UserDirectoryPermission.Type.CREATE);
else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_CONNECTION_CREATE))
newPermission = new ConnectionDirectoryPermission(ConnectionDirectoryPermission.Type.CREATE);
if(newPermission != null)
allPermissions.add(newPermission);
}
return allPermissions;
}
}

View File

@@ -44,6 +44,7 @@ import net.sourceforge.guacamole.net.auth.Connection;
import net.sourceforge.guacamole.net.auth.User;
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.MySQLUser;
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
@@ -53,9 +54,10 @@ 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.UserExample;
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
/**
* Provides convenient provider methods for MySQLUser, MySQLConnection, and MySQLConnctionRecord objects.
* Provides convenient provider methods for MySQL specific implementations.
* @author James Muehlner
*/
public class ProviderUtility {
@@ -77,6 +79,9 @@ public class ProviderUtility {
@Inject
Provider<MySQLConnectionRecord> mySQLConnectionRecordProvider;
@Inject
Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
/**
* Create a new user based on the provided object.
* @param user
@@ -205,6 +210,8 @@ public class ProviderUtility {
public List<MySQLConnectionRecord> getExistingMySQLConnectionRecords(Integer connectionID) {
ConnectionHistoryExample example = new ConnectionHistoryExample();
example.createCriteria().andConnection_idEqualTo(connectionID);
// we want to return the newest records first
example.setOrderByClause("start_date DESC");
List<ConnectionHistory> connectionHistories = connectionHistoryDAO.selectByExample(example);
List<MySQLConnectionRecord> connectionRecords = new ArrayList<MySQLConnectionRecord>();
for(ConnectionHistory history : connectionHistories) {
@@ -223,4 +230,16 @@ public class ProviderUtility {
record.init(history);
return record;
}
/**
* Create a MySQLGuacamoleSocket using the provided ConfiguredGuacamoleSocket and connection ID.
* @param socket
* @param connectionID
* @return
*/
public MySQLGuacamoleSocket getMySQLGuacamoleSocket(ConfiguredGuacamoleSocket socket, int connectionID) {
MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
mySQLGuacamoleSocket.init(socket, connectionID);
return mySQLGuacamoleSocket;
}
}

View File

@@ -35,7 +35,6 @@
* ***** END LICENSE BLOCK ***** */
package net.sourceforge.guacamole.net.auth.mysql.utility;
import com.google.common.base.Preconditions;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -51,18 +50,12 @@ public class Sha256PasswordEncryptionUtility implements PasswordEncryptionUtilit
@Override
public boolean checkCredentials(Credentials credentials, byte[] dbPasswordHash, String dbUsername, byte[] dbSalt) {
Preconditions.checkNotNull(credentials);
Preconditions.checkNotNull(dbPasswordHash);
Preconditions.checkNotNull(dbUsername);
Preconditions.checkNotNull(dbSalt);
byte[] passwordBytes = createPasswordHash(credentials.getPassword(), dbSalt);
return Arrays.equals(passwordBytes, dbPasswordHash);
}
@Override
public byte[] createPasswordHash(String password, byte[] salt) {
Preconditions.checkNotNull(password);
Preconditions.checkNotNull(salt);
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");