diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java index e7e04e5e7..94c7407da 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectService.java @@ -513,7 +513,7 @@ public abstract class ModeledDirectoryObjectService implicitPermissions = getImplicitPermissions(user, model); if (!implicitPermissions.isEmpty()) - getPermissionMapper().insert(implicitPermissions); + getPermissionMapper().insert(implicitPermissions, getCaseSensitiveIdentifiers()); // Add any arbitrary attributes if (model.hasArbitraryAttributes()) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/AbstractPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/AbstractPermissionService.java index eb320bdb3..90dec2f9d 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/AbstractPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/AbstractPermissionService.java @@ -42,7 +42,7 @@ import org.apache.guacamole.net.auth.permission.PermissionSet; public abstract class AbstractPermissionService, PermissionType extends Permission> implements PermissionService { - + /** * Returns the ObjectPermissionSet related to the type of the given entity. * If the given entity represents a user, then the ObjectPermissionSet diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java index fd70f6ac1..f9d55c14d 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledObjectPermissionService.java @@ -133,10 +133,12 @@ public abstract class ModeledObjectPermissionService // Create permissions only if user has permission to do so if (canAlterPermissions(user, targetEntity, permissions)) { + boolean caseSensitive = getCaseSensitiveIdentifiers(); + batchPermissionUpdates(permissions, permissionSubset -> { Collection models = getModelInstances( targetEntity, permissionSubset); - getPermissionMapper().insert(models); + getPermissionMapper().insert(models, caseSensitive); }); return; @@ -156,10 +158,12 @@ public abstract class ModeledObjectPermissionService // Delete permissions only if user has permission to do so if (canAlterPermissions(user, targetEntity, permissions)) { + boolean caseSensitive = getCaseSensitiveIdentifiers(); + batchPermissionUpdates(permissions, permissionSubset -> { Collection models = getModelInstances( targetEntity, permissionSubset); - getPermissionMapper().delete(models); + getPermissionMapper().delete(models, caseSensitive); }); return; @@ -179,7 +183,7 @@ public abstract class ModeledObjectPermissionService // Retrieve permissions only if allowed if (canReadPermissions(user, targetEntity)) return getPermissionMapper().selectOne(targetEntity.getModel(), - type, identifier, effectiveGroups) != null; + type, identifier, effectiveGroups, getCaseSensitiveIdentifiers()) != null; // User cannot read this entity's permissions throw new GuacamoleSecurityException("Permission denied."); @@ -205,7 +209,7 @@ public abstract class ModeledObjectPermissionService if (canReadPermissions(user, targetEntity)) return getPermissionMapper().selectAccessibleIdentifiers( targetEntity.getModel(), permissions, identifiers, - effectiveGroups); + effectiveGroups, getCaseSensitiveIdentifiers()); // User cannot read this entity's permissions throw new GuacamoleSecurityException("Permission denied."); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledPermissionService.java index 6f8c09f73..ee35c44e1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/ModeledPermissionService.java @@ -192,7 +192,10 @@ public abstract class ModeledPermissionService effectiveGroups); + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); /** * Retrieves the subset of the given identifiers for which the given entity @@ -79,6 +84,10 @@ public interface ObjectPermissionMapper extends PermissionMapper selectAccessibleIdentifiers(@Param("entity") EntityModel entity, @Param("permissions") Collection permissions, @Param("identifiers") Collection identifiers, - @Param("effectiveGroups") Collection effectiveGroups); + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionMapper.java index edd66f494..92746e4f3 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionMapper.java @@ -43,12 +43,17 @@ public interface PermissionMapper { * when determining the permissions effectively granted to the user. If * no groups are given, only permissions directly granted to the user * will be used. + * + * @param caseSensitive + * "true" if identifiers should be treated as case-sensitive, otherwise + * "false". * * @return * All permissions associated with the given entity. */ Collection select(@Param("entity") EntityModel entity, - @Param("effectiveGroups") Collection effectiveGroups); + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); /** * Inserts the given permissions into the database. If any permissions @@ -56,11 +61,16 @@ public interface PermissionMapper { * * @param permissions * The permissions to insert. + * + * @param caseSensitive + * "true" if identifiers should be treated as case-sensitive, otherwise + * "false". * * @return * The number of rows inserted. */ - int insert(@Param("permissions") Collection permissions); + int insert(@Param("permissions") Collection permissions, + @Param("caseSensitive") boolean caseSensitive); /** * Deletes the given permissions from the database. If any permissions do @@ -68,10 +78,15 @@ public interface PermissionMapper { * * @param permissions * The permissions to delete. + * + * @param caseSensitive + * "true" if identifiers should be treated as case-sensitive, otherwise + * "false". * * @return * The number of rows deleted. */ - int delete(@Param("permissions") Collection permissions); + int delete(@Param("permissions") Collection permissions, + @Param("caseSensitive") boolean caseSensitive); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionService.java index a48157ebc..63584c032 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/PermissionService.java @@ -43,6 +43,24 @@ import org.apache.guacamole.net.auth.permission.PermissionSet; public interface PermissionService, PermissionType extends Permission> { + /** + * Return "true" if identifiers should be treated as case-sensitive, + * otherwise "false". + * + * @return + * "true" if identifiers should be treated as case-sensitive, otherwise + * "false". + * + * @throws GuacamoleException + * If an error occurs retrieving configuration information related to + * case-sensitivity. + */ + default boolean getCaseSensitiveIdentifiers() throws GuacamoleException { + + // By default identifiers are case-insensitive. + return false; + } + /** * Returns a permission set that can be used to retrieve and manipulate the * permissions of the given entity. diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SystemPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SystemPermissionService.java index 1a0f1523c..63bd8b3bf 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SystemPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/SystemPermissionService.java @@ -98,10 +98,13 @@ public class SystemPermissionService // system permissions if (user.isPrivileged()) { + // Pull identifier case sensitivity + boolean caseSensitive = getCaseSensitiveIdentifiers(); + batchPermissionUpdates(permissions, permissionSubset -> { Collection models = getModelInstances( targetEntity, permissionSubset); - systemPermissionMapper.insert(models); + systemPermissionMapper.insert(models, caseSensitive); }); return; @@ -125,10 +128,13 @@ public class SystemPermissionService if (user.getUser().getIdentifier().equals(targetEntity.getIdentifier())) throw new GuacamoleUnsupportedException("Removing your own administrative permissions is not allowed."); + // Pull case sensitivity + boolean caseSensitive = getCaseSensitiveIdentifiers(); + batchPermissionUpdates(permissions, permissionSubset -> { Collection models = getModelInstances( targetEntity, permissionSubset); - systemPermissionMapper.delete(models); + systemPermissionMapper.delete(models, caseSensitive); }); return; diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java index daa3c0263..b093bdbd1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.java @@ -19,142 +19,7 @@ package org.apache.guacamole.auth.jdbc.permission; -import java.util.Collection; -import org.apache.guacamole.auth.jdbc.base.EntityModel; -import org.apache.guacamole.net.auth.permission.ObjectPermission; -import org.apache.ibatis.annotations.Param; - /** * Mapper for user permissions. */ -public interface UserPermissionMapper extends ObjectPermissionMapper { - - /** - * Deletes the given permissions from the database. If any permissions do - * not exist, they will be ignored. - * - * @param permissions - * The permissions to delete. - * - * @param caseSensitive - * Whether or not string comparisons for usernames will be done in a - * case-sensitive manner. - * - * @return - * The number of rows deleted. - */ - int delete(@Param("permissions") Collection permissions, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Inserts the given permissions into the database. If any permissions - * already exist, they will be ignored. - * - * @param permissions - * The permissions to insert. - * - * @param caseSensitive - * Whether or not string comparisons for usernames will be done in a - * case-sensitive manner. - * - * @return - * The number of rows inserted. - */ - int insert(@Param("permissions") Collection permissions, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Retrieves all permissions associated with the given entity (user or user - * group). - * - * @param entity - * The entity to retrieve permissions for. - * - * @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. - * - * @param caseSensitive - * Whether or not string comparisons for usernames will be done in a - * case-sensitive manner. - * - * @return - * All permissions associated with the given entity. - */ - Collection select(@Param("entity") EntityModel entity, - @Param("effectiveGroups") Collection effectiveGroups, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Retrieve the permission of the given type associated with the given - * entity and object, if it exists. If no such permission exists, null is - * returned. - * - * @param entity - * The entity to retrieve permissions for. - * - * @param type - * The type of permission to return. - * - * @param identifier - * The identifier of the object affected by the permission to return. - * - * @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. - * - * @param caseSensitive - * Whether or not string comparisons for usernames will be done in a - * case-sensitive manner. - * - * @return - * The requested permission, or null if no such permission is granted - * to the given entity for the given object. - */ - ObjectPermissionModel selectOne(@Param("entity") EntityModel entity, - @Param("type") ObjectPermission.Type type, - @Param("identifier") String identifier, - @Param("effectiveGroups") Collection effectiveGroups, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Retrieves the subset of the given identifiers for which the given entity - * has at least one of the given permissions. - * - * @param entity - * The entity to check permissions of. - * - * @param permissions - * The permissions to check. An identifier will be included in the - * resulting collection if at least one of these permissions is granted - * for the associated object - * - * @param identifiers - * The identifiers of the objects affected by the permissions being - * checked. - * - * @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. - * - * @param caseSensitive - * Whether or not string comparisons for usernames will be done in a - * case-sensitive manner. - * - * @return - * A collection containing the subset of identifiers for which at least - * one of the specified permissions is granted. - */ - Collection selectAccessibleIdentifiers(@Param("entity") EntityModel entity, - @Param("permissions") Collection permissions, - @Param("identifiers") Collection identifiers, - @Param("effectiveGroups") Collection effectiveGroups, - @Param("caseSensitive") boolean caseSensitive); - -} +public interface UserPermissionMapper extends ObjectPermissionMapper {} \ No newline at end of file diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionService.java index ed8689a7f..11b453754 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/permission/UserPermissionService.java @@ -24,6 +24,7 @@ import com.google.inject.Provider; import java.util.Set; import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.base.EntityModel; import org.apache.guacamole.auth.jdbc.base.ModeledPermissions; @@ -46,6 +47,17 @@ public class UserPermissionService extends ModeledObjectPermissionService { @Inject private Provider userPermissionSetProvider; + /** + * The server environment for retrieving configuration data. + */ + @Inject + private JDBCEnvironment environment; + + @Override + public boolean getCaseSensitiveIdentifiers() throws GuacamoleException { + return environment.getCaseSensitiveUsernames(); + } + @Override protected ObjectPermissionMapper getPermissionMapper() { return userPermissionMapper;