GUACAMOLE-462: Migrate user/connection record mappers to common base interface.

This commit is contained in:
Michael Jumper
2022-02-09 12:49:56 -08:00
parent 45ac06e0d0
commit b80d8da1bb
10 changed files with 161 additions and 420 deletions

View File

@@ -0,0 +1,135 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.guacamole.auth.jdbc.base;
import java.util.Collection;
import java.util.List;
import org.apache.guacamole.auth.jdbc.user.UserModel;
import org.apache.ibatis.annotations.Param;
/**
* Common interface for mapping activity records.
*
* @param <ModelType>
* The type of model object representing the activity records mapped by
* this mapper.
*/
public interface ActivityRecordMapper<ModelType> {
/**
* Inserts the given activity record.
*
* @param record
* The activity record to insert.
*
* @return
* The number of rows inserted.
*/
int insert(@Param("record") ModelType record);
/**
* Updates the given activity record in the database, assigning an end
* date. No column of the existing activity record is updated except for
* the end date. If the record does not actually exist, this operation has
* no effect.
*
* @param record
* The activity record to update.
*
* @return
* The number of rows updated.
*/
int updateEndDate(@Param("record") ModelType record);
/**
* Searches for up to <code>limit</code> activity records that contain
* the given terms, sorted by the given predicates, regardless of whether
* the data they are associated with 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 {@link searchReadable()} instead.
*
* @param identifier
* The optional identifier of the object whose history is being
* retrieved, or null if records related to any such object should be
* retrieved.
*
* @param terms
* The search terms that must match 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 results of the search performed with the given parameters.
*/
List<ModelType> search(@Param("identifier") String identifier,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit);
/**
* Searches for up to <code>limit</code> activity records that contain
* 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 {@link search()}
* instead.
*
* @param identifier
* The optional identifier of the object whose history is being
* retrieved, or null if records related to any such object should be
* retrieved.
*
* @param user
* The user whose permissions should determine whether a record is
* returned.
*
* @param terms
* The search terms that must match 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.
*
* @param effectiveGroups
* The identifiers of all groups that should be taken into account
* when determining the permissions effectively granted to the user. If
* no groups are given, only permissions directly granted to the user
* will be used.
*
* @return
* The results of the search performed with the given parameters.
*/
List<ModelType> searchReadable(@Param("identifier") String identifier,
@Param("user") UserModel user,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit,
@Param("effectiveGroups") Collection<String> effectiveGroups);
}

View File

@@ -19,127 +19,9 @@
package org.apache.guacamole.auth.jdbc.connection;
import java.util.Collection;
import java.util.List;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordSearchTerm;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordSortPredicate;
import org.apache.ibatis.annotations.Param;
import org.apache.guacamole.auth.jdbc.user.UserModel;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordMapper;
/**
* Mapper for connection record objects.
*/
public interface ConnectionRecordMapper {
/**
* Returns a collection of all connection records associated with the
* connection having the given identifier.
*
* @param identifier
* The identifier of the connection whose records are to be retrieved.
*
* @return
* A collection of all connection records associated with the
* connection having the given identifier. This collection will be
* empty if no such connection exists.
*/
List<ConnectionRecordModel> select(@Param("identifier") String identifier);
/**
* Inserts the given connection record.
*
* @param record
* The connection record to insert.
*
* @return
* The number of rows inserted.
*/
int insert(@Param("record") ConnectionRecordModel record);
/**
* Updates the given connection record in the database, assigning an end
* date. No column of the existing connection record is updated except for
* the end date. If the record does not actually exist, this operation has
* no effect.
*
* @param record
* The connection record to update.
*
* @return
* The number of rows updated.
*/
int updateEndDate(@Param("record") ConnectionRecordModel record);
/**
* Searches for up to <code>limit</code> connection records that contain
* the given terms, sorted by the given predicates, regardless of whether
* 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 {@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.
*
* @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 results of the search performed with the given parameters.
*/
List<ConnectionRecordModel> search(@Param("identifier") String identifier,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit);
/**
* Searches for up to <code>limit</code> connection records that contain
* 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 {@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.
*
* @param terms
* The search terms that must match 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.
*
* @param effectiveGroups
* The identifiers of all groups that should be taken into account
* when determining the permissions effectively granted to the user. If
* no groups are given, only permissions directly granted to the user
* will be used.
*
* @return
* The results of the search performed with the given parameters.
*/
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,
@Param("effectiveGroups") Collection<String> effectiveGroups);
}
public interface ConnectionRecordMapper extends ActivityRecordMapper<ConnectionRecordModel> {}

