GUACAMOLE-220: Inherit from groups even if not determined by database.

This commit is contained in:
Michael Jumper
2018-04-06 14:10:52 -07:00
parent 6e71f330b8
commit 14d10fb42a
39 changed files with 514 additions and 348 deletions

View File

@@ -59,10 +59,11 @@ public class ActiveConnectionPermissionService
@Override @Override
public boolean hasPermission(ModeledAuthenticatedUser user, public boolean hasPermission(ModeledAuthenticatedUser user,
ModeledUser targetUser, ObjectPermission.Type type, ModeledUser targetUser, ObjectPermission.Type type,
String identifier, boolean inherit) throws GuacamoleException { String identifier, Set<String> effectiveGroups) throws GuacamoleException {
// Retrieve permissions // Retrieve permissions
Set<ObjectPermission> permissions = retrievePermissions(user, targetUser, inherit); Set<ObjectPermission> permissions = retrievePermissions(user,
targetUser, effectiveGroups);
// Permission is granted if retrieved permissions contains the // Permission is granted if retrieved permissions contains the
// requested permission // requested permission
@@ -73,7 +74,8 @@ public class ActiveConnectionPermissionService
@Override @Override
public Set<ObjectPermission> retrievePermissions(ModeledAuthenticatedUser user, public Set<ObjectPermission> retrievePermissions(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException {
// Retrieve permissions only if allowed // Retrieve permissions only if allowed
if (canReadPermissions(user, targetUser)) { if (canReadPermissions(user, targetUser)) {
@@ -109,9 +111,10 @@ public class ActiveConnectionPermissionService
@Override @Override
public Collection<String> retrieveAccessibleIdentifiers(ModeledAuthenticatedUser user, public Collection<String> retrieveAccessibleIdentifiers(ModeledAuthenticatedUser user,
ModeledUser targetUser, Collection<ObjectPermission.Type> permissionTypes, ModeledUser targetUser, Collection<ObjectPermission.Type> permissionTypes,
Collection<String> identifiers, boolean inherit) throws GuacamoleException { Collection<String> identifiers, Set<String> effectiveGroups)
throws GuacamoleException {
Set<ObjectPermission> permissions = retrievePermissions(user, targetUser, inherit); Set<ObjectPermission> permissions = retrievePermissions(user, targetUser, effectiveGroups);
Collection<String> accessibleObjects = new ArrayList<String>(permissions.size()); Collection<String> accessibleObjects = new ArrayList<String>(permissions.size());
// For each identifier/permission combination // For each identifier/permission combination
@@ -134,11 +137,12 @@ public class ActiveConnectionPermissionService
@Override @Override
public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user, public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException {
// Create permission set for requested user // Create permission set for requested user
ActiveConnectionPermissionSet permissionSet = activeConnectionPermissionSetProvider.get(); ActiveConnectionPermissionSet permissionSet = activeConnectionPermissionSetProvider.get();
permissionSet.init(user, targetUser, inherit); permissionSet.init(user, targetUser, effectiveGroups);
return permissionSet; return permissionSet;

View File

@@ -57,10 +57,15 @@ public interface ModeledDirectoryObjectMapper<ModelType> {
* The user whose permissions should determine whether an identifier * The user whose permissions should determine whether an identifier
* is returned. * is returned.
* *
* @param effectiveGroups
* The identifiers of any known effective groups that should be taken
* into account, such as those defined externally to the database.
*
* @return * @return
* A Set containing all identifiers of all readable objects. * A Set containing all identifiers of all readable objects.
*/ */
Set<String> selectReadableIdentifiers(@Param("user") UserModel user); Set<String> selectReadableIdentifiers(@Param("user") UserModel user,
@Param("effectiveGroups") Collection<String> effectiveGroups);
/** /**
* Selects all objects which have the given identifiers. If an identifier * Selects all objects which have the given identifiers. If an identifier
@@ -91,11 +96,16 @@ public interface ModeledDirectoryObjectMapper<ModelType> {
* @param identifiers * @param identifiers
* The identifiers of the objects to return. * The identifiers of the objects to return.
* *
* @param effectiveGroups
* The identifiers of any known effective groups that should be taken
* into account, such as those defined externally to the database.
*
* @return * @return
* A Collection of all objects having the given identifiers. * A Collection of all objects having the given identifiers.
*/ */
Collection<ModelType> selectReadable(@Param("user") UserModel user, Collection<ModelType> selectReadable(@Param("user") UserModel user,
@Param("identifiers") Collection<String> identifiers); @Param("identifiers") Collection<String> identifiers,
@Param("effectiveGroups") Collection<String> effectiveGroups);
/** /**
* Inserts the given object into the database. If the object already * Inserts the given object into the database. If the object already

View File

@@ -401,7 +401,8 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers
else else
objects = getObjectMapper().selectReadable(user.getUser().getModel(), identifiers); objects = getObjectMapper().selectReadable(user.getUser().getModel(),
identifiers, user.getEffectiveUserGroups());
// Return collection of requested objects // Return collection of requested objects
return getObjectInstances(user, objects); return getObjectInstances(user, objects);
@@ -512,7 +513,8 @@ public abstract class ModeledDirectoryObjectService<InternalType extends Modeled
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers
else else
return getObjectMapper().selectReadableIdentifiers(user.getUser().getModel()); return getObjectMapper().selectReadableIdentifiers(user.getUser().getModel(),
user.getEffectiveUserGroups());
} }

View File

@@ -19,6 +19,7 @@
package org.apache.guacamole.auth.jdbc.connection; package org.apache.guacamole.auth.jdbc.connection;
import java.util.Collection;
import java.util.Set; import java.util.Set;
import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
import org.apache.guacamole.auth.jdbc.user.UserModel; import org.apache.guacamole.auth.jdbc.user.UserModel;
@@ -61,11 +62,18 @@ public interface ConnectionMapper extends ModeledDirectoryObjectMapper<Connectio
* The identifier of the parent connection group, or null if the root * The identifier of the parent connection group, or null if the root
* connection group is to be queried. * connection group is to be queried.
* *
* @param effectiveGroups
* The identifiers of all groups that should be taken into account
* when determining the permissions effectively granted to the user. If
* no groups are given, only permissions directly granted to the user
* will be used.
*
* @return * @return
* A Set containing all identifiers of all readable objects. * A Set containing all identifiers of all readable objects.
*/ */
Set<String> selectReadableIdentifiersWithin(@Param("user") UserModel user, Set<String> selectReadableIdentifiersWithin(@Param("user") UserModel user,
@Param("parentIdentifier") String parentIdentifier); @Param("parentIdentifier") String parentIdentifier,
@Param("effectiveGroups") Collection<String> effectiveGroups);
/** /**
* Selects the connection within the given parent group and having the * Selects the connection within the given parent group and having the

View File

@@ -102,12 +102,19 @@ public interface ConnectionRecordMapper {
* @param limit * @param limit
* The maximum number of records that should be returned. * The maximum number of records that should be returned.
* *
* @param effectiveGroups
* The identifiers of all groups that should be taken into account
* when determining the permissions effectively granted to the user. If
* no groups are given, only permissions directly granted to the user
* will be used.
*
* @return * @return
* The results of the search performed with the given parameters. * The results of the search performed with the given parameters.
*/ */
List<ConnectionRecordModel> searchReadable(@Param("user") UserModel user, List<ConnectionRecordModel> searchReadable(@Param("user") UserModel user,
@Param("terms") Collection<ActivityRecordSearchTerm> terms, @Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates, @Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit); @Param("limit") int limit,
@Param("effectiveGroups") Collection<String> effectiveGroups);
} }

View File

@@ -303,7 +303,9 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers
else else
return connectionMapper.selectReadableIdentifiersWithin(user.getUser().getModel(), identifier); return connectionMapper.selectReadableIdentifiersWithin(
user.getUser().getModel(), identifier,
user.getEffectiveUserGroups());
} }
@@ -475,8 +477,9 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
// Otherwise only return explicitly readable history records // Otherwise only return explicitly readable history records
else else
searchResults = connectionRecordMapper.searchReadable(user.getUser().getModel(), searchResults = connectionRecordMapper.searchReadable(
requiredContents, sortPredicates, limit); user.getUser().getModel(), requiredContents, sortPredicates,
limit, user.getEffectiveUserGroups());
return getObjectInstances(searchResults); return getObjectInstances(searchResults);

View File

@@ -19,6 +19,7 @@
package org.apache.guacamole.auth.jdbc.connectiongroup; package org.apache.guacamole.auth.jdbc.connectiongroup;
import java.util.Collection;
import java.util.Set; import java.util.Set;
import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
import org.apache.guacamole.auth.jdbc.user.UserModel; import org.apache.guacamole.auth.jdbc.user.UserModel;
@@ -61,11 +62,18 @@ public interface ConnectionGroupMapper extends ModeledDirectoryObjectMapper<Conn
* The identifier of the parent connection group, or null if the root * The identifier of the parent connection group, or null if the root
* connection group is to be queried. * connection group is to be queried.
* *
* @param effectiveGroups
* The identifiers of all groups that should be taken into account
* when determining the permissions effectively granted to the user. If
* no groups are given, only permissions directly granted to the user
* will be used.
*
* @return * @return
* A Set containing all identifiers of all readable objects. * A Set containing all identifiers of all readable objects.
*/ */
Set<String> selectReadableIdentifiersWithin(@Param("user") UserModel user, Set<String> selectReadableIdentifiersWithin(@Param("user") UserModel user,
@Param("parentIdentifier") String parentIdentifier); @Param("parentIdentifier") String parentIdentifier,
@Param("effectiveGroups") Collection<String> effectiveGroups);
/** /**
* Selects the connection group within the given parent group and having * Selects the connection group within the given parent group and having

View File

@@ -223,7 +223,9 @@ public class ConnectionGroupService extends ModeledChildDirectoryObjectService<M
// Otherwise only return explicitly readable identifiers // Otherwise only return explicitly readable identifiers
else else
return connectionGroupMapper.selectReadableIdentifiersWithin(user.getUser().getModel(), identifier); return connectionGroupMapper.selectReadableIdentifiersWithin(
user.getUser().getModel(), identifier,
user.getEffectiveUserGroups());
} }

View File

@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.permission;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
@@ -51,11 +52,12 @@ public class ConnectionGroupPermissionService extends ModeledObjectPermissionSer
@Override @Override
public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user, public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException {
// Create permission set for requested user // Create permission set for requested user
ObjectPermissionSet permissionSet = connectionGroupPermissionSetProvider.get(); ObjectPermissionSet permissionSet = connectionGroupPermissionSetProvider.get();
permissionSet.init(user, targetUser, inherit); permissionSet.init(user, targetUser, effectiveGroups);
return permissionSet; return permissionSet;

View File

@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.permission;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
@@ -51,11 +52,12 @@ public class ConnectionPermissionService extends ModeledObjectPermissionService
@Override @Override
public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user, public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException {
// Create permission set for requested user // Create permission set for requested user
ObjectPermissionSet permissionSet = connectionPermissionSetProvider.get(); ObjectPermissionSet permissionSet = connectionPermissionSetProvider.get();
permissionSet.init(user, targetUser, inherit); permissionSet.init(user, targetUser, effectiveGroups);
return permissionSet; return permissionSet;

View File

@@ -22,6 +22,7 @@ package org.apache.guacamole.auth.jdbc.permission;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
@@ -106,7 +107,7 @@ public abstract class ModeledObjectPermissionService
affectedIdentifiers.add(permission.getObjectIdentifier()); affectedIdentifiers.add(permission.getObjectIdentifier());
// Determine subset of affected identifiers that we have admin access to // Determine subset of affected identifiers that we have admin access to
ObjectPermissionSet affectedPermissionSet = getPermissionSet(user, user.getUser(), true); ObjectPermissionSet affectedPermissionSet = getPermissionSet(user, user.getUser(), user.getEffectiveUserGroups());
Collection<String> allowedSubset = affectedPermissionSet.getAccessibleObjects( Collection<String> allowedSubset = affectedPermissionSet.getAccessibleObjects(
Collections.singleton(ObjectPermission.Type.ADMINISTER), Collections.singleton(ObjectPermission.Type.ADMINISTER),
affectedIdentifiers affectedIdentifiers
@@ -157,11 +158,13 @@ public abstract class ModeledObjectPermissionService
@Override @Override
public boolean hasPermission(ModeledAuthenticatedUser user, public boolean hasPermission(ModeledAuthenticatedUser user,
ModeledUser targetUser, ObjectPermission.Type type, ModeledUser targetUser, ObjectPermission.Type type,
String identifier, boolean inherit) throws GuacamoleException { String identifier, Set<String> effectiveGroups)
throws GuacamoleException {
// Retrieve permissions only if allowed // Retrieve permissions only if allowed
if (canReadPermissions(user, targetUser)) if (canReadPermissions(user, targetUser))
return getPermissionMapper().selectOne(targetUser.getModel(), type, identifier, inherit) != null; return getPermissionMapper().selectOne(targetUser.getModel(), type,
identifier, effectiveGroups) != null;
// User cannot read this user's permissions // User cannot read this user's permissions
throw new GuacamoleSecurityException("Permission denied."); throw new GuacamoleSecurityException("Permission denied.");
@@ -171,7 +174,7 @@ public abstract class ModeledObjectPermissionService
@Override @Override
public Collection<String> retrieveAccessibleIdentifiers(ModeledAuthenticatedUser user, public Collection<String> retrieveAccessibleIdentifiers(ModeledAuthenticatedUser user,
ModeledUser targetUser, Collection<ObjectPermission.Type> permissions, ModeledUser targetUser, Collection<ObjectPermission.Type> permissions,
Collection<String> identifiers, boolean inherit) Collection<String> identifiers, Set<String> effectiveGroups)
throws GuacamoleException { throws GuacamoleException {
// Nothing is always accessible // Nothing is always accessible
@@ -186,7 +189,9 @@ public abstract class ModeledObjectPermissionService
return identifiers; return identifiers;
// Otherwise, return explicitly-retrievable identifiers // Otherwise, return explicitly-retrievable identifiers
return getPermissionMapper().selectAccessibleIdentifiers(targetUser.getModel(), permissions, identifiers, inherit); return getPermissionMapper().selectAccessibleIdentifiers(
targetUser.getModel(), permissions, identifiers,
effectiveGroups);
} }

View File

@@ -140,11 +140,12 @@ public abstract class ModeledPermissionService<PermissionSetType extends Permiss
@Override @Override
public Set<PermissionType> retrievePermissions(ModeledAuthenticatedUser user, public Set<PermissionType> retrievePermissions(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException {
// Retrieve permissions only if allowed // Retrieve permissions only if allowed
if (canReadPermissions(user, targetUser)) if (canReadPermissions(user, targetUser))
return getPermissionInstances(getPermissionMapper().select(targetUser.getModel(), inherit)); return getPermissionInstances(getPermissionMapper().select(targetUser.getModel(), effectiveGroups));
// User cannot read this user's permissions // User cannot read this user's permissions
throw new GuacamoleSecurityException("Permission denied."); throw new GuacamoleSecurityException("Permission denied.");

View File

@@ -43,10 +43,11 @@ public interface ObjectPermissionMapper extends PermissionMapper<ObjectPermissio
* @param identifier * @param identifier
* The identifier of the object affected by the permission to return. * The identifier of the object affected by the permission to return.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* The requested permission, or null if no such permission is granted * The requested permission, or null if no such permission is granted
@@ -55,7 +56,7 @@ public interface ObjectPermissionMapper extends PermissionMapper<ObjectPermissio
ObjectPermissionModel selectOne(@Param("entity") EntityModel entity, ObjectPermissionModel selectOne(@Param("entity") EntityModel entity,
@Param("type") ObjectPermission.Type type, @Param("type") ObjectPermission.Type type,
@Param("identifier") String identifier, @Param("identifier") String identifier,
@Param("inherit") boolean inherit); @Param("effectiveGroups") Collection<String> effectiveGroups);
/** /**
* Retrieves the subset of the given identifiers for which the given entity * Retrieves the subset of the given identifiers for which the given entity
@@ -73,10 +74,11 @@ public interface ObjectPermissionMapper extends PermissionMapper<ObjectPermissio
* The identifiers of the objects affected by the permissions being * The identifiers of the objects affected by the permissions being
* checked. * checked.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* A collection containing the subset of identifiers for which at least * A collection containing the subset of identifiers for which at least
@@ -85,6 +87,6 @@ public interface ObjectPermissionMapper extends PermissionMapper<ObjectPermissio
Collection<String> selectAccessibleIdentifiers(@Param("entity") EntityModel entity, Collection<String> selectAccessibleIdentifiers(@Param("entity") EntityModel entity,
@Param("permissions") Collection<ObjectPermission.Type> permissions, @Param("permissions") Collection<ObjectPermission.Type> permissions,
@Param("identifiers") Collection<String> identifiers, @Param("identifiers") Collection<String> identifiers,
@Param("inherit") boolean inherit); @Param("effectiveGroups") Collection<String> effectiveGroups);
} }

View File

@@ -20,6 +20,7 @@
package org.apache.guacamole.auth.jdbc.permission; package org.apache.guacamole.auth.jdbc.permission;
import java.util.Collection; import java.util.Collection;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
@@ -50,10 +51,11 @@ public interface ObjectPermissionService
* @param identifier * @param identifier
* The identifier of the object affected by the permission to return. * The identifier of the object affected by the permission to return.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* true if permission of the given type and associated with the given * true if permission of the given type and associated with the given
@@ -64,7 +66,7 @@ public interface ObjectPermissionService
*/ */
boolean hasPermission(ModeledAuthenticatedUser user, boolean hasPermission(ModeledAuthenticatedUser user,
ModeledUser targetUser, ObjectPermission.Type type, ModeledUser targetUser, ObjectPermission.Type type,
String identifier, boolean inherit) throws GuacamoleException; String identifier, Set<String> effectiveGroups) throws GuacamoleException;
/** /**
* Retrieves the subset of the given identifiers for which the given user * Retrieves the subset of the given identifiers for which the given user
@@ -85,10 +87,11 @@ public interface ObjectPermissionService
* The identifiers of the objects affected by the permissions being * The identifiers of the objects affected by the permissions being
* checked. * checked.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* A collection containing the subset of identifiers for which at least * A collection containing the subset of identifiers for which at least
@@ -99,7 +102,7 @@ public interface ObjectPermissionService
*/ */
Collection<String> retrieveAccessibleIdentifiers(ModeledAuthenticatedUser user, Collection<String> retrieveAccessibleIdentifiers(ModeledAuthenticatedUser user,
ModeledUser targetUser, Collection<ObjectPermission.Type> permissions, ModeledUser targetUser, Collection<ObjectPermission.Type> permissions,
Collection<String> identifiers, boolean inherit) Collection<String> identifiers, Set<String> effectiveGroups)
throws GuacamoleException; throws GuacamoleException;
} }

View File

@@ -42,11 +42,7 @@ public abstract class ObjectPermissionSet extends RestrictedObject
*/ */
private ModeledUser user; private ModeledUser user;
/** private Set<String> effectiveGroups;
* Whether permissions inherited through user groups should be taken into
* account. If false, only permissions granted directly will be included.
*/
boolean inherit;
/** /**
* Creates a new ObjectPermissionSet. The resulting permission set * Creates a new ObjectPermissionSet. The resulting permission set
@@ -67,16 +63,17 @@ public abstract class ObjectPermissionSet extends RestrictedObject
* @param user * @param user
* The user to whom the permissions in this set are granted. * The user to whom the permissions in this set are granted.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
*/ */
public void init(ModeledAuthenticatedUser currentUser, ModeledUser user, public void init(ModeledAuthenticatedUser currentUser, ModeledUser user,
boolean inherit) { Set<String> effectiveGroups) {
super.init(currentUser); super.init(currentUser);
this.user = user; this.user = user;
this.inherit = inherit; this.effectiveGroups = effectiveGroups;
} }
/** /**
@@ -91,13 +88,13 @@ public abstract class ObjectPermissionSet extends RestrictedObject
@Override @Override
public Set<ObjectPermission> getPermissions() throws GuacamoleException { public Set<ObjectPermission> getPermissions() throws GuacamoleException {
return getObjectPermissionService().retrievePermissions(getCurrentUser(), user, inherit); return getObjectPermissionService().retrievePermissions(getCurrentUser(), user, effectiveGroups);
} }
@Override @Override
public boolean hasPermission(ObjectPermission.Type permission, public boolean hasPermission(ObjectPermission.Type permission,
String identifier) throws GuacamoleException { String identifier) throws GuacamoleException {
return getObjectPermissionService().hasPermission(getCurrentUser(), user, permission, identifier, inherit); return getObjectPermissionService().hasPermission(getCurrentUser(), user, permission, identifier, effectiveGroups);
} }
@Override @Override
@@ -115,7 +112,7 @@ public abstract class ObjectPermissionSet extends RestrictedObject
@Override @Override
public Collection<String> getAccessibleObjects(Collection<ObjectPermission.Type> permissions, public Collection<String> getAccessibleObjects(Collection<ObjectPermission.Type> permissions,
Collection<String> identifiers) throws GuacamoleException { Collection<String> identifiers) throws GuacamoleException {
return getObjectPermissionService().retrieveAccessibleIdentifiers(getCurrentUser(), user, permissions, identifiers, inherit); return getObjectPermissionService().retrieveAccessibleIdentifiers(getCurrentUser(), user, permissions, identifiers, effectiveGroups);
} }
@Override @Override

View File

@@ -38,16 +38,17 @@ public interface PermissionMapper<PermissionType> {
* @param entity * @param entity
* The entity to retrieve permissions for. * The entity to retrieve permissions for.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* All permissions associated with the given entity. * All permissions associated with the given entity.
*/ */
Collection<PermissionType> select(@Param("entity") EntityModel entity, Collection<PermissionType> select(@Param("entity") EntityModel entity,
@Param("inherit") boolean inherit); @Param("effectiveGroups") Collection<String> effectiveGroups);
/** /**
* Inserts the given permissions into the database. If any permissions * Inserts the given permissions into the database. If any permissions

View File

@@ -54,10 +54,11 @@ public interface PermissionService<PermissionSetType extends PermissionSet<Permi
* The user to whom the permissions in the returned permission set are * The user to whom the permissions in the returned permission set are
* granted. * granted.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* A permission set that contains all permissions associated with the * A permission set that contains all permissions associated with the
@@ -69,7 +70,8 @@ public interface PermissionService<PermissionSetType extends PermissionSet<Permi
* user is denied. * user is denied.
*/ */
PermissionSetType getPermissionSet(ModeledAuthenticatedUser user, PermissionSetType getPermissionSet(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException; ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException;
/** /**
* Retrieves all permissions associated with the given user. * Retrieves all permissions associated with the given user.
@@ -80,10 +82,11 @@ public interface PermissionService<PermissionSetType extends PermissionSet<Permi
* @param targetUser * @param targetUser
* The user associated with the permissions to be retrieved. * The user associated with the permissions to be retrieved.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* The permissions associated with the given user. * The permissions associated with the given user.
@@ -92,7 +95,8 @@ public interface PermissionService<PermissionSetType extends PermissionSet<Permi
* If an error occurs while retrieving the requested permissions. * If an error occurs while retrieving the requested permissions.
*/ */
Set<PermissionType> retrievePermissions(ModeledAuthenticatedUser user, Set<PermissionType> retrievePermissions(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException; ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException;
/** /**
* Creates the given permissions within the database. If any permissions * Creates the given permissions within the database. If any permissions

View File

@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.permission;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
@@ -51,11 +52,12 @@ public class SharingProfilePermissionService extends ModeledObjectPermissionServ
@Override @Override
public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user, public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException {
// Create permission set for requested user // Create permission set for requested user
ObjectPermissionSet permissionSet = sharingProfilePermissionSetProvider.get(); ObjectPermissionSet permissionSet = sharingProfilePermissionSetProvider.get();
permissionSet.init(user, targetUser, inherit); permissionSet.init(user, targetUser, effectiveGroups);
return permissionSet; return permissionSet;

View File

@@ -19,6 +19,7 @@
package org.apache.guacamole.auth.jdbc.permission; package org.apache.guacamole.auth.jdbc.permission;
import java.util.Collection;
import org.apache.guacamole.auth.jdbc.base.EntityModel; import org.apache.guacamole.auth.jdbc.base.EntityModel;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.guacamole.net.auth.permission.SystemPermission; import org.apache.guacamole.net.auth.permission.SystemPermission;
@@ -38,10 +39,11 @@ public interface SystemPermissionMapper extends PermissionMapper<SystemPermissio
* @param type * @param type
* The type of permission to return. * The type of permission to return.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* The requested permission, or null if no such permission is granted * The requested permission, or null if no such permission is granted
@@ -49,6 +51,6 @@ public interface SystemPermissionMapper extends PermissionMapper<SystemPermissio
*/ */
SystemPermissionModel selectOne(@Param("entity") EntityModel entity, SystemPermissionModel selectOne(@Param("entity") EntityModel entity,
@Param("type") SystemPermission.Type type, @Param("type") SystemPermission.Type type,
@Param("inherit") boolean inherit); @Param("effectiveGroups") Collection<String> effectiveGroups);
} }

View File

@@ -22,6 +22,7 @@ package org.apache.guacamole.auth.jdbc.permission;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.util.Collection; import java.util.Collection;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
@@ -75,11 +76,11 @@ public class SystemPermissionService
@Override @Override
public SystemPermissionSet getPermissionSet(ModeledAuthenticatedUser user, public SystemPermissionSet getPermissionSet(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups) throws GuacamoleException {
// Create permission set for requested user // Create permission set for requested user
SystemPermissionSet permissionSet = systemPermissionSetProvider.get(); SystemPermissionSet permissionSet = systemPermissionSetProvider.get();
permissionSet.init(user, targetUser, inherit); permissionSet.init(user, targetUser, effectiveGroups);
return permissionSet; return permissionSet;
@@ -136,10 +137,11 @@ public class SystemPermissionService
* @param type * @param type
* The type of permission to retrieve. * The type of permission to retrieve.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
* *
* @return * @return
* true if permission of the given type has been granted to the given * true if permission of the given type has been granted to the given
@@ -150,11 +152,11 @@ public class SystemPermissionService
*/ */
public boolean hasPermission(ModeledAuthenticatedUser user, public boolean hasPermission(ModeledAuthenticatedUser user,
ModeledUser targetUser, SystemPermission.Type type, ModeledUser targetUser, SystemPermission.Type type,
boolean inherit) throws GuacamoleException { Set<String> effectiveGroups) throws GuacamoleException {
// Retrieve permissions only if allowed // Retrieve permissions only if allowed
if (canReadPermissions(user, targetUser)) if (canReadPermissions(user, targetUser))
return getPermissionMapper().selectOne(targetUser.getModel(), type, inherit) != null; return getPermissionMapper().selectOne(targetUser.getModel(), type, effectiveGroups) != null;
// User cannot read this user's permissions // User cannot read this user's permissions
throw new GuacamoleSecurityException("Permission denied."); throw new GuacamoleSecurityException("Permission denied.");

View File

@@ -42,11 +42,7 @@ public class SystemPermissionSet extends RestrictedObject
*/ */
private ModeledUser user; private ModeledUser user;
/** private Set<String> effectiveGroups;
* Whether permissions inherited through user groups should be taken into
* account. If false, only permissions granted directly will be included.
*/
private boolean inherit;
/** /**
* Service for reading and manipulating system permissions. * Service for reading and manipulating system permissions.
@@ -73,27 +69,28 @@ public class SystemPermissionSet extends RestrictedObject
* @param user * @param user
* The user to whom the permissions in this set are granted. * The user to whom the permissions in this set are granted.
* *
* @param inherit * @param effectiveGroups
* Whether permissions inherited through user groups should be taken * The identifiers of all groups that should be taken into account
* into account. If false, only permissions granted directly will be * when determining the permissions effectively granted to the user. If
* included. * no groups are given, only permissions directly granted to the user
* will be used.
*/ */
public void init(ModeledAuthenticatedUser currentUser, ModeledUser user, public void init(ModeledAuthenticatedUser currentUser, ModeledUser user,
boolean inherit) { Set<String> effectiveGroups) {
super.init(currentUser); super.init(currentUser);
this.user = user; this.user = user;
this.inherit = inherit; this.effectiveGroups = effectiveGroups;
} }
@Override @Override
public Set<SystemPermission> getPermissions() throws GuacamoleException { public Set<SystemPermission> getPermissions() throws GuacamoleException {
return systemPermissionService.retrievePermissions(getCurrentUser(), user, inherit); return systemPermissionService.retrievePermissions(getCurrentUser(), user, effectiveGroups);
} }
@Override @Override
public boolean hasPermission(SystemPermission.Type permission) public boolean hasPermission(SystemPermission.Type permission)
throws GuacamoleException { throws GuacamoleException {
return systemPermissionService.hasPermission(getCurrentUser(), user, permission, inherit); return systemPermissionService.hasPermission(getCurrentUser(), user, permission, effectiveGroups);
} }
@Override @Override

View File

@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.permission;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser;
@@ -51,11 +52,12 @@ public class UserPermissionService extends ModeledObjectPermissionService {
@Override @Override
public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user, public ObjectPermissionSet getPermissionSet(ModeledAuthenticatedUser user,
ModeledUser targetUser, boolean inherit) throws GuacamoleException { ModeledUser targetUser, Set<String> effectiveGroups)
throws GuacamoleException {
// Create permission set for requested user // Create permission set for requested user
ObjectPermissionSet permissionSet = userPermissionSetProvider.get(); ObjectPermissionSet permissionSet = userPermissionSetProvider.get();
permissionSet.init(user, targetUser, inherit); permissionSet.init(user, targetUser, effectiveGroups);
return permissionSet; return permissionSet;

View File

@@ -628,7 +628,9 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS
identifiers.add(record.getConnection().getIdentifier()); identifiers.add(record.getConnection().getIdentifier());
// Produce collection of readable connection identifiers // Produce collection of readable connection identifiers
Collection<ConnectionModel> connections = connectionMapper.selectReadable(user.getUser().getModel(), identifiers); Collection<ConnectionModel> connections =
connectionMapper.selectReadable(user.getUser().getModel(),
identifiers, user.getEffectiveUserGroups());
// Ensure set contains only identifiers of readable connections // Ensure set contains only identifiers of readable connections
identifiers.clear(); identifiers.clear();

View File

@@ -351,37 +351,43 @@ public class ModeledUser extends ModeledDirectoryObject<UserModel> implements Us
@Override @Override
public SystemPermissionSet getSystemPermissions() public SystemPermissionSet getSystemPermissions()
throws GuacamoleException { throws GuacamoleException {
return systemPermissionService.getPermissionSet(getCurrentUser(), this, false); return systemPermissionService.getPermissionSet(getCurrentUser(), this,
Collections.<String>emptySet());
} }
@Override @Override
public ObjectPermissionSet getConnectionPermissions() public ObjectPermissionSet getConnectionPermissions()
throws GuacamoleException { throws GuacamoleException {
return connectionPermissionService.getPermissionSet(getCurrentUser(), this, false); return connectionPermissionService.getPermissionSet(getCurrentUser(),
this, Collections.<String>emptySet());
} }
@Override @Override
public ObjectPermissionSet getConnectionGroupPermissions() public ObjectPermissionSet getConnectionGroupPermissions()
throws GuacamoleException { throws GuacamoleException {
return connectionGroupPermissionService.getPermissionSet(getCurrentUser(), this, false); return connectionGroupPermissionService.getPermissionSet(
getCurrentUser(), this, Collections.<String>emptySet());
} }
@Override @Override
public ObjectPermissionSet getSharingProfilePermissions() public ObjectPermissionSet getSharingProfilePermissions()
throws GuacamoleException { throws GuacamoleException {
return sharingProfilePermissionService.getPermissionSet(getCurrentUser(), this, false); return sharingProfilePermissionService.getPermissionSet(
getCurrentUser(), this, Collections.<String>emptySet());
} }
@Override @Override
public ObjectPermissionSet getActiveConnectionPermissions() public ObjectPermissionSet getActiveConnectionPermissions()
throws GuacamoleException { throws GuacamoleException {
return activeConnectionPermissionService.getPermissionSet(getCurrentUser(), this, false); return activeConnectionPermissionService.getPermissionSet(
getCurrentUser(), this, Collections.<String>emptySet());
} }
@Override @Override
public ObjectPermissionSet getUserPermissions() public ObjectPermissionSet getUserPermissions()
throws GuacamoleException { throws GuacamoleException {
return userPermissionService.getPermissionSet(getCurrentUser(), this, false); return userPermissionService.getPermissionSet(getCurrentUser(), this,
Collections.<String>emptySet());
} }
@Override @Override
@@ -864,50 +870,64 @@ public class ModeledUser extends ModeledDirectoryObject<UserModel> implements Us
* apply to this user. * apply to this user.
*/ */
public Set<String> getEffectiveUserGroups() { public Set<String> getEffectiveUserGroups() {
return userService.retrieveEffectiveGroups(this,
// FIXME: STUB Collections.<String>emptySet());
return /*retrieveEffectiveIdentifiers(this, */Collections.<String>emptySet()/*)*/;
} }
@Override @Override
public Permissions getEffectivePermissions() throws GuacamoleException { public Permissions getEffectivePermissions() throws GuacamoleException {
final ModeledAuthenticatedUser authenticatedUser = getCurrentUser();
final Set<String> effectiveGroups;
// If this user is the currently-authenticated user, include any
// additional effective groups declared by the authentication system
if (authenticatedUser.getIdentifier().equals(getIdentifier()))
effectiveGroups = userService.retrieveEffectiveGroups(this,
authenticatedUser.getEffectiveUserGroups());
// Otherwise, just include effective groups from the database
else
effectiveGroups = getEffectiveUserGroups();
// Return a permissions object which describes all effective
// permissions, including any permissions inherited via user groups
return new Permissions() { return new Permissions() {
@Override @Override
public ObjectPermissionSet getActiveConnectionPermissions() public ObjectPermissionSet getActiveConnectionPermissions()
throws GuacamoleException { throws GuacamoleException {
return activeConnectionPermissionService.getPermissionSet(getCurrentUser(), ModeledUser.this, true); return activeConnectionPermissionService.getPermissionSet(authenticatedUser, ModeledUser.this, effectiveGroups);
} }
@Override @Override
public ObjectPermissionSet getConnectionGroupPermissions() public ObjectPermissionSet getConnectionGroupPermissions()
throws GuacamoleException { throws GuacamoleException {
return connectionGroupPermissionService.getPermissionSet(getCurrentUser(), ModeledUser.this, true); return connectionGroupPermissionService.getPermissionSet(authenticatedUser, ModeledUser.this, effectiveGroups);
} }
@Override @Override
public ObjectPermissionSet getConnectionPermissions() public ObjectPermissionSet getConnectionPermissions()
throws GuacamoleException { throws GuacamoleException {
return connectionPermissionService.getPermissionSet(getCurrentUser(), ModeledUser.this, true); return connectionPermissionService.getPermissionSet(authenticatedUser, ModeledUser.this, effectiveGroups);
} }
@Override @Override
public ObjectPermissionSet getSharingProfilePermissions() public ObjectPermissionSet getSharingProfilePermissions()
throws GuacamoleException { throws GuacamoleException {
return sharingProfilePermissionService.getPermissionSet(getCurrentUser(), ModeledUser.this, true); return sharingProfilePermissionService.getPermissionSet(authenticatedUser, ModeledUser.this, effectiveGroups);
} }
@Override @Override
public SystemPermissionSet getSystemPermissions() public SystemPermissionSet getSystemPermissions()
throws GuacamoleException { throws GuacamoleException {
return systemPermissionService.getPermissionSet(getCurrentUser(), ModeledUser.this, true); return systemPermissionService.getPermissionSet(authenticatedUser, ModeledUser.this, effectiveGroups);
} }
@Override @Override
public ObjectPermissionSet getUserPermissions() public ObjectPermissionSet getUserPermissions()
throws GuacamoleException { throws GuacamoleException {
return userPermissionService.getPermissionSet(getCurrentUser(), ModeledUser.this, true); return userPermissionService.getPermissionSet(authenticatedUser, ModeledUser.this, effectiveGroups);
} }
@Override @Override

View File

@@ -19,6 +19,8 @@
package org.apache.guacamole.auth.jdbc.user; package org.apache.guacamole.auth.jdbc.user;
import java.util.Collection;
import java.util.Set;
import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@@ -38,5 +40,25 @@ public interface UserMapper extends ModeledDirectoryObjectMapper<UserModel> {
* The user having the given username, or null if no such user exists. * The user having the given username, or null if no such user exists.
*/ */
UserModel selectOne(@Param("username") String username); UserModel selectOne(@Param("username") String username);
/**
* Returns the set of all group identifiers of which the given user is a
* member, taking into account the given collection of known group
* memberships which are not necessarily defined within the database.
*
* @param user
* The user whose effective groups should be returned.
*
* @param effectiveGroups
* The identifiers of any known effective groups that should be taken
* into account, such as those defined externally to the database.
*
* @return
* The set of identifiers of all groups that the given user is a
* member of, including those where membership is inherited through
* membership in other groups.
*/
Set<String> selectEffectiveGroupIdentifiers(@Param("user") UserModel user,
@Param("effectiveGroups") Collection<String> effectiveGroups);
} }

View File

@@ -113,12 +113,19 @@ public interface UserRecordMapper {
* @param limit * @param limit
* The maximum number of records that should be returned. * The maximum number of records that should be returned.
* *
* @param effectiveGroups
* The identifiers of all groups that should be taken into account
* when determining the permissions effectively granted to the user. If
* no groups are given, only permissions directly granted to the user
* will be used.
*
* @return * @return
* The results of the search performed with the given parameters. * The results of the search performed with the given parameters.
*/ */
List<ActivityRecordModel> searchReadable(@Param("user") UserModel user, List<ActivityRecordModel> searchReadable(@Param("user") UserModel user,
@Param("terms") Collection<ActivityRecordSearchTerm> terms, @Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates, @Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit); @Param("limit") int limit,
@Param("effectiveGroups") Collection<String> effectiveGroups);
} }

View File

@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
@@ -591,11 +592,37 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
// Otherwise only return explicitly readable history records // Otherwise only return explicitly readable history records
else else
searchResults = userRecordMapper.searchReadable(user.getUser().getModel(), searchResults = userRecordMapper.searchReadable(user.getUser().getModel(),
requiredContents, sortPredicates, limit); requiredContents, sortPredicates, limit, user.getEffectiveUserGroups());
return getObjectInstances(searchResults); return getObjectInstances(searchResults);
} }
/**
* Returns the set of all group identifiers of which the given user is a
* member, taking into account the given collection of known group
* memberships which are not necessarily defined within the database.
*
* Note that group visibility with respect to the queried user is NOT taken
* into account. If the user is a member of a group, the identifier of that
* group will be included in the returned set even if the current user lacks
* "READ" permission for that group.
*
* @param user
* The user whose effective groups should be returned.
*
* @param effectiveGroups
* The identifiers of any known effective groups that should be taken
* into account, such as those defined externally to the database.
*
* @return
* The set of identifiers of all groups that the given user is a
* member of, including those where membership is inherited through
* membership in other groups.
*/
public Set<String> retrieveEffectiveGroups(ModeledUser user,
Collection<String> effectiveGroups) {
return userMapper.selectEffectiveGroupIdentifiers(user.getModel(), effectiveGroups);
}
} }

View File

@@ -23,21 +23,40 @@
<mapper namespace="org.apache.guacamole.auth.jdbc.base.EntityMapper" > <mapper namespace="org.apache.guacamole.auth.jdbc.base.EntityMapper" >
<!-- Retrieves the ID of the given entity. If inheritance is enabled, the <!--
IDs of the entities for all applicable user groups are retrieved, as well. --> * SQL fragment which tests whether the value of the given column matches
<sql id="relatedEntities"> * the given entity ID. If group identifiers are provided, the IDs of the
<if test="!${inheritFlag}">${entityID}</if> * entities for all groups having those identifiers are tested, as well.
<if test="${inheritFlag}"> *
WITH RECURSIVE related_entity(entity_id) AS ( * @param column
VALUES (${entityID}) * The name of the column to test. This column MUST contain an entity
UNION * ID (a foreign key into the guacamole_entity table).
SELECT guacamole_user_group.entity_id *
FROM related_entity * @param entityID
JOIN guacamole_user_group_member ON related_entity.entity_id = guacamole_user_group_member.member_entity_id * The ID of the specific entity to test the column against.
JOIN guacamole_user_group ON guacamole_user_group.user_group_id = guacamole_user_group_member.user_group_id *
) * @param groups
SELECT entity_id FROM related_entity * A collection of group identifiers to additionally test the column
</if> * against. Though this functionality is optional, a collection must
* always be given, even if that collection is empty.
-->
<sql id="isRelatedEntity">
(
${column} = ${entityID}
<if test="!${groups}.isEmpty()">
OR ${column} IN (
SELECT entity_id
FROM guacamole_entity
WHERE
type = 'USER_GROUP'::guacamole_entity_type
AND name IN
<foreach collection="${groups}" item="effectiveGroup"
open="(" separator="," close=")">
#{effectiveGroup,jdbcType=VARCHAR}
</foreach>
)
</if>
)
</sql> </sql>
<!-- Insert single entity --> <!-- Insert single entity -->

View File

@@ -68,12 +68,11 @@
SELECT connection_id SELECT connection_id
FROM guacamole_connection_permission FROM guacamole_connection_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ' AND permission = 'READ'
</select> </select>
@@ -94,12 +93,11 @@
WHERE WHERE
<if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}::integer</if> <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}::integer</if>
<if test="parentIdentifier == null">parent_id IS NULL</if> <if test="parentIdentifier == null">parent_id IS NULL</if>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ' AND permission = 'READ'
</select> </select>
@@ -175,12 +173,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND guacamole_connection_permission.entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_connection_permission.entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ' AND permission = 'READ'
GROUP BY guacamole_connection.connection_id; GROUP BY guacamole_connection.connection_id;
@@ -192,12 +189,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
SELECT SELECT
@@ -211,12 +207,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
</select> </select>

View File

@@ -166,23 +166,21 @@
<!-- Restrict to readable connections --> <!-- Restrict to readable connections -->
JOIN guacamole_connection_permission ON JOIN guacamole_connection_permission ON
guacamole_connection_history.connection_id = guacamole_connection_permission.connection_id guacamole_connection_history.connection_id = guacamole_connection_permission.connection_id
AND guacamole_connection_permission.entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_connection_permission.entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND guacamole_connection_permission.permission = 'READ' AND guacamole_connection_permission.permission = 'READ'
<!-- Restrict to readable users --> <!-- Restrict to readable users -->
JOIN guacamole_user_permission ON JOIN guacamole_user_permission ON
guacamole_connection_history.user_id = guacamole_user_permission.affected_user_id guacamole_connection_history.user_id = guacamole_user_permission.affected_user_id
AND guacamole_user_permission.entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND guacamole_user_permission.permission = 'READ' AND guacamole_user_permission.permission = 'READ'
<!-- Search terms --> <!-- Search terms -->

View File

@@ -69,12 +69,11 @@
SELECT connection_group_id SELECT connection_group_id
FROM guacamole_connection_group_permission FROM guacamole_connection_group_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ' AND permission = 'READ'
</select> </select>
@@ -95,12 +94,11 @@
WHERE WHERE
<if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}::integer</if> <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}::integer</if>
<if test="parentIdentifier == null">parent_id IS NULL</if> <if test="parentIdentifier == null">parent_id IS NULL</if>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ' AND permission = 'READ'
</select> </select>
@@ -171,12 +169,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
SELECT parent_id, guacamole_connection_group.connection_group_id SELECT parent_id, guacamole_connection_group.connection_group_id
@@ -187,12 +184,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
SELECT parent_id, guacamole_connection.connection_id SELECT parent_id, guacamole_connection.connection_id
@@ -203,12 +199,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
SELECT SELECT
@@ -222,12 +217,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
</select> </select>

View File

@@ -40,12 +40,11 @@
connection_group_id connection_group_id
FROM guacamole_connection_group_permission FROM guacamole_connection_group_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
</select> </select>
@@ -58,12 +57,11 @@
connection_group_id connection_group_id
FROM guacamole_connection_group_permission FROM guacamole_connection_group_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type
AND connection_group_id = #{identifier,jdbcType=INTEGER}::integer AND connection_group_id = #{identifier,jdbcType=INTEGER}::integer
@@ -75,12 +73,11 @@
SELECT DISTINCT connection_group_id SELECT DISTINCT connection_group_id
FROM guacamole_connection_group_permission FROM guacamole_connection_group_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND connection_group_id IN AND connection_group_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">

View File

@@ -40,12 +40,11 @@
connection_id connection_id
FROM guacamole_connection_permission FROM guacamole_connection_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
</select> </select>
@@ -58,12 +57,11 @@
connection_id connection_id
FROM guacamole_connection_permission FROM guacamole_connection_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type
AND connection_id = #{identifier,jdbcType=INTEGER}::integer AND connection_id = #{identifier,jdbcType=INTEGER}::integer
@@ -75,12 +73,11 @@
SELECT DISTINCT connection_id SELECT DISTINCT connection_id
FROM guacamole_connection_permission FROM guacamole_connection_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND connection_id IN AND connection_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">

View File

@@ -40,13 +40,11 @@
sharing_profile_id sharing_profile_id
FROM guacamole_sharing_profile_permission FROM guacamole_sharing_profile_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
</select> </select>
@@ -59,12 +57,11 @@
sharing_profile_id sharing_profile_id
FROM guacamole_sharing_profile_permission FROM guacamole_sharing_profile_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type
AND sharing_profile_id = #{identifier,jdbcType=INTEGER}::integer AND sharing_profile_id = #{identifier,jdbcType=INTEGER}::integer
@@ -76,12 +73,11 @@
SELECT DISTINCT sharing_profile_id SELECT DISTINCT sharing_profile_id
FROM guacamole_sharing_profile_permission FROM guacamole_sharing_profile_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND sharing_profile_id IN AND sharing_profile_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">

View File

@@ -38,12 +38,11 @@
permission permission
FROM guacamole_system_permission FROM guacamole_system_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
</select> </select>
@@ -55,12 +54,11 @@
permission permission
FROM guacamole_system_permission FROM guacamole_system_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = #{type,jdbcType=VARCHAR}::guacamole_system_permission_type AND permission = #{type,jdbcType=VARCHAR}::guacamole_system_permission_type
</select> </select>

View File

@@ -42,12 +42,11 @@
JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id
JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id
WHERE WHERE
guacamole_user_permission.entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND affected_entity.type = 'USER'::guacamole_entity_type AND affected_entity.type = 'USER'::guacamole_entity_type
</select> </select>
@@ -63,12 +62,11 @@
JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id
JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id
WHERE WHERE
guacamole_user_permission.entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type AND permission = #{type,jdbcType=VARCHAR}::guacamole_object_permission_type
AND affected_entity.name = #{identifier,jdbcType=VARCHAR} AND affected_entity.name = #{identifier,jdbcType=VARCHAR}
AND affected_entity.type = 'USER'::guacamole_entity_type AND affected_entity.type = 'USER'::guacamole_entity_type
@@ -83,12 +81,11 @@
JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id JOIN guacamole_user affected_user ON guacamole_user_permission.affected_user_id = affected_user.user_id
JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id JOIN guacamole_entity affected_entity ON affected_user.entity_id = affected_entity.entity_id
WHERE WHERE
guacamole_user_permission.entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="inherit"/> <property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{entity.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND affected_entity.name IN AND affected_entity.name IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">

View File

@@ -52,12 +52,11 @@
SELECT sharing_profile_id SELECT sharing_profile_id
FROM guacamole_sharing_profile_permission FROM guacamole_sharing_profile_permission
WHERE WHERE
entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ' AND permission = 'READ'
</select> </select>
@@ -104,12 +103,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
SELECT SELECT
@@ -123,12 +121,11 @@
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer #{identifier,jdbcType=INTEGER}::integer
</foreach> </foreach>
AND entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
</select> </select>

View File

@@ -70,16 +70,53 @@
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id
WHERE WHERE
guacamole_user_permission.entity_id IN ( <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND guacamole_entity.type = 'USER'::guacamole_entity_type AND guacamole_entity.type = 'USER'::guacamole_entity_type
AND permission = 'READ' AND permission = 'READ'
</select> </select>
<!-- Select names of all effective (including inherited) groups -->
<select id="selectEffectiveGroupIdentifiers" resultType="string">
WITH RECURSIVE related_entity(entity_id) AS (
SELECT
guacamole_user_group.entity_id
FROM guacamole_user_group
JOIN guacamole_user_group_member ON guacamole_user_group.user_group_id = guacamole_user_group_member.user_group_id
WHERE
guacamole_user_group_member.member_entity_id = #{user.entityID}
<if test="!effectiveGroups.isEmpty()">
UNION
SELECT
guacamole_entity.entity_id
FROM guacamole_entity
WHERE
type = 'USER_GROUP'::guacamole_entity_type
AND name IN
<foreach collection="effectiveGroups" item="effectiveGroup"
open="(" separator="," close=")">
#{effectiveGroup,jdbcType=VARCHAR}
</foreach>
</if>
UNION
SELECT
guacamole_user_group.entity_id
FROM related_entity
JOIN guacamole_user_group_member ON related_entity.entity_id = guacamole_user_group_member.member_entity_id
JOIN guacamole_user_group ON guacamole_user_group.user_group_id = guacamole_user_group_member.user_group_id
)
SELECT name
FROM related_entity
JOIN guacamole_entity ON related_entity.entity_id = guacamole_entity.entity_id
WHERE
guacamole_entity.type = 'USER_GROUP'::guacamole_entity_type;
</select>
<!-- Select multiple users by username --> <!-- Select multiple users by username -->
<select id="select" resultMap="UserResultMap" <select id="select" resultMap="UserResultMap"
resultSets="users,arbitraryAttributes"> resultSets="users,arbitraryAttributes">
@@ -163,12 +200,11 @@
#{identifier,jdbcType=VARCHAR} #{identifier,jdbcType=VARCHAR}
</foreach> </foreach>
AND guacamole_entity.type = 'USER'::guacamole_entity_type AND guacamole_entity.type = 'USER'::guacamole_entity_type
AND guacamole_user_permission.entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ' AND permission = 'READ'
GROUP BY guacamole_user.user_id, guacamole_entity.entity_id; GROUP BY guacamole_user.user_id, guacamole_entity.entity_id;
@@ -186,12 +222,11 @@
#{identifier,jdbcType=VARCHAR} #{identifier,jdbcType=VARCHAR}
</foreach> </foreach>
AND guacamole_entity.type = 'USER'::guacamole_entity_type AND guacamole_entity.type = 'USER'::guacamole_entity_type
AND guacamole_user_permission.entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND permission = 'READ'; AND permission = 'READ';
</select> </select>

View File

@@ -156,12 +156,11 @@
<!-- Restrict to readable users --> <!-- Restrict to readable users -->
JOIN guacamole_user_permission ON JOIN guacamole_user_permission ON
guacamole_user_history.user_id = guacamole_user_permission.affected_user_id guacamole_user_history.user_id = guacamole_user_permission.affected_user_id
AND guacamole_user_permission.entity_id IN ( AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.relatedEntities"> <property name="column" value="guacamole_user_permission.entity_id"/>
<property name="inheritFlag" value="true"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND guacamole_user_permission.permission = 'READ' AND guacamole_user_permission.permission = 'READ'
<!-- Search terms --> <!-- Search terms -->