Ticket #269: Added administrate permission checking.

This commit is contained in:
James Muehlner
2013-02-15 01:11:50 -08:00
parent 66fdcbe0b1
commit e6e9200f98
4 changed files with 168 additions and 35 deletions

View File

@@ -32,6 +32,22 @@ public class MySQLConnection implements Connection {
connection = new net.sourceforge.guacamole.net.auth.mysql.model.Connection();
}
/**
* Get the ID of the underlying connection record.
* @return the ID of the underlying connection
*/
public int getConnectionID() {
return connection.getConnection_id();
}
/**
* Get the underlying connection database record.
* @return the underlying connection record.
*/
public net.sourceforge.guacamole.net.auth.mysql.model.Connection getConnection() {
return connection;
}
/**
* Load an existing connection by name.
* @param connectionName
@@ -82,4 +98,10 @@ public class MySQLConnection implements Connection {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean equals(Object other) {
if(!(other instanceof MySQLConnection))
return false;
return ((MySQLConnection)other).getConnectionID() == this.getConnectionID();
}
}

View File

@@ -202,4 +202,11 @@ public class MySQLUser implements User {
public void removePermission(Permission permission) throws GuacamoleException {
permissions.remove(permission);
}
@Override
public boolean equals(Object other) {
if(!(other instanceof MySQLUser))
return false;
return ((MySQLUser)other).getUserID() == this.getUserID();
}
}

View File

@@ -155,7 +155,7 @@ public class UserDirectory implements Directory<String, User> {
@Override
public Set<String> getIdentifiers() throws GuacamoleException {
Set<String> userNameSet = new HashSet<String>();
List<MySQLUser> users = permissionCheckUtility.getReadableUsers(user.getUserID());
Set<MySQLUser> users = permissionCheckUtility.getReadableUsers(user.getUserID());
for(MySQLUser mySQLUser : users) {
userNameSet.add(mySQLUser.getUsername());
}
@@ -189,6 +189,11 @@ public class UserDirectory implements Directory<String, User> {
List<ConnectionPermission> connectionPermissions = new ArrayList<ConnectionPermission>();
List<SystemPermission> systemPermissions = new ArrayList<SystemPermission>();
// Get the list of all the users and connections that the user performing the user save action has.
// Need to make sure the user saving this user has permission to administrate all the objects in the permission list.
Set<Integer> administerableUsers = permissionCheckUtility.getAdministerableUserIDs(this.user.getUserID());
Set<Integer> administerableConnections = permissionCheckUtility.getAdministerableConnectionIDs(this.user.getUserID());
for(Permission permission : user.getPermissions()) {
if(permission instanceof UserPermission)
userPermissions.add((UserPermission)permission);
@@ -198,8 +203,8 @@ public class UserDirectory implements Directory<String, User> {
systemPermissions.add((SystemPermission)permission);
}
updateUserPermissions(userPermissions, user);
updateConnectionPermissions(connectionPermissions, user);
updateUserPermissions(userPermissions, user, administerableUsers);
updateConnectionPermissions(connectionPermissions, user, administerableConnections);
updateSystemPermissions(systemPermissions, user);
}
@@ -208,7 +213,7 @@ public class UserDirectory implements Directory<String, User> {
* @param permissions
* @param user
*/
private void updateUserPermissions(Iterable<UserPermission> permissions, MySQLUser user) throws GuacamoleException {
private void updateUserPermissions(Iterable<UserPermission> permissions, MySQLUser user, Set<Integer> administerableUsers) throws GuacamoleException {
List<String> usernames = new ArrayList<String>();
for(UserPermission permission : permissions) {
@@ -239,6 +244,14 @@ public class UserDirectory implements Directory<String, User> {
// delete any permissions that are not in the provided list
userPermissionExample.clear();
userPermissionExample.createCriteria().andAffected_user_idNotIn(userIDs);
List<UserPermissionKey> permissionsToDelete = userPermissionDAO.selectByExample(userPermissionExample);
// verify that the user actually has permission to administrate every one of these users
for(UserPermissionKey permissionToDelete : permissionsToDelete) {
if(!administerableUsers.contains(permissionToDelete.getAffected_user_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate user " + permissionToDelete.getAffected_user_id());
}
userPermissionDAO.deleteByExample(userPermissionExample);
// finally, insert the new permissions
@@ -251,6 +264,11 @@ public class UserDirectory implements Directory<String, User> {
if(existingUserIDs.contains(dbAffectedUser.getUser_id()))
continue;
// verify that the user actually has permission to administrate every one of these users
if(!administerableUsers.contains(dbAffectedUser.getUser_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate user " + dbAffectedUser.getUser_id());
UserPermissionKey newPermission = new UserPermissionKey();
newPermission.setAffected_user_id(dbAffectedUser.getUser_id());
newPermission.setPermission(permission.getType().name());
@@ -264,7 +282,7 @@ public class UserDirectory implements Directory<String, User> {
* @param permissions
* @param user
*/
private void updateConnectionPermissions(Iterable<ConnectionPermission> permissions, MySQLUser user) throws GuacamoleException {
private void updateConnectionPermissions(Iterable<ConnectionPermission> permissions, MySQLUser user, Set<Integer> administerableConnections) throws GuacamoleException {
List<String> connectionnames = new ArrayList<String>();
for(ConnectionPermission permission : permissions) {
@@ -295,6 +313,15 @@ public class UserDirectory implements Directory<String, User> {
// delete any permissions that are not in the provided list
connectionPermissionExample.clear();
connectionPermissionExample.createCriteria().andConnection_idNotIn(connectionIDs);
//make sure the user has permission to administrate each of these connections
List<ConnectionPermissionKey> connectionPermissionsToDelete = connectionPermissionDAO.selectByExample(connectionPermissionExample);
for(ConnectionPermissionKey connectionPermissionToDelete : connectionPermissionsToDelete) {
if(!administerableConnections.contains(connectionPermissionToDelete.getConnection_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate connection " + connectionPermissionToDelete.getConnection_id());
}
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
// finally, insert the new permissions
@@ -307,6 +334,10 @@ public class UserDirectory implements Directory<String, User> {
if(existingConnectionIDs.contains(dbConnection.getConnection_id()))
continue;
if(!administerableConnections.contains(dbConnection.getConnection_id()))
throw new GuacamolePermissionException("User '" + this.user.getUsername() + "' does not have permission to administrate connection " + dbConnection.getConnection_id());
ConnectionPermissionKey newPermission = new ConnectionPermissionKey();
newPermission.setConnection_id(dbConnection.getConnection_id());
newPermission.setPermission(permission.getType().name());

View File

@@ -35,6 +35,7 @@
* ***** END LICENSE BLOCK ***** */
package net.sourceforge.guacamole.net.auth.mysql.utility;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.ArrayList;
@@ -294,12 +295,48 @@ public class PermissionCheckUtility {
return count > 0;
}
/**
* Find the list of all user IDs a user has permission to administer.
* @param userID
* @return the list of all user IDs this user has administer access to
*/
public Set<Integer> getAdministerableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_ADMINISTER);
}
/**
* Find the list of all user IDs a user has permission to delete.
* @param userID
* @return the list of all user IDs this user has delete access to
*/
public Set<Integer> getDeletableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_DELETE);
}
/**
* Find the list of all user IDs a user has permission to write.
* @param userID
* @return the list of all user IDs this user has write access to
*/
public Set<Integer> getUpdateableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_UPDATE);
}
/**
* Find the list of all user IDs a user has permission to read.
* @param userID
* @return the list of all user IDs this user has read access to
*/
public Set<Integer> getReadableUserIDs(int userID) {
return getUserIDs(userID, MySQLConstants.USER_READ);
}
/**
* Find the list of all users a user has permission to administer.
* @param userID
* @return the list of all users this user has administer access to
*/
public List<MySQLUser> getAdministerableUsers(int userID) {
public Set<MySQLUser> getAdministerableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_ADMINISTER);
}
@@ -308,7 +345,7 @@ public class PermissionCheckUtility {
* @param userID
* @return the list of all users this user has delete access to
*/
public List<MySQLUser> getDeletableUsers(int userID) {
public Set<MySQLUser> getDeletableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_DELETE);
}
@@ -317,7 +354,7 @@ public class PermissionCheckUtility {
* @param userID
* @return the list of all users this user has write access to
*/
public List<MySQLUser> getUpdateableUsers(int userID) {
public Set<MySQLUser> getUpdateableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_UPDATE);
}
@@ -326,7 +363,7 @@ public class PermissionCheckUtility {
* @param userID
* @return the list of all users this user read has access to
*/
public List<MySQLUser> getReadableUsers(int userID) {
public Set<MySQLUser> getReadableUsers(int userID) {
return getUsers(userID, MySQLConstants.USER_READ);
}
@@ -337,12 +374,12 @@ public class PermissionCheckUtility {
* @param permissionType
* @return the list of all users this user has access to
*/
private List<MySQLUser> getUsers(int userID, String permissionType) {
List<Integer> affectedUserIDs = getUserIDs(userID, permissionType);
private Set<MySQLUser> getUsers(int userID, String permissionType) {
Set<Integer> affectedUserIDs = getUserIDs(userID, permissionType);
UserExample example = new UserExample();
example.createCriteria().andUser_idIn(affectedUserIDs);
example.createCriteria().andUser_idIn(Lists.newArrayList(affectedUserIDs));
List<UserWithBLOBs> userDBOjects = userDAO.selectByExampleWithBLOBs(example);
List<MySQLUser> affectedUsers = new ArrayList<MySQLUser>();
Set<MySQLUser> affectedUsers = new HashSet<MySQLUser>();
for(UserWithBLOBs affectedUser : userDBOjects) {
MySQLUser mySQLUser = mySQLUserProvider.get();
mySQLUser.init(affectedUser);
@@ -359,8 +396,8 @@ public class PermissionCheckUtility {
* @param permissionType
* @return the list of all user IDs this user has access to
*/
private List<Integer> getUserIDs(int userID, String permissionType) {
List<Integer> userIDs = new ArrayList<Integer>();
private Set<Integer> getUserIDs(int userID, String permissionType) {
Set<Integer> userIDs = new HashSet<Integer>();
UserPermissionExample example = new UserPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType);
List<UserPermissionKey> userPermissions = userPermissionDAO.selectByExample(example);
@@ -568,38 +605,74 @@ public class PermissionCheckUtility {
}
/**
* Find the list of all connections a user has permission to administer.
* @param connectionID
* @return the list of all connections this connection has administer access to
* Find the list of all connection IDs a user has permission to administer.
* @param userID
* @return the list of all connection IDs this user has administer access to
*/
public List<MySQLConnection> getAdministerableConnections(int userID) {
public Set<Integer> getAdministerableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_ADMINISTER);
}
/**
* Find the list of all connection IDs a user has permission to delete.
* @param userID
* @return the list of all connection IDs this user has delete access to
*/
public Set<Integer> getDeletableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_DELETE);
}
/**
* Find the list of all connection IDs a user has permission to write.
* @param userID
* @return the list of all connection IDs this user has write access to
*/
public Set<Integer> getUpdateableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_UPDATE);
}
/**
* Find the list of all connection IDs a user has permission to read.
* @param userID
* @return the list of all connection IDs this user has ready access to
*/
public Set<Integer> getReadableConnectionIDs(int userID) {
return getConnectionIDs(userID, MySQLConstants.CONNECTION_READ);
}
/**
* Find the list of all connections a user has permission to administer.
* @param userID
* @return the list of all connections this user has administer access to
*/
public Set<MySQLConnection> getAdministerableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_ADMINISTER);
}
/**
* Find the list of all connections a user has permission to delete.
* @param connectionID
* @return the list of all connections this connection has delete access to
* @param userID
* @return the list of all connections this user has delete access to
*/
public List<MySQLConnection> getDeletableConnections(int userID) {
public Set<MySQLConnection> getDeletableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_DELETE);
}
/**
* Find the list of all connections a user has permission to write.
* @param connectionID
* @return the list of all connections this connection has write access to
* @param userID
* @return the list of all connections this user has write access to
*/
public List<MySQLConnection> getUpdateableConnections(int userID) {
public Set<MySQLConnection> getUpdateableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_UPDATE);
}
/**
* Find the list of all connections a user has permission to read.
* @param connectionID
* @return the list of all connections this connection read has access to
* @param userID
* @return the list of all connections this user has read access to
*/
public List<MySQLConnection> getReadableConnections(int userID) {
public Set<MySQLConnection> getReadableConnections(int userID) {
return getConnections(userID, MySQLConstants.CONNECTION_READ);
}
@@ -610,12 +683,12 @@ public class PermissionCheckUtility {
* @param permissionType
* @return the list of all connections this user has access to
*/
private List<MySQLConnection> getConnections(int userID, String permissionType) {
List<Integer> affectedConnectionIDs = getConnectionIDs(userID, permissionType);
private Set<MySQLConnection> getConnections(int userID, String permissionType) {
Set<Integer> affectedConnectionIDs = getConnectionIDs(userID, permissionType);
ConnectionExample example = new ConnectionExample();
example.createCriteria().andConnection_idIn(affectedConnectionIDs);
example.createCriteria().andConnection_idIn(Lists.newArrayList(affectedConnectionIDs));
List<Connection> connectionDBOjects = connectionDAO.selectByExample(example);
List<MySQLConnection> affectedConnections = new ArrayList<MySQLConnection>();
Set<MySQLConnection> affectedConnections = new HashSet<MySQLConnection>();
for(Connection affectedConnection : connectionDBOjects) {
MySQLConnection mySQLConnection = mySQLConnectionProvider.get();
mySQLConnection.init(affectedConnection);
@@ -632,8 +705,8 @@ public class PermissionCheckUtility {
* @param permissionType
* @return the list of all connection IDs this user has access to
*/
private List<Integer> getConnectionIDs(int userID, String permissionType) {
List<Integer> connectionIDs = new ArrayList<Integer>();
private Set<Integer> getConnectionIDs(int userID, String permissionType) {
Set<Integer> connectionIDs = new HashSet<Integer>();
ConnectionPermissionExample example = new ConnectionPermissionExample();
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType);
List<ConnectionPermissionKey> connectionPermissions = connectionPermissionDAO.selectByExample(example);