GUACAMOLE-1123: Merge standardization on ActivityRecordSet for history retrieval.

This commit is contained in:
Mike Jumper
2020-10-30 11:27:04 -07:00
committed by GitHub
29 changed files with 765 additions and 407 deletions

View File

@@ -48,7 +48,7 @@ public abstract class ModeledActivityRecordSet<RecordType extends ActivityRecord
* strings within the collection will be excluded from the results.
*/
private final Set<ActivityRecordSearchTerm> requiredContents =
new HashSet<ActivityRecordSearchTerm>();
new HashSet<>();
/**
* The maximum number of history records that should be returned by a call
@@ -62,7 +62,7 @@ public abstract class ModeledActivityRecordSet<RecordType extends ActivityRecord
* properties.
*/
private final List<ActivityRecordSortPredicate> sortPredicates =
new ArrayList<ActivityRecordSortPredicate>();
new ArrayList<>();
/**
* Retrieves the history records matching the given criteria. Retrieves up

View File

@@ -62,8 +62,12 @@ public interface ConnectionRecordMapper {
* the data they are associated with is is readable by any particular user.
* This should only be called on behalf of a system administrator. If
* records are needed by a non-administrative user who must have explicit
* read rights, use searchReadable() instead.
* read rights, use {@link searchReadable()} instead.
*
* @param identifier
* The optional connection identifier to which records should be limited,
* or null if all records should be retrieved.
*
* @param terms
* The search terms that must match the returned records.
*
@@ -77,7 +81,8 @@ public interface ConnectionRecordMapper {
* @return
* The results of the search performed with the given parameters.
*/
List<ConnectionRecordModel> search(@Param("terms") Collection<ActivityRecordSearchTerm> terms,
List<ConnectionRecordModel> search(@Param("identifier") String identifier,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit);
@@ -86,8 +91,13 @@ public interface ConnectionRecordMapper {
* the given terms, sorted by the given predicates. Only records that are
* associated with data explicitly readable by the given user will be
* returned. If records are needed by a system administrator (who, by
* definition, does not need explicit read rights), use search() instead.
* definition, does not need explicit read rights), use {@link search()}
* instead.
*
* @param identifier
* The optional connection identifier for which records should be
* retrieved, or null if all readable records should be retrieved.
*
* @param user
* The user whose permissions should determine whether a record is
* returned.
@@ -111,7 +121,8 @@ public interface ConnectionRecordMapper {
* @return
* The results of the search performed with the given parameters.
*/
List<ConnectionRecordModel> searchReadable(@Param("user") UserModel user,
List<ConnectionRecordModel> searchReadable(@Param("identifier") String identifier,
@Param("user") UserModel user,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit,

View File

@@ -27,6 +27,7 @@ import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordSearchTerm;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordSortPredicate;
import org.apache.guacamole.auth.jdbc.base.ModeledActivityRecordSet;
import org.apache.guacamole.auth.jdbc.user.ModeledAuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.ConnectionRecord;
@@ -43,6 +44,30 @@ public class ConnectionRecordSet extends ModeledActivityRecordSet<ConnectionReco
@Inject
private ConnectionService connectionService;
/**
* The identifier of the connection to which this record set should be
* limited, if any. If null, the set should contain all records readable
* by the user making the request.
*/
private String identifier = null;
/**
* Initializes this object, associating it with the current authenticated
* user and connection identifier.
*
* @param currentUser
* The user that created or retrieved this object.
*
* @param identifier
* The connection identifier to which this record set should be limited,
* or null if the record set should contain all records readable by the
* currentUser.
*/
protected void init(ModeledAuthenticatedUser currentUser, String identifier) {
super.init(currentUser);
this.identifier = identifier;
}
@Override
protected Collection<ConnectionRecord> retrieveHistory(
AuthenticatedUser user, Set<ActivityRecordSearchTerm> requiredContents,
@@ -50,7 +75,7 @@ public class ConnectionRecordSet extends ModeledActivityRecordSet<ConnectionReco
throws GuacamoleException {
// Retrieve history from database
return connectionService.retrieveHistory(getCurrentUser(),
return connectionService.retrieveHistory(identifier, getCurrentUser(),
requiredContents, sortPredicates, limit);
}

View File

@@ -213,7 +213,7 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
Map<String, String> parameters = connection.getConfiguration().getParameters();
// Convert parameters to model objects
Collection<ConnectionParameterModel> parameterModels = new ArrayList<ConnectionParameterModel>(parameters.size());
Collection<ConnectionParameterModel> parameterModels = new ArrayList<>(parameters.size());
for (Map.Entry<String, String> parameterEntry : parameters.entrySet()) {
// Get parameter name and value
@@ -329,7 +329,7 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
public Map<String, String> retrieveParameters(ModeledAuthenticatedUser user,
String identifier) {
Map<String, String> parameterMap = new HashMap<String, String>();
Map<String, String> parameterMap = new HashMap<>();
// Determine whether we have permission to read parameters
boolean canRetrieveParameters;
@@ -382,7 +382,7 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
protected List<ConnectionRecord> getObjectInstances(List<ConnectionRecordModel> models) {
// Create new list of records by manually converting each model
List<ConnectionRecord> objects = new ArrayList<ConnectionRecord>(models.size());
List<ConnectionRecord> objects = new ArrayList<>(models.size());
for (ConnectionRecordModel model : models)
objects.add(getObjectInstance(model));
@@ -411,28 +411,16 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
ModeledConnection connection) throws GuacamoleException {
String identifier = connection.getIdentifier();
// Retrieve history only if READ permission is granted
if (hasObjectPermission(user, identifier, ObjectPermission.Type.READ)) {
// Retrieve history
List<ConnectionRecordModel> models = connectionRecordMapper.select(identifier);
// Get currently-active connections
List<ConnectionRecord> records = new ArrayList<ConnectionRecord>(tunnelService.getActiveConnections(connection));
Collections.reverse(records);
// Add past connections from model objects
for (ConnectionRecordModel model : models)
records.add(getObjectInstance(model));
// Return converted history list
return records;
}
// The user does not have permission to read the history
throw new GuacamoleSecurityException("Permission denied.");
// Get current active connections.
List<ConnectionRecord> 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;
}
@@ -442,6 +430,60 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
* the given terms and sorted by the given predicates. Only history records
* associated with data that the given user can read are returned.
*
* @param identifier
* The optional connection identifier for which history records should
* be retrieved, or null if all readable records should be retrieved.
*
* @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<ConnectionRecord> retrieveHistory(String identifier,
ModeledAuthenticatedUser user,
Collection<ActivityRecordSearchTerm> requiredContents,
List<ActivityRecordSortPredicate> sortPredicates, int limit)
throws GuacamoleException {
List<ConnectionRecordModel> searchResults;
// Bypass permission checks if the user is privileged
if (user.isPrivileged())
searchResults = connectionRecordMapper.search(identifier, requiredContents,
sortPredicates, limit);
// Otherwise only return explicitly readable history records
else
searchResults = connectionRecordMapper.searchReadable(identifier,
user.getUser().getModel(), requiredContents, sortPredicates,
limit, user.getEffectiveUserGroups());
return getObjectInstances(searchResults);
}
/**
* Retrieves the connection history records matching the given criteria.
* Retrieves up to <code>limit</code> 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.
*
@@ -467,22 +509,9 @@ public class ConnectionService extends ModeledChildDirectoryObjectService<Modele
Collection<ActivityRecordSearchTerm> requiredContents,
List<ActivityRecordSortPredicate> sortPredicates, int limit)
throws GuacamoleException {
List<ConnectionRecordModel> searchResults;
// Bypass permission checks if the user is privileged
if (user.isPrivileged())
searchResults = connectionRecordMapper.search(requiredContents,
sortPredicates, limit);
// Otherwise only return explicitly readable history records
else
searchResults = connectionRecordMapper.searchReadable(
user.getUser().getModel(), requiredContents, sortPredicates,
limit, user.getEffectiveUserGroups());
return getObjectInstances(searchResults);
return retrieveHistory(null, user, requiredContents, sortPredicates, limit);
}
/**

View File

@@ -40,6 +40,7 @@ import org.apache.guacamole.form.Form;
import org.apache.guacamole.form.NumericField;
import org.apache.guacamole.form.TextField;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.auth.ActivityRecordSet;
import org.apache.guacamole.net.auth.Connection;
import org.apache.guacamole.net.auth.ConnectionRecord;
import org.apache.guacamole.net.auth.GuacamoleProxyConfiguration;
@@ -196,6 +197,12 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod
@Inject
private Provider<ModeledGuacamoleConfiguration> configProvider;
/**
* Provider for creating connection record sets.
*/
@Inject
private Provider<ConnectionRecordSet> connectionRecordSetProvider;
/**
* The manually-set GuacamoleConfiguration, if any.
*/
@@ -252,10 +259,13 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod
public Date getLastActive() {
return getModel().getLastActive();
}
@Override
public List<? extends ConnectionRecord> getHistory() throws GuacamoleException {
return connectionService.retrieveHistory(getCurrentUser(), this);
public ActivityRecordSet<ConnectionRecord> getConnectionHistory()
throws GuacamoleException {
ConnectionRecordSet connectionRecordSet = connectionRecordSetProvider.get();
connectionRecordSet.init(getCurrentUser(), this.getIdentifier());
return connectionRecordSet;
}
@Override

View File

@@ -22,7 +22,6 @@ package org.apache.guacamole.auth.jdbc.sharing.connection;
import com.google.inject.Inject;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.guacamole.GuacamoleException;
@@ -31,7 +30,6 @@ import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService;
import org.apache.guacamole.auth.jdbc.user.RemoteAuthenticatedUser;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.auth.Connection;
import org.apache.guacamole.net.auth.ConnectionRecord;
import org.apache.guacamole.protocol.GuacamoleClientInformation;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
@@ -152,12 +150,6 @@ public class SharedConnection implements Connection {
return null;
}
@Override
public List<? extends ConnectionRecord> getHistory()
throws GuacamoleException {
return Collections.<ConnectionRecord>emptyList();
}
@Override
public Set<String> getSharingProfileIdentifiers()
throws GuacamoleException {

View File

@@ -21,11 +21,9 @@ package org.apache.guacamole.auth.jdbc.sharing.user;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.sharing.permission.SharedObjectPermissionSet;
import org.apache.guacamole.net.auth.ActivityRecord;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Connection;
import org.apache.guacamole.net.auth.ConnectionGroup;
@@ -99,14 +97,6 @@ public class SharedUser implements User {
}
@Override
public List<ActivityRecord> getHistory() throws GuacamoleException {
// History is not recorded for shared users
return Collections.<ActivityRecord>emptyList();
}
@Override
public String getPassword() {
return null;

View File

@@ -47,6 +47,7 @@ import org.apache.guacamole.form.TextField;
import org.apache.guacamole.form.TimeField;
import org.apache.guacamole.form.TimeZoneField;
import org.apache.guacamole.net.auth.ActivityRecord;
import org.apache.guacamole.net.auth.ActivityRecordSet;
import org.apache.guacamole.net.auth.Permissions;
import org.apache.guacamole.net.auth.RelatedObjectSet;
import org.apache.guacamole.net.auth.User;
@@ -182,6 +183,12 @@ public class ModeledUser extends ModeledPermissions<UserModel> implements User {
*/
@Inject
private Provider<UserParentUserGroupSet> parentUserGroupSetProvider;
/**
* Provider for creating user record sets.
*/
@Inject
private Provider<UserRecordSet> userRecordSetProvider;
/**
* Whether attributes which control access restrictions should be exposed
@@ -748,8 +755,11 @@ public class ModeledUser extends ModeledPermissions<UserModel> implements User {
}
@Override
public List<ActivityRecord> getHistory() throws GuacamoleException {
return userService.retrieveHistory(getCurrentUser(), this);
public ActivityRecordSet<ActivityRecord> getUserHistory()
throws GuacamoleException {
UserRecordSet userRecordSet = userRecordSetProvider.get();
userRecordSet.init(getCurrentUser(), this.getIdentifier());
return userRecordSet;
}
@Override

View File

@@ -73,8 +73,12 @@ public interface UserRecordMapper {
* the data they are associated with is is readable by any particular user.
* This should only be called on behalf of a system administrator. If
* records are needed by a non-administrative user who must have explicit
* read rights, use searchReadable() instead.
* read rights, use {@link searchReadable()} instead.
*
* @param username
* The optional username to which records should be limited, or null
* if all records should be retrieved.
*
* @param terms
* The search terms that must match the returned records.
*
@@ -88,7 +92,8 @@ public interface UserRecordMapper {
* @return
* The results of the search performed with the given parameters.
*/
List<ActivityRecordModel> search(@Param("terms") Collection<ActivityRecordSearchTerm> terms,
List<ActivityRecordModel> search(@Param("username") String username,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit);
@@ -97,11 +102,16 @@ public interface UserRecordMapper {
* the given terms, sorted by the given predicates. Only records that are
* associated with data explicitly readable by the given user will be
* returned. If records are needed by a system administrator (who, by
* definition, does not need explicit read rights), use search() instead.
* definition, does not need explicit read rights), use {@link search()}
* instead.
*
* @param username
* The optional username to which records should be limited, or null
* if all readable records should be retrieved.
*
* @param user
* The user whose permissions should determine whether a record is
* returned.
* The user whose permissions should determine whether a record is
* returned.
*
* @param terms
* The search terms that must match the returned records.
@@ -122,7 +132,8 @@ public interface UserRecordMapper {
* @return
* The results of the search performed with the given parameters.
*/
List<ActivityRecordModel> searchReadable(@Param("user") UserModel user,
List<ActivityRecordModel> searchReadable(@Param("username") String username,
@Param("user") UserModel user,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit,

View File

@@ -44,6 +44,31 @@ public class UserRecordSet extends ModeledActivityRecordSet<ActivityRecord> {
@Inject
private UserService userService;
/**
* The identifier that indicates which user object these records should be
* limited to, if any. If null is specified (the default) then all records
* that are readable by the current user will be retrieved.
*/
private String identifier = null;
/**
* Initialize this UserRecordSet with currentUser requesting the login
* records, and, optionally, the identifier of the user to which records
* should be limited.
*
* @param currentUser
* The user requesting login history.
*
* @param identifier
* The identifier of the user whose login history should be contained
* in this record set, or null if the record set should contain all
* records readable by the currentUser.
*/
protected void init(ModeledAuthenticatedUser currentUser, String identifier) {
super.init(currentUser);
this.identifier = identifier;
}
@Override
protected Collection<ActivityRecord> retrieveHistory(
AuthenticatedUser user, Set<ActivityRecordSearchTerm> requiredContents,
@@ -51,7 +76,7 @@ public class UserRecordSet extends ModeledActivityRecordSet<ActivityRecord> {
throws GuacamoleException {
// Retrieve history from database
return userService.retrieveHistory(getCurrentUser(),
return userService.retrieveHistory(identifier, getCurrentUser(),
requiredContents, sortPredicates, limit);
}

View File

@@ -32,7 +32,6 @@ import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectMapper;
import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObjectService;
import org.apache.guacamole.GuacamoleClientException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleSecurityException;
import org.apache.guacamole.GuacamoleUnsupportedException;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordModel;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordSearchTerm;
@@ -593,13 +592,9 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
ModeledUser user) throws GuacamoleException {
String username = user.getIdentifier();
// Retrieve history only if READ permission is granted
if (hasObjectPermission(authenticatedUser, username, ObjectPermission.Type.READ))
return getObjectInstances(userRecordMapper.select(username));
// The user does not have permission to read the history
throw new GuacamoleSecurityException("Permission denied.");
return retrieveHistory(username, authenticatedUser, Collections.emptyList(),
Collections.emptyList(), Integer.MAX_VALUE);
}
@@ -609,6 +604,59 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
* given terms and sorted by the given predicates. Only history records
* associated with data that the given user can read are returned.
*
* @param username
* The optional username to which history records should be limited, or
* null if all readable records should be retrieved.
*
* @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<ActivityRecord> retrieveHistory(String username,
ModeledAuthenticatedUser user,
Collection<ActivityRecordSearchTerm> requiredContents,
List<ActivityRecordSortPredicate> sortPredicates, int limit)
throws GuacamoleException {
List<ActivityRecordModel> searchResults;
// Bypass permission checks if the user is privileged
if (user.isPrivileged())
searchResults = userRecordMapper.search(username, requiredContents,
sortPredicates, limit);
// Otherwise only return explicitly readable history records
else
searchResults = userRecordMapper.searchReadable(username,
user.getUser().getModel(),
requiredContents, sortPredicates, limit, user.getEffectiveUserGroups());
return getObjectInstances(searchResults);
}
/**
* Retrieves user login history records matching the given criteria.
* Retrieves up to <code>limit</code> 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.
*
@@ -633,21 +681,9 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
Collection<ActivityRecordSearchTerm> requiredContents,
List<ActivityRecordSortPredicate> sortPredicates, int limit)
throws GuacamoleException {
List<ActivityRecordModel> searchResults;
// Bypass permission checks if the user is privileged
if (user.isPrivileged())
searchResults = userRecordMapper.search(requiredContents,
sortPredicates, limit);
// Otherwise only return explicitly readable history records
else
searchResults = userRecordMapper.searchReadable(user.getUser().getModel(),
requiredContents, sortPredicates, limit, user.getEffectiveUserGroups());
return getObjectInstances(searchResults);
return retrieveHistory(null, user, requiredContents, sortPredicates, limit);
}
}

View File

@@ -108,28 +108,35 @@
LEFT JOIN guacamole_user ON guacamole_connection_history.user_id = guacamole_user.user_id
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="identifier != null">
guacamole_connection_history.connection_id = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0
)
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0
)
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
@@ -186,31 +193,38 @@
AND guacamole_user_permission.permission = 'READ'
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="identifier != null">
guacamole_connection_history.connection_id = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'
)
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'
)
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>

View File

@@ -105,25 +105,32 @@
FROM guacamole_user_history
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="username != null">
guacamole_user_history.username = #{username,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'),
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'),
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
@@ -164,25 +171,32 @@
AND guacamole_user_permission.permission = 'READ'
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="username != null">
guacamole_entity.name = #{username,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>

View File

@@ -106,28 +106,35 @@
FROM guacamole_connection_history
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="identifier != null">
guacamole_connection_history.connection_id = #{identifier,jdbcType=INTEGER}::integer
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0
)
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0
)
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
@@ -184,31 +191,38 @@
AND guacamole_user_permission.permission = 'READ'
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="identifier != null">
guacamole_connection_history.connection_id = #{identifier,jdbcType=INTEGER}::integer
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'::guacamole_entity_type
)
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_connection_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'::guacamole_entity_type
)
</foreach>
OR guacamole_connection_history.connection_id IN (
SELECT connection_id
FROM guacamole_connection
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>

View File

@@ -105,25 +105,32 @@
FROM guacamole_user_history
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="username != null">
guacamole_user_history.username = #{username,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'::guacamole_entity_type),
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'::guacamole_entity_type),
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
@@ -164,25 +171,31 @@
AND guacamole_user_permission.permission = 'READ'
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="username != null">
guacamole_entity.name = #{username,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'::guacamole_entity_type
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
guacamole_user_history.user_id IN (
SELECT user_id
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
POSITION(#{term.term,jdbcType=VARCHAR} IN guacamole_entity.name) > 0
AND guacamole_entity.type = 'USER'::guacamole_entity_type
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>

View File

@@ -106,28 +106,35 @@
FROM [guacamole_connection_history]
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="identifier != null">
[guacamole_connection_history].connection_id = #{identifier,jdbcType=INTEGER}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
[guacamole_connection_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
WHERE CHARINDEX(#{term.term,jdbcType=VARCHAR}, username) > 0
)
OR [guacamole_connection_history].connection_id IN (
SELECT connection_id
FROM [guacamole_connection]
WHERE CHARINDEX(#{term.term,jdbcType=VARCHAR}, connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
[guacamole_connection_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
WHERE CHARINDEX(#{term.term,jdbcType=VARCHAR}, username) > 0
)
OR [guacamole_connection_history].connection_id IN (
SELECT connection_id
FROM [guacamole_connection]
WHERE CHARINDEX(#{term.term,jdbcType=VARCHAR}, connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
@@ -182,31 +189,38 @@
AND [guacamole_user_permission].permission = 'READ'
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="identifier != null">
[guacamole_connection_history].connection_id = #{identifier,jdbcType=INTEGER}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
[guacamole_connection_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
CHARINDEX(#{term.term,jdbcType=VARCHAR}, [guacamole_entity].name) > 0
AND [guacamole_entity].type = 'USER'
)
OR [guacamole_connection_history].connection_id IN (
SELECT connection_id
FROM [guacamole_connection]
WHERE CHARINDEX(#{term.term,jdbcType=VARCHAR}, connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
[guacamole_connection_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
CHARINDEX(#{term.term,jdbcType=VARCHAR}, [guacamole_entity].name) > 0
AND [guacamole_entity].type = 'USER'
)
OR [guacamole_connection_history].connection_id IN (
SELECT connection_id
FROM [guacamole_connection]
WHERE CHARINDEX(#{term.term,jdbcType=VARCHAR}, connection_name) > 0
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>

View File

@@ -105,25 +105,32 @@
FROM [guacamole_user_history]
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="username != null">
[guacamole_user_history].username = #{username,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
[guacamole_user_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
CHARINDEX(#{term.term,jdbcType=VARCHAR}, [guacamole_entity].name) > 0
AND [guacamole_entity].type = 'USER'),
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
[guacamole_user_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
CHARINDEX(#{term.term,jdbcType=VARCHAR}, [guacamole_entity].name) > 0
AND [guacamole_entity].type = 'USER'),
)
</foreach>
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
@@ -162,25 +169,32 @@
AND [guacamole_user_permission].permission = 'READ'
<!-- Search terms -->
<foreach collection="terms" item="term"
open="WHERE " separator=" AND ">
(
<where>
<if test="username != null">
[guacamole_entity].name = #{username,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
(
[guacamole_user_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
CHARINDEX(#{term.term,jdbcType=VARCHAR}, [guacamole_entity].name) > 0
AND [guacamole_entity].type = 'USER'
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
[guacamole_user_history].user_id IN (
SELECT user_id
FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
CHARINDEX(#{term.term,jdbcType=VARCHAR}, [guacamole_entity].name) > 0
AND [guacamole_entity].type = 'USER'
)
<if test="term.startDate != null and term.endDate != null">
OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
</if>
)
</foreach>
</foreach>
</where>
<!-- Bind sort property enum values for sake of readability -->
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>