View File

@@ -291,7 +291,7 @@ public class ModeledUserContext extends RestrictedObject
// Record logout time only if login time was recorded
if (userRecord != null) {
userRecord.setEndDate(new Date());
userRecordMapper.update(userRecord);
userRecordMapper.updateEndDate(userRecord);
}
}

View File

@@ -19,124 +19,10 @@
package org.apache.guacamole.auth.jdbc.user;
import java.util.Collection;
import java.util.List;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordMapper;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordModel;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordSearchTerm;
import org.apache.guacamole.auth.jdbc.base.ActivityRecordSortPredicate;
import org.apache.ibatis.annotations.Param;
/**
* Mapper for user login activity records.
*/
public interface UserRecordMapper {
/**
* Returns a collection of all user login records associated with the user
* having the given username.
*
* @param username
* The username of the user whose login records are to be retrieved.
*
* @return
* A collection of all user login records associated with the user
* having the given username. This collection will be empty if no such
* user exists.
*/
List<ActivityRecordModel> select(@Param("username") String username);
/**
* Inserts the given user login record.
*
* @param record
* The user login record to insert.
*
* @return
* The number of rows inserted.
*/
int insert(@Param("record") ActivityRecordModel record);
/**
* Updates the given user login record.
*
* @param record
* The user login record to update.
*
* @return
* The number of rows updated.
*/
int update(@Param("record") ActivityRecordModel record);
/**
* Searches for up to <code>limit</code> user login records that contain
* the given terms, sorted by the given predicates, regardless of whether
* 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 {@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.
*
* @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 results of the search performed with the given parameters.
*/
List<ActivityRecordModel> search(@Param("username") String username,
@Param("terms") Collection<ActivityRecordSearchTerm> terms,
@Param("sortPredicates") List<ActivityRecordSortPredicate> sortPredicates,
@Param("limit") int limit);
/**
* Searches for up to <code>limit</code> user login records that contain
* 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 {@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.
*
* @param terms
* The search terms that must match 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.
*
* @param effectiveGroups
* The identifiers of all groups that should be taken into account
* when determining the permissions effectively granted to the user. If
* no groups are given, only permissions directly granted to the user
* will be used.
*
* @return
* The results of the search performed with the given parameters.
*/
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,
@Param("effectiveGroups") Collection<String> effectiveGroups);
}
public interface UserRecordMapper extends ActivityRecordMapper<ActivityRecordModel> {}

View File

@@ -37,29 +37,6 @@
<result column="end_date" property="endDate" jdbcType="TIMESTAMP"/>
</resultMap>
<!-- Select all connection records from a given connection -->
<select id="select" resultMap="ConnectionRecordResultMap">
SELECT
guacamole_connection_history.history_id,
guacamole_connection_history.connection_id,
guacamole_connection_history.connection_name,
guacamole_connection_history.remote_host,
guacamole_connection_history.sharing_profile_id,
guacamole_connection_history.sharing_profile_name,
guacamole_connection_history.user_id,
guacamole_connection_history.username,
guacamole_connection_history.start_date,
guacamole_connection_history.end_date
FROM guacamole_connection_history
WHERE
guacamole_connection_history.connection_id = #{identifier,jdbcType=VARCHAR}
ORDER BY
guacamole_connection_history.start_date DESC,
guacamole_connection_history.end_date DESC
</select>
<!-- Insert the given connection record -->
<insert id="insert" useGeneratedKeys="true" keyProperty="record.recordID"
parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel">
@@ -95,11 +72,9 @@
<!-- Update the given connection record, assigning an end date -->
<update id="updateEndDate" parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel">
UPDATE guacamole_connection_history
SET end_date = #{record.endDate,jdbcType=TIMESTAMP}
WHERE history_id = #{record.recordID,jdbcType=INTEGER}
</update>
<!-- Search for specific connection records -->

View File

