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

Previous versions of the PostgreSQL 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 61dce8bdb1
commit a37e0accb6
16 changed files with 288 additions and 199 deletions

View File

@@ -63,17 +63,38 @@
FROM guacamole_connection
</select>
<!-- Select identifiers of all readable connections -->
<select id="selectReadableIdentifiers" resultType="string">
SELECT connection_id
<!--
* SQL fragment which lists the IDs of all connections 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 connection_id
FROM guacamole_connection_permission
WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
<property name="entityID" value="${entityID}"/>
<property name="groups" value="${groups}"/>
</include>
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 all connection identifiers within a particular connection group -->
@@ -89,16 +110,15 @@
<select id="selectReadableIdentifiersWithin" resultType="string">
SELECT guacamole_connection.connection_id
FROM guacamole_connection
JOIN guacamole_connection_permission ON guacamole_connection_permission.connection_id = guacamole_connection.connection_id
WHERE
<if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}::integer</if>
<if test="parentIdentifier == null">parent_id IS NULL</if>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ'
AND 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>
)
</select>
<!-- Select multiple connections by identifier -->
@@ -166,53 +186,50 @@
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=INTEGER}::integer
</foreach>
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 permission = 'READ'
AND guacamole_connection.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>
)
GROUP BY guacamole_connection.connection_id;
SELECT primary_connection_id, guacamole_sharing_profile.sharing_profile_id
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_sharing_profile.sharing_profile_id IN (
<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
guacamole_connection_attribute.connection_id,
attribute_name,
attribute_value
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_connection_attribute.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>
);
</select>

View File

@@ -170,31 +170,27 @@
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
<!-- 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 -->
<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">
guacamole_connection_history.connection_id = #{identifier,jdbcType=INTEGER}::integer
AND guacamole_connection_history.connection_id = #{identifier,jdbcType=INTEGER}::integer
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">

View File

@@ -64,17 +64,38 @@
FROM guacamole_connection_group
</select>
<!-- Select identifiers of all readable connection groups -->
<select id="selectReadableIdentifiers" resultType="string">
SELECT connection_group_id
<!--
* SQL fragment which lists the IDs of all connection 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 connection_group_id
FROM guacamole_connection_group_permission
WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
<property name="entityID" value="${entityID}"/>
<property name="groups" value="${groups}"/>
</include>
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 all connection identifiers within a particular connection group -->
@@ -90,16 +111,15 @@
<select id="selectReadableIdentifiersWithin" resultType="string">
SELECT guacamole_connection_group.connection_group_id
FROM guacamole_connection_group
JOIN guacamole_connection_group_permission ON guacamole_connection_group_permission.connection_group_id = guacamole_connection_group.connection_group_id
WHERE
<if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}::integer</if>
<if test="parentIdentifier == null">parent_id IS NULL</if>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ'
AND connection_group_id IN (
<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 multiple connection groups by identifier -->
@@ -163,66 +183,62 @@
max_connections_per_user,
enable_session_affinity
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_connection_group.connection_group_id IN (
<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 parent_id, guacamole_connection_group.connection_group_id
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_connection_group.connection_group_id IN (
<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 parent_id, guacamole_connection.connection_id
FROM guacamole_connection
JOIN guacamole_connection_permission ON guacamole_connection_permission.connection_id = guacamole_connection.connection_id
WHERE parent_id IN
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_connection.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>
);
SELECT
guacamole_connection_group_attribute.connection_group_id,
attribute_name,
attribute_value
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_connection_group_attribute.connection_group_id IN (
<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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -47,17 +47,38 @@
FROM guacamole_sharing_profile
</select>
<!-- Select identifiers of all readable sharing profiles -->
<select id="selectReadableIdentifiers" resultType="string">
SELECT sharing_profile_id
<!--
* SQL fragment which lists the IDs of all sharing profiles 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 sharing_profile_id
FROM guacamole_sharing_profile_permission
WHERE
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
<property name="entityID" value="${entityID}"/>
<property name="groups" value="${groups}"/>
</include>
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 multiple sharing profiles by identifier -->
@@ -97,36 +118,34 @@
guacamole_sharing_profile.sharing_profile_name,
primary_connection_id
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_sharing_profile.sharing_profile_id IN (
<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
guacamole_sharing_profile_attribute.sharing_profile_id,
attribute_name,
attribute_value
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=INTEGER}::integer
</foreach>
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_sharing_profile_attribute.sharing_profile_id IN (
<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>

View File

@@ -63,20 +63,45 @@
WHERE guacamole_entity.type = 'USER'::guacamole_entity_type
</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 id="selectReadableIdentifiers" resultType="string">
SELECT guacamole_entity.name
FROM guacamole_user
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
<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>
guacamole_user.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>
)
AND guacamole_entity.type = 'USER'::guacamole_entity_type
AND permission = 'READ'
</select>
<!-- Select multiple users by username -->
@@ -154,7 +179,6 @@
MAX(start_date) AS last_active
FROM guacamole_user
JOIN guacamole_entity ON guacamole_user.entity_id = guacamole_entity.entity_id
JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id
LEFT JOIN guacamole_user_history ON guacamole_user_history.user_id = guacamole_user.user_id
WHERE guacamole_entity.name IN
<foreach collection="identifiers" item="identifier"
@@ -162,12 +186,12 @@
#{identifier,jdbcType=VARCHAR}
</foreach>
AND guacamole_entity.type = 'USER'::guacamole_entity_type
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 permission = 'READ'
AND guacamole_user.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>
)
GROUP BY guacamole_user.user_id, guacamole_entity.entity_id;
SELECT
@@ -177,19 +201,18 @@
FROM guacamole_user_attribute
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_user_permission ON affected_user_id = guacamole_user.user_id
WHERE guacamole_entity.name IN
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=VARCHAR}
</foreach>
AND guacamole_entity.type = 'USER'::guacamole_entity_type
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 permission = 'READ';
AND guacamole_user.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>
);
</select>

