mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 05:31:22 +00:00
GUACAMOLE-394: Merge add support for recording user login/logout history to database auth.
This commit is contained in:
@@ -336,6 +336,7 @@ CREATE TABLE `guacamole_connection_history` (
|
||||
KEY `sharing_profile_id` (`sharing_profile_id`),
|
||||
KEY `start_date` (`start_date`),
|
||||
KEY `end_date` (`end_date`),
|
||||
KEY `connection_start_date` (`connection_id`, `start_date`),
|
||||
|
||||
CONSTRAINT `guacamole_connection_history_ibfk_1`
|
||||
FOREIGN KEY (`user_id`)
|
||||
@@ -351,6 +352,31 @@ CREATE TABLE `guacamole_connection_history` (
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- User login/logout history
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_user_history (
|
||||
|
||||
`history_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) DEFAULT NULL,
|
||||
`username` varchar(128) NOT NULL,
|
||||
`remote_host` varchar(256) DEFAULT NULL,
|
||||
`start_date` datetime NOT NULL,
|
||||
`end_date` datetime DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (history_id),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `start_date` (`start_date`),
|
||||
KEY `end_date` (`end_date`),
|
||||
KEY `user_start_date` (`user_id`, `start_date`),
|
||||
|
||||
CONSTRAINT guacamole_user_history_ibfk_1
|
||||
FOREIGN KEY (user_id)
|
||||
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- User password history
|
||||
--
|
||||
|
@@ -37,3 +37,34 @@ ALTER TABLE guacamole_connection
|
||||
|
||||
ALTER TABLE guacamole_connection_history
|
||||
ADD COLUMN remote_host VARCHAR(256) DEFAULT NULL;
|
||||
|
||||
--
|
||||
-- Add covering index for connection history connection and start date
|
||||
--
|
||||
|
||||
ALTER TABLE guacamole_connection_history ADD KEY (connection_id, start_date);
|
||||
|
||||
--
|
||||
-- User login/logout history
|
||||
--
|
||||
|
||||
CREATE TABLE guacamole_user_history (
|
||||
|
||||
`history_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) DEFAULT NULL,
|
||||
`username` varchar(128) NOT NULL,
|
||||
`remote_host` varchar(256) DEFAULT NULL,
|
||||
`start_date` datetime NOT NULL,
|
||||
`end_date` datetime DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (history_id),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `start_date` (`start_date`),
|
||||
KEY `end_date` (`end_date`),
|
||||
KEY `user_start_date` (`user_id`, `start_date`),
|
||||
|
||||
CONSTRAINT guacamole_user_history_ibfk_1
|
||||
FOREIGN KEY (user_id)
|
||||
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
@@ -39,6 +39,7 @@
|
||||
javaType="org.apache.guacamole.net.auth.GuacamoleProxyConfiguration$EncryptionMethod"/>
|
||||
<result column="connection_weight" property="connectionWeight" jdbcType="INTEGER"/>
|
||||
<result column="failover_only" property="failoverOnly" jdbcType="BOOLEAN"/>
|
||||
<result column="last_active" property="lastActive" jdbcType="TIMESTAMP"/>
|
||||
|
||||
<!-- Associated sharing profiles -->
|
||||
<collection property="sharingProfileIdentifiers" resultSet="sharingProfiles" ofType="java.lang.String"
|
||||
@@ -89,8 +90,8 @@
|
||||
resultSets="connections,sharingProfiles">
|
||||
|
||||
SELECT
|
||||
connection_id,
|
||||
connection_name,
|
||||
guacamole_connection.connection_id,
|
||||
guacamole_connection.connection_name,
|
||||
parent_id,
|
||||
protocol,
|
||||
max_connections,
|
||||
@@ -99,13 +100,16 @@
|
||||
proxy_port,
|
||||
proxy_encryption_method,
|
||||
connection_weight,
|
||||
failover_only
|
||||
failover_only,
|
||||
MAX(start_date) AS last_active
|
||||
FROM guacamole_connection
|
||||
WHERE connection_id IN
|
||||
LEFT JOIN guacamole_connection_history ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
|
||||
WHERE guacamole_connection.connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>;
|
||||
</foreach>
|
||||
GROUP BY guacamole_connection.connection_id;
|
||||
|
||||
SELECT primary_connection_id, sharing_profile_id
|
||||
FROM guacamole_sharing_profile
|
||||
@@ -123,7 +127,7 @@
|
||||
|
||||
SELECT
|
||||
guacamole_connection.connection_id,
|
||||
connection_name,
|
||||
guacamole_connection.connection_name,
|
||||
parent_id,
|
||||
protocol,
|
||||
max_connections,
|
||||
@@ -132,16 +136,19 @@
|
||||
proxy_port,
|
||||
proxy_encryption_method,
|
||||
connection_weight,
|
||||
failover_only
|
||||
failover_only,
|
||||
MAX(start_date) AS last_active
|
||||
FROM guacamole_connection
|
||||
JOIN guacamole_connection_permission ON guacamole_connection_permission.connection_id = guacamole_connection.connection_id
|
||||
LEFT JOIN guacamole_connection_history ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
|
||||
WHERE guacamole_connection.connection_id IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ';
|
||||
AND guacamole_connection_permission.user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
GROUP BY guacamole_connection.connection_id;
|
||||
|
||||
SELECT primary_connection_id, guacamole_sharing_profile.sharing_profile_id
|
||||
FROM guacamole_sharing_profile
|
||||
@@ -160,8 +167,8 @@
|
||||
<select id="selectOneByName" resultMap="ConnectionResultMap">
|
||||
|
||||
SELECT
|
||||
connection_id,
|
||||
connection_name,
|
||||
guacamole_connection.connection_id,
|
||||
guacamole_connection.connection_name,
|
||||
parent_id,
|
||||
protocol,
|
||||
max_connections,
|
||||
@@ -170,12 +177,15 @@
|
||||
proxy_port,
|
||||
proxy_encryption_method,
|
||||
connection_weight,
|
||||
failover_only
|
||||
failover_only,
|
||||
MAX(start_date) AS last_active
|
||||
FROM guacamole_connection
|
||||
LEFT JOIN guacamole_connection_history ON guacamole_connection_history.connection_id = guacamole_connection.connection_id
|
||||
WHERE
|
||||
<if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=VARCHAR}</if>
|
||||
<if test="parentIdentifier == null">parent_id IS NULL</if>
|
||||
AND connection_name = #{name,jdbcType=VARCHAR}
|
||||
AND guacamole_connection.connection_name = #{name,jdbcType=VARCHAR}
|
||||
GROUP BY guacamole_connection.connection_id
|
||||
|
||||
</select>
|
||||
|
||||
|
@@ -41,6 +41,7 @@
|
||||
<result column="email_address" property="emailAddress" jdbcType="VARCHAR"/>
|
||||
<result column="organization" property="organization" jdbcType="VARCHAR"/>
|
||||
<result column="organizational_role" property="organizationalRole" jdbcType="VARCHAR"/>
|
||||
<result column="last_active" property="lastActive" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- Select all usernames -->
|
||||
@@ -63,8 +64,8 @@
|
||||
<select id="select" resultMap="UserResultMap">
|
||||
|
||||
SELECT
|
||||
user_id,
|
||||
username,
|
||||
guacamole_user.user_id,
|
||||
guacamole_user.username,
|
||||
password_hash,
|
||||
password_salt,
|
||||
password_date,
|
||||
@@ -78,13 +79,16 @@
|
||||
full_name,
|
||||
email_address,
|
||||
organization,
|
||||
organizational_role
|
||||
organizational_role,
|
||||
MAX(start_date) AS last_active
|
||||
FROM guacamole_user
|
||||
WHERE username IN
|
||||
LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id
|
||||
WHERE guacamole_user.username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
GROUP BY guacamole_user.user_id
|
||||
|
||||
</select>
|
||||
|
||||
@@ -93,7 +97,7 @@
|
||||
|
||||
SELECT
|
||||
guacamole_user.user_id,
|
||||
username,
|
||||
guacamole_user.username,
|
||||
password_hash,
|
||||
password_salt,
|
||||
password_date,
|
||||
@@ -107,16 +111,19 @@
|
||||
full_name,
|
||||
email_address,
|
||||
organization,
|
||||
organizational_role
|
||||
organizational_role,
|
||||
MAX(start_date) AS last_active
|
||||
FROM guacamole_user
|
||||
JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id
|
||||
WHERE username IN
|
||||
LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id
|
||||
WHERE guacamole_user.username IN
|
||||
<foreach collection="identifiers" item="identifier"
|
||||
open="(" separator="," close=")">
|
||||
#{identifier,jdbcType=VARCHAR}
|
||||
</foreach>
|
||||
AND guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND permission = 'READ'
|
||||
GROUP BY guacamole_user.user_id
|
||||
|
||||
</select>
|
||||
|
||||
@@ -124,8 +131,8 @@
|
||||
<select id="selectOne" resultMap="UserResultMap">
|
||||
|
||||
SELECT
|
||||
user_id,
|
||||
username,
|
||||
guacamole_user.user_id,
|
||||
guacamole_user.username,
|
||||
password_hash,
|
||||
password_salt,
|
||||
password_date,
|
||||
@@ -139,10 +146,13 @@
|
||||
full_name,
|
||||
email_address,
|
||||
organization,
|
||||
organizational_role
|
||||
organizational_role,
|
||||
MAX(start_date) AS last_active
|
||||
FROM guacamole_user
|
||||
LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id
|
||||
WHERE
|
||||
username = #{username,jdbcType=VARCHAR}
|
||||
guacamole_user.username = #{username,jdbcType=VARCHAR}
|
||||
GROUP BY guacamole_user.user_id
|
||||
|
||||
</select>
|
||||
|
||||
|
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<mapper namespace="org.apache.guacamole.auth.jdbc.user.UserRecordMapper" >
|
||||
|
||||
<!-- Result mapper for system permissions -->
|
||||
<resultMap id="UserRecordResultMap" type="org.apache.guacamole.auth.jdbc.base.ActivityRecordModel">
|
||||
<id column="history_id" property="recordID" jdbcType="INTEGER"/>
|
||||
<result column="remote_host" property="remoteHost" jdbcType="VARCHAR"/>
|
||||
<result column="user_id" property="userID" jdbcType="INTEGER"/>
|
||||
<result column="username" property="username" jdbcType="VARCHAR"/>
|
||||
<result column="start_date" property="startDate" jdbcType="TIMESTAMP"/>
|
||||
<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.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
|
||||
WHERE
|
||||
guacamole_user.username = #{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">
|
||||
|
||||
INSERT INTO guacamole_user_history (
|
||||
remote_host,
|
||||
user_id,
|
||||
username,
|
||||
start_date,
|
||||
end_date
|
||||
)
|
||||
VALUES (
|
||||
#{record.remoteHost,jdbcType=VARCHAR},
|
||||
(SELECT user_id FROM guacamole_user
|
||||
WHERE username = #{record.username,jdbcType=VARCHAR}),
|
||||
#{record.username,jdbcType=VARCHAR},
|
||||
#{record.startDate,jdbcType=TIMESTAMP},
|
||||
#{record.endDate,jdbcType=TIMESTAMP}
|
||||
)
|
||||
|
||||
</insert>
|
||||
|
||||
<!-- Update the given user record -->
|
||||
<update id="update" 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
|
||||
WHERE username = #{record.username,jdbcType=VARCHAR}),
|
||||
username = #{record.username,jdbcType=VARCHAR},
|
||||
start_date = #{record.startDate,jdbcType=TIMESTAMP},
|
||||
end_date = #{record.endDate,jdbcType=TIMESTAMP}
|
||||
WHERE history_id = #{record.recordID,jdbcType=INTEGER}
|
||||
</update>
|
||||
|
||||
<!-- Search for specific user records -->
|
||||
<select id="search" resultMap="UserRecordResultMap">
|
||||
|
||||
SELECT
|
||||
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
|
||||
|
||||
<!-- Search terms -->
|
||||
<foreach collection="terms" item="term"
|
||||
open="WHERE " separator=" AND ">
|
||||
(
|
||||
|
||||
guacamole_user_history.user_id IN (
|
||||
SELECT user_id
|
||||
FROM guacamole_user
|
||||
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 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>
|
||||
|
||||
<!-- Bind sort property enum values for sake of readability -->
|
||||
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
|
||||
|
||||
<!-- Sort predicates -->
|
||||
<foreach collection="sortPredicates" item="sortPredicate"
|
||||
open="ORDER BY " separator=", ">
|
||||
<choose>
|
||||
<when test="sortPredicate.property == START_DATE">guacamole_user_history.start_date</when>
|
||||
<otherwise>1</otherwise>
|
||||
</choose>
|
||||
<if test="sortPredicate.descending">DESC</if>
|
||||
</foreach>
|
||||
|
||||
LIMIT #{limit,jdbcType=INTEGER}
|
||||
|
||||
</select>
|
||||
|
||||
<!-- Search for specific user records -->
|
||||
<select id="searchReadable" resultMap="UserRecordResultMap">
|
||||
|
||||
SELECT
|
||||
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
|
||||
|
||||
<!-- Restrict to readable users -->
|
||||
JOIN guacamole_user_permission ON
|
||||
guacamole_user_history.user_id = guacamole_user_permission.affected_user_id
|
||||
AND guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
|
||||
AND guacamole_user_permission.permission = 'READ'
|
||||
|
||||
<!-- Search terms -->
|
||||
<foreach collection="terms" item="term"
|
||||
open="WHERE " separator=" AND ">
|
||||
(
|
||||
|
||||
guacamole_user_history.user_id IN (
|
||||
SELECT user_id
|
||||
FROM guacamole_user
|
||||
WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 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>
|
||||
|
||||
<!-- Bind sort property enum values for sake of readability -->
|
||||
<bind name="START_DATE" value="@org.apache.guacamole.net.auth.ActivityRecordSet$SortableProperty@START_DATE"/>
|
||||
|
||||
<!-- Sort predicates -->
|
||||
<foreach collection="sortPredicates" item="sortPredicate"
|
||||
open="ORDER BY " separator=", ">
|
||||
<choose>
|
||||
<when test="sortPredicate.property == START_DATE">guacamole_user_history.start_date</when>
|
||||
<otherwise>1</otherwise>
|
||||
</choose>
|
||||
<if test="sortPredicate.descending">DESC</if>
|
||||
</foreach>
|
||||
|
||||
LIMIT #{limit,jdbcType=INTEGER}
|
||||
|
||||
</select>
|
||||
|
||||
</mapper>
|
Reference in New Issue
Block a user