From 00a699ade023a1f419e188b5d4332f755f9c6c2a Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Sun, 3 Mar 2013 20:19:46 -0800 Subject: [PATCH] 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. --- .../net/auth/mysql/ConnectionDirectory.java | 10 +++++ .../net/auth/mysql/UserDirectory.java | 24 +++++------- .../auth/mysql/service/ConnectionService.java | 37 +++++++++++++++++- .../mysql/service/PermissionCheckService.java | 38 +++++++++++++++++++ .../net/auth/mysql/service/UserService.java | 33 ++++++++++++++++ 5 files changed, 127 insertions(+), 15 deletions(-) diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java index 2b4b597d2..0b66fde06 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionDirectory.java @@ -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{ @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(), diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java index 4dca4b45b..2e3f5c0b0 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/UserDirectory.java @@ -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 getAllConnections(int userID) { + + // Get all connections defined in the system. + List allConnections = connectionDAO.selectByExample(new ConnectionExample()); + + // Translate database records to MySQLConnections + List allMySQLConnections = new ArrayList(); + + 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 getAllConnectionIDs(int userID) { + List connectionIDs = new ArrayList(); + for(MySQLConnection connection : getAllConnections(userID)) { + connectionIDs.add(connection.getConnectionID()); + } + + return connectionIDs; + } } diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionCheckService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionCheckService.java index a0d9b8dde..c580a10fe 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionCheckService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionCheckService.java @@ -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 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 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); diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java index 3526b7751..828c55bdb 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/UserService.java @@ -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 getAllUsers() { + + // Get all users defined in the system. + List allUsers = userDAO.selectByExampleWithBLOBs(new UserExample()); + + // Translate database records to MySQLUsers + List allMySQLUsers = new ArrayList(); + + 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 getAllUserIDs() { + List userIDs = new ArrayList(); + for(MySQLUser user : getAllUsers()) { + userIDs.add(user.getUserID()); + } + + return userIDs; + } }