GUACAMOLE-1021: Refactor SQL Server queries to NOT duplicate results across related entities.

Previous versions of the SQL Server queries relied on permission for
each object being granted from exactly one location, thus allowing
queries to be narrowed by permission using a simple JOIN. This is no
longer the case, as permissions may be inherited from multiple
locations (groups).
This commit is contained in:
Michael Jumper
2020-10-26 23:54:58 -07:00
parent 349fc36109
commit 624d49847c
16 changed files with 287 additions and 199 deletions

View File

@@ -63,17 +63,38 @@
FROM [guacamole_connection] FROM [guacamole_connection]
</select> </select>
<!-- Select identifiers of all readable connections --> <!--
<select id="selectReadableIdentifiers" resultType="string"> * SQL fragment which lists the IDs of all connections readable by the
SELECT connection_id * entity having the given entity ID. If group identifiers are provided,
* the IDs of the entities for all groups having those identifiers are
* tested, as well. Disabled groups are ignored.
*
* @param entityID
* The ID of the specific entity to test against.
*
* @param groups
* A collection of group identifiers to additionally test against.
* Though this functionality is optional, a collection must always be
* given, even if that collection is empty.
-->
<sql id="getReadableIDs">
SELECT DISTINCT connection_id
FROM [guacamole_connection_permission] FROM [guacamole_connection_permission]
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/> <property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="${entityID}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="${groups}"/>
</include> </include>
AND permission = 'READ' AND permission = 'READ'
</sql>
<!-- Select identifiers of all readable connections -->
<select id="selectReadableIdentifiers" resultType="string">
<include refid="org.apache.guacamole.auth.jdbc.connection.ConnectionMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
</select> </select>
<!-- Select all connection identifiers within a particular connection group --> <!-- Select all connection identifiers within a particular connection group -->
@@ -89,16 +110,15 @@
<select id="selectReadableIdentifiersWithin" resultType="string"> <select id="selectReadableIdentifiersWithin" resultType="string">
SELECT [guacamole_connection].connection_id SELECT [guacamole_connection].connection_id
FROM [guacamole_connection] FROM [guacamole_connection]
JOIN [guacamole_connection_permission] ON [guacamole_connection_permission].connection_id = [guacamole_connection].connection_id
WHERE WHERE
<if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}</if> <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}</if>
<if test="parentIdentifier == null">parent_id IS NULL</if> <if test="parentIdentifier == null">parent_id IS NULL</if>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND connection_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connection.ConnectionMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ' )
</select> </select>
<!-- Select multiple connections by identifier --> <!-- Select multiple connections by identifier -->
@@ -172,51 +192,48 @@
WHERE [guacamole_connection_history].connection_id = [guacamole_connection].connection_id WHERE [guacamole_connection_history].connection_id = [guacamole_connection].connection_id
) AS last_active ) AS last_active
FROM [guacamole_connection] FROM [guacamole_connection]
JOIN [guacamole_connection_permission] ON [guacamole_connection_permission].connection_id = [guacamole_connection].connection_id
WHERE [guacamole_connection].connection_id IN WHERE [guacamole_connection].connection_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_connection].connection_id IN (
<property name="column" value="[guacamole_connection_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connection.ConnectionMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT primary_connection_id, [guacamole_sharing_profile].sharing_profile_id SELECT primary_connection_id, [guacamole_sharing_profile].sharing_profile_id
FROM [guacamole_sharing_profile] FROM [guacamole_sharing_profile]
JOIN [guacamole_sharing_profile_permission] ON [guacamole_sharing_profile_permission].sharing_profile_id = [guacamole_sharing_profile].sharing_profile_id
WHERE primary_connection_id IN WHERE primary_connection_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_sharing_profile].sharing_profile_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT SELECT
[guacamole_connection_attribute].connection_id, [guacamole_connection_attribute].connection_id,
attribute_name, attribute_name,
attribute_value attribute_value
FROM [guacamole_connection_attribute] FROM [guacamole_connection_attribute]
JOIN [guacamole_connection_permission] ON [guacamole_connection_permission].connection_id = [guacamole_connection_attribute].connection_id
WHERE [guacamole_connection_attribute].connection_id IN WHERE [guacamole_connection_attribute].connection_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_connection_attribute].connection_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connection.ConnectionMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
</select> </select>

