mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 05:31:22 +00:00
GUAC-1101: Split JDBC and MySQL code into separate projects.
This commit is contained in:
2
extensions/guacamole-auth-jdbc/.gitignore
vendored
Normal file
2
extensions/guacamole-auth-jdbc/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
target/
|
||||
*~
|
19
extensions/guacamole-auth-jdbc/LICENSE
Normal file
19
extensions/guacamole-auth-jdbc/LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
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.
|
85
extensions/guacamole-auth-jdbc/pom.xml
Normal file
85
extensions/guacamole-auth-jdbc/pom.xml
Normal file
@@ -0,0 +1,85 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.glyptodon.guacamole</groupId>
|
||||
<artifactId>guacamole-auth-jdbc</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>0.9.5</version>
|
||||
<name>guacamole-auth-jdbc</name>
|
||||
<url>http://guac-dev.org/</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<!-- Written for 1.6 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Guacamole Java API -->
|
||||
<dependency>
|
||||
<groupId>org.glyptodon.guacamole</groupId>
|
||||
<artifactId>guacamole-common</artifactId>
|
||||
<version>0.9.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Guacamole Extension API -->
|
||||
<dependency>
|
||||
<groupId>org.glyptodon.guacamole</groupId>
|
||||
<artifactId>guacamole-ext</artifactId>
|
||||
<version>0.9.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- SLF4J - logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.2.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis Guice -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-guice</artifactId>
|
||||
<version>3.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Guice -->
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-multibindings</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.MySQLUserContext;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.MySQLRootConnectionGroup;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.MySQLConnectionGroup;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.ConnectionGroupDirectory;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionDirectory;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.MySQLGuacamoleConfiguration;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.MySQLConnection;
|
||||
import org.glyptodon.guacamole.auth.jdbc.permission.MySQLSystemPermissionSet;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.MySQLUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserDirectory;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.ConnectionGroupMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionRecordMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ParameterMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.permission.SystemPermissionMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.ConnectionGroupService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.socket.GuacamoleSocketService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.security.SHA256PasswordEncryptionService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.security.SaltService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.security.SecureRandomSaltService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.permission.SystemPermissionService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.socket.UnrestrictedGuacamoleSocketService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserService;
|
||||
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
||||
import org.glyptodon.guacamole.environment.Environment;
|
||||
import org.mybatis.guice.MyBatisModule;
|
||||
import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider;
|
||||
|
||||
/**
|
||||
* Guice module which configures the injections used by the JDBC authentication
|
||||
* provider base. This module MUST be included in the Guice injector, or
|
||||
* authentication providers based on JDBC will not function.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class JDBCAuthenticationProviderModule extends MyBatisModule {
|
||||
|
||||
/**
|
||||
* The environment of the Guacamole server.
|
||||
*/
|
||||
private final Environment environment;
|
||||
|
||||
/**
|
||||
* Creates a new JDBC authentication provider module that configures the
|
||||
* various injected base classes using the given environment.
|
||||
*
|
||||
* @param environment
|
||||
* The environment to use to configure injected classes.
|
||||
*/
|
||||
public JDBCAuthenticationProviderModule(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
|
||||
// Datasource
|
||||
bindDataSourceProviderType(PooledDataSourceProvider.class);
|
||||
|
||||
// Transaction factory
|
||||
bindTransactionFactoryType(JdbcTransactionFactory.class);
|
||||
|
||||
// Add MyBatis mappers
|
||||
addMapperClass(ConnectionMapper.class);
|
||||
addMapperClass(ConnectionGroupMapper.class);
|
||||
addMapperClass(ConnectionRecordMapper.class);
|
||||
addMapperClass(ParameterMapper.class);
|
||||
addMapperClass(SystemPermissionMapper.class);
|
||||
addMapperClass(UserMapper.class);
|
||||
|
||||
// Bind core implementations of guacamole-ext classes
|
||||
bind(Environment.class).toInstance(environment);
|
||||
bind(ConnectionDirectory.class);
|
||||
bind(ConnectionGroupDirectory.class);
|
||||
bind(MySQLConnection.class);
|
||||
bind(MySQLConnectionGroup.class);
|
||||
bind(MySQLGuacamoleConfiguration.class);
|
||||
bind(MySQLUser.class);
|
||||
bind(MySQLUserContext.class);
|
||||
bind(MySQLRootConnectionGroup.class);
|
||||
bind(MySQLSystemPermissionSet.class);
|
||||
bind(UserDirectory.class);
|
||||
|
||||
// Bind services
|
||||
bind(ConnectionService.class);
|
||||
bind(ConnectionGroupService.class);
|
||||
bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);
|
||||
bind(SaltService.class).to(SecureRandomSaltService.class);
|
||||
bind(SystemPermissionService.class);
|
||||
bind(UserService.class);
|
||||
|
||||
// Bind appropriate socket service based on policy
|
||||
bind(GuacamoleSocketService.class).to(UnrestrictedGuacamoleSocketService.class);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.base;
|
||||
|
||||
import org.glyptodon.guacamole.net.auth.Identifiable;
|
||||
|
||||
/**
|
||||
* Common base class for objects that will ultimately be made available through
|
||||
* the Directory class. All such objects will need the same base set of queries
|
||||
* to fulfill the needs of the Directory class.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <ModelType>
|
||||
* The type of model object that corresponds to this object.
|
||||
*/
|
||||
public abstract class DirectoryObject<ModelType extends ObjectModel>
|
||||
extends RestrictedObject<ModelType> implements Identifiable {
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return getModel().getIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(String identifier) {
|
||||
getModel().setIdentifier(identifier);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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.base;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserModel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Common interface for objects that will ultimately be made available through
|
||||
* the Directory class. All such objects will need the same base set of queries
|
||||
* to fulfill the needs of the Directory class.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <ModelType>
|
||||
* The type of object contained within the directory whose objects are
|
||||
* mapped by this mapper.
|
||||
*/
|
||||
public interface DirectoryObjectMapper<ModelType> {
|
||||
|
||||
/**
|
||||
* Selects the identifiers of all objects, regardless of whether they
|
||||
* are readable by any particular user. This should only be called on
|
||||
* behalf of a system administrator. If identifiers are needed by a non-
|
||||
* administrative user who must have explicit read rights, use
|
||||
* selectReadableIdentifiers() instead.
|
||||
*
|
||||
* @return
|
||||
* A Set containing all identifiers of all objects.
|
||||
*/
|
||||
Set<String> selectIdentifiers();
|
||||
|
||||
/**
|
||||
* Selects the identifiers of all objects that are explicitly readable by
|
||||
* the given user. If identifiers are needed by a system administrator
|
||||
* (who, by definition, does not need explicit read rights), use
|
||||
* selectIdentifiers() instead.
|
||||
*
|
||||
* @param user
|
||||
* The user whose permissions should determine whether an identifier
|
||||
* is returned.
|
||||
*
|
||||
* @return
|
||||
* A Set containing all identifiers of all readable objects.
|
||||
*/
|
||||
Set<String> selectReadableIdentifiers(@Param("user") UserModel user);
|
||||
|
||||
/**
|
||||
* Selects all objects which have the given identifiers. If an identifier
|
||||
* has no corresponding object, it will be ignored. This should only be
|
||||
* called on behalf of a system administrator. If objects are needed by a
|
||||
* non-administrative user who must have explicit read rights, use
|
||||
* selectReadable() instead.
|
||||
*
|
||||
* @param identifiers
|
||||
* The identifiers of the objects to return.
|
||||
*
|
||||
* @return
|
||||
* A Collection of all objects having the given identifiers.
|
||||
*/
|
||||
Collection<ModelType> select(@Param("identifiers") Collection<String> identifiers);
|
||||
|
||||
/**
|
||||
* Selects all objects which have the given identifiers and are explicitly
|
||||
* readably by the given user. If an identifier has no corresponding
|
||||
* object, or the corresponding object is unreadable, it will be ignored.
|
||||
* If objects are needed by a system administrator (who, by definition,
|
||||
* does not need explicit read rights), use select() instead.
|
||||
*
|
||||
* @param user
|
||||
* The user whose permissions should determine whether an object
|
||||
* is returned.
|
||||
*
|
||||
* @param identifiers
|
||||
* The identifiers of the objects to return.
|
||||
*
|
||||
* @return
|
||||
* A Collection of all objects having the given identifiers.
|
||||
*/
|
||||
Collection<ModelType> selectReadable(@Param("user") UserModel user,
|
||||
@Param("identifiers") Collection<String> identifiers);
|
||||
|
||||
/**
|
||||
* Inserts the given object into the database. If the object already
|
||||
* exists, this will result in an error.
|
||||
*
|
||||
* @param object
|
||||
* The object to insert.
|
||||
*
|
||||
* @return
|
||||
* The number of rows inserted.
|
||||
*/
|
||||
int insert(@Param("object") ModelType object);
|
||||
|
||||
/**
|
||||
* Deletes the given object into the database. If the object does not
|
||||
* exist, this operation has no effect.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to delete.
|
||||
*
|
||||
* @return
|
||||
* The number of rows deleted.
|
||||
*/
|
||||
int delete(@Param("identifier") String identifier);
|
||||
|
||||
/**
|
||||
* Updates the given existing object in the database. If the object does
|
||||
* not actually exist, this operation has no effect.
|
||||
*
|
||||
* @param object
|
||||
* The object to update.
|
||||
*
|
||||
* @return
|
||||
* The number of rows updated.
|
||||
*/
|
||||
int update(@Param("object") ModelType object);
|
||||
|
||||
}
|
@@ -0,0 +1,443 @@
|
||||
/*
|
||||
* 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.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating users. This service will automatically enforce the
|
||||
* permissions of the current user.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <InternalType>
|
||||
* The specific internal implementation of the type of object this service
|
||||
* provides access to.
|
||||
*
|
||||
* @param <ExternalType>
|
||||
* The external interface or implementation of the type of object this
|
||||
* service provides access to, as defined by the guacamole-ext API.
|
||||
*
|
||||
* @param <ModelType>
|
||||
* The underlying model object used to represent InternalType in the
|
||||
* database.
|
||||
*/
|
||||
public abstract class DirectoryObjectService<InternalType extends DirectoryObject<ModelType>,
|
||||
ExternalType, ModelType extends ObjectModel> {
|
||||
|
||||
/**
|
||||
* Returns an instance of a mapper for the type of object used by this
|
||||
* service.
|
||||
*
|
||||
* @return
|
||||
* A mapper which provides access to the model objects associated with
|
||||
* the objects used by this service.
|
||||
*/
|
||||
protected abstract DirectoryObjectMapper<ModelType> getObjectMapper();
|
||||
|
||||
/**
|
||||
* Returns an instance of an object which is backed by the given model
|
||||
* object.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user for whom this object is being created.
|
||||
*
|
||||
* @param model
|
||||
* The model object to use to back the returned object.
|
||||
*
|
||||
* @return
|
||||
* An object which is backed by the given model object.
|
||||
*/
|
||||
protected abstract InternalType getObjectInstance(AuthenticatedUser currentUser,
|
||||
ModelType model);
|
||||
|
||||
/**
|
||||
* Returns an instance of a model object which is based on the given
|
||||
* object.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user for whom this model object is being created.
|
||||
*
|
||||
* @param object
|
||||
* The object to use to produce the returned model object.
|
||||
*
|
||||
* @return
|
||||
* A model object which is based on the given object.
|
||||
*/
|
||||
protected abstract ModelType getModelInstance(AuthenticatedUser currentUser,
|
||||
ExternalType object);
|
||||
|
||||
/**
|
||||
* Returns whether the given user has permission to create the type of
|
||||
* objects that this directory object service manages.
|
||||
*
|
||||
* @param user
|
||||
* The user being checked.
|
||||
*
|
||||
* @return
|
||||
* true if the user has object creation permission relevant to this
|
||||
* directory object service, false otherwise.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to read the user's permissions is denied.
|
||||
*/
|
||||
protected abstract boolean hasCreatePermission(AuthenticatedUser user)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns whether the given user has permission to perform a certain
|
||||
* action on a specific object managed by this directory object service.
|
||||
*
|
||||
* @param user
|
||||
* The user being checked.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to check.
|
||||
*
|
||||
* @param type
|
||||
* The type of action that will be performed.
|
||||
*
|
||||
* @return
|
||||
* true if the user has object permission relevant described, false
|
||||
* otherwise.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to read the user's permissions is denied.
|
||||
*/
|
||||
protected boolean hasObjectPermission(AuthenticatedUser user,
|
||||
String identifier, ObjectPermission.Type type)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get object permissions
|
||||
ObjectPermissionSet permissionSet = getPermissionSet(user);
|
||||
|
||||
// Return whether permission is granted
|
||||
return user.getUser().isAdministrator()
|
||||
|| permissionSet.hasPermission(type, identifier);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the permission set associated with the given user and related
|
||||
* to the type of objects handled by this directory object service.
|
||||
*
|
||||
* @param user
|
||||
* The user whose permissions are being retrieved.
|
||||
*
|
||||
* @return
|
||||
* A permission set which contains the permissions associated with the
|
||||
* given user and related to the type of objects handled by this
|
||||
* directory object service.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to read the user's permissions is denied.
|
||||
*/
|
||||
protected abstract ObjectPermissionSet getPermissionSet(AuthenticatedUser user)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns a collection of objects which are backed by the models in the
|
||||
* given collection.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user for whom these objects are being created.
|
||||
*
|
||||
* @param models
|
||||
* The model objects to use to back the objects within the returned
|
||||
* collection.
|
||||
*
|
||||
* @return
|
||||
* A collection of objects which are backed by the models in the given
|
||||
* collection.
|
||||
*/
|
||||
protected Collection<InternalType> getObjectInstances(AuthenticatedUser currentUser,
|
||||
Collection<ModelType> models) {
|
||||
|
||||
// Create new collection of objects by manually converting each model
|
||||
Collection<InternalType> objects = new ArrayList<InternalType>(models.size());
|
||||
for (ModelType model : models)
|
||||
objects.add(getObjectInstance(currentUser, model));
|
||||
|
||||
return objects;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given object is valid and can be created as-is. The
|
||||
* object does not yet exist in the database, but the user desires to
|
||||
* create a new object with the given values. This function will be called
|
||||
* prior to any creation operation, and provides a means for the
|
||||
* implementation to abort prior to completion. The default implementation
|
||||
* does nothing.
|
||||
*
|
||||
* @param user
|
||||
* The user creating the object.
|
||||
*
|
||||
* @param object
|
||||
* The object to validate.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the object is invalid, or an error prevents validating the given
|
||||
* object.
|
||||
*/
|
||||
protected void validateNewObject(AuthenticatedUser user,
|
||||
ExternalType object) throws GuacamoleException {
|
||||
|
||||
// By default, do nothing.
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given object is valid and can updated as-is. The
|
||||
* object already exists in the database, but the user desires to update
|
||||
* the object to the given values. This function will be called prior to
|
||||
* update operation, and provides a means for the implementation to abort
|
||||
* prior to completion. The default implementation does nothing.
|
||||
*
|
||||
* @param user
|
||||
* The user updating the existing object.
|
||||
*
|
||||
* @param object
|
||||
* The object to validate.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the object is invalid, or an error prevents validating the given
|
||||
* object.
|
||||
*/
|
||||
protected void validateExistingObject(AuthenticatedUser user,
|
||||
InternalType object) throws GuacamoleException {
|
||||
|
||||
// By default, do nothing.
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the single object that has the given identifier, if it exists
|
||||
* and the user has permission to read it.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving the object.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to retrieve.
|
||||
*
|
||||
* @return
|
||||
* The object having the given identifier, or null if no such object
|
||||
* exists.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the requested object.
|
||||
*/
|
||||
public InternalType retrieveObject(AuthenticatedUser user,
|
||||
String identifier) throws GuacamoleException {
|
||||
|
||||
// Pull objects having given identifier
|
||||
Collection<InternalType> objects = retrieveObjects(user, Collections.singleton(identifier));
|
||||
|
||||
// If no such object, return null
|
||||
if (objects.isEmpty())
|
||||
return null;
|
||||
|
||||
// The object collection will have exactly one element unless the
|
||||
// database has seriously lost integrity
|
||||
assert(objects.size() == 1);
|
||||
|
||||
// Return first and only object
|
||||
return objects.iterator().next();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all objects that have the identifiers in the given collection.
|
||||
* Only objects that the user has permission to read will be returned.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving the objects.
|
||||
*
|
||||
* @param identifiers
|
||||
* The identifiers of the objects to retrieve.
|
||||
*
|
||||
* @return
|
||||
* The objects having the given identifiers.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the requested objects.
|
||||
*/
|
||||
public Collection<InternalType> retrieveObjects(AuthenticatedUser user,
|
||||
Collection<String> identifiers) throws GuacamoleException {
|
||||
|
||||
// Do not query if no identifiers given
|
||||
if (identifiers.isEmpty())
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
Collection<ModelType> objects;
|
||||
|
||||
// Bypass permission checks if the user is a system admin
|
||||
if (user.getUser().isAdministrator())
|
||||
objects = getObjectMapper().select(identifiers);
|
||||
|
||||
// Otherwise only return explicitly readable identifiers
|
||||
else
|
||||
objects = getObjectMapper().selectReadable(user.getUser().getModel(), identifiers);
|
||||
|
||||
// Return collection of requested objects
|
||||
return getObjectInstances(user, objects);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the given object within the database. If the object already
|
||||
* exists, an error will be thrown. The internal model object will be
|
||||
* updated appropriately to contain the new database ID.
|
||||
*
|
||||
* @param user
|
||||
* The user creating the object.
|
||||
*
|
||||
* @param object
|
||||
* The object to create.
|
||||
*
|
||||
* @return
|
||||
* The newly-created object.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the user lacks permission to create the object, or an error
|
||||
* occurs while creating the object.
|
||||
*/
|
||||
public InternalType createObject(AuthenticatedUser user, ExternalType object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Only create object if user has permission to do so
|
||||
if (user.getUser().isAdministrator() || hasCreatePermission(user)) {
|
||||
|
||||
// Validate object prior to creation
|
||||
validateNewObject(user, object);
|
||||
|
||||
// Create object
|
||||
ModelType model = getModelInstance(user, object);
|
||||
getObjectMapper().insert(model);
|
||||
|
||||
// FIXME: Insert implicit object permissions, too.
|
||||
return getObjectInstance(user, model);
|
||||
}
|
||||
|
||||
// User lacks permission to create
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the object having the given identifier. If no such object
|
||||
* exists, this function has no effect.
|
||||
*
|
||||
* @param user
|
||||
* The user deleting the object.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the object to delete.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the user lacks permission to delete the object, or an error
|
||||
* occurs while deleting the object.
|
||||
*/
|
||||
public void deleteObject(AuthenticatedUser user, String identifier)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Only delete object if user has permission to do so
|
||||
if (hasObjectPermission(user, identifier, ObjectPermission.Type.DELETE)) {
|
||||
getObjectMapper().delete(identifier);
|
||||
return;
|
||||
}
|
||||
|
||||
// User lacks permission to delete
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the given object in the database, applying any changes that have
|
||||
* been made. If no such object exists, this function has no effect.
|
||||
*
|
||||
* @param user
|
||||
* The user updating the object.
|
||||
*
|
||||
* @param object
|
||||
* The object to update.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the user lacks permission to update the object, or an error
|
||||
* occurs while updating the object.
|
||||
*/
|
||||
public void updateObject(AuthenticatedUser user, InternalType object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Only update object if user has permission to do so
|
||||
if (hasObjectPermission(user, object.getIdentifier(), ObjectPermission.Type.UPDATE)) {
|
||||
|
||||
// Validate object prior to creation
|
||||
validateExistingObject(user, object);
|
||||
|
||||
// Update object
|
||||
getObjectMapper().update(object.getModel());
|
||||
return;
|
||||
}
|
||||
|
||||
// User lacks permission to update
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of all identifiers for all objects in the database that
|
||||
* the user has read access to.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving the identifiers.
|
||||
*
|
||||
* @return
|
||||
* The set of all identifiers for all objects in the database.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while reading identifiers.
|
||||
*/
|
||||
public Set<String> getIdentifiers(AuthenticatedUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Bypass permission checks if the user is a system admin
|
||||
if (user.getUser().isAdministrator())
|
||||
return getObjectMapper().selectIdentifiers();
|
||||
|
||||
// Otherwise only return explicitly readable identifiers
|
||||
else
|
||||
return getObjectMapper().selectReadableIdentifiers(user.getUser().getModel());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.base;
|
||||
|
||||
/**
|
||||
* Object representation of a Guacamole object, such as a user or connection,
|
||||
* as represented in the database.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public abstract class ObjectModel {
|
||||
|
||||
/**
|
||||
* The ID of this object in the database, if any.
|
||||
*/
|
||||
private Integer objectID;
|
||||
|
||||
/**
|
||||
* The unique identifier which identifies this object.
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
/**
|
||||
* Creates a new, empty object.
|
||||
*/
|
||||
public ObjectModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier that uniquely identifies this object.
|
||||
*
|
||||
* @return
|
||||
* The identifier that uniquely identifies this object.
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identifier that uniquely identifies this object.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier that uniquely identifies this object.
|
||||
*/
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of this object in the database, if it exists.
|
||||
*
|
||||
* @return
|
||||
* The ID of this object in the database, or null if this object was
|
||||
* not retrieved from the database.
|
||||
*/
|
||||
public Integer getObjectID() {
|
||||
return objectID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of this object to the given value.
|
||||
*
|
||||
* @param objectID
|
||||
* The ID to assign to this object.
|
||||
*/
|
||||
public void setObjectID(Integer objectID) {
|
||||
this.objectID = objectID;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.base;
|
||||
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
|
||||
/**
|
||||
* Common base class for objects that are associated with the users that
|
||||
* query them, and have an underlying model.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <ModelType>
|
||||
* The type of model object which corresponds to this object.
|
||||
*/
|
||||
public abstract class RestrictedObject<ModelType> {
|
||||
|
||||
/**
|
||||
* The user this object belongs to. Access is based on his/her permission
|
||||
* settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* The internal model object containing the values which represent this
|
||||
* object in the database.
|
||||
*/
|
||||
private ModelType model;
|
||||
|
||||
/**
|
||||
* Initializes this object, associating it with the current authenticated
|
||||
* user and populating it with data from the given model object
|
||||
*
|
||||
* @param currentUser
|
||||
* The user that created or retrieved this object.
|
||||
*
|
||||
* @param model
|
||||
* The backing model object.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser, ModelType model) {
|
||||
setCurrentUser(currentUser);
|
||||
setModel(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user that created or queried this object. This user's
|
||||
* permissions dictate what operations can be performed on or through this
|
||||
* object.
|
||||
*
|
||||
* @return
|
||||
* The user that created or queried this object.
|
||||
*/
|
||||
public AuthenticatedUser getCurrentUser() {
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user that created or queried this object. This user's
|
||||
* permissions dictate what operations can be performed on or through this
|
||||
* object.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user that created or queried this object.
|
||||
*/
|
||||
public void setCurrentUser(AuthenticatedUser currentUser) {
|
||||
this.currentUser = currentUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the backing model object. Changes to the model object will
|
||||
* affect this object, and changes to this object will affect the model
|
||||
* object.
|
||||
*
|
||||
* @return
|
||||
* The backing model object.
|
||||
*/
|
||||
public ModelType getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the backing model object. This will effectively replace all data
|
||||
* contained within this object.
|
||||
*
|
||||
* @param model
|
||||
* The backing model object.
|
||||
*/
|
||||
public void setModel(ModelType model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base classes supporting the MySQL authentication provider and defining the
|
||||
* relationships between the model and the implementations of guacamole-ext
|
||||
* classes.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc.base;
|
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the Connection Directory.
|
||||
*
|
||||
* @author James Muehlner
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ConnectionDirectory implements Directory<Connection> {
|
||||
|
||||
/**
|
||||
* The user this connection directory belongs to. Access is based on
|
||||
* his/her permission settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* Service for managing connection objects.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Set the user for this directory.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user whose permissions define the visibility of connections in
|
||||
* this directory.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser) {
|
||||
this.currentUser = currentUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection get(String identifier) throws GuacamoleException {
|
||||
return connectionService.retrieveObject(currentUser, identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<Connection> getAll(Collection<String> identifiers) throws GuacamoleException {
|
||||
Collection<MySQLConnection> objects = connectionService.retrieveObjects(currentUser, identifiers);
|
||||
return Collections.<Connection>unmodifiableCollection(objects);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
return connectionService.getIdentifiers(currentUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void add(Connection object) throws GuacamoleException {
|
||||
connectionService.createObject(currentUser, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void update(Connection object) throws GuacamoleException {
|
||||
MySQLConnection connection = (MySQLConnection) object;
|
||||
connectionService.updateObject(currentUser, connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
connectionService.deleteObject(currentUser, identifier);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserModel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Mapper for connection objects.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface ConnectionMapper extends DirectoryObjectMapper<ConnectionModel> {
|
||||
|
||||
/**
|
||||
* Selects the identifiers of all connections within the given parent
|
||||
* connection group, regardless of whether they are readable by any
|
||||
* particular user. This should only be called on behalf of a system
|
||||
* administrator. If identifiers are needed by a non-administrative user
|
||||
* who must have explicit read rights, use
|
||||
* selectReadableIdentifiersWithin() instead.
|
||||
*
|
||||
* @param parentIdentifier
|
||||
* The identifier of the parent connection group, or null if the root
|
||||
* connection group is to be queried.
|
||||
*
|
||||
* @return
|
||||
* A Set containing all identifiers of all objects.
|
||||
*/
|
||||
Set<String> selectIdentifiersWithin(@Param("parentIdentifier") String parentIdentifier);
|
||||
|
||||
/**
|
||||
* Selects the identifiers of all connections within the given parent
|
||||
* connection group that are explicitly readable by the given user. If
|
||||
* identifiers are needed by a system administrator (who, by definition,
|
||||
* does not need explicit read rights), use selectIdentifiersWithin()
|
||||
* instead.
|
||||
*
|
||||
* @param user
|
||||
* The user whose permissions should determine whether an identifier
|
||||
* is returned.
|
||||
*
|
||||
* @param parentIdentifier
|
||||
* The identifier of the parent connection group, or null if the root
|
||||
* connection group is to be queried.
|
||||
*
|
||||
* @return
|
||||
* A Set containing all identifiers of all readable objects.
|
||||
*/
|
||||
Set<String> selectReadableIdentifiersWithin(@Param("user") UserModel user,
|
||||
@Param("parentIdentifier") String parentIdentifier);
|
||||
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.ObjectModel;
|
||||
|
||||
/**
|
||||
* Object representation of a Guacamole connection, as represented in the
|
||||
* database.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ConnectionModel extends ObjectModel {
|
||||
|
||||
/**
|
||||
* The identifier of the parent connection group in the database, or null
|
||||
* if the parent connection group is the root group.
|
||||
*/
|
||||
private String parentIdentifier;
|
||||
|
||||
/**
|
||||
* The human-readable name associated with this connection.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The name of the protocol to use when connecting to this connection.
|
||||
*/
|
||||
private String protocol;
|
||||
|
||||
/**
|
||||
* Creates a new, empty connection.
|
||||
*/
|
||||
public ConnectionModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name associated with this connection.
|
||||
*
|
||||
* @return
|
||||
* The name associated with this connection.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name associated with this connection.
|
||||
*
|
||||
* @param name
|
||||
* The name to associate with this connection.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the protocol to use when connecting to this
|
||||
* connection.
|
||||
*
|
||||
* @return
|
||||
* The name of the protocol to use when connecting to this connection.
|
||||
*/
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the protocol to use when connecting to this connection.
|
||||
*
|
||||
* @param protocol
|
||||
* The name of the protocol to use when connecting to this connection.
|
||||
*/
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of the parent connection group, or null if the
|
||||
* parent connection group is the root connection group.
|
||||
*
|
||||
* @return
|
||||
* The identifier of the parent connection group, or null if the parent
|
||||
* connection group is the root connection group.
|
||||
*/
|
||||
public String getParentIdentifier() {
|
||||
return parentIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identifier of the parent connection group.
|
||||
*
|
||||
* @param parentIdentifier
|
||||
* The identifier of the parent connection group, or null if the parent
|
||||
* connection group is the root connection group.
|
||||
*/
|
||||
public void setParentIdentifier(String parentIdentifier) {
|
||||
this.parentIdentifier = parentIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
|
||||
// If no associated ID, then no associated identifier
|
||||
Integer id = getObjectID();
|
||||
if (id == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, the identifier is the ID as a string
|
||||
return id.toString();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(String identifier) {
|
||||
throw new UnsupportedOperationException("Connection identifiers are derived from IDs. They cannot be set.");
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Mapper for connection record objects.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface ConnectionRecordMapper {
|
||||
|
||||
/**
|
||||
* Returns a collection of all connection records associated with the
|
||||
* connection having the given identifier.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the connection whose records are to be retrieved.
|
||||
*
|
||||
* @return
|
||||
* A collection of all connection records associated with the
|
||||
* connection having the given identifier. This collection will be
|
||||
* empty if no such connection exists.
|
||||
*/
|
||||
List<ConnectionRecordModel> select(@Param("identifier") String identifier);
|
||||
|
||||
/**
|
||||
* Inserts the given connection record.
|
||||
*
|
||||
* @param record
|
||||
* The connection record to insert.
|
||||
*
|
||||
* @return
|
||||
* The number of rows inserted.
|
||||
*/
|
||||
int insert(@Param("record") ConnectionRecordModel record);
|
||||
|
||||
}
|
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A single connection record representing a past usage of a particular
|
||||
* connection.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ConnectionRecordModel {
|
||||
|
||||
/**
|
||||
* The identifier of the connection associated with this connection record.
|
||||
*/
|
||||
private String connectionIdentifier;
|
||||
|
||||
/**
|
||||
* The database ID of the user associated with this connection record.
|
||||
*/
|
||||
private Integer userID;
|
||||
|
||||
/**
|
||||
* The username of the user associated with this connection record.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* The time the connection was initiated by the associated user.
|
||||
*/
|
||||
private Date startDate;
|
||||
|
||||
/**
|
||||
* The time the connection ended, or null if the end time is not known or
|
||||
* the connection is still running.
|
||||
*/
|
||||
private Date endDate;
|
||||
|
||||
/**
|
||||
* Returns the identifier of the connection associated with this connection
|
||||
* record.
|
||||
*
|
||||
* @return
|
||||
* The identifier of the connection associated with this connection
|
||||
* record.
|
||||
*/
|
||||
public String getConnectionIdentifier() {
|
||||
return connectionIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identifier of the connection associated with this connection
|
||||
* record.
|
||||
*
|
||||
* @param connectionIdentifier
|
||||
* The identifier of the connection to associate with this connection
|
||||
* record.
|
||||
*/
|
||||
public void setConnectionIdentifier(String connectionIdentifier) {
|
||||
this.connectionIdentifier = connectionIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database ID of the user associated with this connection
|
||||
* record.
|
||||
*
|
||||
* @return
|
||||
* The database ID of the user associated with this connection record.
|
||||
*/
|
||||
public Integer getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database ID of the user associated with this connection record.
|
||||
*
|
||||
* @param userID
|
||||
* The database ID of the user to associate with this connection
|
||||
* record.
|
||||
*/
|
||||
public void setUserID(Integer userID) {
|
||||
this.userID = userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username of the user associated with this connection record.
|
||||
*
|
||||
* @return
|
||||
* The username of the user associated with this connection record.
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username of the user associated with this connection record.
|
||||
*
|
||||
* @param username
|
||||
* The username of the user to associate with this connection record.
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date that the associated connection was established.
|
||||
*
|
||||
* @return
|
||||
* The date the associated connection was established.
|
||||
*/
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the date that the associated connection was established.
|
||||
*
|
||||
* @param startDate
|
||||
* The date that the associated connection was established.
|
||||
*/
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date that the associated connection ended, or null if no
|
||||
* end date was recorded. The lack of an end date does not necessarily
|
||||
* mean that the connection is still active.
|
||||
*
|
||||
* @return
|
||||
* The date the associated connection ended, or null if no end date was
|
||||
* recorded.
|
||||
*/
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the date that the associated connection ended.
|
||||
*
|
||||
* @param endDate
|
||||
* The date that the associated connection ended.
|
||||
*/
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.socket.GuacamoleSocketService;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating connections.
|
||||
*
|
||||
* @author Michael Jumper, James Muehlner
|
||||
*/
|
||||
public class ConnectionService extends DirectoryObjectService<MySQLConnection, Connection, ConnectionModel> {
|
||||
|
||||
/**
|
||||
* Mapper for accessing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionMapper connectionMapper;
|
||||
|
||||
/**
|
||||
* Mapper for accessing connection parameters.
|
||||
*/
|
||||
@Inject
|
||||
private ParameterMapper parameterMapper;
|
||||
|
||||
/**
|
||||
* Mapper for accessing connection history.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionRecordMapper connectionRecordMapper;
|
||||
|
||||
/**
|
||||
* Provider for creating connections.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLConnection> mySQLConnectionProvider;
|
||||
|
||||
/**
|
||||
* Service for creating and tracking sockets.
|
||||
*/
|
||||
@Inject
|
||||
private GuacamoleSocketService socketService;
|
||||
|
||||
@Override
|
||||
protected DirectoryObjectMapper<ConnectionModel> getObjectMapper() {
|
||||
return connectionMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySQLConnection getObjectInstance(AuthenticatedUser currentUser,
|
||||
ConnectionModel model) {
|
||||
MySQLConnection connection = mySQLConnectionProvider.get();
|
||||
connection.init(currentUser, model);
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionModel getModelInstance(AuthenticatedUser currentUser,
|
||||
final Connection object) {
|
||||
|
||||
// Create new MySQLConnection backed by blank model
|
||||
ConnectionModel model = new ConnectionModel();
|
||||
MySQLConnection connection = getObjectInstance(currentUser, model);
|
||||
|
||||
// Set model contents through MySQLConnection, copying the provided connection
|
||||
connection.setParentIdentifier(object.getParentIdentifier());
|
||||
connection.setName(object.getName());
|
||||
connection.setConfiguration(object.getConfiguration());
|
||||
|
||||
return model;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasCreatePermission(AuthenticatedUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Return whether user has explicit connection creation permission
|
||||
SystemPermissionSet permissionSet = user.getUser().getSystemPermissions();
|
||||
return permissionSet.hasPermission(SystemPermission.Type.CREATE_CONNECTION);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectPermissionSet getPermissionSet(AuthenticatedUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Return permissions related to connections
|
||||
return user.getUser().getConnectionPermissions();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateNewObject(AuthenticatedUser user, Connection object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Name must not be blank
|
||||
if (object.getName().trim().isEmpty())
|
||||
throw new GuacamoleClientException("Connection names must not be blank.");
|
||||
|
||||
// FIXME: Do not attempt to create duplicate connections
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateExistingObject(AuthenticatedUser user,
|
||||
MySQLConnection object) throws GuacamoleException {
|
||||
|
||||
// Name must not be blank
|
||||
if (object.getName().trim().isEmpty())
|
||||
throw new GuacamoleClientException("Connection names must not be blank.");
|
||||
|
||||
// FIXME: Check whether such a connection is already present
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an arbitrary Guacamole connection, produces a collection of
|
||||
* parameter model objects containing the name/value pairs of that
|
||||
* connection's parameters.
|
||||
*
|
||||
* @param connection
|
||||
* The connection whose configuration should be used to produce the
|
||||
* collection of parameter models.
|
||||
*
|
||||
* @return
|
||||
* A collection of parameter models containing the name/value pairs
|
||||
* of the given connection's parameters.
|
||||
*/
|
||||
private Collection<ParameterModel> getParameterModels(MySQLConnection connection) {
|
||||
|
||||
Map<String, String> parameters = connection.getConfiguration().getParameters();
|
||||
|
||||
// Convert parameters to model objects
|
||||
Collection<ParameterModel> parameterModels = new ArrayList(parameters.size());
|
||||
for (Map.Entry<String, String> parameterEntry : parameters.entrySet()) {
|
||||
|
||||
// Get parameter name and value
|
||||
String name = parameterEntry.getKey();
|
||||
String value = parameterEntry.getValue();
|
||||
|
||||
// There is no need to insert empty parameters
|
||||
if (value.isEmpty())
|
||||
continue;
|
||||
|
||||
// Produce model object from parameter
|
||||
ParameterModel model = new ParameterModel();
|
||||
model.setConnectionIdentifier(connection.getIdentifier());
|
||||
model.setName(name);
|
||||
model.setValue(value);
|
||||
|
||||
// Add model to list
|
||||
parameterModels.add(model);
|
||||
|
||||
}
|
||||
|
||||
return parameterModels;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public MySQLConnection createObject(AuthenticatedUser user, Connection object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Create connection
|
||||
MySQLConnection connection = super.createObject(user, object);
|
||||
connection.setConfiguration(object.getConfiguration());
|
||||
|
||||
// Insert new parameters, if any
|
||||
Collection<ParameterModel> parameterModels = getParameterModels(connection);
|
||||
if (!parameterModels.isEmpty())
|
||||
parameterMapper.insert(parameterModels);
|
||||
|
||||
return connection;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateObject(AuthenticatedUser user, MySQLConnection object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Update connection
|
||||
super.updateObject(user, object);
|
||||
|
||||
// Replace existing parameters with new parameters
|
||||
Collection<ParameterModel> parameterModels = getParameterModels(object);
|
||||
parameterMapper.delete(object.getIdentifier());
|
||||
parameterMapper.insert(parameterModels);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of all identifiers for all connections within the
|
||||
* connection group having the given identifier. Only connections that the
|
||||
* user has read access to will be returned.
|
||||
*
|
||||
* Permission to read the connection group having the given identifier is
|
||||
* NOT checked.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving the identifiers.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the parent connection group, or null to check the
|
||||
* root connection group.
|
||||
*
|
||||
* @return
|
||||
* The set of all identifiers for all connections in the connection
|
||||
* group having the given identifier that the user has read access to.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while reading identifiers.
|
||||
*/
|
||||
public Set<String> getIdentifiersWithin(AuthenticatedUser user,
|
||||
String identifier)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Bypass permission checks if the user is a system admin
|
||||
if (user.getUser().isAdministrator())
|
||||
return connectionMapper.selectIdentifiersWithin(identifier);
|
||||
|
||||
// Otherwise only return explicitly readable identifiers
|
||||
else
|
||||
return connectionMapper.selectReadableIdentifiersWithin(user.getUser().getModel(), identifier);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all parameters visible to the given user and associated with
|
||||
* the connection having the given identifier. If the given user has no
|
||||
* access to such parameters, or no such connection exists, the returned
|
||||
* map will be empty.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving connection parameters.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the connection whose parameters are being
|
||||
* retrieved.
|
||||
*
|
||||
* @return
|
||||
* A new map of all parameter name/value pairs that the given user has
|
||||
* access to.
|
||||
*/
|
||||
public Map<String, String> retrieveParameters(AuthenticatedUser user,
|
||||
String identifier) {
|
||||
|
||||
Map<String, String> parameterMap = new HashMap<String, String>();
|
||||
|
||||
// Determine whether we have permission to read parameters
|
||||
boolean canRetrieveParameters;
|
||||
try {
|
||||
canRetrieveParameters = hasObjectPermission(user, identifier,
|
||||
ObjectPermission.Type.UPDATE);
|
||||
}
|
||||
|
||||
// Provide empty (but mutable) map if unable to check permissions
|
||||
catch (GuacamoleException e) {
|
||||
return parameterMap;
|
||||
}
|
||||
|
||||
// Populate parameter map if we have permission to do so
|
||||
if (canRetrieveParameters) {
|
||||
for (ParameterModel parameter : parameterMapper.select(identifier))
|
||||
parameterMap.put(parameter.getName(), parameter.getValue());
|
||||
}
|
||||
|
||||
return parameterMap;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the connection history of the given connection, including any
|
||||
* active connections.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving the connection history.
|
||||
*
|
||||
* @param connection
|
||||
* The connection whose history is being retrieved.
|
||||
*
|
||||
* @return
|
||||
* The connection history of the given connection, including any
|
||||
* active connections.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to read the connection history is denied.
|
||||
*/
|
||||
public List<ConnectionRecord> retrieveHistory(AuthenticatedUser user,
|
||||
MySQLConnection connection) throws GuacamoleException {
|
||||
|
||||
String identifier = connection.getIdentifier();
|
||||
|
||||
// Retrieve history only if READ permission is granted
|
||||
if (hasObjectPermission(user, identifier, ObjectPermission.Type.READ)) {
|
||||
|
||||
// Retrieve history
|
||||
List<ConnectionRecordModel> models = connectionRecordMapper.select(identifier);
|
||||
|
||||
// Get currently-active connections
|
||||
List<ConnectionRecord> records = new ArrayList<ConnectionRecord>(socketService.getActiveConnections(connection));
|
||||
|
||||
// Add past connections from model objects
|
||||
for (ConnectionRecordModel model : models)
|
||||
records.add(new MySQLConnectionRecord(model));
|
||||
|
||||
// Return converted history list
|
||||
return records;
|
||||
|
||||
}
|
||||
|
||||
// The user does not have permission to read the history
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the given connection as the given user, using the given
|
||||
* client information. If the user does not have permission to read the
|
||||
* connection, permission will be denied.
|
||||
*
|
||||
* @param user
|
||||
* The user connecting to the connection.
|
||||
*
|
||||
* @param connection
|
||||
* The connection being connected to.
|
||||
*
|
||||
* @param info
|
||||
* Information associated with the connecting client.
|
||||
*
|
||||
* @return
|
||||
* A connected GuacamoleSocket associated with a newly-established
|
||||
* connection.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to connect to this connection is denied.
|
||||
*/
|
||||
public GuacamoleSocket connect(AuthenticatedUser user,
|
||||
MySQLConnection connection, GuacamoleClientInformation info)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Connect only if READ permission is granted
|
||||
if (hasObjectPermission(user, connection.getIdentifier(), ObjectPermission.Type.READ))
|
||||
return socketService.getGuacamoleSocket(user, connection, info);
|
||||
|
||||
// The user does not have permission to connect
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.List;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObject;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.MySQLRootConnectionGroup;
|
||||
import org.glyptodon.guacamole.auth.jdbc.socket.GuacamoleSocketService;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the Connection object.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLConnection extends DirectoryObject<ConnectionModel>
|
||||
implements Connection {
|
||||
|
||||
/**
|
||||
* Service for managing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service for creating and tracking sockets.
|
||||
*/
|
||||
@Inject
|
||||
private GuacamoleSocketService socketService;
|
||||
|
||||
/**
|
||||
* Provider for lazy-loaded, permission-controlled configurations.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLGuacamoleConfiguration> configProvider;
|
||||
|
||||
/**
|
||||
* The manually-set GuacamoleConfiguration, if any.
|
||||
*/
|
||||
private GuacamoleConfiguration config = null;
|
||||
|
||||
/**
|
||||
* Creates a new, empty MySQLConnection.
|
||||
*/
|
||||
public MySQLConnection() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getModel().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
getModel().setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentIdentifier() {
|
||||
|
||||
// Translate null parent to proper identifier
|
||||
String parentIdentifier = getModel().getParentIdentifier();
|
||||
if (parentIdentifier == null)
|
||||
return MySQLRootConnectionGroup.IDENTIFIER;
|
||||
|
||||
return parentIdentifier;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentIdentifier(String parentIdentifier) {
|
||||
|
||||
// Translate root identifier back into null
|
||||
if (parentIdentifier != null
|
||||
&& parentIdentifier.equals(MySQLRootConnectionGroup.IDENTIFIER))
|
||||
parentIdentifier = null;
|
||||
|
||||
getModel().setParentIdentifier(parentIdentifier);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleConfiguration getConfiguration() {
|
||||
|
||||
// If configuration has been manually set, return that
|
||||
if (config != null)
|
||||
return config;
|
||||
|
||||
// Otherwise, return permission-controlled configuration
|
||||
MySQLGuacamoleConfiguration restrictedConfig = configProvider.get();
|
||||
restrictedConfig.init(getCurrentUser(), getModel());
|
||||
return restrictedConfig;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfiguration(GuacamoleConfiguration config) {
|
||||
|
||||
// Store manually-set configuration internally
|
||||
this.config = config;
|
||||
|
||||
// Update model
|
||||
getModel().setProtocol(config.getProtocol());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends ConnectionRecord> getHistory() throws GuacamoleException {
|
||||
return connectionService.retrieveHistory(getCurrentUser(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
|
||||
return connectionService.connect(getCurrentUser(), this, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveConnections() {
|
||||
return socketService.getActiveConnections(this).size();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
|
||||
|
||||
/**
|
||||
* A ConnectionRecord which is based on data stored in MySQL.
|
||||
*
|
||||
* @author James Muehlner
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class MySQLConnectionRecord implements ConnectionRecord {
|
||||
|
||||
/**
|
||||
* The model object backing this connection record.
|
||||
*/
|
||||
private ConnectionRecordModel model;
|
||||
|
||||
/**
|
||||
* Creates a new MySQLConnectionRecord backed by the given model object.
|
||||
* Changes to this record will affect the backing model object, and changes
|
||||
* to the backing model object will affect this record.
|
||||
*
|
||||
* @param model
|
||||
* The model object to use to back this connection record.
|
||||
*/
|
||||
public MySQLConnectionRecord(ConnectionRecordModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getStartDate() {
|
||||
return model.getStartDate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getEndDate() {
|
||||
return model.getEndDate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return model.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Map;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
|
||||
|
||||
/**
|
||||
* Implementation of GuacamoleConfiguration which loads parameter values only
|
||||
* if necessary, and only if allowed.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class MySQLGuacamoleConfiguration extends GuacamoleConfiguration {
|
||||
|
||||
/**
|
||||
* The user this configuration belongs to. Access is based on his/her
|
||||
* permission settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* The internal model object containing the values which represent the
|
||||
* connection associated with this configuration.
|
||||
*/
|
||||
private ConnectionModel connectionModel;
|
||||
|
||||
/**
|
||||
* Service for managing connection parameters.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* The manually-set parameter map, if any.
|
||||
*/
|
||||
private Map<String, String> parameters = null;
|
||||
|
||||
/**
|
||||
* Creates a new, empty MySQLGuacamoleConfiguration.
|
||||
*/
|
||||
public MySQLGuacamoleConfiguration() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this configuration, associating it with the current
|
||||
* authenticated user and populating it with data from the given model
|
||||
* object.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user that created or retrieved this configuration.
|
||||
*
|
||||
* @param connectionModel
|
||||
* The model object backing this configuration.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser, ConnectionModel connectionModel) {
|
||||
this.currentUser = currentUser;
|
||||
this.connectionModel = connectionModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return connectionModel.getProtocol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocol(String protocol) {
|
||||
super.setProtocol(protocol);
|
||||
connectionModel.setProtocol(protocol);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setParameters(Map<String, String> parameters) {
|
||||
this.parameters = parameters;
|
||||
super.setParameters(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getParameters() {
|
||||
|
||||
// Retrieve visible parameters, if not overridden by setParameters()
|
||||
if (parameters == null) {
|
||||
|
||||
// Retrieve all visible parameters
|
||||
Map<String, String> visibleParameters =
|
||||
connectionService.retrieveParameters(currentUser, connectionModel.getIdentifier());
|
||||
|
||||
// Use retrieved parameters to back future operations
|
||||
super.setParameters(visibleParameters);
|
||||
|
||||
}
|
||||
|
||||
return super.getParameters();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Mapper for connection parameter objects.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface ParameterMapper {
|
||||
|
||||
/**
|
||||
* Returns a collection of all parameters associated with the connection
|
||||
* having the given identifier.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the connection whose parameters are to be
|
||||
* retrieved.
|
||||
*
|
||||
* @return
|
||||
* A collection of all parameters associated with the connection
|
||||
* having the given identifier. This collection will be empty if no
|
||||
* such connection exists.
|
||||
*/
|
||||
Collection<ParameterModel> select(@Param("identifier") String identifier);
|
||||
|
||||
/**
|
||||
* Inserts each of the parameter model objects in the given collection as
|
||||
* new connection parameters.
|
||||
*
|
||||
* @param parameters
|
||||
* The connection parameters to insert.
|
||||
*
|
||||
* @return
|
||||
* The number of rows inserted.
|
||||
*/
|
||||
int insert(@Param("parameters") Collection<ParameterModel> parameters);
|
||||
|
||||
/**
|
||||
* Deletes all parameters associated with the connection having the given
|
||||
* identifier.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the connection whose parameters should be
|
||||
* deleted.
|
||||
*
|
||||
* @return
|
||||
* The number of rows deleted.
|
||||
*/
|
||||
int delete(@Param("identifier") String identifier);
|
||||
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.connection;
|
||||
|
||||
/**
|
||||
* A single parameter name/value pair belonging to a connection.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ParameterModel {
|
||||
|
||||
/**
|
||||
* The identifier of the connection associated with this parameter.
|
||||
*/
|
||||
private String connectionIdentifier;
|
||||
|
||||
/**
|
||||
* The name of the parameter.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The value the parameter is set to.
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* Returns the identifier of the connection associated with this parameter.
|
||||
*
|
||||
* @return
|
||||
* The identifier of the connection associated with this parameter.
|
||||
*/
|
||||
public String getConnectionIdentifier() {
|
||||
return connectionIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identifier of the connection associated with this parameter.
|
||||
*
|
||||
* @param connectionIdentifier
|
||||
* The identifier of the connection to associate with this parameter.
|
||||
*/
|
||||
public void setConnectionIdentifier(String connectionIdentifier) {
|
||||
this.connectionIdentifier = connectionIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this parameter.
|
||||
*
|
||||
* @return
|
||||
* The name of this parameter.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of this parameter.
|
||||
*
|
||||
* @param name
|
||||
* The name of this parameter.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this parameter.
|
||||
*
|
||||
* @return
|
||||
* The value of this parameter.
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this parameter.
|
||||
*
|
||||
* @param value
|
||||
* The value of this parameter.
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to connections and their parameters and history.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc.connection;
|
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.connectiongroup;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the ConnectionGroup Directory.
|
||||
*
|
||||
* @author James Muehlner
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ConnectionGroupDirectory implements Directory<ConnectionGroup> {
|
||||
|
||||
/**
|
||||
* The user this connection group directory belongs to. Access is based on
|
||||
* his/her permission settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* Service for managing connection group objects.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Set the user for this directory.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user whose permissions define the visibility of connection
|
||||
* groups in this directory.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser) {
|
||||
this.currentUser = currentUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionGroup get(String identifier) throws GuacamoleException {
|
||||
return connectionGroupService.retrieveObject(currentUser, identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<ConnectionGroup> getAll(Collection<String> identifiers) throws GuacamoleException {
|
||||
Collection<MySQLConnectionGroup> objects = connectionGroupService.retrieveObjects(currentUser, identifiers);
|
||||
return Collections.<ConnectionGroup>unmodifiableCollection(objects);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
return connectionGroupService.getIdentifiers(currentUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void add(ConnectionGroup object) throws GuacamoleException {
|
||||
connectionGroupService.createObject(currentUser, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void update(ConnectionGroup object) throws GuacamoleException {
|
||||
MySQLConnectionGroup connectionGroup = (MySQLConnectionGroup) object;
|
||||
connectionGroupService.updateObject(currentUser, connectionGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
connectionGroupService.deleteObject(currentUser, identifier);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.connectiongroup;
|
||||
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserModel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Mapper for connection group objects.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface ConnectionGroupMapper extends DirectoryObjectMapper<ConnectionGroupModel> {
|
||||
|
||||
/**
|
||||
* Selects the identifiers of all connection groups within the given parent
|
||||
* connection group, regardless of whether they are readable by any
|
||||
* particular user. This should only be called on behalf of a system
|
||||
* administrator. If identifiers are needed by a non-administrative user
|
||||
* who must have explicit read rights, use
|
||||
* selectReadableIdentifiersWithin() instead.
|
||||
*
|
||||
* @param parentIdentifier
|
||||
* The identifier of the parent connection group, or null if the root
|
||||
* connection group is to be queried.
|
||||
*
|
||||
* @return
|
||||
* A Set containing all identifiers of all objects.
|
||||
*/
|
||||
Set<String> selectIdentifiersWithin(@Param("parentIdentifier") String parentIdentifier);
|
||||
|
||||
/**
|
||||
* Selects the identifiers of all connection groups within the given parent
|
||||
* connection group that are explicitly readable by the given user. If
|
||||
* identifiers are needed by a system administrator (who, by definition,
|
||||
* does not need explicit read rights), use selectIdentifiersWithin()
|
||||
* instead.
|
||||
*
|
||||
* @param user
|
||||
* The user whose permissions should determine whether an identifier
|
||||
* is returned.
|
||||
*
|
||||
* @param parentIdentifier
|
||||
* The identifier of the parent connection group, or null if the root
|
||||
* connection group is to be queried.
|
||||
*
|
||||
* @return
|
||||
* A Set containing all identifiers of all readable objects.
|
||||
*/
|
||||
Set<String> selectReadableIdentifiersWithin(@Param("user") UserModel user,
|
||||
@Param("parentIdentifier") String parentIdentifier);
|
||||
|
||||
}
|
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.connectiongroup;
|
||||
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.ObjectModel;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
|
||||
/**
|
||||
* Object representation of a Guacamole connection group, as represented in the
|
||||
* database.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ConnectionGroupModel extends ObjectModel {
|
||||
|
||||
/**
|
||||
* The identifier of the parent connection group in the database, or null
|
||||
* if the parent connection group is the root group.
|
||||
*/
|
||||
private String parentIdentifier;
|
||||
|
||||
/**
|
||||
* The human-readable name associated with this connection group.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The type of this connection group, such as organizational or balancing.
|
||||
*/
|
||||
private ConnectionGroup.Type type;
|
||||
|
||||
/**
|
||||
* Creates a new, empty connection group.
|
||||
*/
|
||||
public ConnectionGroupModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name associated with this connection group.
|
||||
*
|
||||
* @return
|
||||
* The name associated with this connection group.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name associated with this connection group.
|
||||
*
|
||||
* @param name
|
||||
* The name to associate with this connection group.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of the parent connection group, or null if the
|
||||
* parent connection group is the root connection group.
|
||||
*
|
||||
* @return
|
||||
* The identifier of the parent connection group, or null if the parent
|
||||
* connection group is the root connection group.
|
||||
*/
|
||||
public String getParentIdentifier() {
|
||||
return parentIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identifier of the parent connection group.
|
||||
*
|
||||
* @param parentIdentifier
|
||||
* The identifier of the parent connection group, or null if the parent
|
||||
* connection group is the root connection group.
|
||||
*/
|
||||
public void setParentIdentifier(String parentIdentifier) {
|
||||
this.parentIdentifier = parentIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of this connection group, such as organizational or
|
||||
* balancing.
|
||||
*
|
||||
* @return
|
||||
* The type of this connection group.
|
||||
*/
|
||||
public ConnectionGroup.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this connection group, such as organizational or
|
||||
* balancing.
|
||||
*
|
||||
* @param type
|
||||
* The type of this connection group.
|
||||
*/
|
||||
public void setType(ConnectionGroup.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
|
||||
// If no associated ID, then no associated identifier
|
||||
Integer id = getObjectID();
|
||||
if (id == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, the identifier is the ID as a string
|
||||
return id.toString();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(String identifier) {
|
||||
throw new UnsupportedOperationException("Connection group identifiers are derived from IDs. They cannot be set.");
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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.connectiongroup;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.socket.GuacamoleSocketService;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating connection groups.
|
||||
*
|
||||
* @author Michael Jumper, James Muehlner
|
||||
*/
|
||||
public class ConnectionGroupService extends DirectoryObjectService<MySQLConnectionGroup,
|
||||
ConnectionGroup, ConnectionGroupModel> {
|
||||
|
||||
/**
|
||||
* Mapper for accessing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupMapper connectionGroupMapper;
|
||||
|
||||
/**
|
||||
* Provider for creating connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLConnectionGroup> connectionGroupProvider;
|
||||
|
||||
/**
|
||||
* Service for creating and tracking sockets.
|
||||
*/
|
||||
@Inject
|
||||
private GuacamoleSocketService socketService;
|
||||
|
||||
@Override
|
||||
protected DirectoryObjectMapper<ConnectionGroupModel> getObjectMapper() {
|
||||
return connectionGroupMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySQLConnectionGroup getObjectInstance(AuthenticatedUser currentUser,
|
||||
ConnectionGroupModel model) {
|
||||
MySQLConnectionGroup connectionGroup = connectionGroupProvider.get();
|
||||
connectionGroup.init(currentUser, model);
|
||||
return connectionGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionGroupModel getModelInstance(AuthenticatedUser currentUser,
|
||||
final ConnectionGroup object) {
|
||||
|
||||
// Create new MySQLConnectionGroup backed by blank model
|
||||
ConnectionGroupModel model = new ConnectionGroupModel();
|
||||
MySQLConnectionGroup connectionGroup = getObjectInstance(currentUser, model);
|
||||
|
||||
// Set model contents through MySQLConnection, copying the provided connection group
|
||||
connectionGroup.setParentIdentifier(object.getParentIdentifier());
|
||||
connectionGroup.setName(object.getName());
|
||||
connectionGroup.setType(object.getType());
|
||||
|
||||
return model;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasCreatePermission(AuthenticatedUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Return whether user has explicit connection group creation permission
|
||||
SystemPermissionSet permissionSet = user.getUser().getSystemPermissions();
|
||||
return permissionSet.hasPermission(SystemPermission.Type.CREATE_CONNECTION_GROUP);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectPermissionSet getPermissionSet(AuthenticatedUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Return permissions related to connection groups
|
||||
return user.getUser().getConnectionGroupPermissions();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateNewObject(AuthenticatedUser user, ConnectionGroup object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Name must not be blank
|
||||
if (object.getName().trim().isEmpty())
|
||||
throw new GuacamoleClientException("Connection group names must not be blank.");
|
||||
|
||||
// FIXME: Do not attempt to create duplicate connection groups
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateExistingObject(AuthenticatedUser user,
|
||||
MySQLConnectionGroup object) throws GuacamoleException {
|
||||
|
||||
// Name must not be blank
|
||||
if (object.getName().trim().isEmpty())
|
||||
throw new GuacamoleClientException("Connection group names must not be blank.");
|
||||
|
||||
// FIXME: Check whether such a connection group is already present
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of all identifiers for all connection groups within the
|
||||
* connection group having the given identifier. Only connection groups
|
||||
* that the user has read access to will be returned.
|
||||
*
|
||||
* Permission to read the connection group having the given identifier is
|
||||
* NOT checked.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving the identifiers.
|
||||
*
|
||||
* @param identifier
|
||||
* The identifier of the parent connection group, or null to check the
|
||||
* root connection group.
|
||||
*
|
||||
* @return
|
||||
* The set of all identifiers for all connection groups in the
|
||||
* connection group having the given identifier that the user has read
|
||||
* access to.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while reading identifiers.
|
||||
*/
|
||||
public Set<String> getIdentifiersWithin(AuthenticatedUser user,
|
||||
String identifier)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Bypass permission checks if the user is a system admin
|
||||
if (user.getUser().isAdministrator())
|
||||
return connectionGroupMapper.selectIdentifiersWithin(identifier);
|
||||
|
||||
// Otherwise only return explicitly readable identifiers
|
||||
else
|
||||
return connectionGroupMapper.selectReadableIdentifiersWithin(user.getUser().getModel(), identifier);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the given connection group as the given user, using the
|
||||
* given client information. If the user does not have permission to read
|
||||
* the connection group, permission will be denied.
|
||||
*
|
||||
* @param user
|
||||
* The user connecting to the connection group.
|
||||
*
|
||||
* @param connectionGroup
|
||||
* The connectionGroup being connected to.
|
||||
*
|
||||
* @param info
|
||||
* Information associated with the connecting client.
|
||||
*
|
||||
* @return
|
||||
* A connected GuacamoleSocket associated with a newly-established
|
||||
* connection.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to connect to this connection is denied.
|
||||
*/
|
||||
public GuacamoleSocket connect(AuthenticatedUser user,
|
||||
MySQLConnectionGroup connectionGroup, GuacamoleClientInformation info)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Connect only if READ permission is granted
|
||||
if (hasObjectPermission(user, connectionGroup.getIdentifier(), ObjectPermission.Type.READ))
|
||||
return socketService.getGuacamoleSocket(user, connectionGroup, info);
|
||||
|
||||
// The user does not have permission to connect
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.connectiongroup;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObject;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.socket.GuacamoleSocketService;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the ConnectionGroup object.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLConnectionGroup extends DirectoryObject<ConnectionGroupModel>
|
||||
implements ConnectionGroup {
|
||||
|
||||
/**
|
||||
* Service for managing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service for managing connection groups.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Service for creating and tracking sockets.
|
||||
*/
|
||||
@Inject
|
||||
private GuacamoleSocketService socketService;
|
||||
|
||||
/**
|
||||
* Creates a new, empty MySQLConnection.
|
||||
*/
|
||||
public MySQLConnectionGroup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getModel().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
getModel().setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentIdentifier() {
|
||||
|
||||
// Translate null parent to proper identifier
|
||||
String parentIdentifier = getModel().getParentIdentifier();
|
||||
if (parentIdentifier == null)
|
||||
return MySQLRootConnectionGroup.IDENTIFIER;
|
||||
|
||||
return parentIdentifier;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentIdentifier(String parentIdentifier) {
|
||||
|
||||
// Translate root identifier back into null
|
||||
if (parentIdentifier != null
|
||||
&& parentIdentifier.equals(MySQLRootConnectionGroup.IDENTIFIER))
|
||||
parentIdentifier = null;
|
||||
|
||||
getModel().setParentIdentifier(parentIdentifier);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info)
|
||||
throws GuacamoleException {
|
||||
return connectionGroupService.connect(getCurrentUser(), this, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveConnections() {
|
||||
return socketService.getActiveConnections(this).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Type type) {
|
||||
getModel().setType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return getModel().getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getConnectionIdentifiers()
|
||||
throws GuacamoleException {
|
||||
return connectionService.getIdentifiersWithin(getCurrentUser(), getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getConnectionGroupIdentifiers()
|
||||
throws GuacamoleException {
|
||||
return connectionGroupService.getIdentifiersWithin(getCurrentUser(), getIdentifier());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.connectiongroup;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionService;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
/**
|
||||
* The root connection group, here represented as its own dedicated object as
|
||||
* the database does not contain an actual root group.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class MySQLRootConnectionGroup implements ConnectionGroup {
|
||||
|
||||
/**
|
||||
* The identifier used to represent the root connection group. There is no
|
||||
* corresponding entry in the database, thus a reserved identifier that
|
||||
* cannot collide with database-generated identifiers is needed.
|
||||
*/
|
||||
public static final String IDENTIFIER = "ROOT";
|
||||
|
||||
/**
|
||||
* The human-readable name of this connection group. The name of the root
|
||||
* group is not normally visible, and may even be replaced by the web
|
||||
* interface for the sake of translation.
|
||||
*/
|
||||
public static final String NAME = "ROOT";
|
||||
|
||||
/**
|
||||
* The user this group belongs to. Access is based on his/her permission
|
||||
* settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* Service for managing connection objects.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service for managing connection group objects.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupService connectionGroupService;
|
||||
|
||||
/**
|
||||
* Creates a new, empty MySQLRootConnectionGroup.
|
||||
*/
|
||||
public MySQLRootConnectionGroup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this root connection group, associating it with the current
|
||||
* authenticated user.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user that created or retrieved this object.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser) {
|
||||
this.currentUser = currentUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
throw new UnsupportedOperationException("The root connection group cannot be modified.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentIdentifier() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentIdentifier(String parentIdentifier) {
|
||||
throw new UnsupportedOperationException("The root connection group cannot be modified.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return ConnectionGroup.Type.ORGANIZATIONAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Type type) {
|
||||
throw new UnsupportedOperationException("The root connection group cannot be modified.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getConnectionIdentifiers() throws GuacamoleException {
|
||||
return connectionService.getIdentifiersWithin(currentUser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getConnectionGroupIdentifiers()
|
||||
throws GuacamoleException {
|
||||
return connectionGroupService.getIdentifiersWithin(currentUser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(String identifier) {
|
||||
throw new UnsupportedOperationException("The root connection group cannot be modified.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info)
|
||||
throws GuacamoleException {
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveConnections() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to connection groups.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc.connectiongroup;
|
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The base JDBC authentication provider. This authentication provider serves
|
||||
* as a basis for other JDBC authentication provider implementations which are
|
||||
* driven by relatively-common schemas. The only difference between such
|
||||
* implementations are maintained within database-specific MyBatis mappings.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc;
|
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 org.glyptodon.guacamole.auth.jdbc.user.MySQLUser;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
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<SystemPermission> 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<SystemPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
systemPermissionService.createPermissions(currentUser, user, permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePermissions(Set<SystemPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
systemPermissionService.deletePermissions(currentUser, user, permissions);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 object-related permissions.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface ObjectPermissionMapper extends PermissionMapper<ObjectPermissionModel> {
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
|
||||
|
||||
/**
|
||||
* Object representation of an object-related Guacamole permission, as
|
||||
* represented in the database.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ObjectPermissionModel extends PermissionModel<ObjectPermission.Type> {
|
||||
|
||||
/**
|
||||
* The database ID of the object affected by this permission.
|
||||
*/
|
||||
private Integer affectedID;
|
||||
|
||||
/**
|
||||
* The unique identifier of the object affected by this permission.
|
||||
*/
|
||||
private String affectedIdentifier;
|
||||
|
||||
/**
|
||||
* Creates a new, empty object permission.
|
||||
*/
|
||||
public ObjectPermissionModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database ID of the object affected by this permission.
|
||||
*
|
||||
* @return
|
||||
* The database ID of the object affected by this permission.
|
||||
*/
|
||||
public Integer getAffectedID() {
|
||||
return affectedID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database ID of the object affected by this permission.
|
||||
*
|
||||
* @param affectedID
|
||||
* The database ID of the object affected by this permission.
|
||||
*/
|
||||
public void setAffectedID(Integer affectedID) {
|
||||
this.affectedID = affectedID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique identifier of the object affected by this permission.
|
||||
*
|
||||
* @return
|
||||
* The unique identifier of the object affected by this permission.
|
||||
*/
|
||||
public String getAffectedIdentifier() {
|
||||
return affectedIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the unique identifier of the object affected by this permission.
|
||||
*
|
||||
* @param affectedIdentifier
|
||||
* The unique identifier of the object affected by this permission.
|
||||
*/
|
||||
public void setAffectedIdentifier(String affectedIdentifier) {
|
||||
this.affectedIdentifier = affectedIdentifier;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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 java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.MySQLUser;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* deleting object permissions. This service will automatically enforce the
|
||||
* permissions of the current user.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <ModelType>
|
||||
* The underlying model object used to represent PermissionType in the
|
||||
* database.
|
||||
*/
|
||||
public abstract class ObjectPermissionService<ModelType>
|
||||
extends PermissionService<ObjectPermissionSet, ObjectPermission, ModelType> {
|
||||
|
||||
/**
|
||||
* Returns the permission set associated with the given user and related
|
||||
* to the type of objects affected the permissions handled by this
|
||||
* permission service.
|
||||
*
|
||||
* @param user
|
||||
* The user whose permissions are being retrieved.
|
||||
*
|
||||
* @return
|
||||
* A permission set which contains the permissions associated with the
|
||||
* given user and related to the type of objects handled by this
|
||||
* directory object service.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If permission to read the user's permissions is denied.
|
||||
*/
|
||||
protected abstract ObjectPermissionSet getAffectedPermissionSet(AuthenticatedUser user)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Determines whether the current user has permission to update the given
|
||||
* target user, adding or removing the given permissions. Such permission
|
||||
* depends on whether the current user is a system administrator, whether
|
||||
* they have explicit UPDATE permission on the target user, and whether
|
||||
* they have explicit ADMINISTER permission on all affected objects.
|
||||
*
|
||||
* @param user
|
||||
* The user who is changing permissions.
|
||||
*
|
||||
* @param targetUser
|
||||
* The user whose permissions are being changed.
|
||||
*
|
||||
* @param permissions
|
||||
* The permissions that are being added or removed from the target
|
||||
* user.
|
||||
*
|
||||
* @return
|
||||
* true if the user has permission to change the target users
|
||||
* permissions as specified, false otherwise.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while checking permission status, or if
|
||||
* permission is denied to read the current user's permissions.
|
||||
*/
|
||||
protected boolean canAlterPermissions(AuthenticatedUser user, MySQLUser targetUser,
|
||||
Collection<ObjectPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// A system adminstrator can do anything
|
||||
if (user.getUser().isAdministrator())
|
||||
return true;
|
||||
|
||||
// Verify user has update permission on the target user
|
||||
ObjectPermissionSet userPermissionSet = user.getUser().getUserPermissions();
|
||||
if (!userPermissionSet.hasPermission(ObjectPermission.Type.UPDATE, targetUser.getIdentifier()))
|
||||
return false;
|
||||
|
||||
// Produce collection of affected identifiers
|
||||
Collection<String> affectedIdentifiers = new HashSet(permissions.size());
|
||||
for (ObjectPermission permission : permissions)
|
||||
affectedIdentifiers.add(permission.getObjectIdentifier());
|
||||
|
||||
// Determine subset of affected identifiers that we have admin access to
|
||||
ObjectPermissionSet affectedPermissionSet = getAffectedPermissionSet(user);
|
||||
Collection<String> allowedSubset = affectedPermissionSet.getAccessibleObjects(
|
||||
Collections.singleton(ObjectPermission.Type.ADMINISTER),
|
||||
affectedIdentifiers
|
||||
);
|
||||
|
||||
// The permissions can be altered if and only if the set of objects we
|
||||
// are allowed to administer is equal to the set of objects we will be
|
||||
// affecting.
|
||||
|
||||
return affectedIdentifiers.size() == allowedSubset.size();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPermissions(AuthenticatedUser user, MySQLUser targetUser,
|
||||
Collection<ObjectPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Create permissions only if user has permission to do so
|
||||
if (canAlterPermissions(user, targetUser, permissions)) {
|
||||
Collection<ModelType> models = getModelInstances(targetUser, permissions);
|
||||
getPermissionMapper().insert(models);
|
||||
return;
|
||||
}
|
||||
|
||||
// User lacks permission to create object permissions
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePermissions(AuthenticatedUser user, MySQLUser targetUser,
|
||||
Collection<ObjectPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Delete permissions only if user has permission to do so
|
||||
if (canAlterPermissions(user, targetUser, permissions)) {
|
||||
Collection<ModelType> models = getModelInstances(targetUser, permissions);
|
||||
getPermissionMapper().delete(models);
|
||||
return;
|
||||
}
|
||||
|
||||
// User lacks permission to delete object permissions
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 java.util.Collection;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserModel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Generic base for mappers which handle permissions.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <PermissionType>
|
||||
* The type of permission model object handled by this mapper.
|
||||
*/
|
||||
public interface PermissionMapper<PermissionType> {
|
||||
|
||||
/**
|
||||
* Retrieves all permissions associated with the given user.
|
||||
*
|
||||
* @param user
|
||||
* The user to retrieve permissions for.
|
||||
*
|
||||
* @return
|
||||
* All permissions associated with the given user.
|
||||
*/
|
||||
Collection<PermissionType> select(@Param("user") UserModel user);
|
||||
|
||||
/**
|
||||
* Inserts the given permissions into the database. If any permissions
|
||||
* already exist, they will be ignored.
|
||||
*
|
||||
* @param permissions
|
||||
* The permissions to insert.
|
||||
*
|
||||
* @return
|
||||
* The number of rows inserted.
|
||||
*/
|
||||
int insert(@Param("permissions") Collection<PermissionType> permissions);
|
||||
|
||||
/**
|
||||
* Deletes the given permissions from the database. If any permissions do
|
||||
* not exist, they will be ignored.
|
||||
*
|
||||
* @param permissions
|
||||
* The permissions to delete.
|
||||
*
|
||||
* @return
|
||||
* The number of rows deleted.
|
||||
*/
|
||||
int delete(@Param("permissions") Collection<PermissionType> permissions);
|
||||
|
||||
}
|
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Generic base permission model which grants a permission of a particular type
|
||||
* to a specific user.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
* @param <PermissionType>
|
||||
* The type of permissions allowed within this model.
|
||||
*/
|
||||
public abstract class PermissionModel<PermissionType> {
|
||||
|
||||
/**
|
||||
* The database ID of the user to whom this permission is granted.
|
||||
*/
|
||||
private Integer userID;
|
||||
|
||||
/**
|
||||
* The username of the user to whom this permission is granted.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* The type of action granted by this permission.
|
||||
*/
|
||||
private PermissionType type;
|
||||
|
||||
/**
|
||||
* Returns the database ID of the user to whom this permission is granted.
|
||||
*
|
||||
* @return
|
||||
* The database ID of the user to whom this permission is granted.
|
||||
*/
|
||||
public Integer getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database ID of the user to whom this permission is granted.
|
||||
*
|
||||
* @param userID
|
||||
* The database ID of the user to whom this permission is granted.
|
||||
*/
|
||||
public void setUserID(Integer userID) {
|
||||
this.userID = userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username of the user to whom this permission is granted.
|
||||
*
|
||||
* @return
|
||||
* The username of the user to whom this permission is granted.
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username of the user to whom this permission is granted.
|
||||
*
|
||||
* @param username
|
||||
* The username of the user to whom this permission is granted.
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of action granted by this permission.
|
||||
*
|
||||
* @return
|
||||
* The type of action granted by this permission.
|
||||
*/
|
||||
public PermissionType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of action granted by this permission.
|
||||
*
|
||||
* @param type
|
||||
* The type of action granted by this permission.
|
||||
*/
|
||||
public void setType(PermissionType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.MySQLUser;
|
||||
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, 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 <PermissionSetType>
|
||||
* The type of permission sets this service provides access to.
|
||||
*
|
||||
* @param <PermissionType>
|
||||
* The type of permission this service provides access to.
|
||||
*
|
||||
* @param <ModelType>
|
||||
* The underlying model object used to represent PermissionType in the
|
||||
* database.
|
||||
*/
|
||||
public abstract class PermissionService<PermissionSetType extends PermissionSet<PermissionType>,
|
||||
PermissionType extends Permission, ModelType> {
|
||||
|
||||
/**
|
||||
* Returns an instance of a mapper for the type of permission used by this
|
||||
* service.
|
||||
*
|
||||
* @return
|
||||
* A mapper which provides access to the model objects associated with
|
||||
* the permissions used by this service.
|
||||
*/
|
||||
protected abstract PermissionMapper<ModelType> getPermissionMapper();
|
||||
|
||||
/**
|
||||
* Returns an instance of a permission which is based on the given model
|
||||
* object.
|
||||
*
|
||||
* @param model
|
||||
* The model object to use to produce the returned permission.
|
||||
*
|
||||
* @return
|
||||
* A permission which is based on the given model object.
|
||||
*/
|
||||
protected abstract PermissionType getPermissionInstance(ModelType model);
|
||||
|
||||
/**
|
||||
* Returns a collection of permissions which are based on the models in
|
||||
* the given collection.
|
||||
*
|
||||
* @param models
|
||||
* The model objects to use to produce the permissions within the
|
||||
* returned set.
|
||||
*
|
||||
* @return
|
||||
* A set of permissions which are based on the models in the given
|
||||
* collection.
|
||||
*/
|
||||
protected Set<PermissionType> getPermissionInstances(Collection<ModelType> models) {
|
||||
|
||||
// Create new collection of permissions by manually converting each model
|
||||
Set<PermissionType> permissions = new HashSet<PermissionType>(models.size());
|
||||
for (ModelType model : models)
|
||||
permissions.add(getPermissionInstance(model));
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of a model object which is based on the given
|
||||
* permission and target user.
|
||||
*
|
||||
* @param targetUser
|
||||
* The user to whom this permission is granted.
|
||||
*
|
||||
* @param permission
|
||||
* The permission to use to produce the returned model object.
|
||||
*
|
||||
* @return
|
||||
* A model object which is based on the given permission and target
|
||||
* user.
|
||||
*/
|
||||
protected abstract ModelType getModelInstance(MySQLUser targetUser,
|
||||
PermissionType permission);
|
||||
|
||||
/**
|
||||
* Returns a collection of model objects which are based on the given
|
||||
* permissions and target user.
|
||||
*
|
||||
* @param targetUser
|
||||
* The user to whom this permission is granted.
|
||||
*
|
||||
* @param permissions
|
||||
* The permissions to use to produce the returned model objects.
|
||||
*
|
||||
* @return
|
||||
* A collection of model objects which are based on the given
|
||||
* permissions and target user.
|
||||
*/
|
||||
protected Collection<ModelType> getModelInstances(MySQLUser targetUser,
|
||||
Collection<PermissionType> permissions) {
|
||||
|
||||
// Create new collection of models by manually converting each permission
|
||||
Collection<ModelType> models = new ArrayList<ModelType>(permissions.size());
|
||||
for (PermissionType permission : permissions)
|
||||
models.add(getModelInstance(targetUser, permission));
|
||||
|
||||
return models;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a permission set that can be used to retrieve and manipulate the
|
||||
* permissions of the given user.
|
||||
*
|
||||
* @param user
|
||||
* The user who will be retrieving or manipulating permissions through
|
||||
* the returned permission set.
|
||||
*
|
||||
* @param targetUser
|
||||
* The user to whom the permissions in the returned permission set are
|
||||
* granted.
|
||||
*
|
||||
* @return
|
||||
* A permission set that contains all permissions associated with the
|
||||
* given user, and can be used to manipulate that user's permissions.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the permissions of the given
|
||||
* user, or if permission to retrieve the permissions of the given
|
||||
* user is denied.
|
||||
*/
|
||||
public abstract PermissionSetType getPermissionSet(AuthenticatedUser user,
|
||||
MySQLUser targetUser) throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Retrieves all permissions associated with the given user.
|
||||
*
|
||||
* @param user
|
||||
* The user retrieving the permissions.
|
||||
*
|
||||
* @param targetUser
|
||||
* The user associated with the permissions to be retrieved.
|
||||
*
|
||||
* @return
|
||||
* The permissions associated with the given user.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the requested permissions.
|
||||
*/
|
||||
public Set<PermissionType> retrievePermissions(AuthenticatedUser user,
|
||||
MySQLUser targetUser) throws GuacamoleException {
|
||||
|
||||
// Only an admin can read permissions that aren't his own
|
||||
if (user.getUser().getIdentifier().equals(targetUser.getIdentifier())
|
||||
|| user.getUser().isAdministrator())
|
||||
return getPermissionInstances(getPermissionMapper().select(targetUser.getModel()));
|
||||
|
||||
// User cannot read this user's permissions
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the given permissions within the database. If any permissions
|
||||
* already exist, they will be ignored.
|
||||
*
|
||||
* @param user
|
||||
* The user creating the permissions.
|
||||
*
|
||||
* @param targetUser
|
||||
* The user associated with the permissions to be created.
|
||||
*
|
||||
* @param permissions
|
||||
* The permissions to create.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the user lacks permission to create the permissions, or an error
|
||||
* occurs while creating the permissions.
|
||||
*/
|
||||
public abstract void createPermissions(AuthenticatedUser user,
|
||||
MySQLUser targetUser,
|
||||
Collection<PermissionType> permissions) throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Deletes the given permissions. If any permissions do not exist, they
|
||||
* will be ignored.
|
||||
*
|
||||
* @param user
|
||||
* The user deleting the permissions.
|
||||
*
|
||||
* @param targetUser
|
||||
* The user associated with the permissions to be deleted.
|
||||
*
|
||||
* @param permissions
|
||||
* The permissions to delete.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the user lacks permission to delete the permissions, or an error
|
||||
* occurs while deleting the permissions.
|
||||
*/
|
||||
public abstract void deletePermissions(AuthenticatedUser user,
|
||||
MySQLUser targetUser,
|
||||
Collection<PermissionType> permissions) throws GuacamoleException;
|
||||
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 org.glyptodon.guacamole.auth.jdbc.user.UserModel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
|
||||
/**
|
||||
* Mapper for system-level permissions.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface SystemPermissionMapper extends PermissionMapper<SystemPermissionModel> {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
|
||||
/**
|
||||
* Object representation of an system-level Guacamole permission, as
|
||||
* represented in the database.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class SystemPermissionModel extends PermissionModel<SystemPermission.Type> {
|
||||
|
||||
/**
|
||||
* Creates a new, empty System permission.
|
||||
*/
|
||||
public SystemPermissionModel() {
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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 java.util.Collection;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.MySQLUser;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* deleting system permissions. This service will automatically enforce
|
||||
* the permissions of the current user.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class SystemPermissionService
|
||||
extends PermissionService<MySQLSystemPermissionSet, SystemPermission, SystemPermissionModel> {
|
||||
|
||||
/**
|
||||
* Mapper for system-level permissions.
|
||||
*/
|
||||
@Inject
|
||||
private SystemPermissionMapper systemPermissionMapper;
|
||||
|
||||
/**
|
||||
* Provider for creating system permission sets.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLSystemPermissionSet> systemPermissionSetProvider;
|
||||
|
||||
@Override
|
||||
protected SystemPermissionMapper getPermissionMapper() {
|
||||
return systemPermissionMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SystemPermission getPermissionInstance(SystemPermissionModel model) {
|
||||
return new SystemPermission(model.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SystemPermissionModel getModelInstance(final MySQLUser targetUser,
|
||||
final SystemPermission permission) {
|
||||
|
||||
SystemPermissionModel model = new SystemPermissionModel();
|
||||
|
||||
// Populate model object with data from user and permission
|
||||
model.setUserID(targetUser.getModel().getObjectID());
|
||||
model.setUsername(targetUser.getModel().getIdentifier());
|
||||
model.setType(permission.getType());
|
||||
|
||||
return model;
|
||||
|
||||
}
|
||||
|
||||
@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<SystemPermission> permissions) throws GuacamoleException {
|
||||
|
||||
// Only an admin can create system permissions
|
||||
if (user.getUser().isAdministrator()) {
|
||||
Collection<SystemPermissionModel> models = getModelInstances(targetUser, permissions);
|
||||
systemPermissionMapper.insert(models);
|
||||
return;
|
||||
}
|
||||
|
||||
// User lacks permission to create system permissions
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePermissions(AuthenticatedUser user, MySQLUser targetUser,
|
||||
Collection<SystemPermission> permissions) throws GuacamoleException {
|
||||
|
||||
// Only an admin can delete system permissions
|
||||
if (user.getUser().isAdministrator()) {
|
||||
Collection<SystemPermissionModel> models = getModelInstances(targetUser, permissions);
|
||||
systemPermissionMapper.delete(models);
|
||||
return;
|
||||
}
|
||||
|
||||
// User lacks permission to delete system permissions
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()) {
|
||||
|
||||
// Read permission from database, return null if not found
|
||||
SystemPermissionModel model = getPermissionMapper().selectOne(targetUser.getModel(), type);
|
||||
if (model == null)
|
||||
return null;
|
||||
|
||||
return getPermissionInstance(model);
|
||||
|
||||
}
|
||||
|
||||
// User cannot read this user's permissions
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to object- and system-level permissions.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc.permission;
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.security;
|
||||
|
||||
/**
|
||||
* A service to perform password encryption and checking.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public interface PasswordEncryptionService {
|
||||
|
||||
/**
|
||||
* Creates a password hash based on the provided username, password, and
|
||||
* salt.
|
||||
*
|
||||
* @param password The password to hash.
|
||||
* @param salt The salt to use when hashing the password.
|
||||
* @return The generated password hash.
|
||||
*/
|
||||
public byte[] createPasswordHash(String password, byte[] salt);
|
||||
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.security;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
/**
|
||||
* Provides a SHA-256 based implementation of the password encryption functionality.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class SHA256PasswordEncryptionService implements PasswordEncryptionService {
|
||||
|
||||
@Override
|
||||
public byte[] createPasswordHash(String password, byte[] salt) {
|
||||
|
||||
try {
|
||||
|
||||
// Build salted password
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(password);
|
||||
builder.append(DatatypeConverter.printHexBinary(salt));
|
||||
|
||||
// Hash UTF-8 bytes of salted password
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
md.update(builder.toString().getBytes("UTF-8"));
|
||||
return md.digest();
|
||||
|
||||
}
|
||||
|
||||
// Should not happen
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
// Should not happen
|
||||
catch (NoSuchAlgorithmException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.security;
|
||||
|
||||
/**
|
||||
* A service to generate password salts.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public interface SaltService {
|
||||
/**
|
||||
* Generates a new String that can be used as a password salt.
|
||||
* @return a new salt for password encryption.
|
||||
*/
|
||||
public byte[] generateSalt();
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.security;
|
||||
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* Generates password salts via SecureRandom.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class SecureRandomSaltService implements SaltService {
|
||||
|
||||
/**
|
||||
* Instance of SecureRandom for generating the salt.
|
||||
*/
|
||||
private SecureRandom secureRandom = new SecureRandom();
|
||||
|
||||
@Override
|
||||
public byte[] generateSalt() {
|
||||
byte[] salt = new byte[32];
|
||||
secureRandom.nextBytes(salt);
|
||||
return salt;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to hashing or encryption.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc.security;
|
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* 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.socket;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.MySQLConnection;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.MySQLConnectionGroup;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionRecordMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ParameterMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionModel;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionRecordModel;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ParameterModel;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.UserModel;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.environment.Environment;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.InetGuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
|
||||
import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
|
||||
import org.glyptodon.guacamole.token.StandardTokens;
|
||||
import org.glyptodon.guacamole.token.TokenFilter;
|
||||
|
||||
|
||||
/**
|
||||
* Base implementation of the GuacamoleSocketService, handling retrieval of
|
||||
* connection parameters, load balancing, and connection usage counts. The
|
||||
* implementation of concurrency rules is up to policy-specific subclasses.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public abstract class AbstractGuacamoleSocketService implements GuacamoleSocketService {
|
||||
|
||||
/**
|
||||
* The environment of the Guacamole server.
|
||||
*/
|
||||
@Inject
|
||||
private Environment environment;
|
||||
|
||||
/**
|
||||
* Mapper for accessing connection parameters.
|
||||
*/
|
||||
@Inject
|
||||
private ParameterMapper parameterMapper;
|
||||
|
||||
/**
|
||||
* Mapper for accessing connection history.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionRecordMapper connectionRecordMapper;
|
||||
|
||||
/**
|
||||
* The current number of concurrent uses of the connection having a given
|
||||
* identifier.
|
||||
*/
|
||||
private final Map<String, LinkedList<ConnectionRecord>> activeConnections =
|
||||
new HashMap<String, LinkedList<ConnectionRecord>>();
|
||||
|
||||
/**
|
||||
* Atomically increments the current usage count for the given connection.
|
||||
*
|
||||
* @param connection
|
||||
* The connection which is being used.
|
||||
*/
|
||||
private void addActiveConnection(Connection connection, ConnectionRecord record) {
|
||||
synchronized (activeConnections) {
|
||||
|
||||
String identifier = connection.getIdentifier();
|
||||
|
||||
// Get set of active connection records, creating if necessary
|
||||
LinkedList<ConnectionRecord> connections = activeConnections.get(identifier);
|
||||
if (connections == null) {
|
||||
connections = new LinkedList<ConnectionRecord>();
|
||||
activeConnections.put(identifier, connections);
|
||||
}
|
||||
|
||||
// Add active connection
|
||||
connections.addFirst(record);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically decrements the current usage count for the given connection.
|
||||
* If a combination of incrementUsage() and decrementUsage() calls result
|
||||
* in the usage counter being reduced to zero, it is guaranteed that one
|
||||
* of those decrementUsage() calls will remove the value from the map.
|
||||
*
|
||||
* @param connection
|
||||
* The connection which is no longer being used.
|
||||
*/
|
||||
private void removeActiveConnection(Connection connection, ConnectionRecord record) {
|
||||
synchronized (activeConnections) {
|
||||
|
||||
String identifier = connection.getIdentifier();
|
||||
|
||||
// Get set of active connection records
|
||||
LinkedList<ConnectionRecord> connections = activeConnections.get(identifier);
|
||||
assert(connections != null);
|
||||
|
||||
// Remove old record
|
||||
connections.remove(record);
|
||||
|
||||
// If now empty, clean the tracking entry
|
||||
if (connections.isEmpty())
|
||||
activeConnections.remove(identifier);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires possibly-exclusive access to the given connection on behalf of
|
||||
* the given user. If access is denied for any reason, an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @param user
|
||||
* The user acquiring access.
|
||||
*
|
||||
* @param connection
|
||||
* The connection being accessed.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If access is denied to the given user for any reason.
|
||||
*/
|
||||
protected abstract void acquire(AuthenticatedUser user,
|
||||
MySQLConnection connection) throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Releases possibly-exclusive access to the given connection on behalf of
|
||||
* the given user. If the given user did not already have access, the
|
||||
* behavior of this function is undefined.
|
||||
*
|
||||
* @param user
|
||||
* The user releasing access.
|
||||
*
|
||||
* @param connection
|
||||
* The connection being released.
|
||||
*/
|
||||
protected abstract void release(AuthenticatedUser user,
|
||||
MySQLConnection connection);
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket getGuacamoleSocket(final AuthenticatedUser user,
|
||||
final MySQLConnection connection, GuacamoleClientInformation info)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Create record for active connection
|
||||
final ActiveConnectionRecord activeConnection = new ActiveConnectionRecord(user);
|
||||
|
||||
// Generate configuration from available data
|
||||
GuacamoleConfiguration config = new GuacamoleConfiguration();
|
||||
|
||||
// Set protocol from connection
|
||||
ConnectionModel model = connection.getModel();
|
||||
config.setProtocol(model.getProtocol());
|
||||
|
||||
// Set parameters from associated data
|
||||
Collection<ParameterModel> parameters = parameterMapper.select(connection.getIdentifier());
|
||||
for (ParameterModel parameter : parameters)
|
||||
config.setParameter(parameter.getName(), parameter.getValue());
|
||||
|
||||
// Build token filter containing credential tokens
|
||||
TokenFilter tokenFilter = new TokenFilter();
|
||||
StandardTokens.addStandardTokens(tokenFilter, user.getCredentials());
|
||||
|
||||
// Filter the configuration
|
||||
tokenFilter.filterValues(config.getParameters());
|
||||
|
||||
// Return new socket
|
||||
try {
|
||||
|
||||
// Atomically gain access to connection
|
||||
acquire(user, connection);
|
||||
addActiveConnection(connection, activeConnection);
|
||||
|
||||
// Return newly-reserved connection
|
||||
return new ConfiguredGuacamoleSocket(
|
||||
new InetGuacamoleSocket(
|
||||
environment.getRequiredProperty(Environment.GUACD_HOSTNAME),
|
||||
environment.getRequiredProperty(Environment.GUACD_PORT)
|
||||
),
|
||||
config
|
||||
) {
|
||||
|
||||
@Override
|
||||
public void close() throws GuacamoleException {
|
||||
|
||||
// Attempt to close connection
|
||||
super.close();
|
||||
|
||||
// Release connection upon close
|
||||
removeActiveConnection(connection, activeConnection);
|
||||
release(user, connection);
|
||||
|
||||
UserModel userModel = user.getUser().getModel();
|
||||
ConnectionRecordModel recordModel = new ConnectionRecordModel();
|
||||
|
||||
// Copy user information and timestamps into new record
|
||||
recordModel.setUserID(userModel.getObjectID());
|
||||
recordModel.setUsername(userModel.getIdentifier());
|
||||
recordModel.setConnectionIdentifier(connection.getIdentifier());
|
||||
recordModel.setStartDate(activeConnection.getStartDate());
|
||||
recordModel.setEndDate(new Date());
|
||||
|
||||
// Insert connection record
|
||||
connectionRecordMapper.insert(recordModel);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Release connection in case of error
|
||||
catch (GuacamoleException e) {
|
||||
|
||||
// Atomically release access to connection
|
||||
removeActiveConnection(connection, activeConnection);
|
||||
release(user, connection);
|
||||
|
||||
throw e;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConnectionRecord> getActiveConnections(Connection connection) {
|
||||
synchronized (activeConnections) {
|
||||
|
||||
String identifier = connection.getIdentifier();
|
||||
|
||||
// Get set of active connection records
|
||||
LinkedList<ConnectionRecord> connections = activeConnections.get(identifier);
|
||||
if (connections != null)
|
||||
return Collections.unmodifiableList(connections);
|
||||
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket getGuacamoleSocket(AuthenticatedUser user,
|
||||
MySQLConnectionGroup connectionGroup,
|
||||
GuacamoleClientInformation info) throws GuacamoleException {
|
||||
// STUB
|
||||
throw new UnsupportedOperationException("STUB");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConnectionRecord> getActiveConnections(ConnectionGroup connectionGroup) {
|
||||
// STUB
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.socket;
|
||||
|
||||
import java.util.Date;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
|
||||
|
||||
|
||||
/**
|
||||
* A connection record implementation that describes an active connection. As
|
||||
* the associated connection has not yet ended, getEndDate() will always return
|
||||
* null, and isActive() will always return true. The associated start date will
|
||||
* be the time of this objects creation.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ActiveConnectionRecord implements ConnectionRecord {
|
||||
|
||||
/**
|
||||
* The user that connected to the connection associated with this connection
|
||||
* record.
|
||||
*/
|
||||
private final AuthenticatedUser user;
|
||||
|
||||
/**
|
||||
* The time this connection record was created.
|
||||
*/
|
||||
private final Date startDate = new Date();
|
||||
|
||||
/**
|
||||
* Creates a new connection record associated with the given user. The
|
||||
* start date of this connection record will be the time of its creation.
|
||||
*
|
||||
* @param user
|
||||
* The user that connected to the connection associated with this
|
||||
* connection record.
|
||||
*/
|
||||
public ActiveConnectionRecord(AuthenticatedUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getEndDate() {
|
||||
|
||||
// Active connections have not yet ended
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return user.getUser().getIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
|
||||
// Active connections are active by definition
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.socket;
|
||||
|
||||
import java.util.List;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.MySQLConnection;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.MySQLConnectionGroup;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.GuacamoleSocket;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionRecord;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||
|
||||
|
||||
/**
|
||||
* Service which creates pre-configured GuacamoleSocket instances for
|
||||
* connections and balancing groups, applying concurrent usage rules.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface GuacamoleSocketService {
|
||||
|
||||
/**
|
||||
* Creates a socket for the given user which connects to the given
|
||||
* connection. The given client information will be passed to guacd when
|
||||
* the connection is established. This function will apply any concurrent
|
||||
* usage rules in effect, but will NOT test object- or system-level
|
||||
* permissions.
|
||||
*
|
||||
* @param user
|
||||
* The user for whom the connection is being established.
|
||||
*
|
||||
* @param connection
|
||||
* The connection the user is connecting to.
|
||||
*
|
||||
* @param info
|
||||
* Information describing the Guacamole client connecting to the given
|
||||
* connection.
|
||||
*
|
||||
* @return
|
||||
* A new GuacamoleSocket which is configured and connected to the given
|
||||
* connection.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the connection cannot be established due to concurrent usage
|
||||
* rules.
|
||||
*/
|
||||
GuacamoleSocket getGuacamoleSocket(AuthenticatedUser user,
|
||||
MySQLConnection connection, GuacamoleClientInformation info)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns a list containing connection records representing all currently-
|
||||
* active connections using the given connection. These records will have
|
||||
* usernames and start dates, but no end date.
|
||||
*
|
||||
* @param connection
|
||||
* The connection to check.
|
||||
*
|
||||
* @return
|
||||
* A list containing connection records representing all currently-
|
||||
* active connections.
|
||||
*/
|
||||
public List<ConnectionRecord> getActiveConnections(Connection connection);
|
||||
|
||||
/**
|
||||
* Creates a socket for the given user which connects to the given
|
||||
* connection group. The given client information will be passed to guacd
|
||||
* when the connection is established. This function will apply any
|
||||
* concurrent usage rules in effect, but will NOT test object- or
|
||||
* system-level permissions.
|
||||
*
|
||||
* @param user
|
||||
* The user for whom the connection is being established.
|
||||
*
|
||||
* @param connectionGroup
|
||||
* The connection group the user is connecting to.
|
||||
*
|
||||
* @param info
|
||||
* Information describing the Guacamole client connecting to the given
|
||||
* connection group.
|
||||
*
|
||||
* @return
|
||||
* A new GuacamoleSocket which is configured and connected to the given
|
||||
* connection group.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If the connection cannot be established due to concurrent usage
|
||||
* rules, or if the connection group is not balancing.
|
||||
*/
|
||||
GuacamoleSocket getGuacamoleSocket(AuthenticatedUser user,
|
||||
MySQLConnectionGroup connectionGroup,
|
||||
GuacamoleClientInformation info)
|
||||
throws GuacamoleException;
|
||||
|
||||
/**
|
||||
* Returns a list containing connection records representing all currently-
|
||||
* active connections using the given connection group. These records will
|
||||
* have usernames and start dates, but no end date.
|
||||
*
|
||||
* @param connectionGroup
|
||||
* The connection group to check.
|
||||
*
|
||||
* @return
|
||||
* A list containing connection records representing all currently-
|
||||
* active connections.
|
||||
*/
|
||||
public List<ConnectionRecord> getActiveConnections(ConnectionGroup connectionGroup);
|
||||
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.socket;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.MySQLConnection;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
|
||||
|
||||
/**
|
||||
* GuacamoleSocketService implementation which imposes no restrictions
|
||||
* whatsoever on the number of concurrent or duplicate connections.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
@Singleton
|
||||
public class UnrestrictedGuacamoleSocketService
|
||||
extends AbstractGuacamoleSocketService {
|
||||
|
||||
@Override
|
||||
protected void acquire(AuthenticatedUser user, MySQLConnection connection)
|
||||
throws GuacamoleException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void release(AuthenticatedUser user, MySQLConnection connection) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to obtaining/configuring Guacamole sockets, and restricting
|
||||
* access to those sockets.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc.socket;
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
|
||||
/**
|
||||
* Associates a user with the credentials they used to authenticate.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class AuthenticatedUser {
|
||||
|
||||
/**
|
||||
* The user that authenticated.
|
||||
*/
|
||||
private final MySQLUser user;
|
||||
|
||||
/**
|
||||
* The credentials given when this user authenticated.
|
||||
*/
|
||||
private final Credentials credentials;
|
||||
|
||||
/**
|
||||
* Creates a new AuthenticatedUser associating the given user with their
|
||||
* corresponding credentials.
|
||||
*
|
||||
* @param user
|
||||
* The user this object should represent.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials given by the user when they authenticated.
|
||||
*/
|
||||
public AuthenticatedUser(MySQLUser user, Credentials credentials) {
|
||||
this.user = user;
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user that authenticated.
|
||||
*
|
||||
* @return
|
||||
* The user that authenticated.
|
||||
*/
|
||||
public MySQLUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the credentials given during authentication by this user.
|
||||
*
|
||||
* @return
|
||||
* The credentials given during authentication by this user.
|
||||
*/
|
||||
public Credentials getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObject;
|
||||
import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.security.SaltService;
|
||||
import org.glyptodon.guacamole.auth.jdbc.permission.SystemPermissionService;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.simple.SimpleObjectPermissionSet;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the User object.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLUser extends DirectoryObject<UserModel> implements User {
|
||||
|
||||
/**
|
||||
* Service for hashing passwords.
|
||||
*/
|
||||
@Inject
|
||||
private PasswordEncryptionService encryptionService;
|
||||
|
||||
/**
|
||||
* Service for providing secure, random salts.
|
||||
*/
|
||||
@Inject
|
||||
private SaltService saltService;
|
||||
|
||||
/**
|
||||
* Service for retrieving system permissions.
|
||||
*/
|
||||
@Inject
|
||||
private SystemPermissionService systemPermissionService;
|
||||
|
||||
/**
|
||||
* The plaintext password previously set by a call to setPassword(), if
|
||||
* any. The password of a user cannot be retrieved once saved into the
|
||||
* database, so this serves to ensure getPassword() returns a reasonable
|
||||
* value if setPassword() is called. If no password has been set, or the
|
||||
* user was retrieved from the database, this will be null.
|
||||
*/
|
||||
private String password = null;
|
||||
|
||||
/**
|
||||
* Creates a new, empty MySQLUser.
|
||||
*/
|
||||
public MySQLUser() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPassword(String password) {
|
||||
|
||||
UserModel userModel = getModel();
|
||||
|
||||
// Store plaintext password internally
|
||||
this.password = password;
|
||||
|
||||
// If no password provided, clear password salt and hash
|
||||
if (password == null) {
|
||||
userModel.setPasswordSalt(null);
|
||||
userModel.setPasswordHash(null);
|
||||
}
|
||||
|
||||
// Otherwise generate new salt and hash given password using newly-generated salt
|
||||
else {
|
||||
byte[] salt = saltService.generateSalt();
|
||||
byte[] hash = encryptionService.createPasswordHash(password, salt);
|
||||
|
||||
// Set stored salt and hash
|
||||
userModel.setPasswordSalt(salt);
|
||||
userModel.setPasswordHash(hash);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this user is a system administrator, and thus is not
|
||||
* restricted by permissions.
|
||||
*
|
||||
* @return
|
||||
* true if this user is a system administrator, false otherwise.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while determining the user's system administrator
|
||||
* status.
|
||||
*/
|
||||
public boolean isAdministrator() throws GuacamoleException {
|
||||
SystemPermissionSet systemPermissionSet = getSystemPermissions();
|
||||
return systemPermissionSet.hasPermission(SystemPermission.Type.ADMINISTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SystemPermissionSet getSystemPermissions()
|
||||
throws GuacamoleException {
|
||||
return systemPermissionService.getPermissionSet(getCurrentUser(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPermissionSet getConnectionPermissions()
|
||||
throws GuacamoleException {
|
||||
// STUB
|
||||
return new SimpleObjectPermissionSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPermissionSet getConnectionGroupPermissions()
|
||||
throws GuacamoleException {
|
||||
// STUB
|
||||
return new SimpleObjectPermissionSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPermissionSet getUserPermissions()
|
||||
throws GuacamoleException {
|
||||
// STUB
|
||||
return new SimpleObjectPermissionSet();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.MySQLRootConnectionGroup;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.ConnectionGroupDirectory;
|
||||
import org.glyptodon.guacamole.auth.jdbc.connection.ConnectionDirectory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.Connection;
|
||||
import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
|
||||
/**
|
||||
* The MySQL representation of a UserContext.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLUserContext implements UserContext {
|
||||
|
||||
/**
|
||||
* The the user owning this context.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* User directory restricted by the permissions of the user associated
|
||||
* with this context.
|
||||
*/
|
||||
@Inject
|
||||
private UserDirectory userDirectory;
|
||||
|
||||
/**
|
||||
* Connection directory restricted by the permissions of the user
|
||||
* associated with this context.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionDirectory connectionDirectory;
|
||||
|
||||
/**
|
||||
* Connection group directory restricted by the permissions of the user
|
||||
* associated with this context.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionGroupDirectory connectionGroupDirectory;
|
||||
|
||||
/**
|
||||
* Provider for creating the root group.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLRootConnectionGroup> rootGroupProvider;
|
||||
|
||||
/**
|
||||
* Initializes the user and directories associated with this context.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user owning this context.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser) {
|
||||
|
||||
this.currentUser = currentUser;
|
||||
|
||||
// Init directories
|
||||
userDirectory.init(currentUser);
|
||||
connectionDirectory.init(currentUser);
|
||||
connectionGroupDirectory.init(currentUser);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public User self() {
|
||||
return currentUser.getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<User> getUserDirectory() throws GuacamoleException {
|
||||
return userDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<Connection> getConnectionDirectory() throws GuacamoleException {
|
||||
return connectionDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<ConnectionGroup> getConnectionGroupDirectory() throws GuacamoleException {
|
||||
return connectionGroupDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionGroup getRootConnectionGroup() throws GuacamoleException {
|
||||
|
||||
// Build and return a root group for the current user
|
||||
MySQLRootConnectionGroup rootGroup = rootGroupProvider.get();
|
||||
rootGroup.init(currentUser);
|
||||
return rootGroup;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||
|
||||
/**
|
||||
* Service which creates new UserContext instances for valid users based on
|
||||
* credentials.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class UserContextService {
|
||||
|
||||
/**
|
||||
* Service for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Provider for retrieving UserContext instances.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLUserContext> userContextProvider;
|
||||
|
||||
/**
|
||||
* Authenticates the user having the given credentials, returning a new
|
||||
* UserContext instance if the credentials are valid.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials to use to produce the UserContext.
|
||||
*
|
||||
* @return
|
||||
* A new UserContext instance for the user identified by the given
|
||||
* credentials, or null if the credentials are not valid.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs during authentication.
|
||||
*/
|
||||
public UserContext getUserContext(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Authenticate user
|
||||
MySQLUser user = userService.retrieveUser(credentials);
|
||||
if (user != null) {
|
||||
|
||||
// Upon successful authentication, return new user context
|
||||
MySQLUserContext context = userContextProvider.get();
|
||||
context.init(user.getCurrentUser());
|
||||
return context;
|
||||
|
||||
}
|
||||
|
||||
// Otherwise, unauthorized
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.Directory;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the User Directory.
|
||||
*
|
||||
* @author James Muehlner
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class UserDirectory implements Directory<User> {
|
||||
|
||||
/**
|
||||
* The user this user directory belongs to. Access is based on his/her
|
||||
* permission settings.
|
||||
*/
|
||||
private AuthenticatedUser currentUser;
|
||||
|
||||
/**
|
||||
* Service for managing user objects.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Set the user for this directory.
|
||||
*
|
||||
* @param currentUser
|
||||
* The user whose permissions define the visibility of other users in
|
||||
* this directory.
|
||||
*/
|
||||
public void init(AuthenticatedUser currentUser) {
|
||||
this.currentUser = currentUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User get(String identifier) throws GuacamoleException {
|
||||
return userService.retrieveObject(currentUser, identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<User> getAll(Collection<String> identifiers) throws GuacamoleException {
|
||||
Collection<MySQLUser> objects = userService.retrieveObjects(currentUser, identifiers);
|
||||
return Collections.<User>unmodifiableCollection(objects);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
return userService.getIdentifiers(currentUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void add(User object) throws GuacamoleException {
|
||||
userService.createObject(currentUser, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void update(User object) throws GuacamoleException {
|
||||
MySQLUser user = (MySQLUser) object;
|
||||
userService.updateObject(currentUser, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
userService.deleteObject(currentUser, identifier);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* Mapper for user objects.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public interface UserMapper extends DirectoryObjectMapper<UserModel> {
|
||||
|
||||
/**
|
||||
* Returns the user having the given username and password, if any. If no
|
||||
* such user exists, null is returned.
|
||||
*
|
||||
* @param username
|
||||
* The username of the user to return.
|
||||
*
|
||||
* @param password
|
||||
* The password of the user to return.
|
||||
*
|
||||
* @return
|
||||
* The user having the given username and password, or null if no such
|
||||
* user exists.
|
||||
*/
|
||||
UserModel selectByCredentials(@Param("username") String username,
|
||||
@Param("password") String password);
|
||||
|
||||
}
|
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.ObjectModel;
|
||||
|
||||
/**
|
||||
* Object representation of a Guacamole user, as represented in the database.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class UserModel extends ObjectModel {
|
||||
|
||||
/**
|
||||
* The SHA-256 hash of the password and salt.
|
||||
*/
|
||||
private byte[] passwordHash;
|
||||
|
||||
/**
|
||||
* The 32-byte random binary password salt that was appended to the
|
||||
* password prior to hashing.
|
||||
*/
|
||||
private byte[] passwordSalt;
|
||||
|
||||
/**
|
||||
* Creates a new, empty user.
|
||||
*/
|
||||
public UserModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash of this user's password and password salt. This may be
|
||||
* null if the user was not retrieved from the database, and setPassword()
|
||||
* has not yet been called.
|
||||
*
|
||||
* @return
|
||||
* The hash of this user's password and password salt.
|
||||
*/
|
||||
public byte[] getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hash of this user's password and password salt. This is
|
||||
* normally only set upon retrieval from the database, or through a call
|
||||
* to the higher-level setPassword() function.
|
||||
*
|
||||
* @param passwordHash
|
||||
* The hash of this user's password and password salt.
|
||||
*/
|
||||
public void setPasswordHash(byte[] passwordHash) {
|
||||
this.passwordHash = passwordHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the random salt that was used when generating this user's
|
||||
* password hash. This may be null if the user was not retrieved from the
|
||||
* database, and setPassword() has not yet been called.
|
||||
*
|
||||
* @return
|
||||
* The random salt that was used when generating this user's password
|
||||
* hash.
|
||||
*/
|
||||
public byte[] getPasswordSalt() {
|
||||
return passwordSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the random salt that was used when generating this user's password
|
||||
* hash. This is normally only set upon retrieval from the database, or
|
||||
* through a call to the higher-level setPassword() function.
|
||||
*
|
||||
* @param passwordSalt
|
||||
* The random salt used when generating this user's password hash.
|
||||
*/
|
||||
public void setPasswordSalt(byte[] passwordSalt) {
|
||||
this.passwordSalt = passwordSalt;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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.user;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import org.glyptodon.guacamole.net.auth.Credentials;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectMapper;
|
||||
import org.glyptodon.guacamole.auth.jdbc.base.DirectoryObjectService;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.net.auth.User;
|
||||
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
|
||||
import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating users.
|
||||
*
|
||||
* @author Michael Jumper, James Muehlner
|
||||
*/
|
||||
public class UserService extends DirectoryObjectService<MySQLUser, User, UserModel> {
|
||||
|
||||
/**
|
||||
* Mapper for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserMapper userMapper;
|
||||
|
||||
/**
|
||||
* Provider for creating users.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLUser> mySQLUserProvider;
|
||||
|
||||
@Override
|
||||
protected DirectoryObjectMapper<UserModel> getObjectMapper() {
|
||||
return userMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MySQLUser getObjectInstance(AuthenticatedUser currentUser,
|
||||
UserModel model) {
|
||||
MySQLUser user = mySQLUserProvider.get();
|
||||
user.init(currentUser, model);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserModel getModelInstance(AuthenticatedUser currentUser,
|
||||
final User object) {
|
||||
|
||||
// Create new MySQLUser backed by blank model
|
||||
UserModel model = new UserModel();
|
||||
MySQLUser user = getObjectInstance(currentUser, model);
|
||||
|
||||
// Set model contents through MySQLUser, copying the provided user
|
||||
user.setIdentifier(object.getIdentifier());
|
||||
user.setPassword(object.getPassword());
|
||||
|
||||
return model;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasCreatePermission(AuthenticatedUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Return whether user has explicit user creation permission
|
||||
SystemPermissionSet permissionSet = user.getUser().getSystemPermissions();
|
||||
return permissionSet.hasPermission(SystemPermission.Type.CREATE_USER);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectPermissionSet getPermissionSet(AuthenticatedUser user)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Return permissions related to users
|
||||
return user.getUser().getUserPermissions();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateNewObject(AuthenticatedUser user, User object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Username must not be blank
|
||||
if (object.getIdentifier().trim().isEmpty())
|
||||
throw new GuacamoleClientException("The username must not be blank.");
|
||||
|
||||
// Do not create duplicate users
|
||||
Collection<UserModel> existing = userMapper.select(Collections.singleton(object.getIdentifier()));
|
||||
if (!existing.isEmpty())
|
||||
throw new GuacamoleClientException("User \"" + object.getIdentifier() + "\" already exists.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateExistingObject(AuthenticatedUser user,
|
||||
MySQLUser object) throws GuacamoleException {
|
||||
|
||||
// Username must not be blank
|
||||
if (object.getIdentifier().trim().isEmpty())
|
||||
throw new GuacamoleClientException("The username must not be blank.");
|
||||
|
||||
// Check whether such a user is already present
|
||||
MySQLUser existing = retrieveObject(user, object.getIdentifier());
|
||||
if (existing != null) {
|
||||
|
||||
UserModel existingModel = existing.getModel();
|
||||
UserModel updatedModel = object.getModel();
|
||||
|
||||
// Do not rename to existing user
|
||||
if (!existingModel.getObjectID().equals(updatedModel.getObjectID()))
|
||||
throw new GuacamoleClientException("User \"" + object.getIdentifier() + "\" already exists.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the user corresponding to the given credentials from the
|
||||
* database.
|
||||
*
|
||||
* @param credentials The credentials to use when locating the user.
|
||||
* @return The existing MySQLUser object if the credentials given are
|
||||
* valid, null otherwise.
|
||||
*/
|
||||
public MySQLUser retrieveUser(Credentials credentials) {
|
||||
|
||||
// Get username and password
|
||||
String username = credentials.getUsername();
|
||||
String password = credentials.getPassword();
|
||||
|
||||
// Retrieve user model, if the user exists
|
||||
UserModel userModel = userMapper.selectByCredentials(username, password);
|
||||
if (userModel == null)
|
||||
return null;
|
||||
|
||||
// Return corresponding user, set up cyclic reference
|
||||
MySQLUser user = getObjectInstance(null, userModel);
|
||||
user.setCurrentUser(new AuthenticatedUser(user, credentials));
|
||||
return user;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to Guacamole users.
|
||||
*/
|
||||
package org.glyptodon.guacamole.auth.jdbc.user;
|
Reference in New Issue
Block a user