diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java index 8ff0cc1c7f..5ff8edf156 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledDirectoryObjectMapper.java @@ -76,11 +76,16 @@ Set selectReadableIdentifiers(@Param("user") UserModel user, * * @param identifiers * The identifiers of the objects to return. + * + * @param caseSensitive + * true if the query should evaluate identifiers in a case-sensitive + * manner, otherwise false. * * @return * A Collection of all objects having the given identifiers. */ - Collection select(@Param("identifiers") Collection identifiers); + Collection select(@Param("identifiers") Collection identifiers, + @Param("caseSensitive") boolean caseSensitive); /** * Selects all objects which have the given identifiers and are explicitly @@ -99,13 +104,18 @@ Set selectReadableIdentifiers(@Param("user") UserModel user, * @param effectiveGroups * The identifiers of any known effective groups that should be taken * into account, such as those defined externally to the database. + * + * @param caseSensitive + * true if the query should evaluate identifiers in a case-sensitive + * manner, otherwise false. * * @return * A Collection of all objects having the given identifiers. */ Collection selectReadable(@Param("user") UserModel user, @Param("identifiers") Collection identifiers, - @Param("effectiveGroups") Collection effectiveGroups); + @Param("effectiveGroups") Collection effectiveGroups, + @Param("caseSensitive") boolean caseSensitive); /** * Inserts the given object into the database. If the object already @@ -125,11 +135,16 @@ Collection selectReadable(@Param("user") UserModel user, * * @param identifier * The identifier of the object to delete. + * + * @param caseSensitive + * true if the query should evaluate the identifier in a + * case-sensitive manner, otherwise false. * * @return * The number of rows deleted. */ - int delete(@Param("identifier") String identifier); + int delete(@Param("identifier") String identifier, + @Param("caseSensitive") boolean caseSensitive); /** * Updates the given existing object in the database. If the object does 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 fe587160dc..e7e04e5e71 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 @@ -115,7 +115,25 @@ public abstract class ModeledDirectoryObjectService retrieveObjects(ModeledAuthenticatedUser user, int batchSize = environment.getBatchSize(); boolean userIsPrivileged = user.isPrivileged(); + + boolean caseSensitive = getCaseSensitiveIdentifiers(); // Process the filteredIdentifiers in batches using Lists.partition() and flatMap Collection allObjects = Lists.partition(filteredIdentifiers, batchSize).stream() @@ -415,12 +435,12 @@ public Collection retrieveObjects(ModeledAuthenticatedUser user, // Bypass permission checks if the user is privileged if (userIsPrivileged) - objects = getObjectMapper().select(chunk); + objects = getObjectMapper().select(chunk, caseSensitive); // Otherwise only return explicitly readable identifiers else objects = getObjectMapper().selectReadable(user.getUser().getModel(), - chunk, user.getEffectiveUserGroups()); + chunk, user.getEffectiveUserGroups(), caseSensitive); return objects.stream(); }) @@ -510,7 +530,7 @@ public void deleteObject(ModeledAuthenticatedUser user, String identifier) beforeDelete(user, identifier); // Delete object - getObjectMapper().delete(identifier); + getObjectMapper().delete(identifier, getCaseSensitiveIdentifiers()); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectRelationMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectRelationMapper.java index c2763ecc80..df09b7734e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectRelationMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ObjectRelationMapper.java @@ -48,12 +48,18 @@ public interface ObjectRelationMapper { * @param children * The identifiers of the objects on the child side of the one-to-many * relationship represented by the RelatedObjectSet. + * + * @param caseSensitive + * true if child identifiers should be treated as case-sensitive when + * performing lookups on them, or false if the queries should be done + * case-insensitively. * * @return * The number of rows inserted. */ int insert(@Param("parent") ParentModelType parent, - @Param("children") Collection children); + @Param("children") Collection children, + @Param("caseSensitive") boolean caseSensitive); /** * Deletes rows as necessary to modify the one-to-many relationship @@ -69,12 +75,18 @@ int insert(@Param("parent") ParentModelType parent, * @param children * The identifiers of the objects on the child side of the one-to-many * relationship represented by the RelatedObjectSet. + * + * @param caseSensitive + * true if child identifiers should be treated as case-sensitive when + * performing lookups on them, or false if the queries should be done + * case-insensitively. * * @return * The number of rows deleted. */ int delete(@Param("parent") ParentModelType parent, - @Param("children") Collection children); + @Param("children") Collection children, + @Param("caseSensitive") boolean caseSensitive); /** * Retrieves the identifiers of all objects on the child side of the diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java index add954c5ae..b661c3bf5c 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/RelatedObjectSet.java @@ -75,6 +75,24 @@ public void init(ModeledAuthenticatedUser currentUser, ParentObjectType parent) this.parent = parent; } + /** + * Return "true" if identifiers within a related object set 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 on + * case-sensitivity. + */ + protected boolean getCaseSensitiveIdentifiers() throws GuacamoleException { + + // Identifiers are not case-sensitive by default. + return false; + } + /** * Returns the mapper which provides low-level access to the database * models which drive the relation represented by this RelatedObjectSet. @@ -184,7 +202,7 @@ public void addObjects(Set identifiers) throws GuacamoleException { // Create relations only if permission is granted if (canAlterRelation(identifiers)) - getObjectRelationMapper().insert(parent.getModel(), identifiers); + getObjectRelationMapper().insert(parent.getModel(), identifiers, getCaseSensitiveIdentifiers()); // User lacks permission to add user groups else @@ -201,7 +219,7 @@ public void removeObjects(Set identifiers) throws GuacamoleException { // Delete relations only if permission is granted if (canAlterRelation(identifiers)) - getObjectRelationMapper().delete(parent.getModel(), identifiers); + getObjectRelationMapper().delete(parent.getModel(), identifiers, getCaseSensitiveIdentifiers()); // User lacks permission to remove user groups else diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java index e0a6091b07..2dcd168b91 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java @@ -638,7 +638,7 @@ private List getBalancedConnections(ModeledAuthenticatedUser identifiers = getPreferredConnections(user, identifiers); // Retrieve all children - Collection models = connectionMapper.select(identifiers); + Collection models = connectionMapper.select(identifiers, false); List connections = new ArrayList(models.size()); // Convert each retrieved model to a modeled connection @@ -679,7 +679,7 @@ public Collection getActiveConnections(ModeledAuthentica // Produce collection of readable connection identifiers Collection connections = connectionMapper.selectReadable(user.getUser().getModel(), - identifiers, user.getEffectiveUserGroups()); + identifiers, user.getEffectiveUserGroups(), false); // Ensure set contains only identifiers of readable connections identifiers.clear(); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java index 243618c2b0..f9e63a6e55 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserMapper.java @@ -19,7 +19,6 @@ package org.apache.guacamole.auth.jdbc.user; -import java.util.Collection; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper; import org.apache.ibatis.annotations.Param; @@ -36,7 +35,7 @@ public interface UserMapper extends ModeledDirectoryObjectMapper { * The username of the user to return. * * @param caseSensitive - * true if the search should evaluate usernames in a case-sensitive + * true if the search should evaluate the username in a case-sensitive * manner, otherwise false. * * @return @@ -44,72 +43,5 @@ public interface UserMapper extends ModeledDirectoryObjectMapper { */ UserModel selectOne(@Param("username") String username, @Param("caseSensitive") boolean caseSensitive); - - /** - * Selects all users which have the given identifiers. If an identifier - * has no corresponding object, it will be ignored. This should only be - * called on behalf of a system administrator. If users are needed by a - * non-administrative user who must have explicit read rights, use - * selectReadable() instead. - * - * @param identifiers - * The identifiers of the users to return. - * - * @param caseSensitive - * true if the query should evaluate username identifiers in a - * case-sensitive manner, otherwise false. - * - * @return - * A Collection of all objects having the given identifiers. - */ - Collection select(@Param("identifiers") Collection identifiers, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Selects all users which have the given identifiers and are explicitly - * readable by the given user. If an identifier has no corresponding - * object, or the corresponding user is unreadable, it will be ignored. - * If users are needed by a system administrator (who, by definition, - * does not need explicit read rights), use select() instead. - * - * @param user - * The user whose permissions should determine whether an object - * is returned. - * - * @param identifiers - * The identifiers of the users 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. - * - * @param caseSensitive - * true if the query should evaluate username identifiers in a - * case-sensitive manner, otherwise false. - * - * @return - * A Collection of all objects having the given identifiers. - */ - Collection selectReadable(@Param("user") UserModel user, - @Param("identifiers") Collection identifiers, - @Param("effectiveGroups") Collection effectiveGroups, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Deletes the given user from the database. If the user does not - * exist, this operation has no effect. - * - * @param identifier - * The identifier of the user to delete. - * - * @param caseSensitive - * true if the query should evaluate username identifiers in a - * case-sensitive manner, otherwise false. - * - * @return - * The number of rows deleted. - */ - int delete(@Param("identifier") String identifier, - @Param("caseSensitive") boolean caseSensitive); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java index 9478fd3719..686486a85a 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java @@ -217,6 +217,11 @@ protected UserModel getModelInstance(ModeledAuthenticatedUser currentUser, return model; } + + @Override + protected boolean getCaseSensitiveIdentifiers() throws GuacamoleException { + return environment.getCaseSensitiveUsernames(); + } @Override protected boolean hasCreatePermission(ModeledAuthenticatedUser user) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java index 93435afcf1..393a5bed52 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserMapper.java @@ -27,59 +27,4 @@ * Mapper for the one-to-many relationship between a user group and its user * members. */ -public interface UserGroupMemberUserMapper extends ObjectRelationMapper { - - /** - * Inserts rows as necessary to establish the one-to-many relationship - * represented by the RelatedObjectSet between the given parent and - * children. If the relation for any parent/child pair is already present, - * no attempt is made to insert a new row for that relation. - * - * @param parent - * The model of the object on the parent side of the one-to-many - * relationship represented by the RelatedObjectSet. - * - * @param children - * The identifiers of the objects on the child side of the one-to-many - * relationship represented by the RelatedObjectSet. - * - * @param caseSensitive - * True if username case should be respected when looking up the username - * in the guacamole_entity table, or false if the query to the - * guacamole_entity table should be done case-insensitively. - * - * @return - * The number of rows inserted. - */ - int insert(@Param("parent") UserGroupModel parent, - @Param("children") Collection children, - @Param("caseSensitive") boolean caseSensitive); - - /** - * Deletes rows as necessary to modify the one-to-many relationship - * represented by the RelatedObjectSet between the given parent and - * children. If the relation for any parent/child pair does not exist, - * that specific relation is ignored, and deletion proceeds with the - * remaining relations. - * - * @param parent - * The model of the object on the parent side of the one-to-many - * relationship represented by the RelatedObjectSet. - * - * @param children - * The identifiers of the objects on the child side of the one-to-many - * relationship represented by the RelatedObjectSet. - * - * @param caseSensitive - * True if username case should be respected when looking up the username - * in the guacamole_entity table, or false if the query to the - * guacamole_entity table should be done case-insensitively. - * - * @return - * The number of rows deleted. - */ - int delete(@Param("parent") UserGroupModel parent, - @Param("children") Collection children, - @Param("caseSensitive") boolean caseSensitive); - -} +public interface UserGroupMemberUserMapper extends ObjectRelationMapper {} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java index 989df551f1..e694edd8b7 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/usergroup/UserGroupMemberUserSet.java @@ -21,6 +21,7 @@ import com.google.inject.Inject; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.base.ObjectRelationMapper; import org.apache.guacamole.auth.jdbc.base.RelatedObjectSet; import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; @@ -36,7 +37,18 @@ public class UserGroupMemberUserSet extends RelatedObjectSet getObjectRelationMapper() { return userGroupMemberUserMapper;