View File

@@ -168,31 +168,27 @@
LEFT JOIN [guacamole_connection] ON [guacamole_connection_history].connection_id = [guacamole_connection].connection_id LEFT JOIN [guacamole_connection] ON [guacamole_connection_history].connection_id = [guacamole_connection].connection_id
LEFT JOIN [guacamole_user] ON [guacamole_connection_history].user_id = [guacamole_user].user_id LEFT JOIN [guacamole_user] ON [guacamole_connection_history].user_id = [guacamole_user].user_id
<!-- Restrict to readable connections -->
JOIN [guacamole_connection_permission] ON
[guacamole_connection_history].connection_id = [guacamole_connection_permission].connection_id
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="[guacamole_connection_permission].entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND [guacamole_connection_permission].permission = 'READ'
<!-- Restrict to readable users -->
JOIN [guacamole_user_permission] ON
[guacamole_connection_history].user_id = [guacamole_user_permission].affected_user_id
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="[guacamole_user_permission].entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND [guacamole_user_permission].permission = 'READ'
<!-- Search terms --> <!-- Search terms -->
<where> <where>
<!-- Restrict to readable connections -->
[guacamole_connection_history].connection_id IN (
<include refid="org.apache.guacamole.auth.jdbc.connection.ConnectionMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
)
<!-- Restrict to readable users -->
AND [guacamole_connection_history].user_id IN (
<include refid="org.apache.guacamole.auth.jdbc.user.UserMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
)
<if test="identifier != null"> <if test="identifier != null">
[guacamole_connection_history].connection_id = #{identifier,jdbcType=INTEGER} AND [guacamole_connection_history].connection_id = #{identifier,jdbcType=INTEGER}
</if> </if>
<foreach collection="terms" item="term" open=" AND " separator=" AND "> <foreach collection="terms" item="term" open=" AND " separator=" AND ">

View File

