diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/AuthenticatedUser.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/AuthenticatedUser.java new file mode 100644 index 000000000..a6aab2b15 --- /dev/null +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/AuthenticatedUser.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package net.sourceforge.guacamole.net.auth.mysql; + +import org.glyptodon.guacamole.net.auth.Credentials; + +/** + * Represents an authenticated user via their database ID and corresponding + * credentials. + * + * @author Michael Jumper + */ +public class AuthenticatedUser { + + /** + * The database ID of this user. + */ + private final int userID; + + /** + * The credentials given when this user authenticated. + */ + private final Credentials credentials; + + /** + * Creates a new AuthenticatedUser associated with the given database ID + * and credentials. + * + * @param userID + * The database ID of the user this object should represent. + * + * @param credentials + * The credentials given by the user when they authenticated. + */ + public AuthenticatedUser(int userID, Credentials credentials) { + this.userID = userID; + this.credentials = credentials; + } + + /** + * Returns the ID of this user. + * + * @return + * The ID of this user. + */ + public int getUserID() { + return userID; + } + + /** + * Returns the credentials given during authentication by this user. + * + * @return + * The credentials given during authentication by this user. + */ + public Credentials getCredentials() { + return credentials; + } + +} 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 9f91b776e..e9fde29dc 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 @@ -50,10 +50,10 @@ import org.mybatis.guice.transactional.Transactional; public class ConnectionDirectory implements Directory{ /** - * The ID of the user who this connection directory belongs to. - * Access is based on his/her permission settings. + * The user who this connection directory belongs to. Access is based on + * his/her permission settings. */ - private int user_id; + private AuthenticatedUser currentUser; /** * The ID of the parent connection group. @@ -93,12 +93,15 @@ public class ConnectionDirectory implements Directory{ /** * Set the user and parentID for this directory. * - * @param user_id The ID of the user owning this connection directory. - * @param parentID The ID of the parent connection group. + * @param currentUser + * The user owning this connection directory. + * + * @param parentID + * The ID of the parent connection group. */ - public void init(int user_id, Integer parentID) { + public void init(AuthenticatedUser currentUser, Integer parentID) { + this.currentUser = currentUser; this.parentID = parentID; - this.user_id = user_id; } @Transactional @@ -107,18 +110,18 @@ public class ConnectionDirectory implements Directory{ // Get connection MySQLConnection connection = - connectionService.retrieveConnection(identifier, user_id); + connectionService.retrieveConnection(identifier, currentUser); if(connection == null) return null; // Verify permission to use the parent connection group for organizational purposes permissionCheckService.verifyConnectionGroupUsageAccess - (connection.getParentID(), user_id, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); + (connection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); // Verify access is granted permissionCheckService.verifyConnectionAccess( - this.user_id, + currentUser, connection.getConnectionID(), MySQLConstants.CONNECTION_READ); @@ -133,9 +136,9 @@ public class ConnectionDirectory implements Directory{ // Verify permission to use the connection group for organizational purposes permissionCheckService.verifyConnectionGroupUsageAccess - (parentID, user_id, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); + (parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); - return permissionCheckService.retrieveConnectionIdentifiers(user_id, + return permissionCheckService.retrieveConnectionIdentifiers(currentUser, parentID, MySQLConstants.CONNECTION_READ); } @@ -148,26 +151,26 @@ public class ConnectionDirectory implements Directory{ throw new GuacamoleClientException("The connection name cannot be blank."); // Verify permission to create - permissionCheckService.verifySystemAccess(this.user_id, + permissionCheckService.verifySystemAccess(currentUser, MySQLConstants.SYSTEM_CONNECTION_CREATE); // Verify permission to edit the connection group - permissionCheckService.verifyConnectionGroupAccess(this.user_id, + permissionCheckService.verifyConnectionGroupAccess(currentUser, this.parentID, MySQLConstants.CONNECTION_GROUP_UPDATE); // Verify permission to use the connection group for organizational purposes permissionCheckService.verifyConnectionGroupUsageAccess - (parentID, user_id, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); + (parentID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); // Verify that no connection already exists with this name. MySQLConnection previousConnection = - connectionService.retrieveConnection(name, parentID, user_id); + connectionService.retrieveConnection(name, parentID, currentUser); if(previousConnection != null) throw new GuacamoleClientException("That connection name is already in use."); // Create connection MySQLConnection connection = connectionService.createConnection( - name, object.getConfiguration().getProtocol(), user_id, parentID); + name, object.getConfiguration().getProtocol(), currentUser, parentID); // Set the connection ID object.setIdentifier(connection.getIdentifier()); @@ -179,7 +182,7 @@ public class ConnectionDirectory implements Directory{ // Finally, give the current user full access to the newly created // connection. ConnectionPermissionKey newConnectionPermission = new ConnectionPermissionKey(); - newConnectionPermission.setUser_id(this.user_id); + newConnectionPermission.setUser_id(currentUser.getUserID()); newConnectionPermission.setConnection_id(connection.getConnectionID()); // Read permission @@ -238,7 +241,7 @@ public class ConnectionDirectory implements Directory{ MySQLConnection mySQLConnection = (MySQLConnection) object; // Verify permission to update - permissionCheckService.verifyConnectionAccess(this.user_id, + permissionCheckService.verifyConnectionAccess(currentUser, mySQLConnection.getConnectionID(), MySQLConstants.CONNECTION_UPDATE); @@ -262,17 +265,17 @@ public class ConnectionDirectory implements Directory{ // Get connection MySQLConnection mySQLConnection = - connectionService.retrieveConnection(identifier, user_id); + connectionService.retrieveConnection(identifier, currentUser); if(mySQLConnection == null) throw new GuacamoleResourceNotFoundException("Connection not found."); // Verify permission to use the parent connection group for organizational purposes permissionCheckService.verifyConnectionGroupUsageAccess - (mySQLConnection.getParentID(), user_id, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); + (mySQLConnection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); // Verify permission to delete - permissionCheckService.verifyConnectionAccess(this.user_id, + permissionCheckService.verifyConnectionAccess(currentUser, mySQLConnection.getConnectionID(), MySQLConstants.CONNECTION_DELETE); @@ -292,36 +295,36 @@ public class ConnectionDirectory implements Directory{ // Get connection MySQLConnection mySQLConnection = - connectionService.retrieveConnection(identifier, user_id); + connectionService.retrieveConnection(identifier, currentUser); if(mySQLConnection == null) throw new GuacamoleResourceNotFoundException("Connection not found."); // Verify permission to update the connection - permissionCheckService.verifyConnectionAccess(this.user_id, + permissionCheckService.verifyConnectionAccess(currentUser, mySQLConnection.getConnectionID(), MySQLConstants.CONNECTION_UPDATE); // Verify permission to use the from connection group for organizational purposes permissionCheckService.verifyConnectionGroupUsageAccess - (mySQLConnection.getParentID(), user_id, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); + (mySQLConnection.getParentID(), currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); // Verify permission to update the from connection group - permissionCheckService.verifyConnectionGroupAccess(this.user_id, + permissionCheckService.verifyConnectionGroupAccess(currentUser, mySQLConnection.getParentID(), MySQLConstants.CONNECTION_GROUP_UPDATE); // Verify permission to use the to connection group for organizational purposes permissionCheckService.verifyConnectionGroupUsageAccess - (toConnectionGroupID, user_id, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); + (toConnectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL); // Verify permission to update the to connection group - permissionCheckService.verifyConnectionGroupAccess(this.user_id, + permissionCheckService.verifyConnectionGroupAccess(currentUser, toConnectionGroupID, MySQLConstants.CONNECTION_GROUP_UPDATE); // Verify that no connection already exists with this name. MySQLConnection previousConnection = connectionService.retrieveConnection(mySQLConnection.getName(), - toConnectionGroupID, user_id); + toConnectionGroupID, currentUser); if(previousConnection != null) throw new GuacamoleClientException("That connection name is already in use."); diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionGroupDirectory.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionGroupDirectory.java index a8353d8ea..1b68f7dc3 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionGroupDirectory.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/ConnectionGroupDirectory.java @@ -46,10 +46,10 @@ import org.mybatis.guice.transactional.Transactional; public class ConnectionGroupDirectory implements Directory{ /** - * The ID of the user who this connection directory belongs to. - * Access is based on his/her permission settings. + * The user who this connection directory belongs to. Access is based on + * his/her permission settings. */ - private int user_id; + private AuthenticatedUser currentUser; /** * The ID of the parent connection group. @@ -77,12 +77,15 @@ public class ConnectionGroupDirectory implements Directory history, int userID) { + List history, + AuthenticatedUser currentUser) { this.connectionID = connectionID; this.setParentID(parentID); @@ -132,13 +147,13 @@ public class MySQLConnection extends AbstractConnection { setIdentifier(identifier); setConfiguration(config); this.history.addAll(history); - this.userID = userID; + this.currentUser = currentUser; } @Override public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException { - return connectionService.connect(this, info, userID, null); + return connectionService.connect(this, info, currentUser, null); } @Override diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionGroup.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionGroup.java index f41e6d7e5..53380bb5c 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionGroup.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLConnectionGroup.java @@ -52,9 +52,9 @@ public class MySQLConnectionGroup extends AbstractConnectionGroup { private Integer parentID; /** - * The ID of the user who queried or created this connection group. + * The user who queried or created this connection group. */ - private int userID; + private AuthenticatedUser currentUser; /** * A Directory of connections that have this connection group as a parent. @@ -136,27 +136,39 @@ public class MySQLConnectionGroup extends AbstractConnectionGroup { /** * Initialize from explicit values. * - * @param connectionGroupID The ID of the associated database record, if any. - * @param parentID The ID of the parent connection group for this connection group, if any. - * @param name The name of this connection group. - * @param identifier The unique identifier associated with this connection group. - * @param type The type of this connection group. - * @param userID The IID of the user who queried this connection. + * @param connectionGroupID + * The ID of the associated database record, if any. + * + * @param parentID + * The ID of the parent connection group for this connection group, if + * any. + * + * @param name + * The name of this connection group. + * + * @param identifier + * The unique identifier associated with this connection group. + * + * @param type + * The type of this connection group. + * + * @param currentUser + * The user who queried this connection. */ public void init(Integer connectionGroupID, Integer parentID, String name, - String identifier, ConnectionGroup.Type type, int userID) { + String identifier, ConnectionGroup.Type type, AuthenticatedUser currentUser) { this.connectionGroupID = connectionGroupID; this.setParentID(parentID); setName(name); setIdentifier(identifier); setType(type); - this.userID = userID; + this.currentUser = currentUser; connectionDirectory = connectionDirectoryProvider.get(); - connectionDirectory.init(userID, connectionGroupID); + connectionDirectory.init(currentUser, connectionGroupID); connectionGroupDirectory = connectionGroupDirectoryProvider.get(); - connectionGroupDirectory.init(userID, connectionGroupID); + connectionGroupDirectory.init(currentUser, connectionGroupID); } @Override @@ -164,14 +176,14 @@ public class MySQLConnectionGroup extends AbstractConnectionGroup { // Verify permission to use the connection group for balancing purposes permissionCheckService.verifyConnectionGroupUsageAccess - (this.connectionGroupID, this.userID, MySQLConstants.CONNECTION_GROUP_BALANCING); + (this.connectionGroupID, currentUser, MySQLConstants.CONNECTION_GROUP_BALANCING); // Verify permission to delete - permissionCheckService.verifyConnectionGroupAccess(this.userID, + permissionCheckService.verifyConnectionGroupAccess(currentUser, this.connectionGroupID, MySQLConstants.CONNECTION_GROUP_READ); - return connectionGroupService.connect(this, info, userID); + return connectionGroupService.connect(this, info, currentUser); } @Override diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java index c25f63a78..43f0728bb 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUserContext.java @@ -30,6 +30,7 @@ import org.glyptodon.guacamole.net.auth.Directory; import org.glyptodon.guacamole.net.auth.User; import org.glyptodon.guacamole.net.auth.UserContext; import net.sourceforge.guacamole.net.auth.mysql.service.UserService; +import org.glyptodon.guacamole.net.auth.Credentials; /** * The MySQL representation of a UserContext. @@ -38,10 +39,10 @@ import net.sourceforge.guacamole.net.auth.mysql.service.UserService; public class MySQLUserContext implements UserContext { /** - * The ID of the user owning this context. The permissions of this user - * dictate the access given via the user and connection directories. + * The the user owning this context. The permissions of this user dictate + * the access given via the user and connection directories. */ - private int user_id; + private AuthenticatedUser currentUser; /** * User directory restricted by the permissions of the user associated @@ -65,20 +66,21 @@ public class MySQLUserContext implements UserContext { /** * Initializes the user and directories associated with this context. * - * @param user_id The ID of the user owning this context. + * @param currentUser + * The user owning this context. */ - public void init(int user_id) { - this.user_id = user_id; - userDirectory.init(user_id); + public void init(AuthenticatedUser currentUser) { + this.currentUser = currentUser; + userDirectory.init(currentUser); rootConnectionGroup.init(null, null, MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER, MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER, - ConnectionGroup.Type.ORGANIZATIONAL, user_id); + ConnectionGroup.Type.ORGANIZATIONAL, currentUser); } @Override public User self() { - return userService.retrieveUser(user_id); + return userService.retrieveUser(currentUser.getUserID()); } @Override 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 34e61237c..66a1a16df 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 @@ -67,10 +67,10 @@ import org.mybatis.guice.transactional.Transactional; public class UserDirectory implements Directory { /** - * The ID of the user who this user directory belongs to. - * Access is based on his/her permission settings. + * The user this user directory belongs to. Access is based on his/her + * permission settings. */ - private int user_id; + private AuthenticatedUser currentUser; /** * Service for accessing users. @@ -123,11 +123,12 @@ public class UserDirectory implements Directory { /** * Set the user for this directory. * - * @param user_id The ID of the user whose permissions define the visibility - * of other users in this directory. + * @param currentUser + * The user whose permissions define the visibility of other users in + * this directory. */ - public void init(int user_id) { - this.user_id = user_id; + public void init(AuthenticatedUser currentUser) { + this.currentUser = currentUser; } @Transactional @@ -142,7 +143,7 @@ public class UserDirectory implements Directory { return null; // Verify access is granted - permissionCheckService.verifyUserAccess(this.user_id, + permissionCheckService.verifyUserAccess(currentUser, user.getUserID(), MySQLConstants.USER_READ); @@ -154,7 +155,7 @@ public class UserDirectory implements Directory { @Transactional @Override public Set getIdentifiers() throws GuacamoleException { - return permissionCheckService.retrieveUsernames(user_id, + return permissionCheckService.retrieveUsernames(currentUser, MySQLConstants.USER_READ); } @@ -168,7 +169,7 @@ public class UserDirectory implements Directory { throw new GuacamoleClientException("The username cannot be blank."); // Verify current user has permission to create users - permissionCheckService.verifySystemAccess(this.user_id, + permissionCheckService.verifySystemAccess(currentUser, MySQLConstants.SYSTEM_USER_CREATE); Preconditions.checkNotNull(object); @@ -185,7 +186,7 @@ public class UserDirectory implements Directory { // Give the current user full access to the newly created user. UserPermissionKey newUserPermission = new UserPermissionKey(); - newUserPermission.setUser_id(this.user_id); + newUserPermission.setUser_id(currentUser.getUserID()); newUserPermission.setAffected_user_id(user.getUserID()); // READ permission on new user @@ -304,7 +305,7 @@ public class UserDirectory implements Directory { // Get list of administerable user IDs List administerableUserIDs = - permissionCheckService.retrieveUserIDs(this.user_id, + permissionCheckService.retrieveUserIDs(currentUser, MySQLConstants.USER_ADMINISTER); // Get set of usernames corresponding to administerable users @@ -322,13 +323,13 @@ public class UserDirectory implements Directory { // every one of these users if (affected_id == null) throw new GuacamoleSecurityException( - "User #" + this.user_id + "User #" + currentUser.getUserID() + " does not have permission to administrate user " + permission.getObjectIdentifier()); // Create new permission UserPermissionKey newPermission = new UserPermissionKey(); - newPermission.setUser_id(user_id); + newPermission.setUser_id(currentUser.getUserID()); newPermission.setPermission(MySQLConstants.getUserConstant(permission.getType())); newPermission.setAffected_user_id(affected_id); userPermissionDAO.insert(newPermission); @@ -356,7 +357,7 @@ public class UserDirectory implements Directory { // Get list of administerable user IDs List administerableUserIDs = - permissionCheckService.retrieveUserIDs(this.user_id, + permissionCheckService.retrieveUserIDs(currentUser, MySQLConstants.USER_ADMINISTER); // Get set of usernames corresponding to administerable users @@ -374,7 +375,7 @@ public class UserDirectory implements Directory { // every one of these users if (affected_id == null) throw new GuacamoleSecurityException( - "User #" + this.user_id + "User #" + currentUser.getUserID() + " does not have permission to administrate user " + permission.getObjectIdentifier()); @@ -410,7 +411,7 @@ public class UserDirectory implements Directory { // Get list of administerable connection IDs Set administerableConnectionIDs = Sets.newHashSet( - permissionCheckService.retrieveConnectionIDs(this.user_id, + permissionCheckService.retrieveConnectionIDs(currentUser, MySQLConstants.CONNECTION_ADMINISTER)); // Insert all given permissions @@ -423,7 +424,7 @@ public class UserDirectory implements Directory { // is not granted if (!administerableConnectionIDs.contains(connection_id)) throw new GuacamoleSecurityException( - "User #" + this.user_id + "User #" + currentUser.getUserID() + " does not have permission to administrate connection " + permission.getObjectIdentifier()); @@ -457,7 +458,7 @@ public class UserDirectory implements Directory { // Get list of administerable connection group IDs Set administerableConnectionGroupIDs = Sets.newHashSet( - permissionCheckService.retrieveConnectionGroupIDs(this.user_id, + permissionCheckService.retrieveConnectionGroupIDs(currentUser, MySQLConstants.CONNECTION_GROUP_ADMINISTER)); // Insert all given permissions @@ -470,7 +471,7 @@ public class UserDirectory implements Directory { // is not granted if (!administerableConnectionGroupIDs.contains(connection_group_id)) throw new GuacamoleSecurityException( - "User #" + this.user_id + "User #" + currentUser.getUserID() + " does not have permission to administrate connection group" + permission.getObjectIdentifier()); @@ -503,7 +504,7 @@ public class UserDirectory implements Directory { // Get list of administerable connection IDs Set administerableConnectionIDs = Sets.newHashSet( - permissionCheckService.retrieveConnectionIDs(this.user_id, + permissionCheckService.retrieveConnectionIDs(currentUser, MySQLConstants.CONNECTION_ADMINISTER)); // Delete requested permissions @@ -516,7 +517,7 @@ public class UserDirectory implements Directory { // every one of these connections if (!administerableConnectionIDs.contains(connection_id)) throw new GuacamoleSecurityException( - "User #" + this.user_id + "User #" + currentUser.getUserID() + " does not have permission to administrate connection " + permission.getObjectIdentifier()); @@ -550,7 +551,7 @@ public class UserDirectory implements Directory { // Get list of administerable connection group IDs Set administerableConnectionGroupIDs = Sets.newHashSet( - permissionCheckService.retrieveConnectionGroupIDs(this.user_id, + permissionCheckService.retrieveConnectionGroupIDs(currentUser, MySQLConstants.CONNECTION_GROUP_ADMINISTER)); // Delete requested permissions @@ -563,7 +564,7 @@ public class UserDirectory implements Directory { // every one of these connection groups if (!administerableConnectionGroupIDs.contains(connection_group_id)) throw new GuacamoleSecurityException( - "User #" + this.user_id + "User #" + currentUser.getUserID() + " does not have permission to administrate connection group" + permission.getObjectIdentifier()); @@ -597,7 +598,7 @@ public class UserDirectory implements Directory { // Only a system administrator can add system permissions. permissionCheckService.verifySystemAccess( - this.user_id, SystemPermission.Type.ADMINISTER.name()); + currentUser, SystemPermission.Type.ADMINISTER.name()); // Insert all requested permissions for (SystemPermission permission : permissions) { @@ -631,7 +632,7 @@ public class UserDirectory implements Directory { return; // Prevent self-de-adminifying - if (user_id == this.user_id) + if (user_id == currentUser.getUserID()) throw new GuacamoleUnsupportedException("Removing your own administrative permissions is not allowed."); // Build list of requested system permissions @@ -660,7 +661,7 @@ public class UserDirectory implements Directory { MySQLUser mySQLUser = (MySQLUser) object; // Validate permission to update this user is granted - permissionCheckService.verifyUserAccess(this.user_id, + permissionCheckService.verifyUserAccess(currentUser, mySQLUser.getUserID(), MySQLConstants.USER_UPDATE); @@ -685,11 +686,11 @@ public class UserDirectory implements Directory { MySQLUser user = userService.retrieveUser(identifier); // Prevent self-deletion - if (user.getUserID() == this.user_id) + if (user.getUserID() == currentUser.getUserID()) throw new GuacamoleUnsupportedException("Deleting your own user is not allowed."); // Validate current user has permission to remove the specified user - permissionCheckService.verifyUserAccess(this.user_id, + permissionCheckService.verifyUserAccess(currentUser, user.getUserID(), MySQLConstants.USER_DELETE); diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java index ba34e5052..4c21ee548 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java @@ -31,6 +31,7 @@ import java.util.Set; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.GuacamoleSocket; import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap; +import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup; import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants; @@ -82,14 +83,21 @@ public class ConnectionGroupService { * Retrieves the connection group having the given * name from the database. * - * @param name The name of the connection to return. - * @param parentID The ID of the parent connection group. - * @param userID The ID of the user who queried this connection group. - * @return The connection having the given name, or null if no such - * connection group could be found. + * @param name + * The name of the connection to return. + * + * @param parentID + * The ID of the parent connection group. + * + * @param currentUser + * The user who queried this connection group. + * + * @return + * The connection having the given name, or null if no such connection + * group could be found. */ public MySQLConnectionGroup retrieveConnectionGroup(String name, Integer parentID, - int userID) { + AuthenticatedUser currentUser) { // Create criteria ConnectionGroupExample example = new ConnectionGroupExample(); @@ -108,7 +116,7 @@ public class ConnectionGroupService { return null; // Otherwise, return found connection - return toMySQLConnectionGroup(connectionGroups.get(0), userID); + return toMySQLConnectionGroup(connectionGroups.get(0), currentUser); } @@ -116,13 +124,21 @@ public class ConnectionGroupService { * Retrieves the connection group having the given unique identifier * from the database. * - * @param uniqueIdentifier The unique identifier of the connection group to retrieve. - * @param userID The ID of the user who queried this connection group. - * @return The connection group having the given unique identifier, - * or null if no such connection group was found. + * @param uniqueIdentifier + * The unique identifier of the connection group to retrieve. + * + * @param currentUser + * The user who queried this connection group. + * + * @return + * The connection group having the given unique identifier, or null if + * no such connection group was found. + * + * @throws GuacamoleException + * If an error occurs while retrieving the connection group. */ public MySQLConnectionGroup retrieveConnectionGroup(String uniqueIdentifier, - int userID) throws GuacamoleException { + AuthenticatedUser currentUser) throws GuacamoleException { // The unique identifier for a MySQLConnectionGroup is the database ID Integer connectionGroupID = null; @@ -136,18 +152,23 @@ public class ConnectionGroupService { } } - return retrieveConnectionGroup(connectionGroupID, userID); + return retrieveConnectionGroup(connectionGroupID, currentUser); } /** * Retrieves the connection group having the given ID from the database. * - * @param id The ID of the connection group to retrieve. - * @param userID The ID of the user who queried this connection. - * @return The connection group having the given ID, or null if no such - * connection was found. + * @param id + * The ID of the connection group to retrieve. + * + * @param currentUser + * The user who queried this connection. + * + * @return + * The connection group having the given ID, or null if no such + * connection was found. */ - public MySQLConnectionGroup retrieveConnectionGroup(Integer id, int userID) { + public MySQLConnectionGroup retrieveConnectionGroup(Integer id, AuthenticatedUser currentUser) { // This is the root connection group, so just create it here if(id == null) { @@ -156,7 +177,7 @@ public class ConnectionGroupService { MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER, MySQLConstants.CONNECTION_GROUP_ROOT_IDENTIFIER, org.glyptodon.guacamole.net.auth.ConnectionGroup.Type.ORGANIZATIONAL, - userID); + currentUser); return connectionGroup; } @@ -169,23 +190,31 @@ public class ConnectionGroupService { return null; // Otherwise, return found connection - return toMySQLConnectionGroup(connectionGroup, userID); + return toMySQLConnectionGroup(connectionGroup, currentUser); } /** * Connect to the connection within the given group with the lowest number * of currently active users. * - * @param group The group to load balance across. - * @param info The information to use when performing the connection - * handshake. - * @param userID The ID of the user who is connecting to the socket. - * @return The connected socket. - * @throws GuacamoleException If an error occurs while connecting the - * socket. + * @param group + * The group to load balance across. + * + * @param info + * The information to use when performing the connection handshake. + * + * @param currentUser + * The user who is connecting to the socket. + * + * @return + * The connected socket. + * + * @throws GuacamoleException + * If an error occurs while connecting the socket. */ public GuacamoleSocket connect(MySQLConnectionGroup group, - GuacamoleClientInformation info, int userID) throws GuacamoleException { + GuacamoleClientInformation info, AuthenticatedUser currentUser) + throws GuacamoleException { // Get all connections in the group. List connectionIDs = connectionService.getAllConnectionIDs @@ -208,16 +237,16 @@ public class ConnectionGroupService { if(GuacamoleProperties.getProperty( MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true) - && activeConnectionMap.isConnectionGroupUserActive(group.getConnectionGroupID(), userID)) + && activeConnectionMap.isConnectionGroupUserActive(group.getConnectionGroupID(), currentUser.getUserID())) throw new GuacamoleClientTooManyException ("Cannot connect. Connection group already in use by this user."); // Get the connection MySQLConnection connection = connectionService - .retrieveConnection(leastUsedConnectionID, userID); + .retrieveConnection(leastUsedConnectionID, currentUser); // Connect to the connection - return connectionService.connect(connection, info, userID, group.getConnectionGroupID()); + return connectionService.connect(connection, info, currentUser, group.getConnectionGroupID()); } @@ -287,12 +316,18 @@ public class ConnectionGroupService { * The parameters of the given connection will be read and added to the * MySQLConnection in the process. * - * @param connection The connection to convert. - * @param userID The user who queried this connection. - * @return A new MySQLConnection containing all data associated with the - * specified connection. + * @param connection + * The connection to convert. + * + * @param currentUser + * The user who queried this connection. + * + * @return + * A new MySQLConnection containing all data associated with the + * specified connection. */ - private MySQLConnectionGroup toMySQLConnectionGroup(ConnectionGroup connectionGroup, int userID) { + private MySQLConnectionGroup toMySQLConnectionGroup(ConnectionGroup connectionGroup, + AuthenticatedUser currentUser) { // Create new MySQLConnection from retrieved data MySQLConnectionGroup mySQLConnectionGroup = mysqlConnectionGroupProvider.get(); @@ -311,7 +346,7 @@ public class ConnectionGroupService { connectionGroup.getConnection_group_name(), Integer.toString(connectionGroup.getConnection_group_id()), authType, - userID + currentUser ); return mySQLConnectionGroup; @@ -341,13 +376,22 @@ public class ConnectionGroupService { /** * Creates a new connection group having the given name and type. * - * @param name The name to assign to the new connection group. - * @param userID The ID of the user who created this connection group. - * @param Type The type of the new connection group. + * @param name + * The name to assign to the new connection group. + * + * @param currentUser + * The user who created this connection group. + * + * @param parentID + * The ID of the parent of the new connection group, if any. + * + * @param type + * The type of the new connection group. + * * @return A new MySQLConnectionGroup containing the data of the newly created * connection group. */ - public MySQLConnectionGroup createConnectionGroup(String name, int userID, + public MySQLConnectionGroup createConnectionGroup(String name, AuthenticatedUser currentUser, Integer parentID, String type) { // Initialize database connection @@ -358,7 +402,7 @@ public class ConnectionGroupService { // Create connection connectionGroupDAO.insert(connectionGroup); - return toMySQLConnectionGroup(connectionGroup, userID); + return toMySQLConnectionGroup(connectionGroup, currentUser); } diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java index c17e09976..63126eb76 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java @@ -35,6 +35,7 @@ import org.glyptodon.guacamole.net.GuacamoleSocket; import org.glyptodon.guacamole.net.InetGuacamoleSocket; import org.glyptodon.guacamole.net.SSLGuacamoleSocket; import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionMap; +import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord; import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket; @@ -56,6 +57,8 @@ import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; import org.apache.ibatis.session.RowBounds; import org.glyptodon.guacamole.GuacamoleClientTooManyException; import org.glyptodon.guacamole.GuacamoleResourceConflictException; +import org.glyptodon.guacamole.token.StandardTokens; +import org.glyptodon.guacamole.token.TokenFilter; /** * Service which provides convenience methods for creating, retrieving, and @@ -110,14 +113,21 @@ public class ConnectionService { /** * Retrieves the connection having the given name from the database. * - * @param name The name of the connection to return. - * @param parentID The ID of the parent connection group. - * @param userID The ID of the user who queried this connection. - * @return The connection having the given name, or null if no such - * connection could be found. + * @param name + * The name of the connection to return. + * + * @param parentID + * The ID of the parent connection group. + * + * @param currentUser + * The user who queried this connection. + * + * @return + * The connection having the given name, or null if no such + * connection could be found. */ public MySQLConnection retrieveConnection(String name, Integer parentID, - int userID) { + AuthenticatedUser currentUser) { // Create criteria ConnectionExample example = new ConnectionExample(); @@ -136,7 +146,7 @@ public class ConnectionService { return null; // Otherwise, return found connection - return toMySQLConnection(connections.get(0), userID); + return toMySQLConnection(connections.get(0), currentUser); } @@ -144,12 +154,17 @@ public class ConnectionService { * Retrieves the connection having the given unique identifier * from the database. * - * @param uniqueIdentifier The unique identifier of the connection to retrieve. - * @param userID The ID of the user who queried this connection. - * @return The connection having the given unique identifier, - * or null if no such connection was found. + * @param uniqueIdentifier + * The unique identifier of the connection to retrieve. + * + * @param currentUser + * The user who queried this connection. + * + * @return + * The connection having the given unique identifier, or null if no + * such connection was found. */ - public MySQLConnection retrieveConnection(String uniqueIdentifier, int userID) { + public MySQLConnection retrieveConnection(String uniqueIdentifier, AuthenticatedUser currentUser) { // The unique identifier for a MySQLConnection is the database ID int connectionID; @@ -160,18 +175,23 @@ public class ConnectionService { return null; } - return retrieveConnection(connectionID, userID); + return retrieveConnection(connectionID, currentUser); } /** * Retrieves the connection having the given ID from the database. * - * @param id The ID of the connection to retrieve. - * @param userID The ID of the user who queried this connection. - * @return The connection having the given ID, or null if no such - * connection was found. + * @param id + * The ID of the connection to retrieve. + * + * @param currentUser + * The user who queried this connection. + * + * @return + * The connection having the given ID, or null if no such connection + * was found. */ - public MySQLConnection retrieveConnection(int id, int userID) { + public MySQLConnection retrieveConnection(int id, AuthenticatedUser currentUser) { // Query connection by ID Connection connection = connectionDAO.selectByPrimaryKey(id); @@ -181,7 +201,7 @@ public class ConnectionService { return null; // Otherwise, return found connection - return toMySQLConnection(connection, userID); + return toMySQLConnection(connection, currentUser); } /** @@ -218,12 +238,16 @@ public class ConnectionService { * The parameters of the given connection will be read and added to the * MySQLConnection in the process. * - * @param connection The connection to convert. - * @param userID The user who queried this connection. + * @param connection + * The connection to convert. + * + * @param currentUser + * The user who queried this connection. + * * @return A new MySQLConnection containing all data associated with the * specified connection. */ - private MySQLConnection toMySQLConnection(Connection connection, int userID) { + private MySQLConnection toMySQLConnection(Connection connection, AuthenticatedUser currentUser) { // Build configuration GuacamoleConfiguration config = new GuacamoleConfiguration(); @@ -251,7 +275,7 @@ public class ConnectionService { Integer.toString(connection.getConnection_id()), config, retrieveHistory(connection.getConnection_id()), - userID + currentUser ); return mySQLConnection; @@ -326,18 +350,28 @@ public class ConnectionService { /** * Create a MySQLGuacamoleSocket using the provided connection. * - * @param connection The connection to use when connecting the socket. - * @param info The information to use when performing the connection - * handshake. - * @param userID The ID of the user who is connecting to the socket. - * @param connectionGroupID The ID of the balancing connection group that is - * being connected to; null if not used. - * @return The connected socket. - * @throws GuacamoleException If an error occurs while connecting the - * socket. + * @param connection + * The connection to use when connecting the socket. + * + * @param info + * The information to use when performing the connection handshake. + * + * @param currentUser + * The user who is connecting to the socket. + * + * @param connectionGroupID + * The ID of the balancing connection group that is being connected to; + * null if not used. + * + * @return + * The connected socket. + * + * @throws GuacamoleException + * If an error occurs while connecting the socket. */ public MySQLGuacamoleSocket connect(MySQLConnection connection, - GuacamoleClientInformation info, int userID, Integer connectionGroupID) + GuacamoleClientInformation info, AuthenticatedUser currentUser, + Integer connectionGroupID) throws GuacamoleException { synchronized (activeConnectionMap) { @@ -351,7 +385,7 @@ public class ConnectionService { if(GuacamoleProperties.getProperty( MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true) - && activeConnectionMap.isConnectionUserActive(connection.getConnectionID(), userID)) + && activeConnectionMap.isConnectionUserActive(connection.getConnectionID(), currentUser.getUserID())) throw new GuacamoleClientTooManyException ("Cannot connect. Connection already in use by this user."); @@ -359,22 +393,30 @@ public class ConnectionService { String host = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_HOSTNAME); int port = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_PORT); + // Build token filter containing credential tokens + TokenFilter tokenFilter = new TokenFilter(); + StandardTokens.addStandardTokens(tokenFilter, currentUser.getCredentials()); + + // Filter the configuration + GuacamoleConfiguration config = new GuacamoleConfiguration(connection.getConfiguration()); + tokenFilter.filterValues(config.getParameters()); + // Get socket GuacamoleSocket socket; if (GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_SSL, false)) socket = new ConfiguredGuacamoleSocket( new SSLGuacamoleSocket(host, port), - connection.getConfiguration(), info + config, info ); else socket = new ConfiguredGuacamoleSocket( new InetGuacamoleSocket(host, port), - connection.getConfiguration(), info + config, info ); // Mark this connection as active int historyID = activeConnectionMap.openConnection(connection.getConnectionID(), - userID, connectionGroupID); + currentUser.getUserID(), connectionGroupID); // Return new MySQLGuacamoleSocket MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get(); @@ -389,15 +431,24 @@ 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. - * @param userID The ID of the user who created this connection. - * @param parentID The ID of the parent connection group. - * @return A new MySQLConnection containing the data of the newly created - * connection. + * @param name + * The name to assign to the new connection. + * + * @param protocol + * The protocol to assign to the new connection. + * + * @param currentUser + * The user who created this connection. + * + * @param parentID + * The ID of the parent connection group. + * + * @return + * A new MySQLConnection containing the data of the newly created + * connection. */ public MySQLConnection createConnection(String name, String protocol, - int userID, Integer parentID) { + AuthenticatedUser currentUser, Integer parentID) { // Initialize database connection Connection connection = new Connection(); @@ -407,7 +458,7 @@ public class ConnectionService { // Create connection connectionDAO.insert(connection); - return toMySQLConnection(connection, userID); + return toMySQLConnection(connection, currentUser); } 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 ca8440db8..a6a8d2326 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 @@ -29,6 +29,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser; import org.glyptodon.guacamole.GuacamoleSecurityException; import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionGroup; import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants; @@ -103,18 +104,24 @@ public class PermissionCheckService { * Verifies that the user has the specified access to the given other * user. If permission is denied, a GuacamoleSecurityException is thrown. * - * @param userID The ID of the user to check. - * @param affectedUserID The user that would be affected by the operation - * if permission is granted. - * @param permissionType The type of permission to check for. - * @throws GuacamoleSecurityException If the specified permission is not - * granted. + * @param currentUser + * The user to check. + * + * @param affectedUserID + * The user that would be affected by the operation if permission is + * granted. + * + * @param permissionType + * The type of permission to check for. + * + * @throws GuacamoleSecurityException + * If the specified permission is not granted. */ - public void verifyUserAccess(int userID, int affectedUserID, + public void verifyUserAccess(AuthenticatedUser currentUser, int affectedUserID, String permissionType) throws GuacamoleSecurityException { // If permission does not exist, throw exception - if(!checkUserAccess(userID, affectedUserID, permissionType)) + if(!checkUserAccess(currentUser, affectedUserID, permissionType)) throw new GuacamoleSecurityException("Permission denied."); } @@ -123,17 +130,24 @@ public class PermissionCheckService { * Verifies that the user has the specified access to the given connection. * If permission is denied, a GuacamoleSecurityException is thrown. * - * @param userID The ID of the user to check. - * @param affectedConnectionID The connection that would be affected by the - * operation if permission is granted. - * @param permissionType The type of permission to check for. - * @throws GuacamoleSecurityException If the specified permission is not - * granted. + * @param currentUser + * The user to check. + * + * @param affectedConnectionID + * The connection that would be affected by the operation if permission + * is granted. + * + * @param permissionType + * The type of permission to check for. + * + * @throws GuacamoleSecurityException + * If the specified permission is not granted. */ - public void verifyConnectionAccess(int userID, int affectedConnectionID, String permissionType) throws GuacamoleSecurityException { + public void verifyConnectionAccess(AuthenticatedUser currentUser, + int affectedConnectionID, String permissionType) throws GuacamoleSecurityException { // If permission does not exist, throw exception - if(!checkConnectionAccess(userID, affectedConnectionID, permissionType)) + if(!checkConnectionAccess(currentUser, affectedConnectionID, permissionType)) throw new GuacamoleSecurityException("Permission denied."); } @@ -142,17 +156,24 @@ public class PermissionCheckService { * Verifies that the user has the specified access to the given connection group. * If permission is denied, a GuacamoleSecurityException is thrown. * - * @param userID The ID of the user to check. - * @param affectedConnectionGroupID The connection group that would be affected by the - * operation if permission is granted. - * @param permissionType The type of permission to check for. - * @throws GuacamoleSecurityException If the specified permission is not - * granted. + * @param currentUser + * The user to check. + * + * @param affectedConnectionGroupID + * The connection group that would be affected by the operation if + * permission is granted. + * + * @param permissionType + * The type of permission to check for. + * + * @throws GuacamoleSecurityException + * If the specified permission is not granted. */ - public void verifyConnectionGroupAccess(int userID, Integer affectedConnectionGroupID, String permissionType) throws GuacamoleSecurityException { + public void verifyConnectionGroupAccess(AuthenticatedUser currentUser, + Integer affectedConnectionGroupID, String permissionType) throws GuacamoleSecurityException { // If permission does not exist, throw exception - if(!checkConnectionGroupAccess(userID, affectedConnectionGroupID, permissionType)) + if(!checkConnectionGroupAccess(currentUser, affectedConnectionGroupID, permissionType)) throw new GuacamoleSecurityException("Permission denied."); } @@ -161,16 +182,20 @@ public class PermissionCheckService { * Verifies that the user has the specified access to the system. If * permission is denied, a GuacamoleSecurityException is thrown. * - * @param userID The ID of the user to check. - * @param systemPermissionType The type of permission to check for. - * @throws GuacamoleSecurityException If the specified permission is not - * granted. + * @param currentUser + * The user to check. + * + * @param systemPermissionType + * The type of permission to check for. + * + * @throws GuacamoleSecurityException + * If the specified permission is not granted. */ - public void verifySystemAccess(int userID, String systemPermissionType) + public void verifySystemAccess(AuthenticatedUser currentUser, String systemPermissionType) throws GuacamoleSecurityException { // If permission does not exist, throw exception - if(!checkSystemAccess(userID, systemPermissionType)) + if(!checkSystemAccess(currentUser, systemPermissionType)) throw new GuacamoleSecurityException("Permission denied."); } @@ -179,21 +204,29 @@ public class PermissionCheckService { * Checks whether a user has the specified type of access to the affected * user. * - * @param userID The ID of the user to check. - * @param affectedUserID The user that would be affected by the operation - * if permission is granted. - * @param permissionType The type of permission to check for. - * @return true if the specified permission is granted, false otherwise. + * @param currentUser + * The user to check. + * + * @param affectedUserID + * The user that would be affected by the operation if permission is + * granted. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * true if the specified permission is granted, false otherwise. */ - public boolean checkUserAccess(int userID, Integer affectedUserID, String permissionType) { + public boolean checkUserAccess(AuthenticatedUser currentUser, + Integer affectedUserID, String permissionType) { // A system administrator has full access to everything. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return true; // Check existence of requested permission UserPermissionExample example = new UserPermissionExample(); - example.createCriteria().andUser_idEqualTo(userID).andAffected_user_idEqualTo(affectedUserID).andPermissionEqualTo(permissionType); + example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andAffected_user_idEqualTo(affectedUserID).andPermissionEqualTo(permissionType); return userPermissionDAO.countByExample(example) > 0; } @@ -202,21 +235,29 @@ public class PermissionCheckService { * Checks whether a user has the specified type of access to the affected * connection. * - * @param userID The ID of the user to check. - * @param affectedConnectionID The connection that would be affected by the - * operation if permission is granted. - * @param permissionType The type of permission to check for. - * @return true if the specified permission is granted, false otherwise. + * @param currentUser + * The user to check. + * + * @param affectedConnectionID + * The connection that would be affected by the operation if permission + * is granted. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * true if the specified permission is granted, false otherwise. */ - public boolean checkConnectionAccess(int userID, Integer affectedConnectionID, String permissionType) { + public boolean checkConnectionAccess(AuthenticatedUser currentUser, + Integer affectedConnectionID, String permissionType) { // A system administrator has full access to everything. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return true; // Check existence of requested permission ConnectionPermissionExample example = new ConnectionPermissionExample(); - example.createCriteria().andUser_idEqualTo(userID).andConnection_idEqualTo(affectedConnectionID).andPermissionEqualTo(permissionType); + example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andConnection_idEqualTo(affectedConnectionID).andPermissionEqualTo(permissionType); return connectionPermissionDAO.countByExample(example) > 0; } @@ -225,13 +266,21 @@ public class PermissionCheckService { * Checks whether a user has the specified type of access to the affected * connection group. * - * @param userID The ID of the user to check. - * @param affectedConnectionGroupID The connection group that would be affected by the - * operation if permission is granted. - * @param permissionType The type of permission to check for. - * @return true if the specified permission is granted, false otherwise. + * @param currentUser + * The user to check. + * + * @param affectedConnectionGroupID + * The connection group that would be affected by the operation if + * permission is granted. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * true if the specified permission is granted, false otherwise. */ - public boolean checkConnectionGroupAccess(int userID, Integer affectedConnectionGroupID, String permissionType) { + public boolean checkConnectionGroupAccess(AuthenticatedUser currentUser, + Integer affectedConnectionGroupID, String permissionType) { // All users have implicit permission to read and update the root connection group if(affectedConnectionGroupID == null && @@ -240,12 +289,12 @@ public class PermissionCheckService { return true; // A system administrator has full access to everything. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return true; // Check existence of requested permission ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample(); - example.createCriteria().andUser_idEqualTo(userID).andConnection_group_idEqualTo(affectedConnectionGroupID).andPermissionEqualTo(permissionType); + example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andConnection_group_idEqualTo(affectedConnectionGroupID).andPermissionEqualTo(permissionType); return connectionGroupPermissionDAO.countByExample(example) > 0; } @@ -253,19 +302,24 @@ public class PermissionCheckService { /** * Checks whether a user has the specified type of access to the system. * - * @param userID The ID of the user to check. - * @param systemPermissionType The type of permission to check for. - * @return true if the specified permission is granted, false otherwise. + * @param currentUser + * The user to check. + * + * @param systemPermissionType + * The type of permission to check for. + * + * @return + * true if the specified permission is granted, false otherwise. */ - private boolean checkSystemAccess(int userID, String systemPermissionType) { + private boolean checkSystemAccess(AuthenticatedUser currentUser, String systemPermissionType) { // A system administrator has full access to everything. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return true; // Check existence of requested permission SystemPermissionExample example = new SystemPermissionExample(); - example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(systemPermissionType); + example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andPermissionEqualTo(systemPermissionType); return systemPermissionDAO.countByExample(example) > 0; } @@ -273,15 +327,18 @@ public class PermissionCheckService { /** * 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. + * @param currentUser + * The user to check. + * + * @return + * true if the system administrator access exists, false otherwise. */ - private boolean checkSystemAdministratorAccess(int userID) { + private boolean checkSystemAdministratorAccess(AuthenticatedUser currentUser) { // Check existence of system administrator permission SystemPermissionExample example = new SystemPermissionExample(); - example.createCriteria().andUser_idEqualTo(userID). - andPermissionEqualTo(MySQLConstants.SYSTEM_ADMINISTER); + example.createCriteria().andUser_idEqualTo(currentUser.getUserID()) + .andPermissionEqualTo(MySQLConstants.SYSTEM_ADMINISTER); return systemPermissionDAO.countByExample(example) > 0; } @@ -289,46 +346,61 @@ public class PermissionCheckService { * Verifies that the specified group can be used for organization * by the given user. * - * @param connectionGroupID The ID of the affected ConnectionGroup. - * @param userID The ID of the user to check. - * @throws GuacamoleSecurityException If the connection group - * cannot be used for organization. + * @param connectionGroupID + * The ID of the affected ConnectionGroup. + * + * @param currentUser + * The user to check. + * + * @param type + * The desired usage. + * + * @throws GuacamoleSecurityException + * If the connection group cannot be used for organization. */ public void verifyConnectionGroupUsageAccess(Integer connectionGroupID, - int userID, String type) throws GuacamoleSecurityException { + AuthenticatedUser currentUser, String type) throws GuacamoleSecurityException { // If permission does not exist, throw exception - if(!checkConnectionGroupUsageAccess(connectionGroupID, userID, type)) + if(!checkConnectionGroupUsageAccess(connectionGroupID, currentUser, type)) throw new GuacamoleSecurityException("Permission denied."); } /** * Check whether a user can use connectionGroup for the given usage. - * @param connectionGroupID the ID of the affected connection group. - * @param userID The ID of the user to check. - * @param usage The desired usage. - * @return true if the user can use the connection group for the given usage. + * + * @param connectionGroupID + * The ID of the affected connection group. + * + * @param currentUser + * The user to check. + * + * @param usage + * The desired usage. + * + * @return + * true if the user can use the connection group for the given usage. */ private boolean checkConnectionGroupUsageAccess( - Integer connectionGroupID, int userID, String usage) { + Integer connectionGroupID, AuthenticatedUser currentUser, String usage) { // The root level connection group can only be used for organization if(connectionGroupID == null) return MySQLConstants.CONNECTION_GROUP_ORGANIZATIONAL.equals(usage); // A system administrator has full access to everything. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return true; // A connection group administrator can use the group either way. - if(checkConnectionGroupAccess(userID, connectionGroupID, + if(checkConnectionGroupAccess(currentUser, connectionGroupID, MySQLConstants.CONNECTION_GROUP_ADMINISTER)) return true; // Query the connection group MySQLConnectionGroup connectionGroup = connectionGroupService. - retrieveConnectionGroup(connectionGroupID, userID); + retrieveConnectionGroup(connectionGroupID, currentUser); // If the connection group is not found, it cannot be used. if(connectionGroup == null) @@ -344,29 +416,34 @@ public class PermissionCheckService { * Find the list of the IDs of all users a user has permission to. * The access type is defined by permissionType. * - * @param userID The ID of the user to check. - * @param permissionType The type of permission to check for. - * @return A list of all user IDs this user has the specified access to. + * @param currentUser + * The user to check. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * A list of all user IDs this user has the specified access to. */ - public List retrieveUserIDs(int userID, String permissionType) { + public List retrieveUserIDs(AuthenticatedUser currentUser, String permissionType) { // A system administrator has access to all users. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return userService.getAllUserIDs(); // Query all user permissions for the given user and permission type UserPermissionExample example = new UserPermissionExample(); - example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType); + example.createCriteria().andUser_idEqualTo(currentUser.getUserID()).andPermissionEqualTo(permissionType); example.setDistinct(true); List userPermissions = userPermissionDAO.selectByExample(example); // Convert result into list of IDs - List userIDs = new ArrayList(userPermissions.size()); + List currentUsers = new ArrayList(userPermissions.size()); for(UserPermissionKey permission : userPermissions) - userIDs.add(permission.getAffected_user_id()); + currentUsers.add(permission.getAffected_user_id()); - return userIDs; + return currentUsers; } @@ -374,15 +451,19 @@ public class PermissionCheckService { * Find the list of the IDs of all connections a user has permission to. * The access type is defined by permissionType. * - * @param userID The ID of the user to check. - * @param permissionType The type of permission to check for. - * @return A list of all connection IDs this user has the specified access - * to. + * @param currentUser + * The user to check. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * A list of all connection IDs this user has the specified access to. */ - public List retrieveConnectionIDs(int userID, + public List retrieveConnectionIDs(AuthenticatedUser currentUser, String permissionType) { - return retrieveConnectionIDs(userID, null, permissionType, false); + return retrieveConnectionIDs(currentUser, null, permissionType, false); } @@ -390,16 +471,22 @@ public class PermissionCheckService { * Find the list of the IDs of all connections a user has permission to. * The access type is defined by permissionType. * - * @param userID The ID of the user to check. - * @param parentID the parent connection group. - * @param permissionType The type of permission to check for. - * @return A list of all connection IDs this user has the specified access - * to. + * @param currentUser + * The user to check. + * + * @param parentID + * The parent connection group. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * A list of all connection IDs this user has the specified access to. */ - public List retrieveConnectionIDs(int userID, Integer parentID, + public List retrieveConnectionIDs(AuthenticatedUser currentUser, Integer parentID, String permissionType) { - return retrieveConnectionIDs(userID, parentID, permissionType, true); + return retrieveConnectionIDs(currentUser, parentID, permissionType, true); } @@ -407,18 +494,26 @@ public class PermissionCheckService { * Find the list of the IDs of all connections a user has permission to. * The access type is defined by permissionType. * - * @param userID The ID of the user to check. - * @param parentID the parent connection group. - * @param permissionType The type of permission to check for. - * @param checkParentID Whether the parentID should be checked or not. - * @return A list of all connection IDs this user has the specified access - * to. + * @param currentUser + * The user to check. + * + * @param parentID + * The parent connection group. + * + * @param permissionType + * The type of permission to check for. + * + * @param checkParentID + * Whether the parentID should be checked or not. + * + * @return + * A list of all connection IDs this user has the specified access to. */ - private List retrieveConnectionIDs(int userID, Integer parentID, + private List retrieveConnectionIDs(AuthenticatedUser currentUser, Integer parentID, String permissionType, boolean checkParentID) { // A system administrator has access to all connections. - if(checkSystemAdministratorAccess(userID)) { + if(checkSystemAdministratorAccess(currentUser)) { if(checkParentID) return connectionService.getAllConnectionIDs(parentID); else @@ -427,7 +522,7 @@ public class PermissionCheckService { // Query all connection permissions for the given user and permission type ConnectionPermissionExample example = new ConnectionPermissionExample(); - Criteria criteria = example.createCriteria().andUser_idEqualTo(userID) + Criteria criteria = example.createCriteria().andUser_idEqualTo(currentUser.getUserID()) .andPermissionEqualTo(permissionType); // Ensure that the connections are all under the parent ID, if needed @@ -458,15 +553,20 @@ public class PermissionCheckService { * Find the list of the IDs of all connection groups a user has permission to. * The access type is defined by permissionType. * - * @param userID The ID of the user to check. - * @param permissionType The type of permission to check for. - * @return A list of all connection group IDs this user has the specified access - * to. + * @param currentUser + * The user to check. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * A list of all connection group IDs this user has the specified + * access to. */ - public List retrieveConnectionGroupIDs(int userID, + public List retrieveConnectionGroupIDs(AuthenticatedUser currentUser, String permissionType) { - return retrieveConnectionGroupIDs(userID, null, permissionType, false); + return retrieveConnectionGroupIDs(currentUser, null, permissionType, false); } @@ -474,16 +574,23 @@ public class PermissionCheckService { * Find the list of the IDs of all connection groups a user has permission to. * The access type is defined by permissionType. * - * @param userID The ID of the user to check. - * @param parentID the parent connection group. - * @param permissionType The type of permission to check for. - * @return A list of all connection group IDs this user has the specified access - * to. + * @param currentUser + * The user to check. + * + * @param parentID + * The parent connection group. + * + * @param permissionType + * The type of permission to check for. + * + * @return + * A list of all connection group IDs this user has the specified + * access to. */ - public List retrieveConnectionGroupIDs(int userID, Integer parentID, + public List retrieveConnectionGroupIDs(AuthenticatedUser currentUser, Integer parentID, String permissionType) { - return retrieveConnectionGroupIDs(userID, parentID, permissionType, true); + return retrieveConnectionGroupIDs(currentUser, parentID, permissionType, true); } @@ -491,18 +598,27 @@ public class PermissionCheckService { * Find the list of the IDs of all connection groups a user has permission to. * The access type is defined by permissionType. * - * @param userID The ID of the user to check. - * @param parentID the parent connection group. - * @param permissionType The type of permission to check for. - * @param checkParentID Whether the parentID should be checked or not. - * @return A list of all connection group IDs this user has the specified access - * to. + * @param currentUser + * The user to check. + * + * @param parentID + * The parent connection group. + * + * @param permissionType + * The type of permission to check for. + * + * @param checkParentID + * Whether the parentID should be checked or not. + * + * @return + * A list of all connection group IDs this user has the specified + * access to. */ - private List retrieveConnectionGroupIDs(int userID, Integer parentID, + private List retrieveConnectionGroupIDs(AuthenticatedUser currentUser, Integer parentID, String permissionType, boolean checkParentID) { // A system administrator has access to all connectionGroups . - if(checkSystemAdministratorAccess(userID)) { + if(checkSystemAdministratorAccess(currentUser)) { if(checkParentID) return connectionGroupService.getAllConnectionGroupIDs(parentID); else @@ -512,7 +628,7 @@ public class PermissionCheckService { // Query all connection permissions for the given user and permission type ConnectionGroupPermissionExample example = new ConnectionGroupPermissionExample(); ConnectionGroupPermissionExample.Criteria criteria = - example.createCriteria().andUser_idEqualTo(userID) + example.createCriteria().andUser_idEqualTo(currentUser.getUserID()) .andPermissionEqualTo(permissionType); // Ensure that the connection groups are all under the parent ID, if needed @@ -550,23 +666,28 @@ public class PermissionCheckService { * Retrieve all existing usernames that the given user has permission to * perform the given operation upon. * - * @param userID The user whose permissions should be checked. - * @param permissionType The permission to check. - * @return A set of all usernames for which the given user has the given - * permission. + * @param currentUser + * The user whose permissions should be checked. + * + * @param permissionType + * The permission to check. + * + * @return + * A set of all usernames for which the given user has the given + * permission. */ - public Set retrieveUsernames(int userID, String permissionType) { + public Set retrieveUsernames(AuthenticatedUser currentUser, String permissionType) { // A system administrator has access to all users. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return userService.getAllUsernames(); // List of all user IDs for which this user has read access - List userIDs = - retrieveUserIDs(userID, MySQLConstants.USER_READ); + List currentUsers = + retrieveUserIDs(currentUser, MySQLConstants.USER_READ); // Query all associated users - return userService.translateUsernames(userIDs).keySet(); + return userService.translateUsernames(currentUsers).keySet(); } @@ -574,22 +695,29 @@ public class PermissionCheckService { * Retrieve all existing connection identifiers that the given user has * permission to perform the given operation upon. * - * @param userID The user whose permissions should be checked. - * @param permissionType The permission to check. - * @param parentID The parent connection group. - * @return A set of all connection identifiers for which the given user - * has the given permission. + * @param currentUser + * The user whose permissions should be checked. + * + * @param permissionType + * The permission to check. + * + * @param parentID + * The parent connection group. + * + * @return + * A set of all connection identifiers for which the given user has the + * given permission. */ - public Set retrieveConnectionIdentifiers(int userID, Integer parentID, + public Set retrieveConnectionIdentifiers(AuthenticatedUser currentUser, Integer parentID, String permissionType) { // A system administrator has access to all connections. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return connectionService.getAllConnectionIdentifiers(parentID); // List of all connection IDs for which this user has access List connectionIDs = - retrieveConnectionIDs(userID, parentID, permissionType); + retrieveConnectionIDs(currentUser, parentID, permissionType); // Unique Identifiers for MySQLConnections are the database IDs Set connectionIdentifiers = new HashSet(); @@ -604,22 +732,29 @@ public class PermissionCheckService { * Retrieve all existing connection group identifiers that the given user * has permission to perform the given operation upon. * - * @param userID The user whose permissions should be checked. - * @param permissionType The permission to check. - * @param parentID The parent connection group. - * @return A set of all connection group identifiers for which the given - * user has the given permission. + * @param currentUser + * The user whose permissions should be checked. + * + * @param permissionType + * The permission to check. + * + * @param parentID + * The parent connection group. + * + * @return + * A set of all connection group identifiers for which the given user + * has the given permission. */ - public Set retrieveConnectionGroupIdentifiers(int userID, Integer parentID, + public Set retrieveConnectionGroupIdentifiers(AuthenticatedUser currentUser, Integer parentID, String permissionType) { // A system administrator has access to all connections. - if(checkSystemAdministratorAccess(userID)) + if(checkSystemAdministratorAccess(currentUser)) return connectionGroupService.getAllConnectionGroupIdentifiers(parentID); // List of all connection group IDs for which this user has access List connectionGroupIDs = - retrieveConnectionGroupIDs(userID, parentID, permissionType); + retrieveConnectionGroupIDs(currentUser, parentID, permissionType); // Unique Identifiers for MySQLConnectionGroups are the database IDs Set connectionGroupIdentifiers = new HashSet();