diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java index 2e6301c37..52fbf9e64 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ActivityRecordMapper.java @@ -71,6 +71,11 @@ public interface ActivityRecordMapper { * retrieved, or null if records related to any such object should be * retrieved. * + * @param recordIdentifier + * The identifier of the specific history record to retrieve, if not + * all matching records. Search terms, etc. will still be applied to + * the single record. + * * @param terms * The search terms that must match the returned records. * @@ -85,6 +90,7 @@ public interface ActivityRecordMapper { * The results of the search performed with the given parameters. */ List search(@Param("identifier") String identifier, + @Param("recordIdentifier") String recordIdentifier, @Param("terms") Collection terms, @Param("sortPredicates") List sortPredicates, @Param("limit") int limit); @@ -106,6 +112,11 @@ public interface ActivityRecordMapper { * The user whose permissions should determine whether a record is * returned. * + * @param recordIdentifier + * The identifier of the specific history record to retrieve, if not + * all matching records. Search terms, etc. will still be applied to + * the single record. + * * @param terms * The search terms that must match the returned records. * @@ -127,6 +138,7 @@ public interface ActivityRecordMapper { */ List searchReadable(@Param("identifier") String identifier, @Param("user") UserModel user, + @Param("recordIdentifier") String recordIdentifier, @Param("terms") Collection terms, @Param("sortPredicates") List sortPredicates, @Param("limit") int limit, diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledActivityRecordSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledActivityRecordSet.java index 60446aab5..79346f51e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledActivityRecordSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ModeledActivityRecordSet.java @@ -29,6 +29,8 @@ import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.ActivityRecordSet.SortableProperty; import org.apache.guacamole.net.auth.AuthenticatedUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A JDBC implementation of ActivityRecordSet. Calls to asCollection() will @@ -41,6 +43,11 @@ import org.apache.guacamole.net.auth.AuthenticatedUser; public abstract class ModeledActivityRecordSet extends RestrictedObject implements ActivityRecordSet { + /** + * Logger for this class. + */ + private static final Logger logger = LoggerFactory.getLogger(ModeledActivityRecordSet.class); + /** * The set of strings that each must occur somewhere within the returned * records, whether within the associated username, an associated date, or @@ -73,6 +80,11 @@ public abstract class ModeledActivityRecordSet retrieveHistory( - AuthenticatedUser user, + protected abstract List retrieveHistory( + AuthenticatedUser user, String recordIdentifier, Set requiredContents, List sortPredicates, int limit) throws GuacamoleException; + @Override + public RecordType get(String identifier) throws GuacamoleException { + + List records = retrieveHistory(getCurrentUser(), + identifier, requiredContents, sortPredicates, limit); + + if (records.isEmpty()) + return null; + + if (records.size() == 1) + return records.get(0); + + logger.warn("Multiple history records match ID \"{}\"! This should " + + "not be possible and may indicate a bug or database " + + "corruption.", identifier); + return null; + + } + @Override public Collection asCollection() throws GuacamoleException { - return retrieveHistory(getCurrentUser(), requiredContents, + return retrieveHistory(getCurrentUser(), null, requiredContents, sortPredicates, limit); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java index baf005675..b788cab11 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java @@ -20,7 +20,6 @@ package org.apache.guacamole.auth.jdbc.connection; import com.google.inject.Inject; -import java.util.Collection; import java.util.List; import java.util.Set; import java.util.UUID; @@ -79,14 +78,15 @@ public class ConnectionRecordSet extends ModeledActivityRecordSet retrieveHistory( - AuthenticatedUser user, Set requiredContents, - List sortPredicates, int limit) - throws GuacamoleException { + protected List retrieveHistory( + AuthenticatedUser user, String recordIdentifier, + Set requiredContents, + List sortPredicates, + int limit) throws GuacamoleException { // Retrieve history from database return connectionService.retrieveHistory(identifier, getCurrentUser(), - requiredContents, sortPredicates, limit); + recordIdentifier, requiredContents, sortPredicates, limit); } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java index 16d378432..b3ed89ce8 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionService.java @@ -390,40 +390,6 @@ public class ConnectionService extends ModeledChildDirectoryObjectService retrieveHistory(ModeledAuthenticatedUser user, - ModeledConnection connection) throws GuacamoleException { - - String identifier = connection.getIdentifier(); - - // Get current active connections. - List records = new ArrayList<>(tunnelService.getActiveConnections(connection)); - Collections.reverse(records); - - // Add in the history records. - records.addAll(retrieveHistory(identifier, user, Collections.emptyList(), - Collections.emptyList(), Integer.MAX_VALUE)); - - return records; - - } - /** * Retrieves the connection history records matching the given criteria. * Retrieves up to limit connection history records matching @@ -437,6 +403,11 @@ public class ConnectionService extends ModeledChildDirectoryObjectService retrieveHistory(String identifier, - ModeledAuthenticatedUser user, + ModeledAuthenticatedUser user, String recordIdentifier, Collection requiredContents, List sortPredicates, int limit) throws GuacamoleException { @@ -465,54 +436,19 @@ public class ConnectionService extends ModeledChildDirectoryObjectServicelimit connection history records matching - * the given terms and sorted by the given predicates. Only history records - * associated with data that the given user can read are returned. - * - * @param user - * The user retrieving the connection history. - * - * @param requiredContents - * The search terms that must be contained somewhere within each of the - * returned records. - * - * @param sortPredicates - * A list of predicates to sort the returned records by, in order of - * priority. - * - * @param limit - * The maximum number of records that should be returned. - * - * @return - * The connection history of the given connection, including any - * active connections. - * - * @throws GuacamoleException - * If permission to read the connection history is denied. - */ - public List retrieveHistory(ModeledAuthenticatedUser user, - Collection requiredContents, - List sortPredicates, int limit) - throws GuacamoleException { - - return retrieveHistory(null, user, requiredContents, sortPredicates, limit); - - } /** * Connects to the given connection as the given user, using the given diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserRecordSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserRecordSet.java index a1ccf1212..f1c2771fb 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserRecordSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserRecordSet.java @@ -20,7 +20,6 @@ package org.apache.guacamole.auth.jdbc.user; import com.google.inject.Inject; -import java.util.Collection; import java.util.List; import java.util.Set; import java.util.UUID; @@ -80,14 +79,15 @@ public class UserRecordSet extends ModeledActivityRecordSet { } @Override - protected Collection retrieveHistory( - AuthenticatedUser user, Set requiredContents, + protected List retrieveHistory( + AuthenticatedUser user, String recordIdentifier, + Set requiredContents, List sortPredicates, int limit) throws GuacamoleException { // Retrieve history from database return userService.retrieveHistory(identifier, getCurrentUser(), - requiredContents, sortPredicates, limit); + recordIdentifier, requiredContents, sortPredicates, limit); } 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 03010e835..c43aa1b01 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 @@ -572,32 +572,6 @@ public class UserService extends ModeledDirectoryObjectService retrieveHistory(ModeledAuthenticatedUser authenticatedUser, - ModeledUser user) throws GuacamoleException { - - String username = user.getIdentifier(); - - return retrieveHistory(username, authenticatedUser, Collections.emptyList(), - Collections.emptyList(), Integer.MAX_VALUE); - - } - /** * Retrieves user login history records matching the given criteria. * Retrieves up to limit user history records matching the @@ -611,6 +585,11 @@ public class UserService extends ModeledDirectoryObjectService retrieveHistory(String username, - ModeledAuthenticatedUser user, + ModeledAuthenticatedUser user, String recordIdentifier, Collection requiredContents, List sortPredicates, int limit) throws GuacamoleException { @@ -638,52 +617,18 @@ public class UserService extends ModeledDirectoryObjectServicelimit user history records matching the - * given terms and sorted by the given predicates. Only history records - * associated with data that the given user can read are returned. - * - * @param user - * The user retrieving the login history. - * - * @param requiredContents - * The search terms that must be contained somewhere within each of the - * returned records. - * - * @param sortPredicates - * A list of predicates to sort the returned records by, in order of - * priority. - * - * @param limit - * The maximum number of records that should be returned. - * - * @return - * The login history of the given user, including any active sessions. - * - * @throws GuacamoleException - * If permission to read the user login history is denied. - */ - public List retrieveHistory(ModeledAuthenticatedUser user, - Collection requiredContents, - List sortPredicates, int limit) - throws GuacamoleException { - - return retrieveHistory(null, user, requiredContents, sortPredicates, limit); - - } } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml index 2ff98127c..11ca348dd 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml @@ -97,9 +97,13 @@ - + + + guacamole_connection_history.history_id = #{recordIdentifier,jdbcType=VARCHAR} + + - guacamole_connection_history.connection_id = #{identifier,jdbcType=VARCHAR} + AND guacamole_connection_history.connection_id = #{identifier,jdbcType=VARCHAR} @@ -163,9 +167,13 @@ - + + + guacamole_connection_history.history_id = #{recordIdentifier,jdbcType=VARCHAR} + + - guacamole_connection_history.connection_id IN ( + AND guacamole_connection_history.connection_id IN ( diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml index 5d47c9baa..9857193b4 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml @@ -95,11 +95,15 @@ - - - guacamole_connection_history.connection_id = #{identifier,jdbcType=INTEGER}::integer + + + guacamole_connection_history.history_id = #{recordIdentifier,jdbcType=INTEGER}::integer - + + + AND guacamole_connection_history.connection_id = #{identifier,jdbcType=INTEGER}::integer + + ( @@ -161,9 +165,13 @@ - + + + guacamole_connection_history.history_id = #{recordIdentifier,jdbcType=INTEGER}::integer + + - guacamole_connection_history.connection_id IN ( + AND guacamole_connection_history.connection_id IN ( diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml index 4642303f8..81f31d428 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml @@ -95,9 +95,13 @@ - + + + [guacamole_connection_history].history_id = #{recordIdentifier,jdbcType=INTEGER} + + - [guacamole_connection_history].connection_id = #{identifier,jdbcType=INTEGER} + AND [guacamole_connection_history].connection_id = #{identifier,jdbcType=INTEGER} @@ -159,9 +163,13 @@ - + + + [guacamole_connection_history].history_id = #{recordIdentifier,jdbcType=INTEGER} + + - [guacamole_connection_history].connection_id IN ( + AND [guacamole_connection_history].connection_id IN (