@@ -64,17 +64,38 @@
FROM [guacamole_connection_group] FROM [guacamole_connection_group]
</select> </select>
<!-- Select identifiers of all readable connection groups --> <!--
<select id="selectReadableIdentifiers" resultType="string"> * SQL fragment which lists the IDs of all connection groups readable by
SELECT connection_group_id * the entity having the given entity ID. If group identifiers are
* provided, the IDs of the entities for all groups having those
* identifiers are tested, as well. Disabled groups are ignored.
*
* @param entityID
* The ID of the specific entity to test against.
*
* @param groups
* A collection of group identifiers to additionally test against.
* Though this functionality is optional, a collection must always be
* given, even if that collection is empty.
-->
<sql id="getReadableIDs">
SELECT DISTINCT connection_group_id
FROM [guacamole_connection_group_permission] FROM [guacamole_connection_group_permission]
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/> <property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="${entityID}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="${groups}"/>
</include> </include>
AND permission = 'READ' AND permission = 'READ'
</sql>
<!-- Select identifiers of all readable connection groups -->
<select id="selectReadableIdentifiers" resultType="string">
<include refid="org.apache.guacamole.auth.jdbc.connectiongroup.ConnectionGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
</select> </select>
<!-- Select all connection identifiers within a particular connection group --> <!-- Select all connection identifiers within a particular connection group -->
@@ -90,16 +111,15 @@
<select id="selectReadableIdentifiersWithin" resultType="string"> <select id="selectReadableIdentifiersWithin" resultType="string">
SELECT [guacamole_connection_group].connection_group_id SELECT [guacamole_connection_group].connection_group_id
FROM [guacamole_connection_group] FROM [guacamole_connection_group]
JOIN [guacamole_connection_group_permission] ON [guacamole_connection_group_permission].connection_group_id = [guacamole_connection_group].connection_group_id
WHERE WHERE
<if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}</if> <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}</if>
<if test="parentIdentifier == null">parent_id IS NULL</if> <if test="parentIdentifier == null">parent_id IS NULL</if>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND connection_group_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connectiongroup.ConnectionGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ' )
</select> </select>
<!-- Select multiple connection groups by identifier --> <!-- Select multiple connection groups by identifier -->
@@ -163,66 +183,62 @@
max_connections_per_user, max_connections_per_user,
enable_session_affinity enable_session_affinity
FROM [guacamole_connection_group] FROM [guacamole_connection_group]
JOIN [guacamole_connection_group_permission] ON [guacamole_connection_group_permission].connection_group_id = [guacamole_connection_group].connection_group_id
WHERE [guacamole_connection_group].connection_group_id IN WHERE [guacamole_connection_group].connection_group_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_connection_group].connection_group_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connectiongroup.ConnectionGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT parent_id, [guacamole_connection_group].connection_group_id SELECT parent_id, [guacamole_connection_group].connection_group_id
FROM [guacamole_connection_group] FROM [guacamole_connection_group]
JOIN [guacamole_connection_group_permission] ON [guacamole_connection_group_permission].connection_group_id = [guacamole_connection_group].connection_group_id
WHERE parent_id IN WHERE parent_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_connection_group].connection_group_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connectiongroup.ConnectionGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT parent_id, [guacamole_connection].connection_id SELECT parent_id, [guacamole_connection].connection_id
FROM [guacamole_connection] FROM [guacamole_connection]
JOIN [guacamole_connection_permission] ON [guacamole_connection_permission].connection_id = [guacamole_connection].connection_id
WHERE parent_id IN WHERE parent_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_connection].connection_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connection.ConnectionMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT SELECT
[guacamole_connection_group_attribute].connection_group_id, [guacamole_connection_group_attribute].connection_group_id,
attribute_name, attribute_name,
attribute_value attribute_value
FROM [guacamole_connection_group_attribute] FROM [guacamole_connection_group_attribute]
JOIN [guacamole_connection_group_permission] ON [guacamole_connection_group_permission].connection_group_id = [guacamole_connection_group_attribute].connection_group_id
WHERE [guacamole_connection_group_attribute].connection_group_id IN WHERE [guacamole_connection_group_attribute].connection_group_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_connection_group_attribute].connection_group_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.connectiongroup.ConnectionGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
</select> </select>

View File

@@ -34,7 +34,7 @@
<!-- Select all permissions for a given entity --> <!-- Select all permissions for a given entity -->
<select id="select" resultMap="ConnectionGroupPermissionResultMap"> <select id="select" resultMap="ConnectionGroupPermissionResultMap">
SELECT SELECT DISTINCT
#{entity.entityID,jdbcType=INTEGER} AS entity_id, #{entity.entityID,jdbcType=INTEGER} AS entity_id,
permission, permission,
connection_group_id connection_group_id

View File

@@ -34,7 +34,7 @@
<!-- Select all permissions for a given entity --> <!-- Select all permissions for a given entity -->
<select id="select" resultMap="ConnectionPermissionResultMap"> <select id="select" resultMap="ConnectionPermissionResultMap">
SELECT SELECT DISTINCT
#{entity.entityID,jdbcType=INTEGER} AS entity_id, #{entity.entityID,jdbcType=INTEGER} AS entity_id,
permission, permission,
connection_id connection_id

View File

@@ -34,7 +34,7 @@
<!-- Select all permissions for a given entity --> <!-- Select all permissions for a given entity -->
<select id="select" resultMap="SharingProfilePermissionResultMap"> <select id="select" resultMap="SharingProfilePermissionResultMap">
SELECT SELECT DISTINCT
#{entity.entityID,jdbcType=INTEGER} AS entity_id, #{entity.entityID,jdbcType=INTEGER} AS entity_id,
permission, permission,
sharing_profile_id sharing_profile_id