@@ -33,27 +33,6 @@
<result column="end_date" property="endDate" jdbcType="TIMESTAMP"/>
</resultMap>
<!-- Select all user records from a given user -->
<select id="select" resultMap="UserRecordResultMap">
SELECT
guacamole_user_history.history_id,
guacamole_user_history.remote_host,
guacamole_user_history.user_id,
guacamole_user_history.username,
guacamole_user_history.start_date,
guacamole_user_history.end_date
FROM guacamole_user_history
JOIN guacamole_user ON guacamole_user_history.user_id = guacamole_user.user_id
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
guacamole_entity.name = #{username,jdbcType=VARCHAR}
ORDER BY
guacamole_user_history.start_date DESC,
guacamole_user_history.end_date DESC
</select>
<!-- Insert the given user record -->
<insert id="insert" useGeneratedKeys="true" keyProperty="record.recordID"
parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
@@ -79,18 +58,10 @@
</insert>
<!-- Update the given user record -->
<update id="update" parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
<!-- Update the given user record, assigning an end date -->
<update id="updateEndDate" parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
UPDATE guacamole_user_history
SET remote_host = #{record.remoteHost,jdbcType=VARCHAR},
user_id = (SELECT user_id FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
guacamole_entity.name = #{record.username,jdbcType=VARCHAR}
AND guacamole_entity.type = 'USER'),
username = #{record.username,jdbcType=VARCHAR},
start_date = #{record.startDate,jdbcType=TIMESTAMP},
end_date = #{record.endDate,jdbcType=TIMESTAMP}
SET end_date = #{record.endDate,jdbcType=TIMESTAMP}
WHERE history_id = #{record.recordID,jdbcType=INTEGER}
</update>
@@ -109,8 +80,8 @@
<!-- Search terms -->
<where>
<if test="username != null">
guacamole_user_history.username = #{username,jdbcType=VARCHAR}
<if test="identifier != null">
guacamole_user_history.username = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
@@ -174,8 +145,8 @@
</include>
)
<if test="username != null">
AND guacamole_entity.name = #{username,jdbcType=VARCHAR}
<if test="identifier != null">
AND guacamole_entity.name = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">

View File

@@ -37,29 +37,6 @@
<result column="end_date" property="endDate" jdbcType="TIMESTAMP"/>
</resultMap>
<!-- Select all connection records from a given connection -->
<select id="select" resultMap="ConnectionRecordResultMap">
SELECT
guacamole_connection_history.history_id,
guacamole_connection_history.connection_id,
guacamole_connection_history.connection_name,
guacamole_connection_history.remote_host,
guacamole_connection_history.sharing_profile_id,
guacamole_connection_history.sharing_profile_name,
guacamole_connection_history.user_id,
guacamole_connection_history.username,
guacamole_connection_history.start_date,
guacamole_connection_history.end_date
FROM guacamole_connection_history
WHERE
guacamole_connection_history.connection_id = #{identifier,jdbcType=INTEGER}::integer
ORDER BY
guacamole_connection_history.start_date DESC,
guacamole_connection_history.end_date DESC
</select>
<!-- Insert the given connection record -->
<insert id="insert" useGeneratedKeys="true" keyProperty="record.recordID"
parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel">
@@ -95,11 +72,9 @@
<!-- Update the given connection record, assigning an end date -->
<update id="updateEndDate" parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel">
UPDATE guacamole_connection_history
SET end_date = #{record.endDate,jdbcType=TIMESTAMP}
WHERE history_id = #{record.recordID,jdbcType=INTEGER}::integer
</update>
<!-- Search for specific connection records -->

View File

@@ -33,27 +33,6 @@
<result column="end_date" property="endDate" jdbcType="TIMESTAMP"/>
</resultMap>
<!-- Select all user records from a given user -->
<select id="select" resultMap="UserRecordResultMap">
SELECT
guacamole_user_history.history_id,
guacamole_user_history.remote_host,
guacamole_user_history.user_id,
guacamole_user_history.username,
guacamole_user_history.start_date,
guacamole_user_history.end_date
FROM guacamole_user_history
JOIN guacamole_user ON guacamole_user_history.user_id = guacamole_user.user_id
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
guacamole_entity.name = #{username,jdbcType=VARCHAR}
ORDER BY
guacamole_user_history.start_date DESC,
guacamole_user_history.end_date DESC
</select>
<!-- Insert the given user record -->
<insert id="insert" useGeneratedKeys="true" keyProperty="record.recordID"
parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
@@ -79,18 +58,10 @@
</insert>
<!-- Update the given user record -->
<update id="update" parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
<!-- Update the given user record, assigning an end date -->
<update id="updateEndDate" parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
UPDATE guacamole_user_history
SET remote_host = #{record.remoteHost,jdbcType=VARCHAR},
user_id = (SELECT user_id FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
WHERE
guacamole_entity.name = #{record.username,jdbcType=VARCHAR}
AND guacamole_entity.type = 'USER'::guacamole_entity_type),
username = #{record.username,jdbcType=VARCHAR},
start_date = #{record.startDate,jdbcType=TIMESTAMP},
end_date = #{record.endDate,jdbcType=TIMESTAMP}
SET end_date = #{record.endDate,jdbcType=TIMESTAMP}
WHERE history_id = #{record.recordID,jdbcType=INTEGER}::integer
</update>
@@ -109,8 +80,8 @@
<!-- Search terms -->
<where>
<if test="username != null">
guacamole_user_history.username = #{username,jdbcType=VARCHAR}
<if test="identifier != null">
guacamole_user_history.username = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
@@ -174,8 +145,8 @@
</include>
)
<if test="username != null">
AND guacamole_entity.name = #{username,jdbcType=VARCHAR}
<if test="identifier != null">
AND guacamole_entity.name = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">

