Ticket #269: Added full system administrator access to everything, and throwing GuacamoleClientException when empty or duplicate users or connections are added, or multiple connections are attempted when disallowed.

This commit is contained in:
James Muehlner
2013-03-03 20:19:46 -08:00
parent 4bfc219324
commit 00a699ade0
5 changed files with 127 additions and 15 deletions

View File

@@ -40,6 +40,7 @@ package net.sourceforge.guacamole.net.auth.mysql;
import com.google.inject.Inject;
import java.util.List;
import java.util.Set;
import net.sourceforge.guacamole.GuacamoleClientException;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.auth.Connection;
import net.sourceforge.guacamole.net.auth.Directory;
@@ -136,10 +137,19 @@ public class ConnectionDirectory implements Directory<String, Connection>{
@Override
public void add(Connection object) throws GuacamoleException {
if(object.getIdentifier().isEmpty())
throw new GuacamoleClientException("The connection identifier cannot be blank.");
// Verify permission to create
permissionCheckService.verifySystemAccess(this.user_id,
MySQLConstants.SYSTEM_CONNECTION_CREATE);
// Verify that no connection already exists with this identifier.
MySQLConnection previousConnection =
connectionService.retrieveConnection(object.getIdentifier(), user_id);
if(previousConnection != null)
throw new GuacamoleClientException("That connection identifier is already in use.");
// Create connection
MySQLConnection connection = connectionService.createConnection(
object.getIdentifier(), object.getConfiguration().getProtocol(),

View File

@@ -44,6 +44,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.guacamole.GuacamoleClientException;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.GuacamoleSecurityException;
import net.sourceforge.guacamole.net.auth.Directory;
@@ -57,9 +58,7 @@ 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;
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
import net.sourceforge.guacamole.net.auth.permission.Permission;
@@ -115,18 +114,6 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
@Inject
private PermissionCheckService permissionCheckService;
/**
* Service for encrypting passwords.
*/
@Inject
private PasswordEncryptionService passwordService;
/**
* Service for generating random salts.
*/
@Inject
private SaltService saltService;
/**
* Set the user for this directory.
*
@@ -174,11 +161,20 @@ public class UserDirectory implements Directory<String, net.sourceforge.guacamol
public void add(net.sourceforge.guacamole.net.auth.User object)
throws GuacamoleException {
if(object.getUsername().isEmpty())
throw new GuacamoleClientException("The username cannot be blank.");
// Verify current user has permission to create users
permissionCheckService.verifySystemAccess(this.user_id,
MySQLConstants.SYSTEM_USER_CREATE);
Preconditions.checkNotNull(object);
// Verify that no user already exists with this username.
MySQLUser previousUser =
userService.retrieveUser(object.getUsername());
if(previousUser != null)
throw new GuacamoleClientException("That username is already in use.");
// Create new user
MySQLUser user = userService.createUser(object.getUsername(),
object.getPassword());

View File

@@ -49,6 +49,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.guacamole.GuacamoleClientException;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.GuacamoleSocket;
import net.sourceforge.guacamole.net.InetGuacamoleSocket;
@@ -340,7 +341,7 @@ public class ConnectionService {
if(GuacamoleProperties.getProperty(
MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
&& activeConnectionSet.isActive(connection.getConnectionID()))
throw new GuacamoleException("Cannot connect. This connection is in use.");
throw new GuacamoleClientException("Cannot connect. This connection is in use.");
// Get guacd connection information
String host = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME);
@@ -411,6 +412,40 @@ public class ConnectionService {
connectionDAO.updateByPrimaryKeySelective(connection);
}
/**
* Get all the connections defined in the system.
* @param userID The ID of the user who is querying the connections.
* @return A list of all connections defined in the system.
*/
public List<MySQLConnection> getAllConnections(int userID) {
// Get all connections defined in the system.
List<Connection> allConnections = connectionDAO.selectByExample(new ConnectionExample());
// Translate database records to MySQLConnections
List<MySQLConnection> allMySQLConnections = new ArrayList<MySQLConnection>();
for(Connection connection : allConnections) {
allMySQLConnections.add(toMySQLConnection(connection, userID));
}
return allMySQLConnections;
}
/**
* Get the IDs of all the connection defined in the system.
* @param userID The ID of the user who is querying the connections.
* @return A list of IDs of all the connections defined in the system.
*/
public List<Integer> getAllConnectionIDs(int userID) {
List<Integer> connectionIDs = new ArrayList<Integer>();
for(MySQLConnection connection : getAllConnections(userID)) {
connectionIDs.add(connection.getConnectionID());
}
return connectionIDs;
}
}

View File

@@ -161,6 +161,10 @@ public class PermissionCheckService {
*/
public boolean checkUserAccess(int userID, Integer affectedUserID, String permissionType) {
// A system administrator has full access to everything.
if(checkSystemAdministratorAccess(userID))
return true;
// Check existence of requested permission
UserPermissionExample example = new UserPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).andAffected_user_idEqualTo(affectedUserID).andPermissionEqualTo(permissionType);
@@ -180,6 +184,10 @@ public class PermissionCheckService {
*/
public boolean checkConnectionAccess(int userID, Integer affectedConnectionID, String permissionType) {
// A system administrator has full access to everything.
if(checkSystemAdministratorAccess(userID))
return true;
// Check existence of requested permission
ConnectionPermissionExample example = new ConnectionPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).andConnection_idEqualTo(affectedConnectionID).andPermissionEqualTo(permissionType);
@@ -196,12 +204,32 @@ public class PermissionCheckService {
*/
private boolean checkSystemAccess(int userID, String systemPermissionType) {
// A system administrator has full access to everything.
if(checkSystemAdministratorAccess(userID))
return true;
// Check existence of requested permission
SystemPermissionExample example = new SystemPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(systemPermissionType);
return systemPermissionDAO.countByExample(example) > 0;
}
/**
* Checks whether a user has system administrator access to the system.
*
* @param userID The ID of the user to check.
* @return true if the system administrator access exists, false otherwise.
*/
private boolean checkSystemAdministratorAccess(int userID) {
// Check existence of system administrator permission
SystemPermissionExample example = new SystemPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).
andPermissionEqualTo(MySQLConstants.SYSTEM_ADMINISTER);
return systemPermissionDAO.countByExample(example) > 0;
}
/**
* Find the list of the IDs of all users a user has permission to.
@@ -213,6 +241,11 @@ public class PermissionCheckService {
*/
public List<Integer> retrieveUserIDs(int userID, String permissionType) {
// A system administrator has access to all users.
if(checkSystemAdministratorAccess(userID)) {
return userService.getAllUserIDs();
}
// Query all user permissions for the given user and permission type
UserPermissionExample example = new UserPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType);
@@ -241,6 +274,11 @@ public class PermissionCheckService {
public List<Integer> retrieveConnectionIDs(int userID,
String permissionType) {
// A system administrator has access to all connections.
if(checkSystemAdministratorAccess(userID)) {
return connectionService.getAllConnectionIDs(userID);
}
// Query all connection permissions for the given user and permission type
ConnectionPermissionExample example = new ConnectionPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType);

View File

@@ -40,6 +40,7 @@ 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;
@@ -355,6 +356,38 @@ public class UserService {
userDAO.updateByPrimaryKeySelective(user);
}
/**
* Get all the users defined in the system.
* @return A list of all users defined in the system.
*/
public List<MySQLUser> getAllUsers() {
// Get all users defined in the system.
List<UserWithBLOBs> allUsers = userDAO.selectByExampleWithBLOBs(new UserExample());
// Translate database records to MySQLUsers
List<MySQLUser> allMySQLUsers = new ArrayList<MySQLUser>();
for(UserWithBLOBs user : allUsers) {
allMySQLUsers.add(toMySQLUser(user));
}
return allMySQLUsers;
}
/**
* Get the IDs of all the user defined in the system.
* @return A list of IDs of all the users defined in the system.
*/
public List<Integer> getAllUserIDs() {
List<Integer> userIDs = new ArrayList<Integer>();
for(MySQLUser user : getAllUsers()) {
userIDs.add(user.getUserID());
}
return userIDs;
}
}