View File

@@ -34,7 +34,7 @@
<!-- Select all permissions for a given entity --> <!-- Select all permissions for a given entity -->
<select id="select" resultMap="UserGroupPermissionResultMap"> <select id="select" resultMap="UserGroupPermissionResultMap">
SELECT SELECT DISTINCT
#{entity.entityID,jdbcType=INTEGER} AS entity_id, #{entity.entityID,jdbcType=INTEGER} AS entity_id,
permission, permission,
affected_entity.name AS affected_name affected_entity.name AS affected_name

View File

@@ -34,7 +34,7 @@
<!-- Select all permissions for a given entity --> <!-- Select all permissions for a given entity -->
<select id="select" resultMap="UserPermissionResultMap"> <select id="select" resultMap="UserPermissionResultMap">
SELECT SELECT DISTINCT
#{entity.entityID,jdbcType=INTEGER} AS entity_id, #{entity.entityID,jdbcType=INTEGER} AS entity_id,
permission, permission,
affected_entity.name AS affected_name affected_entity.name AS affected_name

View File

@@ -47,17 +47,38 @@
FROM [guacamole_sharing_profile] FROM [guacamole_sharing_profile]
</select> </select>
<!-- Select identifiers of all readable sharing profiles --> <!--
<select id="selectReadableIdentifiers" resultType="string"> * SQL fragment which lists the IDs of all sharing profiles readable by
SELECT sharing_profile_id * the entity having the given entity ID. If group identifiers are
* provided, the IDs of the entities for all groups having those
* identifiers are tested, as well. Disabled groups are ignored.
*
* @param entityID
* The ID of the specific entity to test against.
*
* @param groups
* A collection of group identifiers to additionally test against.
* Though this functionality is optional, a collection must always be
* given, even if that collection is empty.
-->
<sql id="getReadableIDs">
SELECT DISTINCT sharing_profile_id
FROM [guacamole_sharing_profile_permission] FROM [guacamole_sharing_profile_permission]
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/> <property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="${entityID}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="${groups}"/>
</include> </include>
AND permission = 'READ' AND permission = 'READ'
</sql>
<!-- Select identifiers of all readable sharing profiles -->
<select id="selectReadableIdentifiers" resultType="string">
<include refid="org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
</select> </select>
<!-- Select multiple sharing profiles by identifier --> <!-- Select multiple sharing profiles by identifier -->
@@ -97,36 +118,34 @@
[guacamole_sharing_profile].sharing_profile_name, [guacamole_sharing_profile].sharing_profile_name,
primary_connection_id primary_connection_id
FROM [guacamole_sharing_profile] FROM [guacamole_sharing_profile]
JOIN [guacamole_sharing_profile_permission] ON [guacamole_sharing_profile_permission].sharing_profile_id = [guacamole_sharing_profile].sharing_profile_id
WHERE [guacamole_sharing_profile].sharing_profile_id IN WHERE [guacamole_sharing_profile].sharing_profile_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_sharing_profile].sharing_profile_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT SELECT
[guacamole_sharing_profile_attribute].sharing_profile_id, [guacamole_sharing_profile_attribute].sharing_profile_id,
attribute_name, attribute_name,
attribute_value attribute_value
FROM [guacamole_sharing_profile_attribute] FROM [guacamole_sharing_profile_attribute]
JOIN [guacamole_sharing_profile_permission] ON [guacamole_sharing_profile_permission].sharing_profile_id = [guacamole_sharing_profile_attribute].sharing_profile_id
WHERE [guacamole_sharing_profile_attribute].sharing_profile_id IN WHERE [guacamole_sharing_profile_attribute].sharing_profile_id IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER} #{identifier,jdbcType=INTEGER}
</foreach> </foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_sharing_profile_attribute].sharing_profile_id IN (
<property name="column" value="entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
</select> </select>

View File

@@ -63,20 +63,45 @@
WHERE [guacamole_entity].type = 'USER' WHERE [guacamole_entity].type = 'USER'
</select> </select>
<!--
* SQL fragment which lists the IDs of all users readable by the entity
* having the given entity ID. If group identifiers are provided, the IDs
* of the entities for all groups having those identifiers are tested, as
* well. Disabled groups are ignored.
*
* @param entityID
* The ID of the specific entity to test against.
*
* @param groups
* A collection of group identifiers to additionally test against.
* Though this functionality is optional, a collection must always be
* given, even if that collection is empty.
-->
<sql id="getReadableIDs">
SELECT DISTINCT [guacamole_user_permission].affected_user_id
FROM [guacamole_user_permission]
WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="${entityID}"/>
<property name="groups" value="${groups}"/>
</include>
AND permission = 'READ'
</sql>
<!-- Select usernames of all readable users --> <!-- Select usernames of all readable users -->
<select id="selectReadableIdentifiers" resultType="string"> <select id="selectReadableIdentifiers" resultType="string">
SELECT [guacamole_entity].name SELECT [guacamole_entity].name
FROM [guacamole_user] FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_permission] ON affected_user_id = [guacamole_user].user_id
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> [guacamole_user].user_id IN (
<property name="column" value="[guacamole_user_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.user.UserMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND [guacamole_entity].type = 'USER' AND [guacamole_entity].type = 'USER'
AND permission = 'READ'
</select> </select>
<!-- Select multiple users by username --> <!-- Select multiple users by username -->
@@ -160,19 +185,18 @@
) AS last_active ) AS last_active
FROM [guacamole_user] FROM [guacamole_user]
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_permission] ON affected_user_id = [guacamole_user].user_id
WHERE [guacamole_entity].name IN WHERE [guacamole_entity].name IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=VARCHAR} #{identifier,jdbcType=VARCHAR}
</foreach> </foreach>
AND [guacamole_entity].type = 'USER' AND [guacamole_entity].type = 'USER'
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_user].user_id IN (
<property name="column" value="[guacamole_user_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.user.UserMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT SELECT
[guacamole_user_attribute].user_id, [guacamole_user_attribute].user_id,
@@ -181,19 +205,18 @@
FROM [guacamole_user_attribute] FROM [guacamole_user_attribute]
JOIN [guacamole_user] ON [guacamole_user].user_id = [guacamole_user_attribute].user_id JOIN [guacamole_user] ON [guacamole_user].user_id = [guacamole_user_attribute].user_id
JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id JOIN [guacamole_entity] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_permission] ON affected_user_id = [guacamole_user].user_id
WHERE [guacamole_entity].name IN WHERE [guacamole_entity].name IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=VARCHAR} #{identifier,jdbcType=VARCHAR}
</foreach> </foreach>
AND [guacamole_entity].type = 'USER' AND [guacamole_entity].type = 'USER'
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_user].user_id IN (
<property name="column" value="[guacamole_user_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.user.UserMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
</select> </select>

View File

@@ -40,16 +40,15 @@
FROM [guacamole_user_group_member] FROM [guacamole_user_group_member]
JOIN [guacamole_user_group] ON [guacamole_user_group_member].user_group_id = [guacamole_user_group].user_group_id JOIN [guacamole_user_group] ON [guacamole_user_group_member].user_group_id = [guacamole_user_group].user_group_id
JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group].entity_id JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group].entity_id
JOIN [guacamole_user_group_permission] ON affected_user_group_id = [guacamole_user_group].user_group_id
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> [guacamole_user_group].user_group_id IN (
<property name="column" value="[guacamole_user_group_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND [guacamole_user_group_member].member_entity_id = #{parent.entityID,jdbcType=INTEGER} AND [guacamole_user_group_member].member_entity_id = #{parent.entityID,jdbcType=INTEGER}
AND [guacamole_entity].type = 'USER_GROUP' AND [guacamole_entity].type = 'USER_GROUP'
AND permission = 'READ'
</select> </select>
<!-- Delete parent groups by name --> <!-- Delete parent groups by name -->

View File

@@ -158,21 +158,19 @@
[guacamole_user_history].end_date [guacamole_user_history].end_date
FROM [guacamole_user_history] 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 <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="[guacamole_user_permission].entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND [guacamole_user_permission].permission = 'READ'
<!-- Search terms --> <!-- Search terms -->
<where> <where>
<!-- Restrict to readable users -->
[guacamole_connection_history].user_id IN (
<include refid="org.apache.guacamole.auth.jdbc.user.UserMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
)
<if test="username != null"> <if test="username != null">
[guacamole_entity].name = #{username,jdbcType=VARCHAR} AND [guacamole_entity].name = #{username,jdbcType=VARCHAR}
</if> </if>
<foreach collection="terms" item="term" open=" AND " separator=" AND "> <foreach collection="terms" item="term" open=" AND " separator=" AND ">

View File

@@ -49,20 +49,45 @@
WHERE [guacamole_entity].type = 'USER_GROUP' WHERE [guacamole_entity].type = 'USER_GROUP'
</select> </select>
<!--
* SQL fragment which lists the IDs of all user groups readable by the
* entity having the given entity ID. If group identifiers are provided,
* the IDs of the entities for all groups having those identifiers are
* tested, as well. Disabled groups are ignored.
*
* @param entityID
* The ID of the specific entity to test against.
*
* @param groups
* A collection of group identifiers to additionally test against.
* Though this functionality is optional, a collection must always be
* given, even if that collection is empty.
-->
<sql id="getReadableIDs">
SELECT DISTINCT [guacamole_user_group_permission].affected_user_group_id
FROM [guacamole_user_group_permission]
WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="${entityID}"/>
<property name="groups" value="${groups}"/>
</include>
AND permission = 'READ'
</sql>
<!-- Select names of all readable groups --> <!-- Select names of all readable groups -->
<select id="selectReadableIdentifiers" resultType="string"> <select id="selectReadableIdentifiers" resultType="string">
SELECT [guacamole_entity].name SELECT [guacamole_entity].name
FROM [guacamole_user_group] FROM [guacamole_user_group]
JOIN [guacamole_entity] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id JOIN [guacamole_entity] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_group_permission] ON affected_user_group_id = [guacamole_user_group].user_group_id
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> [guacamole_user_group].user_group_id IN (
<property name="column" value="[guacamole_user_group_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND [guacamole_entity].type = 'USER_GROUP' AND [guacamole_entity].type = 'USER_GROUP'
AND permission = 'READ'
</select> </select>
<!-- Select multiple groups by name --> <!-- Select multiple groups by name -->
@@ -110,19 +135,18 @@
disabled disabled
FROM [guacamole_user_group] FROM [guacamole_user_group]
JOIN [guacamole_entity] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id JOIN [guacamole_entity] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_group_permission] ON affected_user_group_id = [guacamole_user_group].user_group_id
WHERE [guacamole_entity].name IN WHERE [guacamole_entity].name IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=VARCHAR} #{identifier,jdbcType=VARCHAR}
</foreach> </foreach>
AND [guacamole_entity].type = 'USER_GROUP' AND [guacamole_entity].type = 'USER_GROUP'
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_user_group].user_group_id IN (
<property name="column" value="[guacamole_user_group_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
SELECT SELECT
[guacamole_user_group_attribute].user_group_id, [guacamole_user_group_attribute].user_group_id,
@@ -131,19 +155,18 @@
FROM [guacamole_user_group_attribute] FROM [guacamole_user_group_attribute]
JOIN [guacamole_user_group] ON [guacamole_user_group].user_group_id = [guacamole_user_group_attribute].user_group_id JOIN [guacamole_user_group] ON [guacamole_user_group].user_group_id = [guacamole_user_group_attribute].user_group_id
JOIN [guacamole_entity] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id JOIN [guacamole_entity] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_group_permission] ON affected_user_group_id = [guacamole_user_group].user_group_id
WHERE [guacamole_entity].name IN WHERE [guacamole_entity].name IN
<foreach collection="identifiers" item="identifier" <foreach collection="identifiers" item="identifier"
open="(" separator="," close=")"> open="(" separator="," close=")">
#{identifier,jdbcType=VARCHAR} #{identifier,jdbcType=VARCHAR}
</foreach> </foreach>
AND [guacamole_entity].type = 'USER_GROUP' AND [guacamole_entity].type = 'USER_GROUP'
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> AND [guacamole_user_group].user_group_id IN (
<property name="column" value="[guacamole_user_group_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
AND permission = 'READ'; );
</select> </select>

