GUAC-1101: Implement querying of user permissions.

This commit is contained in:
Michael Jumper
2015-02-28 20:29:07 -08:00
parent 9f22d6bd71
commit 8d2e953a23
6 changed files with 266 additions and 3 deletions

View File

@@ -55,6 +55,9 @@ import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionGroupPermissionSet
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionMapper; import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionMapper;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService; import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionSet; import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionSet;
import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionMapper;
import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionService;
import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionSet;
import org.glyptodon.guacamole.environment.Environment; import org.glyptodon.guacamole.environment.Environment;
import org.mybatis.guice.MyBatisModule; import org.mybatis.guice.MyBatisModule;
import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider; import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider;
@@ -103,6 +106,7 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
addMapperClass(ParameterMapper.class); addMapperClass(ParameterMapper.class);
addMapperClass(SystemPermissionMapper.class); addMapperClass(SystemPermissionMapper.class);
addMapperClass(UserMapper.class); addMapperClass(UserMapper.class);
addMapperClass(UserPermissionMapper.class);
// Bind core implementations of guacamole-ext classes // Bind core implementations of guacamole-ext classes
bind(Environment.class).toInstance(environment); bind(Environment.class).toInstance(environment);
@@ -118,6 +122,7 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
bind(SystemPermissionSet.class); bind(SystemPermissionSet.class);
bind(UserContext.class); bind(UserContext.class);
bind(UserDirectory.class); bind(UserDirectory.class);
bind(UserPermissionSet.class);
// Bind services // Bind services
bind(ConnectionGroupPermissionService.class); bind(ConnectionGroupPermissionService.class);
@@ -127,6 +132,7 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class); bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);
bind(SaltService.class).to(SecureRandomSaltService.class); bind(SaltService.class).to(SecureRandomSaltService.class);
bind(SystemPermissionService.class); bind(SystemPermissionService.class);
bind(UserPermissionService.class);
bind(UserService.class); bind(UserService.class);
// Bind appropriate socket service based on policy // Bind appropriate socket service based on policy

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2015 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.glyptodon.guacamole.auth.jdbc.permission;
/**
* Mapper for user permissions.
*
* @author Michael Jumper
*/
public interface UserPermissionMapper extends ObjectPermissionMapper {}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2013 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.glyptodon.guacamole.auth.jdbc.permission;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.auth.jdbc.user.ModeledUser;
/**
* Service which provides convenience methods for creating, retrieving, and
* deleting user permissions. This service will automatically enforce the
* permissions of the current user.
*
* @author Michael Jumper
*/
public class UserPermissionService extends ObjectPermissionService {
/**
* Mapper for user permissions.
*/
@Inject
private UserPermissionMapper userPermissionMapper;
/**
* Provider for user permission sets.
*/
@Inject
private Provider<UserPermissionSet> userPermissionSetProvider;
@Override
protected ObjectPermissionMapper getPermissionMapper() {
return userPermissionMapper;
}
@Override
public ObjectPermissionSet getPermissionSet(AuthenticatedUser user,
ModeledUser targetUser) throws GuacamoleException {
// Create permission set for requested user
ObjectPermissionSet permissionSet = userPermissionSetProvider.get();
permissionSet.init(user, targetUser);
return permissionSet;
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2015 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.glyptodon.guacamole.auth.jdbc.permission;
import com.google.inject.Inject;
/**
* A database implementation of ObjectPermissionSet which uses an injected
* service to query and manipulate the user permissions associated with a
* particular user.
*
* @author Michael Jumper
*/
public class UserPermissionSet extends ObjectPermissionSet {
/**
* Service for querying and manipulating user permissions.
*/
@Inject
private UserPermissionService userPermissionService;
@Override
protected ObjectPermissionService getObjectPermissionService() {
return userPermissionService;
}
}

View File

@@ -30,11 +30,11 @@ import org.glyptodon.guacamole.auth.jdbc.permission.SystemPermissionService;
import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionGroupPermissionService; import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionGroupPermissionService;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService; import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService;
import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionService;
import org.glyptodon.guacamole.net.auth.User; import org.glyptodon.guacamole.net.auth.User;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermission; import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
import org.glyptodon.guacamole.net.auth.simple.SimpleObjectPermissionSet;
/** /**
* An implementation of the User object which is backed by a database model. * An implementation of the User object which is backed by a database model.
@@ -73,6 +73,12 @@ public class ModeledUser extends DirectoryObject<UserModel> implements User {
*/ */
@Inject @Inject
private ConnectionGroupPermissionService connectionGroupPermissionService; private ConnectionGroupPermissionService connectionGroupPermissionService;
/**
* Service for retrieving user permissions.
*/
@Inject
private UserPermissionService userPermissionService;
/** /**
* The plaintext password previously set by a call to setPassword(), if * The plaintext password previously set by a call to setPassword(), if
@@ -157,8 +163,7 @@ public class ModeledUser extends DirectoryObject<UserModel> implements User {
@Override @Override
public ObjectPermissionSet getUserPermissions() public ObjectPermissionSet getUserPermissions()
throws GuacamoleException { throws GuacamoleException {
// STUB return userPermissionService.getPermissionSet(getCurrentUser(), this);
return new SimpleObjectPermissionSet();
} }
} }

View File

@@ -0,0 +1,106 @@
<?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" >
<!--
Copyright (C) 2015 Glyptodon LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<mapper namespace="org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionMapper" >
<!-- Result mapper for user permissions -->
<resultMap id="UserPermissionResultMap" type="org.glyptodon.guacamole.auth.jdbc.permission.ObjectPermissionModel">
<result column="user_id" property="userID" jdbcType="INTEGER"/>
<result column="username" property="username" jdbcType="VARCHAR"/>
<result column="permission" property="type" jdbcType="VARCHAR"
javaType="org.glyptodon.guacamole.net.auth.permission.ObjectPermission$Type"/>
<result column="affected_username" property="objectIdentifier" jdbcType="INTEGER"/>
</resultMap>
<!-- Select all permissions for a given user -->
<select id="select" resultMap="UserPermissionResultMap">
SELECT
guacamole_user_permission.user_id,
guacamole_user.username,
permission,
affected.username AS affected_username
FROM guacamole_user_permission
JOIN guacamole_user ON guacamole_user_permission.user_id = guacamole_user.user_id
JOIN guacamole_user affected ON guacamole_user_permission.affected_user_id = affected.user_id
WHERE guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
</select>
<!-- Select the single permission matching the given criteria -->
<select id="selectOne" resultMap="UserPermissionResultMap">
SELECT
guacamole_user_permission.user_id,
guacamole_user.username,
permission,
affected.username AS affected_username
FROM guacamole_user_permission
JOIN guacamole_user ON guacamole_user_permission.user_id = guacamole_user.user_id
JOIN guacamole_user affected ON guacamole_user_permission.affected_user_id = affected.user_id
WHERE
guacamole_user_permission.user_id = #{user.objectID,jdbcType=INTEGER}
AND permission = #{type,jdbcType=VARCHAR}
</select>
<!-- Delete all given permissions -->
<delete id="delete" parameterType="org.glyptodon.guacamole.auth.jdbc.permission.ObjectPermissionModel">
DELETE FROM guacamole_user_permission
USING guacamole_user_permission
JOIN guacamole_user affected ON guacamole_user_permission.affected_user_id = affected.user_id
WHERE
(guacamole_user_permission.user_id, permission, affected.username) IN
<foreach collection="permissions" item="permission"
open="(" separator="," close=")">
(#{permission.userID,jdbcType=INTEGER},
#{permission.type,jdbcType=VARCHAR},
#{permission.objectIdentifier,jdbcType=VARCHAR})
</foreach>
</delete>
<!-- Insert all given permissions -->
<insert id="insert" parameterType="org.glyptodon.guacamole.auth.jdbc.permission.ObjectPermissionModel">
INSERT IGNORE INTO guacamole_user_permission (
user_id,
permission,
affected_user_id
)
SELECT permissions.user_id, permissions.permission, guacamole_user.user_id FROM (
<foreach collection="permissions" item="permission" separator="UNION ALL">
SELECT #{permission.userID,jdbcType=INTEGER} AS user_id,
#{permission.type,jdbcType=VARCHAR} AS permission,
#{permission.objectIdentifier,jdbcType=VARCHAR} AS username
</foreach>
) AS permissions
JOIN guacamole_user ON guacamole_user.username = permissions.username;
</insert>
</mapper>