View File

@@ -37,36 +37,11 @@
<result column="end_date" property="endDate" jdbcType="TIMESTAMP"/>
</resultMap>
<!-- Select all connection records from a given connection -->
<select id="select" resultMap="ConnectionRecordResultMap">
SELECT
[guacamole_connection_history].history_id,
[guacamole_connection_history].connection_id,
[guacamole_connection_history].connection_name,
[guacamole_connection_history].remote_host,
[guacamole_connection_history].sharing_profile_id,
[guacamole_connection_history].sharing_profile_name,
[guacamole_connection_history].user_id,
[guacamole_connection_history].username,
[guacamole_connection_history].start_date,
[guacamole_connection_history].end_date
FROM [guacamole_connection_history]
WHERE
[guacamole_connection_history].connection_id = #{identifier,jdbcType=INTEGER}
ORDER BY
[guacamole_connection_history].start_date DESC,
[guacamole_connection_history].end_date DESC
</select>
<!-- Update the given connection record, assigning an end date -->
<update id="updateEndDate" parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel">
UPDATE [guacamole_connection_history]
SET end_date = #{record.endDate,jdbcType=TIMESTAMP}
WHERE history_id = #{record.recordID,jdbcType=INTEGER}
</update>
<!-- Insert the given connection record -->

View File

@@ -33,27 +33,6 @@
<result column="end_date" property="endDate" jdbcType="TIMESTAMP"/>
</resultMap>
<!-- Select all user records from a given user -->
<select id="select" resultMap="UserRecordResultMap">
SELECT
[guacamole_user_history].history_id,
[guacamole_user_history].remote_host,
[guacamole_user_history].user_id,
[guacamole_user_history].username,
[guacamole_user_history].start_date,
[guacamole_user_history].end_date
FROM [guacamole_user_history]
JOIN [guacamole_user] ON [guacamole_user_history].user_id = [guacamole_user].user_id
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
[guacamole_entity].name = #{username,jdbcType=VARCHAR}
ORDER BY
[guacamole_user_history].start_date DESC,
[guacamole_user_history].end_date DESC
</select>
<!-- Insert the given user record -->
<insert id="insert" useGeneratedKeys="true" keyProperty="record.recordID"
parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
@@ -79,18 +58,10 @@
</insert>
<!-- Update the given user record -->
<update id="update" parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
<!-- Update the given user record, assigning an end date -->
<update id="updateEndDate" parameterType="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
UPDATE [guacamole_user_history]
SET remote_host = #{record.remoteHost,jdbcType=VARCHAR},
user_id = (SELECT user_id FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
WHERE
[guacamole_entity].name = #{record.username,jdbcType=VARCHAR}
AND [guacamole_entity].type = 'USER'),
username = #{record.username,jdbcType=VARCHAR},
start_date = #{record.startDate,jdbcType=TIMESTAMP},
end_date = #{record.endDate,jdbcType=TIMESTAMP}
SET end_date = #{record.endDate,jdbcType=TIMESTAMP}
WHERE history_id = #{record.recordID,jdbcType=INTEGER}
</update>
@@ -109,8 +80,8 @@
<!-- Search terms -->
<where>
<if test="username != null">
[guacamole_user_history].username = #{username,jdbcType=VARCHAR}
<if test="identifier != null">
[guacamole_user_history].username = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">
@@ -172,8 +143,8 @@
</include>
)
<if test="username != null">
AND [guacamole_entity].name = #{username,jdbcType=VARCHAR}
<if test="identifier != null">
AND [guacamole_entity].name = #{identifier,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">