View File

@@ -39,16 +39,15 @@
FROM [guacamole_user_group_member] FROM [guacamole_user_group_member]
JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group_member].member_entity_id JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group_member].member_entity_id
JOIN [guacamole_user_group] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id JOIN [guacamole_user_group] ON [guacamole_user_group].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_group_permission] ON affected_user_group_id = [guacamole_user_group].user_group_id
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> [guacamole_user_group].user_group_id IN (
<property name="column" value="[guacamole_user_group_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND [guacamole_user_group_member].user_group_id = #{parent.objectID,jdbcType=INTEGER} AND [guacamole_user_group_member].user_group_id = #{parent.objectID,jdbcType=INTEGER}
AND [guacamole_entity].type = 'USER_GROUP' AND [guacamole_entity].type = 'USER_GROUP'
AND permission = 'READ'
</select> </select>
<!-- Delete member groups by name --> <!-- Delete member groups by name -->

View File

@@ -39,16 +39,15 @@
FROM [guacamole_user_group_member] FROM [guacamole_user_group_member]
JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group_member].member_entity_id JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group_member].member_entity_id
JOIN [guacamole_user] ON [guacamole_user].entity_id = [guacamole_entity].entity_id JOIN [guacamole_user] ON [guacamole_user].entity_id = [guacamole_entity].entity_id
JOIN [guacamole_user_permission] ON affected_user_id = [guacamole_user].user_id
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> [guacamole_user].user_id IN (
<property name="column" value="[guacamole_user_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.user.UserMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND [guacamole_user_group_member].user_group_id = #{parent.objectID,jdbcType=INTEGER} AND [guacamole_user_group_member].user_group_id = #{parent.objectID,jdbcType=INTEGER}
AND [guacamole_entity].type = 'USER' AND [guacamole_entity].type = 'USER'
AND permission = 'READ'
</select> </select>
<!-- Delete member users by name --> <!-- Delete member users by name -->

View File

@@ -40,16 +40,15 @@
FROM [guacamole_user_group_member] FROM [guacamole_user_group_member]
JOIN [guacamole_user_group] ON [guacamole_user_group_member].user_group_id = [guacamole_user_group].user_group_id JOIN [guacamole_user_group] ON [guacamole_user_group_member].user_group_id = [guacamole_user_group].user_group_id
JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group].entity_id JOIN [guacamole_entity] ON [guacamole_entity].entity_id = [guacamole_user_group].entity_id
JOIN [guacamole_user_group_permission] ON affected_user_group_id = [guacamole_user_group].user_group_id
WHERE WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity"> [guacamole_user_group].user_group_id IN (
<property name="column" value="[guacamole_user_group_permission].entity_id"/> <include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/> <property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/> <property name="groups" value="effectiveGroups"/>
</include> </include>
)
AND [guacamole_user_group_member].member_entity_id = #{parent.entityID,jdbcType=INTEGER} AND [guacamole_user_group_member].member_entity_id = #{parent.entityID,jdbcType=INTEGER}
AND [guacamole_entity].type = 'USER_GROUP' AND [guacamole_entity].type = 'USER_GROUP'
AND permission = 'READ'
</select> </select>
<!-- Delete parent groups by name --> <!-- Delete parent groups by name -->