View File

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

View File

@@ -160,20 +160,19 @@
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 <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 -->
<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">
guacamole_entity.name = #{username,jdbcType=VARCHAR}
AND guacamole_entity.name = #{username,jdbcType=VARCHAR}
</if>
<foreach collection="terms" item="term" open=" AND " separator=" AND ">

View File

@@ -49,20 +49,45 @@
WHERE guacamole_entity.type = 'USER_GROUP'::guacamole_entity_type
</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 id="selectReadableIdentifiers" resultType="string">
SELECT guacamole_entity.name
FROM guacamole_user_group
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
<include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="guacamole_user_group_permission.entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
guacamole_user_group.user_group_id IN (
<include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
)
AND guacamole_entity.type = 'USER_GROUP'::guacamole_entity_type
AND permission = 'READ'
</select>
<!-- Select multiple groups by name -->
@@ -110,19 +135,18 @@
disabled
FROM guacamole_user_group
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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=VARCHAR}
</foreach>
AND guacamole_entity.type = 'USER_GROUP'::guacamole_entity_type
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="guacamole_user_group_permission.entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_user_group.user_group_id IN (
<include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
);
SELECT
guacamole_user_group_attribute.user_group_id,
@@ -131,19 +155,18 @@
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_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
<foreach collection="identifiers" item="identifier"
open="(" separator="," close=")">
#{identifier,jdbcType=VARCHAR}
</foreach>
AND guacamole_entity.type = 'USER_GROUP'::guacamole_entity_type
AND <include refid="org.apache.guacamole.auth.jdbc.base.EntityMapper.isRelatedEntity">
<property name="column" value="guacamole_user_group_permission.entity_id"/>
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
AND permission = 'READ';
AND guacamole_user_group.user_group_id IN (
<include refid="org.apache.guacamole.auth.jdbc.usergroup.UserGroupMapper.getReadableIDs">
<property name="entityID" value="#{user.entityID,jdbcType=INTEGER}"/>
<property name="groups" value="effectiveGroups"/>
</include>
);
</select>

View File

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

View File

@@ -39,16 +39,15 @@
FROM guacamole_user_group_member
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_permission ON affected_user_id = guacamole_user.user_id
WHERE
<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>
guacamole_user.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>
)
AND guacamole_user_group_member.user_group_id = #{parent.objectID,jdbcType=INTEGER}
AND guacamole_entity.type = 'USER'::guacamole_entity_type
AND permission = 'READ'
</select>
<!-- Delete member users by name -->

View File

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