diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java index 68c26ee24..294752ea0 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLAuthenticationProvider.java @@ -140,6 +140,7 @@ public class MySQLAuthenticationProvider implements AuthenticationProvider { // Bind interfaces bind(MySQLUser.class); bind(MySQLUserContext.class); + bind(MySQLSystemPermissionSet.class); bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class); bind(SaltService.class).to(SecureRandomSaltService.class); bind(SystemPermissionService.class); diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLSystemPermissionSet.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLSystemPermissionSet.java new file mode 100644 index 000000000..5343feffb --- /dev/null +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLSystemPermissionSet.java @@ -0,0 +1,119 @@ +/* + * 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 net.sourceforge.guacamole.net.auth.mysql; + +import com.google.inject.Inject; +import java.util.Collections; +import java.util.Set; +import net.sourceforge.guacamole.net.auth.mysql.service.SystemPermissionService; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.net.auth.permission.SystemPermission; +import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; + +/** + * A database implementation of SystemPermissionSet which uses an injected + * service to query and manipulate the system permissions associated with a + * particular user. + * + * @author Michael Jumper + */ +public class MySQLSystemPermissionSet implements SystemPermissionSet { + + /** + * The user that queried this permission set. Access is based on his/her + * permission settings. + */ + private AuthenticatedUser currentUser; + + /** + * The user associated with this permission set. Each of the permissions in + * this permission set is granted to this user. + */ + private MySQLUser user; + + /** + * Service for reading and manipulating system permissions. + */ + @Inject + private SystemPermissionService systemPermissionService; + + /** + * Creates a new MySQLSystemPermissionSet. The resulting permission set + * must still be initialized by a call to init(), or the information + * necessary to read and modify this set will be missing. + */ + public MySQLSystemPermissionSet() { + } + + /** + * Initializes this permission set with the current user and the user + * to whom the permissions in this set are granted. + * + * @param currentUser + * The user who queried this permission set, and whose permissions + * dictate the access level of all operations performed on this set. + * + * @param user + * The user to whom the permissions in this set are granted. + */ + public void init(AuthenticatedUser currentUser, MySQLUser user) { + this.currentUser = currentUser; + this.user = user; + } + + @Override + public Set getPermissions() throws GuacamoleException { + return systemPermissionService.retrievePermissions(currentUser, user); + } + + @Override + public boolean hasPermission(SystemPermission.Type permission) + throws GuacamoleException { + return systemPermissionService.retrievePermission(currentUser, user, permission) != null; + } + + @Override + public void addPermission(SystemPermission.Type permission) + throws GuacamoleException { + addPermissions(Collections.singleton(new SystemPermission(permission))); + } + + @Override + public void removePermission(SystemPermission.Type permission) + throws GuacamoleException { + removePermissions(Collections.singleton(new SystemPermission(permission))); + } + + @Override + public void addPermissions(Set permissions) + throws GuacamoleException { + systemPermissionService.createPermissions(currentUser, user, permissions); + } + + @Override + public void removePermissions(Set permissions) + throws GuacamoleException { + systemPermissionService.deletePermissions(currentUser, user, permissions); + } + +} diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java index a2e0f2cfb..fd8d8fa49 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLUser.java @@ -163,8 +163,7 @@ public class MySQLUser implements User, DirectoryObject { @Override public SystemPermissionSet getSystemPermissions() throws GuacamoleException { - // STUB - return new SimpleSystemPermissionSet(systemPermissionService.retrievePermissions(getCurrentUser(), this)); + return systemPermissionService.getPermissionSet(getCurrentUser(), this); } @Override diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.java index e1ff02019..8646a3774 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.java @@ -23,6 +23,9 @@ package net.sourceforge.guacamole.net.auth.mysql.dao; import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionModel; +import net.sourceforge.guacamole.net.auth.mysql.model.UserModel; +import org.apache.ibatis.annotations.Param; +import org.glyptodon.guacamole.net.auth.permission.SystemPermission; /** * Mapper for system-level permissions. @@ -30,4 +33,22 @@ import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionModel; * @author Michael Jumper */ public interface SystemPermissionMapper extends PermissionMapper { + + /** + * Retrieve the permission of the given type associated with the given + * user, if it exists. If no such permission exists, null is returned. + * + * @param user + * The user to retrieve permissions for. + * + * @param type + * The type of permission to return. + * + * @return + * The requested permission, or null if no such permission is granted + * to the given user. + */ + SystemPermissionModel selectOne(@Param("user") UserModel user, + @Param("type") SystemPermission.Type type); + } \ No newline at end of file diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ObjectPermissionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ObjectPermissionService.java index 0132e4871..9a6290504 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ObjectPermissionService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ObjectPermissionService.java @@ -38,15 +38,12 @@ import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; * permissions of the current user. * * @author Michael Jumper - * @param - * The type of object permission this service provides access to. - * * @param * The underlying model object used to represent PermissionType in the * database. */ -public abstract class ObjectPermissionService - extends PermissionService { +public abstract class ObjectPermissionService + extends PermissionService { /** * Returns the permission set associated with the given user and related @@ -93,7 +90,7 @@ public abstract class ObjectPermissionService permissions) + Collection permissions) throws GuacamoleException { // A system adminstrator can do anything @@ -107,7 +104,7 @@ public abstract class ObjectPermissionService affectedIdentifiers = new HashSet(permissions.size()); - for (ObjectPermissionType permission : permissions) + for (ObjectPermission permission : permissions) affectedIdentifiers.add(permission.getObjectIdentifier()); // Determine subset of affected identifiers that we have admin access to @@ -127,7 +124,7 @@ public abstract class ObjectPermissionService permissions) + Collection permissions) throws GuacamoleException { // Create permissions only if user has permission to do so @@ -144,7 +141,7 @@ public abstract class ObjectPermissionService permissions) + Collection permissions) throws GuacamoleException { // Delete permissions only if user has permission to do so diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionService.java index 926db0ee2..ef3cf07ca 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/PermissionService.java @@ -32,13 +32,18 @@ import net.sourceforge.guacamole.net.auth.mysql.dao.PermissionMapper; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.GuacamoleSecurityException; import org.glyptodon.guacamole.net.auth.permission.Permission; +import org.glyptodon.guacamole.net.auth.permission.PermissionSet; /** * Service which provides convenience methods for creating, retrieving, and - * deleting permissions. This service will automatically enforce the - * permissions of the current user. + * deleting permissions, and for obtaining the permission sets that contain + * these permissions. This service will automatically enforce the permissions + * of the current user. * * @author Michael Jumper + * @param + * The type of permission sets this service provides access to. + * * @param * The type of permission this service provides access to. * @@ -46,7 +51,8 @@ import org.glyptodon.guacamole.net.auth.permission.Permission; * The underlying model object used to represent PermissionType in the * database. */ -public abstract class PermissionService { +public abstract class PermissionService, + PermissionType extends Permission, ModelType> { /** * Returns an instance of a mapper for the type of permission used by this @@ -135,7 +141,31 @@ public abstract class PermissionService { + extends PermissionService { /** * Mapper for system-level permissions. */ @Inject private SystemPermissionMapper systemPermissionMapper; - + + /** + * Provider for creating system permission sets. + */ + @Inject + private Provider systemPermissionSetProvider; + @Override protected SystemPermissionMapper getPermissionMapper() { return systemPermissionMapper; } - + @Override protected SystemPermission getPermissionInstance(SystemPermissionModel model) { return new SystemPermission(model.getType()); @@ -114,6 +122,18 @@ public class SystemPermissionService } + @Override + public MySQLSystemPermissionSet getPermissionSet(AuthenticatedUser user, + MySQLUser targetUser) throws GuacamoleException { + + // Create permission set for requested user + MySQLSystemPermissionSet permissionSet = systemPermissionSetProvider.get(); + permissionSet.init(user, targetUser); + + return permissionSet; + + } + @Override public void createPermissions(AuthenticatedUser user, MySQLUser targetUser, Collection permissions) throws GuacamoleException { @@ -146,4 +166,37 @@ public class SystemPermissionService } + /** + * Retrieves the permission of the given type associated with the given + * user, if it exists. If no such permission exists, null is returned. + * + * @param user + * The user retrieving the permission. + * + * @param targetUser + * The user associated with the permission to be retrieved. + * + * @param type + * The type of permission to retrieve. + * + * @return + * The permission of the given type associated with the given user, or + * null if no such permission exists. + * + * @throws GuacamoleException + * If an error occurs while retrieving the requested permission. + */ + public SystemPermission retrievePermission(AuthenticatedUser user, + MySQLUser targetUser, SystemPermission.Type type) throws GuacamoleException { + + // Only an admin can read permissions that aren't his own + if (user.getUser().getIdentifier().equals(targetUser.getIdentifier()) + || user.getUser().isAdministrator()) + return getPermissionInstance(getPermissionMapper().selectOne(targetUser.getModel(), type)); + + // User cannot read this user's permissions + throw new GuacamoleSecurityException("Permission denied."); + + } + } diff --git a/extensions/guacamole-auth-mysql/src/main/resources/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.xml b/extensions/guacamole-auth-mysql/src/main/resources/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.xml index 1164e2b6b..ae80c70be 100644 --- a/extensions/guacamole-auth-mysql/src/main/resources/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.xml +++ b/extensions/guacamole-auth-mysql/src/main/resources/net/sourceforge/guacamole/net/auth/mysql/dao/SystemPermissionMapper.xml @@ -47,6 +47,21 @@ + + +