GUAC-1101: Add permission check upon connect. Move connection stub into connection service. Add hasObjectPermission() utility function.

This commit is contained in:
Michael Jumper
2015-02-24 12:18:15 -08:00
parent ee3f817bbd
commit 925687fc90
3 changed files with 85 additions and 13 deletions

View File

@@ -22,11 +22,12 @@
package net.sourceforge.guacamole.net.auth.mysql;
import com.google.inject.Inject;
import java.util.Collections;
import java.util.List;
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionModel;
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.GuacamoleUnsupportedException;
import org.glyptodon.guacamole.net.GuacamoleSocket;
import org.glyptodon.guacamole.net.auth.Connection;
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
@@ -51,6 +52,12 @@ public class MySQLConnection implements Connection, DirectoryObject<ConnectionMo
*/
private ConnectionModel connectionModel;
/**
* Service for managing connections.
*/
@Inject
private ConnectionService connectionService;
/**
* Creates a new, empty MySQLConnection.
*/
@@ -156,8 +163,7 @@ public class MySQLConnection implements Connection, DirectoryObject<ConnectionMo
@Override
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
/* STUB */
throw new GuacamoleUnsupportedException("STUB - connecting not implemented at the moment");
return connectionService.connect(currentUser, this, info);
}
@Override

View File

@@ -32,10 +32,15 @@ import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper;
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionModel;
import org.glyptodon.guacamole.GuacamoleClientException;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.GuacamoleSecurityException;
import org.glyptodon.guacamole.GuacamoleUnsupportedException;
import org.glyptodon.guacamole.net.GuacamoleSocket;
import org.glyptodon.guacamole.net.auth.Connection;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
/**
* Service which provides convenience methods for creating, retrieving, and
@@ -157,4 +162,40 @@ public class ConnectionService extends DirectoryObjectService<MySQLConnection, C
}
/**
* Connects to the given connection as the given user, using the given
* client information. If the user does not have permission to read the
* connection, permission will be denied.
*
* @param user
* The user connecting to the connection.
*
* @param connection
* The connection being connected to.
*
* @param info
* Information associated with the connecting client.
*
* @return
* A connected GuacamoleSocket associated with a newly-established
* connection.
*
* @throws GuacamoleException
* If permission to connect to this connection is denied.
*/
public GuacamoleSocket connect(AuthenticatedUser user,
MySQLConnection connection, GuacamoleClientInformation info)
throws GuacamoleException {
// Connect only if READ permission is granted
if (hasObjectPermission(user, connection.getIdentifier(), ObjectPermission.Type.READ)) {
// STUB
throw new GuacamoleUnsupportedException("STUB - connecting not implemented at the moment");
}
// The user does not have permission to connect
throw new GuacamoleSecurityException("Permission denied.");
}
}

View File

@@ -114,6 +114,39 @@ public abstract class DirectoryObjectService<InternalType extends DirectoryObjec
protected abstract boolean hasCreatePermission(AuthenticatedUser user)
throws GuacamoleException;
/**
* Returns whether the given user has permission to perform a certain
* action on a specific object managed by this directory object service.
*
* @param user
* The user being checked.
*
* @param identifier
* The identifier of the object to check.
*
* @param type
* The type of action that will be performed.
*
* @return
* true if the user has object permission relevant described, false
* otherwise.
*
* @throws GuacamoleException
* If permission to read the user's permissions is denied.
*/
protected boolean hasObjectPermission(AuthenticatedUser user,
String identifier, ObjectPermission.Type type)
throws GuacamoleException {
// Get object permissions
ObjectPermissionSet permissionSet = getPermissionSet(user);
// Return whether permission is granted
return user.getUser().isAdministrator()
|| permissionSet.hasPermission(type, identifier);
}
/**
* Returns the permission set associated with the given user and related
* to the type of objects handled by this directory object service.
@@ -335,12 +368,8 @@ public abstract class DirectoryObjectService<InternalType extends DirectoryObjec
public void deleteObject(AuthenticatedUser user, String identifier)
throws GuacamoleException {
// Get object permissions
ObjectPermissionSet permissionSet = getPermissionSet(user);
// Only delete object if user has permission to do so
if (user.getUser().isAdministrator()
|| permissionSet.hasPermission(ObjectPermission.Type.DELETE, identifier)) {
if (hasObjectPermission(user, identifier, ObjectPermission.Type.DELETE)) {
getObjectMapper().delete(identifier);
return;
}
@@ -367,12 +396,8 @@ public abstract class DirectoryObjectService<InternalType extends DirectoryObjec
public void updateObject(AuthenticatedUser user, InternalType object)
throws GuacamoleException {
// Get object permissions
ObjectPermissionSet permissionSet = getPermissionSet(user);
// Only update object if user has permission to do so
if (user.getUser().isAdministrator()
|| permissionSet.hasPermission(ObjectPermission.Type.UPDATE, object.getIdentifier())) {
if (hasObjectPermission(user, object.getIdentifier(), ObjectPermission.Type.UPDATE)) {
// Validate object prior to creation
validateExistingObject(user, object);