From b2f74a68298049ec3d2f1500a23680375100de0e Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Thu, 10 Oct 2024 07:46:45 -0400 Subject: [PATCH 1/3] GUACAMOLE-1239: Correct spelling of parameter annotations for caseSensitive parameters. --- .../guacamole/auth/jdbc/permission/UserPermissionMapper.java | 2 +- .../auth/jdbc/usergroup/UserGroupMemberUserMapper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 c3489e508..daa3c0263 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 @@ -155,6 +155,6 @@ public interface UserPermissionMapper extends ObjectPermissionMapper { @Param("permissions") Collection permissions, @Param("identifiers") Collection identifiers, @Param("effectiveGroups") Collection effectiveGroups, - @Param("caseSenstive") boolean caseSensitive); + @Param("caseSensitive") boolean caseSensitive); } 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 3b2c3175b..93435afcf 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 @@ -80,6 +80,6 @@ public interface UserGroupMemberUserMapper extends ObjectRelationMapper children, - @Param("caseSesitive") boolean caseSensitive); + @Param("caseSensitive") boolean caseSensitive); } From 3d86026cb1760a0ef7a64e63d69407109e1bb962 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Fri, 11 Oct 2024 11:19:04 -0400 Subject: [PATCH 2/3] GUACAMOLE-1239: Make sure case sensitivity warnings are only displayed at startup. --- .../mysql/MySQLAuthenticationProviderModule.java | 16 ++++++++++++++++ .../auth/mysql/conf/MySQLEnvironment.java | 15 ++------------- .../SQLServerAuthenticationProviderModule.java | 16 ++++++++++++++++ .../sqlserver/conf/SQLServerEnvironment.java | 9 --------- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java index 62cf0c4c0..faedb237a 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLAuthenticationProviderModule.java @@ -30,12 +30,19 @@ import org.apache.guacamole.auth.mysql.conf.MySQLDriver; import org.apache.guacamole.auth.mysql.conf.MySQLEnvironment; import org.apache.guacamole.auth.mysql.conf.MySQLSSLMode; import org.mybatis.guice.datasource.helper.JdbcHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Guice module which configures MySQL-specific injections. */ public class MySQLAuthenticationProviderModule implements Module { + /** + * Logger for this class. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(MySQLAuthenticationProviderModule.class); + /** * MyBatis-specific configuration properties. */ @@ -121,6 +128,15 @@ public class MySQLAuthenticationProviderModule implements Module { TimeZone serverTz = environment.getServerTimeZone(); if (serverTz != null) driverProperties.setProperty("serverTimezone", serverTz.getID()); + + // Check for case-sensitivity and warn admin + if (environment.getCaseSensitiveUsernames()) + LOGGER.warn("The MySQL module is currently configured to support " + + "case-sensitive username comparisons, however, the default " + + "collations for MySQL databases do not support " + + "case-sensitive string comparisons. If you want usernames " + + "within Guacamole to be treated as case-sensitive, further " + + "database configuration may be required."); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java index 08ccf5404..c26317332 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java @@ -446,23 +446,12 @@ public class MySQLEnvironment extends JDBCEnvironment { @Override public boolean getCaseSensitiveUsernames() throws GuacamoleException { - // Get the configured value for the property. - boolean caseSensitiveUsernames = getProperty( + // Return the configured value for the property, or the global value. + return getProperty( MySQLGuacamoleProperties.MYSQL_CASE_SENSITIVE_USERNAMES, super.getCaseSensitiveUsernames() ); - // If property has been set to true, warn the admin. - if (caseSensitiveUsernames) - logger.warn("You have enabled case-sensitive usernames; however, " - + "MySQL's default collations do not support case-sensitive " - + "string comparisons. If you really want case-sensitive " - + "usernames you will need to configure your database " - + "appropriately."); - - // Return the configured setting. - return caseSensitiveUsernames; - } } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java index 5a3d4002b..f2f5e45cd 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java @@ -28,12 +28,19 @@ import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.sqlserver.conf.SQLServerDriver; import org.apache.guacamole.auth.sqlserver.conf.SQLServerEnvironment; import org.mybatis.guice.datasource.helper.JdbcHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Guice module which configures SQLServer-specific injections. */ public class SQLServerAuthenticationProviderModule implements Module { + /** + * Logger for this class. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(SQLServerAuthenticationProviderModule.class); + /** * MyBatis-specific configuration properties. */ @@ -88,6 +95,15 @@ public class SQLServerAuthenticationProviderModule implements Module { // Capture which driver to use for the connection. this.sqlServerDriver = environment.getSQLServerDriver(); + + // Check for case-sensitivity and warn admin. + if (environment.getCaseSensitiveUsernames()) + LOGGER.warn("The SQL Server module is currently configured to support " + + "case-sensitive username comparisons, however, the default " + + "collations for SQL Server databases do not support " + + "case-sensitive string comparisons. If you want usernames " + + "within Guacamole to be treated as case-sensitive, further " + + "database configuration may be required."); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java index 9e2d540bb..68568d658 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/conf/SQLServerEnvironment.java @@ -338,15 +338,6 @@ public class SQLServerEnvironment extends JDBCEnvironment { super.getCaseSensitiveUsernames() ); - // If property has been set to true, warn the admin. - if (caseSensitiveUsernames) - logger.warn("You have configured this extension for case-sensitive " - + "username comparisons, however, the default collations " - + "for SQL Server databases do not support case-sensitive " - + "string comparisons. Further database configuration may " - + "be required in order for case-sensitive username " - + "comparisons to function correctly."); - // Return as configured return caseSensitiveUsernames; From 76d37b40719c01d76114e95d6417493449b879cc Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Fri, 11 Oct 2024 11:21:36 -0400 Subject: [PATCH 3/3] GUACAMOLE-1239: Move caseSensitive parameter to the base mapper classes. --- .../base/ModeledDirectoryObjectMapper.java | 21 +++++- .../base/ModeledDirectoryObjectService.java | 28 ++++++-- .../auth/jdbc/base/ObjectRelationMapper.java | 16 ++++- .../auth/jdbc/base/RelatedObjectSet.java | 22 +++++- .../AbstractGuacamoleTunnelService.java | 4 +- .../guacamole/auth/jdbc/user/UserMapper.java | 70 +------------------ .../guacamole/auth/jdbc/user/UserService.java | 5 ++ .../usergroup/UserGroupMemberUserMapper.java | 57 +-------------- .../usergroup/UserGroupMemberUserSet.java | 12 ++++ 9 files changed, 97 insertions(+), 138 deletions(-) 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 8ff0cc1c7..5ff8edf15 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 @@ public interface ModeledDirectoryObjectMapper { * * @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 @@ public interface ModeledDirectoryObjectMapper { * @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 @@ public interface ModeledDirectoryObjectMapper { * * @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 fe587160d..e7e04e5e7 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 allObjects = Lists.partition(filteredIdentifiers, batchSize).stream() @@ -415,12 +435,12 @@ public abstract class ModeledDirectoryObjectService { * @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 @@ 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 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 add954c5a..b661c3bf5 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 abstract class RelatedObjectSet 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 abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS // 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 243618c2b..f9e63a6e5 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 9478fd371..686486a85 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 @@ public class UserService extends ModeledDirectoryObjectService { - - /** - * 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 989df551f..e694edd8b 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 @@ package org.apache.guacamole.auth.jdbc.usergroup; 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;