From f9584bb59da95bc9adc23322f8f00603deca2448 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 20 Mar 2015 17:36:54 -0700 Subject: [PATCH] GUAC-1132: Split non-database permission service functions into interfaces. --- .../ConnectionGroupPermissionService.java | 2 +- .../ConnectionPermissionService.java | 2 +- .../ModeledObjectPermissionService.java | 210 ++++++++++++++++++ .../permission/ModeledPermissionService.java | 196 ++++++++++++++++ .../permission/ObjectPermissionService.java | 169 +------------- .../jdbc/permission/PermissionService.java | 153 +------------ .../permission/SystemPermissionService.java | 2 +- .../permission/UserPermissionService.java | 2 +- 8 files changed, 423 insertions(+), 313 deletions(-) create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledPermissionService.java diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionGroupPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionGroupPermissionService.java index e64d6c71f..b16078efe 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionGroupPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionGroupPermissionService.java @@ -35,7 +35,7 @@ import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser; * * @author Michael Jumper */ -public class ConnectionGroupPermissionService extends ObjectPermissionService { +public class ConnectionGroupPermissionService extends ModeledObjectPermissionService { /** * Mapper for connection group permissions. diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionPermissionService.java index 0903f71ab..d0bb6f7f9 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ConnectionPermissionService.java @@ -35,7 +35,7 @@ import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser; * * @author Michael Jumper */ -public class ConnectionPermissionService extends ObjectPermissionService { +public class ConnectionPermissionService extends ModeledObjectPermissionService { /** * Mapper for connection permissions. diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java new file mode 100644 index 000000000..ad4f65859 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java @@ -0,0 +1,210 @@ +/* + * 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 org.glyptodon.guacamole.auth.jdbc.permission; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser; +import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.GuacamoleSecurityException; +import org.glyptodon.guacamole.net.auth.permission.ObjectPermission; +import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; + +/** + * Service which provides convenience methods for creating, retrieving, and + * deleting object permissions within a backend database model. This service + * will automatically enforce the permissions of the current user. + * + * @author Michael Jumper + */ +public abstract class ModeledObjectPermissionService + extends ModeledPermissionService + implements ObjectPermissionService { + + @Override + protected abstract ObjectPermissionMapper getPermissionMapper(); + + @Override + protected ObjectPermission getPermissionInstance(ObjectPermissionModel model) { + return new ObjectPermission(model.getType(), model.getObjectIdentifier()); + } + + @Override + protected ObjectPermissionModel getModelInstance(ModeledUser targetUser, + ObjectPermission permission) { + + ObjectPermissionModel model = new ObjectPermissionModel(); + + // Populate model object with data from user and permission + model.setUserID(targetUser.getModel().getObjectID()); + model.setUsername(targetUser.getModel().getIdentifier()); + model.setType(permission.getType()); + model.setObjectIdentifier(permission.getObjectIdentifier()); + + return model; + + } + + /** + * Determines whether the current user has permission to update the given + * target user, adding or removing the given permissions. Such permission + * depends on whether the current user is a system administrator, whether + * they have explicit UPDATE permission on the target user, and whether + * they have explicit ADMINISTER permission on all affected objects. + * + * @param user + * The user who is changing permissions. + * + * @param targetUser + * The user whose permissions are being changed. + * + * @param permissions + * The permissions that are being added or removed from the target + * user. + * + * @return + * true if the user has permission to change the target users + * permissions as specified, false otherwise. + * + * @throws GuacamoleException + * If an error occurs while checking permission status, or if + * permission is denied to read the current user's permissions. + */ + protected boolean canAlterPermissions(AuthenticatedUser user, ModeledUser targetUser, + Collection permissions) + throws GuacamoleException { + + // A system adminstrator can do anything + if (user.getUser().isAdministrator()) + return true; + + // Verify user has update permission on the target user + ObjectPermissionSet userPermissionSet = user.getUser().getUserPermissions(); + if (!userPermissionSet.hasPermission(ObjectPermission.Type.UPDATE, targetUser.getIdentifier())) + return false; + + // Produce collection of affected identifiers + Collection affectedIdentifiers = new HashSet(permissions.size()); + for (ObjectPermission permission : permissions) + affectedIdentifiers.add(permission.getObjectIdentifier()); + + // Determine subset of affected identifiers that we have admin access to + ObjectPermissionSet affectedPermissionSet = getPermissionSet(user, user.getUser()); + Collection allowedSubset = affectedPermissionSet.getAccessibleObjects( + Collections.singleton(ObjectPermission.Type.ADMINISTER), + affectedIdentifiers + ); + + // The permissions can be altered if and only if the set of objects we + // are allowed to administer is equal to the set of objects we will be + // affecting. + + return affectedIdentifiers.size() == allowedSubset.size(); + + } + + @Override + public void createPermissions(AuthenticatedUser user, ModeledUser targetUser, + Collection permissions) + throws GuacamoleException { + + // Create permissions only if user has permission to do so + if (canAlterPermissions(user, targetUser, permissions)) { + Collection models = getModelInstances(targetUser, permissions); + getPermissionMapper().insert(models); + return; + } + + // User lacks permission to create object permissions + throw new GuacamoleSecurityException("Permission denied."); + + } + + @Override + public void deletePermissions(AuthenticatedUser user, ModeledUser targetUser, + Collection permissions) + throws GuacamoleException { + + // Delete permissions only if user has permission to do so + if (canAlterPermissions(user, targetUser, permissions)) { + Collection models = getModelInstances(targetUser, permissions); + getPermissionMapper().delete(models); + return; + } + + // User lacks permission to delete object permissions + throw new GuacamoleSecurityException("Permission denied."); + + } + + @Override + public ObjectPermission retrievePermission(AuthenticatedUser user, + ModeledUser targetUser, ObjectPermission.Type type, + String identifier) throws GuacamoleException { + + // Retrieve permissions only if allowed + if (canReadPermissions(user, targetUser)) { + + // Read permission from database, return null if not found + ObjectPermissionModel model = getPermissionMapper().selectOne(targetUser.getModel(), type, identifier); + if (model == null) + return null; + + return getPermissionInstance(model); + + } + + // User cannot read this user's permissions + throw new GuacamoleSecurityException("Permission denied."); + + } + + @Override + public Collection retrieveAccessibleIdentifiers(AuthenticatedUser user, + ModeledUser targetUser, Collection permissions, + Collection identifiers) throws GuacamoleException { + + // Nothing is always accessible + if (identifiers.isEmpty()) + return identifiers; + + // Retrieve permissions only if allowed + if (canReadPermissions(user, targetUser)) { + + // If user is an admin, everything is accessible + if (user.getUser().isAdministrator()) + return identifiers; + + // Otherwise, return explicitly-retrievable identifiers + return getPermissionMapper().selectAccessibleIdentifiers(targetUser.getModel(), permissions, identifiers); + + } + + // User cannot read this user's permissions + throw new GuacamoleSecurityException("Permission denied."); + + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledPermissionService.java new file mode 100644 index 000000000..25f4de718 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ModeledPermissionService.java @@ -0,0 +1,196 @@ +/* + * 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 org.glyptodon.guacamole.auth.jdbc.permission; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser; +import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.GuacamoleSecurityException; +import org.glyptodon.guacamole.net.auth.permission.ObjectPermission; +import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; +import org.glyptodon.guacamole.net.auth.permission.Permission; +import org.glyptodon.guacamole.net.auth.permission.PermissionSet; + +/** + * Service which provides convenience methods for creating, retrieving, and + * deleting permissions within a backend database model, and for obtaining the + * permission sets that contain these permissions. This service will + * automatically enforce the permissions of the current user. + * + * @author Michael Jumper + * @param + * The type of permission sets this service provides access to. + * + * @param + * The type of permission this service provides access to. + * + * @param + * The underlying model object used to represent PermissionType in the + * database. + */ +public abstract class ModeledPermissionService, + PermissionType extends Permission, ModelType> + implements PermissionService { + + /** + * Returns an instance of a mapper for the type of permission used by this + * service. + * + * @return + * A mapper which provides access to the model objects associated with + * the permissions used by this service. + */ + protected abstract PermissionMapper getPermissionMapper(); + + /** + * Returns an instance of a permission which is based on the given model + * object. + * + * @param model + * The model object to use to produce the returned permission. + * + * @return + * A permission which is based on the given model object. + */ + protected abstract PermissionType getPermissionInstance(ModelType model); + + /** + * Returns a collection of permissions which are based on the models in + * the given collection. + * + * @param models + * The model objects to use to produce the permissions within the + * returned set. + * + * @return + * A set of permissions which are based on the models in the given + * collection. + */ + protected Set getPermissionInstances(Collection models) { + + // Create new collection of permissions by manually converting each model + Set permissions = new HashSet(models.size()); + for (ModelType model : models) + permissions.add(getPermissionInstance(model)); + + return permissions; + + } + + /** + * Returns an instance of a model object which is based on the given + * permission and target user. + * + * @param targetUser + * The user to whom this permission is granted. + * + * @param permission + * The permission to use to produce the returned model object. + * + * @return + * A model object which is based on the given permission and target + * user. + */ + protected abstract ModelType getModelInstance(ModeledUser targetUser, + PermissionType permission); + + /** + * Returns a collection of model objects which are based on the given + * permissions and target user. + * + * @param targetUser + * The user to whom this permission is granted. + * + * @param permissions + * The permissions to use to produce the returned model objects. + * + * @return + * A collection of model objects which are based on the given + * permissions and target user. + */ + protected Collection getModelInstances(ModeledUser targetUser, + Collection permissions) { + + // Create new collection of models by manually converting each permission + Collection models = new ArrayList(permissions.size()); + for (PermissionType permission : permissions) + models.add(getModelInstance(targetUser, permission)); + + return models; + + } + + /** + * Determines whether the given user can read the permissions currently + * granted to the given target user. If the reading user and the target + * user are not the same, then explicit READ or SYSTEM_ADMINISTER access is + * required. + * + * @param user + * The user attempting to read permissions. + * + * @param targetUser + * The user whose permissions are being read. + * + * @return + * true if permission is granted, false otherwise. + * + * @throws GuacamoleException + * If an error occurs while checking permission status, or if + * permission is denied to read the current user's permissions. + */ + protected boolean canReadPermissions(AuthenticatedUser user, + ModeledUser targetUser) throws GuacamoleException { + + // A user can always read their own permissions + if (user.getUser().getIdentifier().equals(targetUser.getIdentifier())) + return true; + + // A system adminstrator can do anything + if (user.getUser().isAdministrator()) + return true; + + // Can read permissions on target user if explicit READ is granted + ObjectPermissionSet userPermissionSet = user.getUser().getUserPermissions(); + return userPermissionSet.hasPermission(ObjectPermission.Type.READ, targetUser.getIdentifier()); + + } + + @Override + public Set retrievePermissions(AuthenticatedUser user, + ModeledUser targetUser) throws GuacamoleException { + + // Retrieve permissions only if allowed + if (canReadPermissions(user, targetUser)) + return getPermissionInstances(getPermissionMapper().select(targetUser.getModel())); + + // User cannot read this user's permissions + throw new GuacamoleSecurityException("Permission denied."); + + } + +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ObjectPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ObjectPermissionService.java index 4e3beb0e1..04e66ad1d 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ObjectPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/ObjectPermissionService.java @@ -23,12 +23,9 @@ package org.glyptodon.guacamole.auth.jdbc.permission; import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser; import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser; import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.GuacamoleSecurityException; import org.glyptodon.guacamole.net.auth.permission.ObjectPermission; import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; @@ -39,124 +36,8 @@ import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; * * @author Michael Jumper */ -public abstract class ObjectPermissionService - extends PermissionService { - - @Override - protected abstract ObjectPermissionMapper getPermissionMapper(); - - @Override - protected ObjectPermission getPermissionInstance(ObjectPermissionModel model) { - return new ObjectPermission(model.getType(), model.getObjectIdentifier()); - } - - @Override - protected ObjectPermissionModel getModelInstance(ModeledUser targetUser, - ObjectPermission permission) { - - ObjectPermissionModel model = new ObjectPermissionModel(); - - // Populate model object with data from user and permission - model.setUserID(targetUser.getModel().getObjectID()); - model.setUsername(targetUser.getModel().getIdentifier()); - model.setType(permission.getType()); - model.setObjectIdentifier(permission.getObjectIdentifier()); - - return model; - - } - - /** - * Determines whether the current user has permission to update the given - * target user, adding or removing the given permissions. Such permission - * depends on whether the current user is a system administrator, whether - * they have explicit UPDATE permission on the target user, and whether - * they have explicit ADMINISTER permission on all affected objects. - * - * @param user - * The user who is changing permissions. - * - * @param targetUser - * The user whose permissions are being changed. - * - * @param permissions - * The permissions that are being added or removed from the target - * user. - * - * @return - * true if the user has permission to change the target users - * permissions as specified, false otherwise. - * - * @throws GuacamoleException - * If an error occurs while checking permission status, or if - * permission is denied to read the current user's permissions. - */ - protected boolean canAlterPermissions(AuthenticatedUser user, ModeledUser targetUser, - Collection permissions) - throws GuacamoleException { - - // A system adminstrator can do anything - if (user.getUser().isAdministrator()) - return true; - - // Verify user has update permission on the target user - ObjectPermissionSet userPermissionSet = user.getUser().getUserPermissions(); - if (!userPermissionSet.hasPermission(ObjectPermission.Type.UPDATE, targetUser.getIdentifier())) - return false; - - // Produce collection of affected identifiers - Collection affectedIdentifiers = new HashSet(permissions.size()); - for (ObjectPermission permission : permissions) - affectedIdentifiers.add(permission.getObjectIdentifier()); - - // Determine subset of affected identifiers that we have admin access to - ObjectPermissionSet affectedPermissionSet = getPermissionSet(user, user.getUser()); - Collection allowedSubset = affectedPermissionSet.getAccessibleObjects( - Collections.singleton(ObjectPermission.Type.ADMINISTER), - affectedIdentifiers - ); - - // The permissions can be altered if and only if the set of objects we - // are allowed to administer is equal to the set of objects we will be - // affecting. - - return affectedIdentifiers.size() == allowedSubset.size(); - - } - - @Override - public void createPermissions(AuthenticatedUser user, ModeledUser targetUser, - Collection permissions) - throws GuacamoleException { - - // Create permissions only if user has permission to do so - if (canAlterPermissions(user, targetUser, permissions)) { - Collection models = getModelInstances(targetUser, permissions); - getPermissionMapper().insert(models); - return; - } - - // User lacks permission to create object permissions - throw new GuacamoleSecurityException("Permission denied."); - - } - - @Override - public void deletePermissions(AuthenticatedUser user, ModeledUser targetUser, - Collection permissions) - throws GuacamoleException { - - // Delete permissions only if user has permission to do so - if (canAlterPermissions(user, targetUser, permissions)) { - Collection models = getModelInstances(targetUser, permissions); - getPermissionMapper().delete(models); - return; - } - - // User lacks permission to delete object permissions - throw new GuacamoleSecurityException("Permission denied."); - - } +public interface ObjectPermissionService + extends PermissionService { /** * Retrieves the permission of the given type associated with the given @@ -181,26 +62,9 @@ public abstract class ObjectPermissionService * @throws GuacamoleException * If an error occurs while retrieving the requested permission. */ - public ObjectPermission retrievePermission(AuthenticatedUser user, + ObjectPermission retrievePermission(AuthenticatedUser user, ModeledUser targetUser, ObjectPermission.Type type, - String identifier) throws GuacamoleException { - - // Retrieve permissions only if allowed - if (canReadPermissions(user, targetUser)) { - - // Read permission from database, return null if not found - ObjectPermissionModel model = getPermissionMapper().selectOne(targetUser.getModel(), type, identifier); - if (model == null) - return null; - - return getPermissionInstance(model); - - } - - // User cannot read this user's permissions - throw new GuacamoleSecurityException("Permission denied."); - - } + String identifier) throws GuacamoleException; /** * Retrieves the subset of the given identifiers for which the given user @@ -228,29 +92,8 @@ public abstract class ObjectPermissionService * @throws GuacamoleException * If an error occurs while retrieving permissions. */ - public Collection retrieveAccessibleIdentifiers(AuthenticatedUser user, + Collection retrieveAccessibleIdentifiers(AuthenticatedUser user, ModeledUser targetUser, Collection permissions, - Collection identifiers) throws GuacamoleException { - - // Nothing is always accessible - if (identifiers.isEmpty()) - return identifiers; - - // Retrieve permissions only if allowed - if (canReadPermissions(user, targetUser)) { - - // If user is an admin, everything is accessible - if (user.getUser().isAdministrator()) - return identifiers; - - // Otherwise, return explicitly-retrievable identifiers - return getPermissionMapper().selectAccessibleIdentifiers(targetUser.getModel(), permissions, identifiers); - - } - - // User cannot read this user's permissions - throw new GuacamoleSecurityException("Permission denied."); - - } + Collection identifiers) throws GuacamoleException; } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/PermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/PermissionService.java index b4c35ba5e..c350c3c95 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/PermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/PermissionService.java @@ -47,137 +47,9 @@ import org.glyptodon.guacamole.net.auth.permission.PermissionSet; * * @param * The type of permission this service provides access to. - * - * @param - * The underlying model object used to represent PermissionType in the - * database. */ -public abstract class PermissionService, - PermissionType extends Permission, ModelType> { - - /** - * Returns an instance of a mapper for the type of permission used by this - * service. - * - * @return - * A mapper which provides access to the model objects associated with - * the permissions used by this service. - */ - protected abstract PermissionMapper getPermissionMapper(); - - /** - * Returns an instance of a permission which is based on the given model - * object. - * - * @param model - * The model object to use to produce the returned permission. - * - * @return - * A permission which is based on the given model object. - */ - protected abstract PermissionType getPermissionInstance(ModelType model); - - /** - * Returns a collection of permissions which are based on the models in - * the given collection. - * - * @param models - * The model objects to use to produce the permissions within the - * returned set. - * - * @return - * A set of permissions which are based on the models in the given - * collection. - */ - protected Set getPermissionInstances(Collection models) { - - // Create new collection of permissions by manually converting each model - Set permissions = new HashSet(models.size()); - for (ModelType model : models) - permissions.add(getPermissionInstance(model)); - - return permissions; - - } - - /** - * Returns an instance of a model object which is based on the given - * permission and target user. - * - * @param targetUser - * The user to whom this permission is granted. - * - * @param permission - * The permission to use to produce the returned model object. - * - * @return - * A model object which is based on the given permission and target - * user. - */ - protected abstract ModelType getModelInstance(ModeledUser targetUser, - PermissionType permission); - - /** - * Returns a collection of model objects which are based on the given - * permissions and target user. - * - * @param targetUser - * The user to whom this permission is granted. - * - * @param permissions - * The permissions to use to produce the returned model objects. - * - * @return - * A collection of model objects which are based on the given - * permissions and target user. - */ - protected Collection getModelInstances(ModeledUser targetUser, - Collection permissions) { - - // Create new collection of models by manually converting each permission - Collection models = new ArrayList(permissions.size()); - for (PermissionType permission : permissions) - models.add(getModelInstance(targetUser, permission)); - - return models; - - } - - /** - * Determines whether the given user can read the permissions currently - * granted to the given target user. If the reading user and the target - * user are not the same, then explicit READ or SYSTEM_ADMINISTER access is - * required. - * - * @param user - * The user attempting to read permissions. - * - * @param targetUser - * The user whose permissions are being read. - * - * @return - * true if permission is granted, false otherwise. - * - * @throws GuacamoleException - * If an error occurs while checking permission status, or if - * permission is denied to read the current user's permissions. - */ - protected boolean canReadPermissions(AuthenticatedUser user, - ModeledUser targetUser) throws GuacamoleException { - - // A user can always read their own permissions - if (user.getUser().getIdentifier().equals(targetUser.getIdentifier())) - return true; - - // A system adminstrator can do anything - if (user.getUser().isAdministrator()) - return true; - - // Can read permissions on target user if explicit READ is granted - ObjectPermissionSet userPermissionSet = user.getUser().getUserPermissions(); - return userPermissionSet.hasPermission(ObjectPermission.Type.READ, targetUser.getIdentifier()); - - } +public interface PermissionService, + PermissionType extends Permission> { /** * Returns a permission set that can be used to retrieve and manipulate the @@ -200,7 +72,7 @@ public abstract class PermissionService retrievePermissions(AuthenticatedUser user, - ModeledUser targetUser) throws GuacamoleException { - - // Retrieve permissions only if allowed - if (canReadPermissions(user, targetUser)) - return getPermissionInstances(getPermissionMapper().select(targetUser.getModel())); - - // User cannot read this user's permissions - throw new GuacamoleSecurityException("Permission denied."); - - } + Set retrievePermissions(AuthenticatedUser user, + ModeledUser targetUser) throws GuacamoleException; /** * Creates the given permissions within the database. If any permissions @@ -247,8 +110,7 @@ public abstract class PermissionService permissions) throws GuacamoleException; /** @@ -268,8 +130,7 @@ public abstract class PermissionService permissions) throws GuacamoleException; } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/SystemPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/SystemPermissionService.java index 2a7837e58..47a0c1795 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/SystemPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/SystemPermissionService.java @@ -40,7 +40,7 @@ import org.glyptodon.guacamole.net.auth.permission.SystemPermission; * @author Michael Jumper */ public class SystemPermissionService - extends PermissionService { + extends ModeledPermissionService { /** * Mapper for system-level permissions. diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/UserPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/UserPermissionService.java index 33497496a..c70d71706 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/UserPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/glyptodon/guacamole/auth/jdbc/permission/UserPermissionService.java @@ -35,7 +35,7 @@ import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser; * * @author Michael Jumper */ -public class UserPermissionService extends ObjectPermissionService { +public class UserPermissionService extends ModeledObjectPermissionService { /** * Mapper for user permissions.