GUAC-1101: Modify base interfaces/classes to support permissions.

This commit is contained in:
Michael Jumper
2015-02-12 20:48:57 -08:00
parent d3d5fef1e7
commit b514fc910d
5 changed files with 95 additions and 38 deletions

View File

@@ -25,17 +25,16 @@ package net.sourceforge.guacamole.net.auth.mysql;
import org.glyptodon.guacamole.net.auth.Credentials; import org.glyptodon.guacamole.net.auth.Credentials;
/** /**
* Represents an authenticated user via their database ID and corresponding * Associates a user with the credentials they used to authenticate.
* credentials.
* *
* @author Michael Jumper * @author Michael Jumper
*/ */
public class AuthenticatedUser { public class AuthenticatedUser {
/** /**
* The database ID of this user. * The user that authenticated.
*/ */
private final int userID; private final MySQLUser user;
/** /**
* The credentials given when this user authenticated. * The credentials given when this user authenticated.
@@ -43,28 +42,28 @@ public class AuthenticatedUser {
private final Credentials credentials; private final Credentials credentials;
/** /**
* Creates a new AuthenticatedUser associated with the given database ID * Creates a new AuthenticatedUser associating the given user with their
* and credentials. * corresponding credentials.
* *
* @param userID * @param user
* The database ID of the user this object should represent. * The user this object should represent.
* *
* @param credentials * @param credentials
* The credentials given by the user when they authenticated. * The credentials given by the user when they authenticated.
*/ */
public AuthenticatedUser(int userID, Credentials credentials) { public AuthenticatedUser(MySQLUser user, Credentials credentials) {
this.userID = userID; this.user = user;
this.credentials = credentials; this.credentials = credentials;
} }
/** /**
* Returns the ID of this user. * Returns the user that authenticated.
* *
* @return * @return
* The ID of this user. * The user that authenticated.
*/ */
public int getUserID() { public MySQLUser getUser() {
return userID; return user;
} }
/** /**

View File

@@ -66,12 +66,15 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider {
// Get user service // Get user service
UserService userService = injector.getInstance(UserService.class); UserService userService = injector.getInstance(UserService.class);
// Get user // Authenticate user
MySQLUser user = userService.retrieveUser(credentials); MySQLUser user = userService.retrieveUser(credentials);
if (user != null) { if (user != null) {
// Upon successful authentication, return new user context
MySQLUserContext context = injector.getInstance(MySQLUserContext.class); MySQLUserContext context = injector.getInstance(MySQLUserContext.class);
context.init(user); context.init(new AuthenticatedUser(user, credentials));
return context; return context;
} }
// Otherwise, unauthorized // Otherwise, unauthorized

View File

@@ -43,7 +43,7 @@ public class MySQLUserContext implements UserContext {
/** /**
* The the user owning this context. * The the user owning this context.
*/ */
private MySQLUser currentUser; private AuthenticatedUser currentUser;
/** /**
* User directory restricted by the permissions of the user associated * User directory restricted by the permissions of the user associated
@@ -58,13 +58,14 @@ public class MySQLUserContext implements UserContext {
* @param currentUser * @param currentUser
* The user owning this context. * The user owning this context.
*/ */
public void init(MySQLUser currentUser) { public void init(AuthenticatedUser currentUser) {
this.currentUser = currentUser; this.currentUser = currentUser;
userDirectory.init(currentUser);
} }
@Override @Override
public User self() { public User self() {
return currentUser; return currentUser.getUser();
} }
@Override @Override

View File

@@ -42,12 +42,29 @@ import org.mybatis.guice.transactional.Transactional;
*/ */
public class UserDirectory implements Directory<String, User> { public class UserDirectory implements Directory<String, User> {
/**
* The user this user directory belongs to. Access is based on his/her
* permission settings.
*/
private AuthenticatedUser currentUser;
/** /**
* Service for managing user objects. * Service for managing user objects.
*/ */
@Inject @Inject
private UserService userService; private UserService userService;
/**
* Set the user for this directory.
*
* @param currentUser
* The user whose permissions define the visibility of other users in
* this directory.
*/
public void init(AuthenticatedUser currentUser) {
this.currentUser = currentUser;
}
@Override @Override
public void move(String identifier, Directory<String, User> groupIdentifier) public void move(String identifier, Directory<String, User> groupIdentifier)
throws GuacamoleException { throws GuacamoleException {
@@ -56,43 +73,40 @@ public class UserDirectory implements Directory<String, User> {
@Override @Override
public User get(String identifier) throws GuacamoleException { public User get(String identifier) throws GuacamoleException {
return userService.retrieveObject(identifier); return userService.retrieveObject(currentUser, identifier);
} }
@Override @Override
@Transactional @Transactional
public Collection<User> getAll(Collection<String> identifiers) throws GuacamoleException { public Collection<User> getAll(Collection<String> identifiers) throws GuacamoleException {
return Collections.<User>unmodifiableCollection(userService.retrieveObjects(identifiers)); Collection<MySQLUser> objects = userService.retrieveObjects(currentUser, identifiers);
return Collections.<User>unmodifiableCollection(objects);
} }
@Override @Override
@Transactional @Transactional
public Set<String> getIdentifiers() throws GuacamoleException { public Set<String> getIdentifiers() throws GuacamoleException {
// STUB return userService.getIdentifiers(currentUser);
return userService.getIdentifiers();
} }
@Override @Override
@Transactional @Transactional
public void add(User object) throws GuacamoleException { public void add(User object) throws GuacamoleException {
// STUB
MySQLUser user = (MySQLUser) object; MySQLUser user = (MySQLUser) object;
userService.createObject(user); userService.createObject(currentUser, user);
} }
@Override @Override
@Transactional @Transactional
public void update(User object) throws GuacamoleException { public void update(User object) throws GuacamoleException {
// STUB
MySQLUser user = (MySQLUser) object; MySQLUser user = (MySQLUser) object;
userService.updateObject(user); userService.updateObject(currentUser, user);
} }
@Override @Override
@Transactional @Transactional
public void remove(String identifier) throws GuacamoleException { public void remove(String identifier) throws GuacamoleException {
// STUB userService.deleteObject(currentUser, identifier);
userService.deleteObject(identifier);
} }
} }

View File

@@ -26,8 +26,10 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import net.sourceforge.guacamole.net.auth.mysql.AuthenticatedUser;
import net.sourceforge.guacamole.net.auth.mysql.DirectoryObject; import net.sourceforge.guacamole.net.auth.mysql.DirectoryObject;
import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper; import net.sourceforge.guacamole.net.auth.mysql.dao.DirectoryObjectMapper;
import org.glyptodon.guacamole.GuacamoleException;
/** /**
* Service which provides convenience methods for creating, retrieving, and * Service which provides convenience methods for creating, retrieving, and
@@ -89,7 +91,11 @@ public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<
} }
/** /**
* Retrieves the single object that has the given identifier, if it exists. * Retrieves the single object that has the given identifier, if it exists
* and the user has permission to read it.
*
* @param user
* The user retrieving the object.
* *
* @param identifier * @param identifier
* The identifier of the object to retrieve. * The identifier of the object to retrieve.
@@ -98,10 +104,11 @@ public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<
* The object having the given identifier, or null if no such object * The object having the given identifier, or null if no such object
* exists. * exists.
*/ */
public ObjectType retrieveObject(String identifier) { public ObjectType retrieveObject(AuthenticatedUser user,
String identifier) {
// Pull objects having given identifier // Pull objects having given identifier
Collection<ObjectType> objects = retrieveObjects(Collections.singleton(identifier)); Collection<ObjectType> objects = retrieveObjects(user, Collections.singleton(identifier));
// If no such object, return null // If no such object, return null
if (objects.isEmpty()) if (objects.isEmpty())
@@ -118,6 +125,10 @@ public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<
/** /**
* Retrieves all objects that have the identifiers in the given collection. * Retrieves all objects that have the identifiers in the given collection.
* Only objects that the user has permission to read will be returned.
*
* @param user
* The user retrieving the objects.
* *
* @param identifiers * @param identifiers
* The identifiers of the objects to retrieve. * The identifiers of the objects to retrieve.
@@ -125,7 +136,8 @@ public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<
* @return * @return
* The objects having the given identifiers. * The objects having the given identifiers.
*/ */
public Collection<ObjectType> retrieveObjects(Collection<String> identifiers) { public Collection<ObjectType> retrieveObjects(AuthenticatedUser user,
Collection<String> identifiers) {
// Do not query if no identifiers given // Do not query if no identifiers given
if (identifiers.isEmpty()) if (identifiers.isEmpty())
@@ -141,10 +153,18 @@ public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<
* exists, an error will be thrown. The internal model object will be * exists, an error will be thrown. The internal model object will be
* updated appropriately to contain the new database ID. * updated appropriately to contain the new database ID.
* *
* @param user
* The user creating the object.
*
* @param object * @param object
* The object to create. * The object to create.
*
* @throws GuacamoleException
* If the user lacks permission to create the object, or an error
* occurs while creating the object.
*/ */
public void createObject(ObjectType object) { public void createObject(AuthenticatedUser user, ObjectType object)
throws GuacamoleException {
getObjectMapper().insert(object.getModel()); getObjectMapper().insert(object.getModel());
} }
@@ -152,10 +172,18 @@ public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<
* Deletes the object having the given identifier. If no such object * Deletes the object having the given identifier. If no such object
* exists, this function has no effect. * exists, this function has no effect.
* *
* @param user
* The user deleting the object.
*
* @param identifier * @param identifier
* The identifier of the object to delete. * The identifier of the object to delete.
*
* @throws GuacamoleException
* If the user lacks permission to delete the object, or an error
* occurs while deleting the object.
*/ */
public void deleteObject(String identifier) { public void deleteObject(AuthenticatedUser user, String identifier)
throws GuacamoleException {
getObjectMapper().delete(identifier); getObjectMapper().delete(identifier);
} }
@@ -163,20 +191,32 @@ public abstract class DirectoryObjectService<ObjectType extends DirectoryObject<
* Updates the given object in the database, applying any changes that have * Updates the given object in the database, applying any changes that have
* been made. If no such object exists, this function has no effect. * been made. If no such object exists, this function has no effect.
* *
* @param user
* The user updating the object.
*
* @param object * @param object
* The object to update. * The object to update.
*
* @throws GuacamoleException
* If the user lacks permission to update the object, or an error
* occurs while updating the object.
*/ */
public void updateObject(ObjectType object) { public void updateObject(AuthenticatedUser user, ObjectType object)
throws GuacamoleException {
getObjectMapper().update(object.getModel()); getObjectMapper().update(object.getModel());
} }
/** /**
* Returns the set of all identifiers for all objects in the database. * Returns the set of all identifiers for all objects in the database that
* the user has read access to.
*
* @param user
* The user retrieving the identifiers.
* *
* @return * @return
* The set of all identifiers for all objects in the database. * The set of all identifiers for all objects in the database.
*/ */
public Set<String> getIdentifiers() { public Set<String> getIdentifiers(AuthenticatedUser user) {
return getObjectMapper().selectIdentifiers(); return getObjectMapper().selectIdentifiers();
} }