mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
Merge guacamole-auth-mysql as extension.
This commit is contained in:
2
extensions/guacamole-auth-mysql/.gitignore
vendored
Normal file
2
extensions/guacamole-auth-mysql/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
target/
|
||||
*~
|
171
extensions/guacamole-auth-mysql/README
Normal file
171
extensions/guacamole-auth-mysql/README
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
------------------------------------------------------------
|
||||
About this README
|
||||
------------------------------------------------------------
|
||||
|
||||
This README is intended to provide quick and to-the-point documentation for
|
||||
technical users intending to compile parts of Guacamole themselves.
|
||||
|
||||
Distribution-specific packages are available from the files section of the main
|
||||
project page:
|
||||
|
||||
http://sourceforge.net/projects/guacamole/files/
|
||||
|
||||
Distribution-specific documentation is provided on the Guacamole wiki:
|
||||
|
||||
http://guac-dev.org/
|
||||
|
||||
|
||||
------------------------------------------------------------
|
||||
What is guacamole-auth-mysql?
|
||||
------------------------------------------------------------
|
||||
|
||||
guacamole-auth-ldap is a Java library for use with the Guacamole web
|
||||
application to provide MySQL based authentication.
|
||||
|
||||
guacamole-auth-mysql provides an authentication provider which can be
|
||||
set in guacamole.properties to allow MySQL authentication of Guacamole
|
||||
users. Additional properties are required to configure the mysql
|
||||
connection parameters.
|
||||
|
||||
A schema file are provided to create the required tables in your
|
||||
mysql database.
|
||||
|
||||
|
||||
------------------------------------------------------------
|
||||
Compiling and installing guacamole-auth-mysql
|
||||
------------------------------------------------------------
|
||||
|
||||
guacamole-auth-mysql is built using Maven. Building guacamole-auth-mysql
|
||||
compiles all classes and packages them into a redistributable .jar file. This
|
||||
.jar file can be installed in the library directory configured in
|
||||
guacamole.properties such that the authentication provider is available.
|
||||
|
||||
1) Set up a MySQL database with the Guacamole schema.
|
||||
|
||||
When guacamole-auth-mysql is compiling, it needs to generate source
|
||||
based on a database schema. Because the source generator uses a
|
||||
connection to an actual database to do this, you must have a MySQL
|
||||
database running with the Guacamole schema set up.
|
||||
|
||||
First, create a database. For the sake of these instructions, we will
|
||||
call the database "guacamole", and will run all scripts as the root user:
|
||||
|
||||
$ mysql -u root -p
|
||||
Enter password:
|
||||
mysql> CREATE DATABASE guacamole;
|
||||
Query OK, 1 row affected (0.00 sec)
|
||||
|
||||
mysql> exit
|
||||
Bye
|
||||
|
||||
The schema files are in the schema/ subdirectory of the source. If run
|
||||
in order, they will create the schema and a default user:
|
||||
|
||||
$ cat schema/*.sql | mysql -u root -p guacamole
|
||||
|
||||
2) Set up your ~/.m2/settings.xml
|
||||
|
||||
Once the database is set up, Maven will need to have the credentials
|
||||
required to connect to it and query the schema. This information is
|
||||
specified in properties inside your ~/.m2/settings.xml file. If this
|
||||
file does not exist yet, simply create it.
|
||||
|
||||
For ease of compilation, we've included an example settings.xml
|
||||
defining the required properties in doc/example/settings.xml. You can
|
||||
simply copy this file into ~/.m2 and edit as necessary.
|
||||
|
||||
If you wish to write the file yourself, the file should look like this in
|
||||
general:
|
||||
|
||||
<settings>
|
||||
<profiles>
|
||||
...profiles...
|
||||
</profiles>
|
||||
</settings>
|
||||
|
||||
We need to add a profile which defines the required properties by
|
||||
placing a section like the following within the "profiles" section of your
|
||||
settings.xml:
|
||||
|
||||
<profile>
|
||||
<id>guacamole-mybatis</id>
|
||||
<properties>
|
||||
<guacamole.database.catalog>DATABASE</guacamole.database.catalog>
|
||||
<guacamole.database.user>USERNAME</guacamole.database.user>
|
||||
<guacamole.database.password>PASSWORD</guacamole.database.password>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
Obviously, the DATABASE, USERNAME, and PASSWORD placeholders above must
|
||||
be replaced with the appropriate values for your system.
|
||||
|
||||
Finally, to make the profile available to the build, it must be activated.
|
||||
Place a section like the following at the bottom of your settings.xml,
|
||||
right after the profiles section:
|
||||
|
||||
<activeProfiles>
|
||||
<activeProfile>guacamole-mybatis</activeProfile>
|
||||
</activeProfiles>
|
||||
|
||||
Maven's documentation has more details on writing the settings.xml file
|
||||
if you have different needs or the above directions are not clear.
|
||||
|
||||
3) Run mvn package
|
||||
|
||||
$ mvn package
|
||||
|
||||
Maven will download any needed dependencies for building the .jar file.
|
||||
Once all dependencies have been downloaded, the .jar file will be
|
||||
created in the target/ subdirectory of the current directory.
|
||||
|
||||
If this process fails, check the build errors, and verify that the
|
||||
contents of your settings.xml file is correct.
|
||||
|
||||
4) Extract the .tar.gz file now present in the target/ directory, and
|
||||
place the .jar files in the extracted lib/ subdirectory in the library
|
||||
directory specified in guacamole.properties.
|
||||
|
||||
You will likely need to do this as root.
|
||||
|
||||
If you do not have a library directory configured in your
|
||||
guacamole.properties, you will need to specify one. The directory
|
||||
is specified using the "lib-directory" property.
|
||||
|
||||
5) Set up your MySQL database to authenticate Guacamole users
|
||||
|
||||
A schema file is provided in the schema directory for creating
|
||||
the guacamole authentication tables in your MySQL database.
|
||||
|
||||
Additionally, a script is provided to create a default admin user
|
||||
with username 'guacadmin' and password 'guacadmin'. This user can
|
||||
be used to set up any other connections and users.
|
||||
|
||||
6) Configure guacamole.properties for MySQL
|
||||
|
||||
There are additional properties required by the MySQL JDBC driver
|
||||
which must be added/changed in your guacamole.properties:
|
||||
|
||||
# Configuration for MySQL connection
|
||||
mysql-hostname: mysql.host.name
|
||||
mysql-port: 3306
|
||||
mysql-database: guacamole.database.name
|
||||
mysql-username: user
|
||||
mysql-password: pass
|
||||
|
||||
Optionally, the authentication provider can be configured
|
||||
not to allow multiple users to use the same connection
|
||||
at the same time:
|
||||
|
||||
mysql-disallow-simultaneous-connections: true
|
||||
|
||||
|
||||
------------------------------------------------------------
|
||||
Reporting problems
|
||||
------------------------------------------------------------
|
||||
|
||||
Please report any bugs encountered by opening a new ticket at the Trac system
|
||||
hosted at:
|
||||
|
||||
http://guac-dev.org/trac/
|
||||
|
21
extensions/guacamole-auth-mysql/doc/example/settings.xml
Normal file
21
extensions/guacamole-auth-mysql/doc/example/settings.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<settings>
|
||||
|
||||
<!-- Profile defining the properties required for a MyBatis build -->
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>guacamole-mybatis</id>
|
||||
<properties>
|
||||
<guacamole.database.catalog>SCHEMA</guacamole.database.catalog>
|
||||
<guacamole.database.schema>DATABASE</guacamole.database.schema>
|
||||
<guacamole.database.user>USER</guacamole.database.user>
|
||||
<guacamole.database.password>PASS</guacamole.database.password>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<!-- Activate by default -->
|
||||
<activeProfiles>
|
||||
<activeProfile>guacamole-mybatis</activeProfile>
|
||||
</activeProfiles>
|
||||
|
||||
</settings>
|
141
extensions/guacamole-auth-mysql/pom.xml
Normal file
141
extensions/guacamole-auth-mysql/pom.xml
Normal file
@@ -0,0 +1,141 @@
|
||||
<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>net.sourceforge.guacamole</groupId>
|
||||
<artifactId>guacamole-auth-mysql</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>0.8.0</version>
|
||||
<name>guacamole-auth-mysql</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>
|
||||
|
||||
<!-- Assembly plugin - for easy distribution -->
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2-beta-5</version>
|
||||
<configuration>
|
||||
<finalName>${project.artifactId}-${project.version}</finalName>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/dist.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-dist-archive</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- MyBatis Generator plugin -->
|
||||
<plugin>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
||||
<version>1.3.2</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>Generate MyBatis Artifacts</id>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
<!-- MySQL Connector -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.23</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Guacamole Java API -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.guacamole</groupId>
|
||||
<artifactId>guacamole-common</artifactId>
|
||||
<version>0.8.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Guacamole Extension API -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.guacamole</groupId>
|
||||
<artifactId>guacamole-ext</artifactId>
|
||||
<version>0.8.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SLF4J - logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jcl</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis Guice -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-guice</artifactId>
|
||||
<version>3.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Google Collections -->
|
||||
<dependency>
|
||||
<groupId>com.google.collections</groupId>
|
||||
<artifactId>google-collections</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
|
||||
<!-- Central Guacamole repository -->
|
||||
<repository>
|
||||
<id>guac-dev</id>
|
||||
<url>http://guac-dev.org/repo</url>
|
||||
</repository>
|
||||
|
||||
</repositories>
|
||||
|
||||
</project>
|
153
extensions/guacamole-auth-mysql/schema/001-create-schema.sql
Normal file
153
extensions/guacamole-auth-mysql/schema/001-create-schema.sql
Normal file
@@ -0,0 +1,153 @@
|
||||
|
||||
--
|
||||
-- Table of connections. Each connection has a name, protocol, and
|
||||
-- associated set of parameters.
|
||||
--
|
||||
|
||||
CREATE TABLE `guacamole_connection` (
|
||||
|
||||
`connection_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`connection_name` varchar(128) NOT NULL,
|
||||
`protocol` varchar(32) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`connection_id`),
|
||||
UNIQUE KEY `connection_name` (`connection_name`)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of users. Each user has a unique username and a hashed password
|
||||
-- with corresponding salt.
|
||||
--
|
||||
|
||||
CREATE TABLE `guacamole_user` (
|
||||
|
||||
`user_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(128) NOT NULL,
|
||||
`password_hash` binary(32) NOT NULL,
|
||||
`password_salt` binary(32) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`user_id`),
|
||||
UNIQUE KEY `username` (`username`)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of connection parameters. Each parameter is simply a name/value pair
|
||||
-- associated with a connection.
|
||||
--
|
||||
|
||||
CREATE TABLE `guacamole_connection_parameter` (
|
||||
|
||||
`connection_id` int(11) NOT NULL,
|
||||
`parameter_name` varchar(128) NOT NULL,
|
||||
`parameter_value` varchar(4096) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`connection_id`,`parameter_name`),
|
||||
|
||||
CONSTRAINT `guacamole_connection_parameter_ibfk_1`
|
||||
FOREIGN KEY (`connection_id`)
|
||||
REFERENCES `guacamole_connection` (`connection_id`) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of connection permissions. Each connection permission grants a user
|
||||
-- specific access to a connection.
|
||||
--
|
||||
|
||||
CREATE TABLE `guacamole_connection_permission` (
|
||||
|
||||
`user_id` int(11) NOT NULL,
|
||||
`connection_id` int(11) NOT NULL,
|
||||
`permission` enum('READ',
|
||||
'UPDATE',
|
||||
'DELETE',
|
||||
'ADMINISTER') NOT NULL,
|
||||
|
||||
PRIMARY KEY (`user_id`,`connection_id`,`permission`),
|
||||
|
||||
CONSTRAINT `guacamole_connection_permission_ibfk_1`
|
||||
FOREIGN KEY (`connection_id`)
|
||||
REFERENCES `guacamole_connection` (`connection_id`) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT `guacamole_connection_permission_ibfk_2`
|
||||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of system permissions. Each system permission grants a user a
|
||||
-- system-level privilege of some kind.
|
||||
--
|
||||
|
||||
CREATE TABLE `guacamole_system_permission` (
|
||||
|
||||
`user_id` int(11) NOT NULL,
|
||||
`permission` enum('CREATE_CONNECTION',
|
||||
'CREATE_USER',
|
||||
'ADMINISTER') NOT NULL,
|
||||
|
||||
PRIMARY KEY (`user_id`,`permission`),
|
||||
|
||||
CONSTRAINT `guacamole_system_permission_ibfk_1`
|
||||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of user permissions. Each user permission grants a user access to
|
||||
-- another user (the "affected" user) for a specific type of operation.
|
||||
--
|
||||
|
||||
CREATE TABLE `guacamole_user_permission` (
|
||||
|
||||
`user_id` int(11) NOT NULL,
|
||||
`affected_user_id` int(11) NOT NULL,
|
||||
`permission` enum('READ',
|
||||
'UPDATE',
|
||||
'DELETE',
|
||||
'ADMINISTER') NOT NULL,
|
||||
|
||||
PRIMARY KEY (`user_id`,`affected_user_id`,`permission`),
|
||||
|
||||
CONSTRAINT `guacamole_user_permission_ibfk_1`
|
||||
FOREIGN KEY (`affected_user_id`)
|
||||
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT `guacamole_user_permission_ibfk_2`
|
||||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table of connection history records. Each record defines a specific user's
|
||||
-- session, including the connection used, the start time, and the end time
|
||||
-- (if any).
|
||||
--
|
||||
|
||||
CREATE TABLE `guacamole_connection_history` (
|
||||
|
||||
`history_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`connection_id` int(11) NOT NULL,
|
||||
`start_date` datetime NOT NULL,
|
||||
`end_date` datetime DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (`history_id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `connection_id` (`connection_id`),
|
||||
|
||||
CONSTRAINT `guacamole_connection_history_ibfk_1`
|
||||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE,
|
||||
|
||||
CONSTRAINT `guacamole_connection_history_ibfk_2`
|
||||
FOREIGN KEY (`connection_id`)
|
||||
REFERENCES `guacamole_connection` (`connection_id`) ON DELETE CASCADE
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
@@ -0,0 +1,16 @@
|
||||
|
||||
-- Create default user "guacadmin" with password "guacadmin"
|
||||
insert into guacamole_user values(1, 'guacadmin',
|
||||
x'CA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960', -- 'guacadmin'
|
||||
x'FE24ADC5E11E2B25288D1704ABE67A79E342ECC26064CE69C5B3177795A82264');
|
||||
|
||||
-- Grant this user create permissions
|
||||
insert into guacamole_system_permission values(1, 'CREATE_CONNECTION');
|
||||
insert into guacamole_system_permission values(1, 'CREATE_USER');
|
||||
insert into guacamole_system_permission values(1, 'ADMINISTER');
|
||||
|
||||
-- Grant admin permission to read/update/administer self
|
||||
insert into guacamole_user_permission values(1, 1, 'READ');
|
||||
insert into guacamole_user_permission values(1, 1, 'UPDATE');
|
||||
insert into guacamole_user_permission values(1, 1, 'ADMINISTER');
|
||||
|
54
extensions/guacamole-auth-mysql/src/main/assembly/dist.xml
Normal file
54
extensions/guacamole-auth-mysql/src/main/assembly/dist.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
|
||||
<id>dist</id>
|
||||
<baseDirectory>${project.artifactId}-${project.version}</baseDirectory>
|
||||
|
||||
<!-- Output tar.gz -->
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
|
||||
<!-- Include docs and schema -->
|
||||
<fileSets>
|
||||
|
||||
<!-- Include docs -->
|
||||
<fileSet>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<directory>doc</directory>
|
||||
</fileSet>
|
||||
|
||||
<!-- Include schema -->
|
||||
<fileSet>
|
||||
<outputDirectory>/schema</outputDirectory>
|
||||
<directory>schema</directory>
|
||||
</fileSet>
|
||||
|
||||
</fileSets>
|
||||
|
||||
<!-- Include self and all dependencies except guacamole-common
|
||||
and guacamole-ext -->
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
|
||||
<outputDirectory>/lib</outputDirectory>
|
||||
<scope>runtime</scope>
|
||||
<unpack>false</unpack>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
|
||||
<excludes>
|
||||
|
||||
<!-- Do not include guacamole-common -->
|
||||
<exclude>net.sourceforge.guacamole:guacamole-common</exclude>
|
||||
|
||||
<!-- Do not include guacamole-ext -->
|
||||
<exclude>net.sourceforge.guacamole:guacamole-ext</exclude>
|
||||
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
</assembly>
|
@@ -0,0 +1,121 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
||||
|
||||
/**
|
||||
* Represents the set of currently active Connections. Whenever a socket is
|
||||
* opened, the connection ID should be added to this set, and whenever a socket
|
||||
* is closed, the connection ID should be removed from this set.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ActiveConnectionSet {
|
||||
|
||||
/**
|
||||
* DAO for accessing connection history.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionHistoryMapper connectionHistoryDAO;
|
||||
|
||||
/**
|
||||
* Set of all the connections that are currently active.
|
||||
*/
|
||||
private Set<Integer> activeConnectionSet = new HashSet<Integer>();
|
||||
|
||||
/**
|
||||
* Check if a connection is currently in use.
|
||||
* @param connectionID The connection to check the status of.
|
||||
* @return true if the connection is currently in use.
|
||||
*/
|
||||
public boolean isActive(int connectionID) {
|
||||
return activeConnectionSet.contains(connectionID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a connection as open.
|
||||
* @param connectionID The ID of the connection that is being opened.
|
||||
* @param userID The ID of the user who is opening the connection.
|
||||
* @return The ID of the history record created for this open connection.
|
||||
*/
|
||||
public int openConnection(int connectionID, int userID) {
|
||||
|
||||
// Create the connection history record
|
||||
ConnectionHistory connectionHistory = new ConnectionHistory();
|
||||
connectionHistory.setConnection_id(connectionID);
|
||||
connectionHistory.setUser_id(userID);
|
||||
connectionHistory.setStart_date(new Date());
|
||||
connectionHistoryDAO.insert(connectionHistory);
|
||||
|
||||
// Mark the connection as active
|
||||
activeConnectionSet.add(connectionID);
|
||||
|
||||
return connectionHistory.getHistory_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a connection as closed.
|
||||
* @param connectionID The ID of the connection that is being opened.
|
||||
* @param historyID The ID of the history record about the open connection.
|
||||
* @throws GuacamoleException If the open connection history is not found.
|
||||
*/
|
||||
public void closeConnection(int connectionID, int historyID)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get the existing history record
|
||||
ConnectionHistory connectionHistory =
|
||||
connectionHistoryDAO.selectByPrimaryKey(historyID);
|
||||
|
||||
if(connectionHistory == null)
|
||||
throw new GuacamoleException("History record not found.");
|
||||
|
||||
// Update the connection history record to mark that it is now closed
|
||||
connectionHistory.setEnd_date(new Date());
|
||||
connectionHistoryDAO.updateByPrimaryKey(connectionHistory);
|
||||
|
||||
// Remove the connection from the set of active connections.
|
||||
activeConnectionSet.remove(connectionID);
|
||||
}
|
||||
}
|
@@ -0,0 +1,254 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleClientException;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.Connection;
|
||||
import net.sourceforge.guacamole.net.auth.Directory;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionParameterMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL-based implementation of the connection directory.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class ConnectionDirectory implements Directory<String, Connection>{
|
||||
|
||||
/**
|
||||
* The ID of the user who this connection directory belongs to.
|
||||
* Access is based on his/her permission settings.
|
||||
*/
|
||||
private int user_id;
|
||||
|
||||
/**
|
||||
* Service for checking permissions.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Service managing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Service for manipulating connection permissions in the database.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionPermissionMapper connectionPermissionDAO;
|
||||
|
||||
/**
|
||||
* Service for manipulating connection parameters in the database.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionParameterMapper connectionParameterDAO;
|
||||
|
||||
/**
|
||||
* Set the user for this directory.
|
||||
*
|
||||
* @param user_id The ID of the user owning this connection directory.
|
||||
*/
|
||||
public void init(int user_id) {
|
||||
this.user_id = user_id;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Connection get(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get connection
|
||||
MySQLConnection connection =
|
||||
connectionService.retrieveConnection(identifier, user_id);
|
||||
|
||||
// Verify access is granted
|
||||
permissionCheckService.verifyConnectionAccess(
|
||||
this.user_id,
|
||||
connection.getConnectionID(),
|
||||
MySQLConstants.CONNECTION_READ);
|
||||
|
||||
// Return connection
|
||||
return connection;
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
return permissionCheckService.retrieveConnectionNames(user_id,
|
||||
MySQLConstants.CONNECTION_READ);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void add(Connection object) throws GuacamoleException {
|
||||
|
||||
String identifier = object.getIdentifier().trim();
|
||||
if(identifier.isEmpty())
|
||||
throw new GuacamoleClientException("The connection identifier cannot be blank.");
|
||||
|
||||
// Verify permission to create
|
||||
permissionCheckService.verifySystemAccess(this.user_id,
|
||||
MySQLConstants.SYSTEM_CONNECTION_CREATE);
|
||||
|
||||
// Verify that no connection already exists with this identifier.
|
||||
MySQLConnection previousConnection =
|
||||
connectionService.retrieveConnection(identifier, user_id);
|
||||
if(previousConnection != null)
|
||||
throw new GuacamoleClientException("That connection identifier is already in use.");
|
||||
|
||||
// Create connection
|
||||
MySQLConnection connection = connectionService.createConnection(
|
||||
identifier, object.getConfiguration().getProtocol(),
|
||||
user_id);
|
||||
|
||||
// Add connection parameters
|
||||
createConfigurationValues(connection.getConnectionID(),
|
||||
object.getConfiguration());
|
||||
|
||||
// Finally, give the current user full access to the newly created
|
||||
// connection.
|
||||
ConnectionPermissionKey newConnectionPermission = new ConnectionPermissionKey();
|
||||
newConnectionPermission.setUser_id(this.user_id);
|
||||
newConnectionPermission.setConnection_id(connection.getConnectionID());
|
||||
|
||||
// Read permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_READ);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
// Update permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_UPDATE);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
// Delete permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_DELETE);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
// Administer permission
|
||||
newConnectionPermission.setPermission(MySQLConstants.CONNECTION_ADMINISTER);
|
||||
connectionPermissionDAO.insert(newConnectionPermission);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts all parameter values from the given configuration into the
|
||||
* database, associating them with the connection having the givenID.
|
||||
*
|
||||
* @param connection_id The ID of the connection to associate all
|
||||
* parameters with.
|
||||
* @param config The GuacamoleConfiguration to read parameters from.
|
||||
*/
|
||||
private void createConfigurationValues(int connection_id,
|
||||
GuacamoleConfiguration config) {
|
||||
|
||||
// Insert new parameters for each parameter in the config
|
||||
for (String name : config.getParameterNames()) {
|
||||
|
||||
// Create a ConnectionParameter based on the current parameter
|
||||
ConnectionParameter parameter = new ConnectionParameter();
|
||||
parameter.setConnection_id(connection_id);
|
||||
parameter.setParameter_name(name);
|
||||
parameter.setParameter_value(config.getParameter(name));
|
||||
|
||||
// Insert connection parameter
|
||||
connectionParameterDAO.insert(parameter);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void update(Connection object) throws GuacamoleException {
|
||||
|
||||
// If connection not actually from this auth provider, we can't handle
|
||||
// the update
|
||||
if (!(object instanceof MySQLConnection))
|
||||
throw new GuacamoleException("Connection not from database.");
|
||||
|
||||
MySQLConnection mySQLConnection = (MySQLConnection) object;
|
||||
|
||||
// Verify permission to update
|
||||
permissionCheckService.verifyConnectionAccess(this.user_id,
|
||||
mySQLConnection.getConnectionID(),
|
||||
MySQLConstants.CONNECTION_UPDATE);
|
||||
|
||||
// Perform update
|
||||
connectionService.updateConnection(mySQLConnection);
|
||||
|
||||
// Delete old connection parameters
|
||||
ConnectionParameterExample parameterExample = new ConnectionParameterExample();
|
||||
parameterExample.createCriteria().andConnection_idEqualTo(mySQLConnection.getConnectionID());
|
||||
connectionParameterDAO.deleteByExample(parameterExample);
|
||||
|
||||
// Add connection parameters
|
||||
createConfigurationValues(mySQLConnection.getConnectionID(),
|
||||
object.getConfiguration());
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get connection
|
||||
MySQLConnection mySQLConnection =
|
||||
connectionService.retrieveConnection(identifier, user_id);
|
||||
|
||||
// Verify permission to delete
|
||||
permissionCheckService.verifyConnectionAccess(this.user_id,
|
||||
mySQLConnection.getConnectionID(),
|
||||
MySQLConstants.CONNECTION_DELETE);
|
||||
|
||||
// Delete the connection itself
|
||||
connectionService.deleteConnection(mySQLConnection.getConnectionID());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,177 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.name.Names;
|
||||
import java.util.Properties;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.AuthenticationProvider;
|
||||
import net.sourceforge.guacamole.net.auth.Credentials;
|
||||
import net.sourceforge.guacamole.net.auth.UserContext;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionParameterMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PasswordEncryptionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.SaltService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.SecureRandomSaltService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.SHA256PasswordEncryptionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||
import net.sourceforge.guacamole.properties.GuacamoleProperties;
|
||||
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
||||
import org.mybatis.guice.MyBatisModule;
|
||||
import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider;
|
||||
import org.mybatis.guice.datasource.helper.JdbcHelper;
|
||||
|
||||
/**
|
||||
* Provides a MySQL based implementation of the AuthenticationProvider
|
||||
* functionality.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
/**
|
||||
* Set of all active connections.
|
||||
*/
|
||||
private ActiveConnectionSet activeConnectionSet = new ActiveConnectionSet();
|
||||
|
||||
/**
|
||||
* Injector which will manage the object graph of this authentication
|
||||
* provider.
|
||||
*/
|
||||
private Injector injector;
|
||||
|
||||
@Override
|
||||
public UserContext getUserContext(Credentials credentials) throws GuacamoleException {
|
||||
|
||||
// Get user service
|
||||
UserService userService = injector.getInstance(UserService.class);
|
||||
|
||||
// Get user
|
||||
MySQLUser authenticatedUser = userService.retrieveUser(credentials);
|
||||
if (authenticatedUser != null) {
|
||||
MySQLUserContext context = injector.getInstance(MySQLUserContext.class);
|
||||
context.init(authenticatedUser.getUserID());
|
||||
return context;
|
||||
}
|
||||
|
||||
// Otherwise, unauthorized
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new MySQLAuthenticationProvider that reads and writes
|
||||
* authentication data to a MySQL database defined by properties in
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException If a required property is missing, or
|
||||
* an error occurs while parsing a property.
|
||||
*/
|
||||
public MySQLAuthenticationProvider() throws GuacamoleException {
|
||||
|
||||
final Properties myBatisProperties = new Properties();
|
||||
|
||||
// Set the mysql properties for MyBatis.
|
||||
myBatisProperties.setProperty("mybatis.environment.id", "guacamole");
|
||||
myBatisProperties.setProperty("JDBC.host", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_HOSTNAME));
|
||||
myBatisProperties.setProperty("JDBC.port", String.valueOf(GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_PORT)));
|
||||
myBatisProperties.setProperty("JDBC.schema", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_DATABASE));
|
||||
myBatisProperties.setProperty("JDBC.username", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_USERNAME));
|
||||
myBatisProperties.setProperty("JDBC.password", GuacamoleProperties.getRequiredProperty(MySQLGuacamoleProperties.MYSQL_PASSWORD));
|
||||
myBatisProperties.setProperty("JDBC.autoCommit", "false");
|
||||
|
||||
// Set up Guice injector.
|
||||
injector = Guice.createInjector(
|
||||
JdbcHelper.MySQL,
|
||||
|
||||
new Module() {
|
||||
@Override
|
||||
public void configure(Binder binder) {
|
||||
Names.bindProperties(binder, myBatisProperties);
|
||||
}
|
||||
},
|
||||
|
||||
new MyBatisModule() {
|
||||
@Override
|
||||
protected void initialize() {
|
||||
|
||||
// Datasource
|
||||
bindDataSourceProviderType(PooledDataSourceProvider.class);
|
||||
|
||||
// Transaction factory
|
||||
bindTransactionFactoryType(JdbcTransactionFactory.class);
|
||||
|
||||
// Add MyBatis mappers
|
||||
addMapperClass(ConnectionHistoryMapper.class);
|
||||
addMapperClass(ConnectionMapper.class);
|
||||
addMapperClass(ConnectionParameterMapper.class);
|
||||
addMapperClass(ConnectionPermissionMapper.class);
|
||||
addMapperClass(SystemPermissionMapper.class);
|
||||
addMapperClass(UserMapper.class);
|
||||
addMapperClass(UserPermissionMapper.class);
|
||||
|
||||
// Bind interfaces
|
||||
bind(MySQLUserContext.class);
|
||||
bind(UserDirectory.class);
|
||||
bind(MySQLUser.class);
|
||||
bind(SaltService.class).to(SecureRandomSaltService.class);
|
||||
bind(PasswordEncryptionService.class).to(SHA256PasswordEncryptionService.class);
|
||||
bind(PermissionCheckService.class);
|
||||
bind(ConnectionService.class);
|
||||
bind(UserService.class);
|
||||
bind(ActiveConnectionSet.class).toInstance(activeConnectionSet);
|
||||
|
||||
}
|
||||
} // end of mybatis module
|
||||
|
||||
);
|
||||
} // end of constructor
|
||||
|
||||
}
|
@@ -0,0 +1,132 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.AbstractConnection;
|
||||
import net.sourceforge.guacamole.net.auth.ConnectionRecord;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the Connection object.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLConnection extends AbstractConnection {
|
||||
|
||||
/**
|
||||
* The ID associated with this connection in the database.
|
||||
*/
|
||||
private Integer connectionID;
|
||||
|
||||
/**
|
||||
* The ID of the user who queried or created this connection.
|
||||
*/
|
||||
private int userID;
|
||||
|
||||
/**
|
||||
* History of this connection.
|
||||
*/
|
||||
private List<ConnectionRecord> history = new ArrayList<ConnectionRecord>();
|
||||
|
||||
/**
|
||||
* Service for managing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* Create a default, empty connection.
|
||||
*/
|
||||
public MySQLConnection() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the corresponding connection record.
|
||||
* @return The ID of the corresponding connection, if any.
|
||||
*/
|
||||
public Integer getConnectionID() {
|
||||
return connectionID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of the corresponding connection record.
|
||||
* @param connectionID The ID to assign to this connection.
|
||||
*/
|
||||
public void setConnectionID(Integer connectionID) {
|
||||
this.connectionID = connectionID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize from explicit values.
|
||||
*
|
||||
* @param connectionID The ID of the associated database record, if any.
|
||||
* @param identifier The unique identifier associated with this connection.
|
||||
* @param config The GuacamoleConfiguration associated with this connection.
|
||||
* @param history All ConnectionRecords associated with this connection.
|
||||
* @param userID The IID of the user who queried this connection.
|
||||
*/
|
||||
public void init(Integer connectionID, String identifier,
|
||||
GuacamoleConfiguration config,
|
||||
List<? extends ConnectionRecord> history, int userID) {
|
||||
|
||||
this.connectionID = connectionID;
|
||||
setIdentifier(identifier);
|
||||
setConfiguration(config);
|
||||
this.history.addAll(history);
|
||||
this.userID = userID;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleSocket connect(GuacamoleClientInformation info) throws GuacamoleException {
|
||||
return connectionService.connect(this, info, userID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends ConnectionRecord> getHistory() throws GuacamoleException {
|
||||
return Collections.unmodifiableList(history);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import java.util.Date;
|
||||
import net.sourceforge.guacamole.net.auth.ConnectionRecord;
|
||||
|
||||
/**
|
||||
* A ConnectionRecord which is based on data stored in MySQL.
|
||||
*
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLConnectionRecord implements ConnectionRecord {
|
||||
|
||||
/**
|
||||
* The start date of the ConnectionRecord.
|
||||
*/
|
||||
private Date startDate;
|
||||
|
||||
/**
|
||||
* The end date of the ConnectionRecord.
|
||||
*/
|
||||
private Date endDate;
|
||||
|
||||
/**
|
||||
* The name of the user that is associated with this ConnectionRecord.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Initialize this MySQLConnectionRecord with the start/end dates,
|
||||
* and the name of the user it represents.
|
||||
*
|
||||
* @param startDate The start date of the connection history.
|
||||
* @param endDate The end date of the connection history.
|
||||
* @param username The name of the user that used the connection.
|
||||
*/
|
||||
public MySQLConnectionRecord(Date startDate, Date endDate,
|
||||
String username) {
|
||||
if (startDate != null) this.startDate = new Date(startDate.getTime());
|
||||
if (endDate != null) this.endDate = new Date(endDate.getTime());
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getStartDate() {
|
||||
if (startDate == null) return null;
|
||||
return new Date(startDate.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getEndDate() {
|
||||
if (endDate == null) return null;
|
||||
return new Date(endDate.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
// If the end date hasn't been stored yet, the connection is still open.
|
||||
return endDate == null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,186 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
import net.sourceforge.guacamole.net.auth.permission.ObjectPermission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* A set of constants that are useful for the MySQL-based authentication provider.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public final class MySQLConstants {
|
||||
|
||||
/**
|
||||
* This class should not be instantiated.
|
||||
*/
|
||||
private MySQLConstants() {}
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent READ access to a user.
|
||||
*/
|
||||
public static final String USER_READ = "READ";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent UPDATE access to a user.
|
||||
*/
|
||||
public static final String USER_UPDATE = "UPDATE";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent DELETE access to a user.
|
||||
*/
|
||||
public static final String USER_DELETE = "DELETE";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent ADMINISTER access to a
|
||||
* user.
|
||||
*/
|
||||
public static final String USER_ADMINISTER = "ADMINISTER";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent READ access to a
|
||||
* connection.
|
||||
*/
|
||||
public static final String CONNECTION_READ = "READ";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent UPDATE access to a
|
||||
* connection.
|
||||
*/
|
||||
public static final String CONNECTION_UPDATE = "UPDATE";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent DELETE access to a
|
||||
* connection.
|
||||
*/
|
||||
public static final String CONNECTION_DELETE = "DELETE";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent ADMINISTER access to a
|
||||
* connection.
|
||||
*/
|
||||
public static final String CONNECTION_ADMINISTER = "ADMINISTER";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent permission to create
|
||||
* users.
|
||||
*/
|
||||
public static final String SYSTEM_USER_CREATE = "CREATE_USER";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent permission to create
|
||||
* connections.
|
||||
*/
|
||||
public static final String SYSTEM_CONNECTION_CREATE = "CREATE_CONNECTION";
|
||||
|
||||
/**
|
||||
* The string stored in the database to represent permission to administer
|
||||
* the system as a whole.
|
||||
*/
|
||||
public static final String SYSTEM_ADMINISTER = "ADMINISTER";
|
||||
|
||||
/**
|
||||
* Given the type of a permission affecting a user, returns the MySQL
|
||||
* constant representing that permission type.
|
||||
*
|
||||
* @param type The type of permission to look up.
|
||||
* @return The MySQL constant corresponding to the given permission type.
|
||||
*/
|
||||
public static String getUserConstant(ObjectPermission.Type type) {
|
||||
|
||||
// Convert permission type to MySQL constant
|
||||
switch (type) {
|
||||
case READ: return USER_READ;
|
||||
case UPDATE: return USER_UPDATE;
|
||||
case ADMINISTER: return USER_ADMINISTER;
|
||||
case DELETE: return USER_DELETE;
|
||||
}
|
||||
|
||||
// If we get here, permission support was not properly implemented
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported permission type: " + type);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the type of a permission affecting a connection, returns the MySQL
|
||||
* constant representing that permission type.
|
||||
*
|
||||
* @param type The type of permission to look up.
|
||||
* @return The MySQL constant corresponding to the given permission type.
|
||||
*/
|
||||
public static String getConnectionConstant(ObjectPermission.Type type) {
|
||||
|
||||
// Convert permission type to MySQL constant
|
||||
switch (type) {
|
||||
case READ: return CONNECTION_READ;
|
||||
case UPDATE: return CONNECTION_UPDATE;
|
||||
case ADMINISTER: return CONNECTION_ADMINISTER;
|
||||
case DELETE: return CONNECTION_DELETE;
|
||||
}
|
||||
|
||||
// If we get here, permission support was not properly implemented
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported permission type: " + type);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given the type of a permission affecting the system, returns the MySQL
|
||||
* constant representing that permission type.
|
||||
*
|
||||
* @param type The type of permission to look up.
|
||||
* @return The MySQL constant corresponding to the given permission type.
|
||||
*/
|
||||
public static String getSystemConstant(SystemPermission.Type type) {
|
||||
|
||||
// Convert permission type to MySQL constant
|
||||
switch (type) {
|
||||
case CREATE_USER: return SYSTEM_USER_CREATE;
|
||||
case CREATE_CONNECTION: return SYSTEM_CONNECTION_CREATE;
|
||||
case ADMINISTER: return SYSTEM_ADMINISTER;
|
||||
}
|
||||
|
||||
// If we get here, permission support was not properly implemented
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported permission type: " + type);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.io.GuacamoleReader;
|
||||
import net.sourceforge.guacamole.io.GuacamoleWriter;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
||||
|
||||
/**
|
||||
* A MySQL specific wrapper around a ConfiguredGuacamoleSocket.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLGuacamoleSocket implements GuacamoleSocket {
|
||||
|
||||
/**
|
||||
* Injected ActiveConnectionSet which will contain all active connections.
|
||||
*/
|
||||
@Inject
|
||||
private ActiveConnectionSet activeConnectionSet;
|
||||
|
||||
/**
|
||||
* The wrapped socket.
|
||||
*/
|
||||
private GuacamoleSocket socket;
|
||||
|
||||
/**
|
||||
* The ID associated with the connection associated with the wrapped
|
||||
* socket.
|
||||
*/
|
||||
private int connectionID;
|
||||
|
||||
/**
|
||||
* The ID of the history record associated with this instance of the
|
||||
* connection.
|
||||
*/
|
||||
private int historyID;
|
||||
|
||||
/**
|
||||
* Initialize this MySQLGuacamoleSocket with the provided GuacamoleSocket.
|
||||
*
|
||||
* @param socket The ConfiguredGuacamoleSocket to wrap.
|
||||
* @param connectionID The ID of the connection associated with the given
|
||||
* socket.
|
||||
* @param historyID The ID of the history record associated with this
|
||||
* instance of the connection.
|
||||
*/
|
||||
public void init(GuacamoleSocket socket, int connectionID, int historyID) {
|
||||
this.socket = socket;
|
||||
this.connectionID = connectionID;
|
||||
this.historyID = historyID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleReader getReader() {
|
||||
return socket.getReader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleWriter getWriter() {
|
||||
return socket.getWriter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws GuacamoleException {
|
||||
|
||||
// Close socket
|
||||
socket.close();
|
||||
|
||||
// Mark this connection as inactive
|
||||
activeConnectionSet.closeConnection(connectionID, historyID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return socket.isOpen();
|
||||
}
|
||||
}
|
@@ -0,0 +1,193 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.AbstractUser;
|
||||
import net.sourceforge.guacamole.net.auth.User;
|
||||
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the User object.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLUser extends AbstractUser {
|
||||
|
||||
/**
|
||||
* The ID of this user in the database, if any.
|
||||
*/
|
||||
private Integer userID;
|
||||
|
||||
/**
|
||||
* The set of current permissions a user has.
|
||||
*/
|
||||
private Set<Permission> permissions = new HashSet<Permission>();
|
||||
|
||||
/**
|
||||
* Any newly added permissions that have yet to be committed.
|
||||
*/
|
||||
private Set<Permission> newPermissions = new HashSet<Permission>();
|
||||
|
||||
/**
|
||||
* Any newly deleted permissions that have yet to be deleted.
|
||||
*/
|
||||
private Set<Permission> removedPermissions = new HashSet<Permission>();
|
||||
|
||||
/**
|
||||
* Creates a new, empty MySQLUser.
|
||||
*/
|
||||
public MySQLUser() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new MySQLUser having the given username.
|
||||
*
|
||||
* @param name The name to assign to this MySQLUser.
|
||||
*/
|
||||
public void init(String name) {
|
||||
init(null, name, null, Collections.EMPTY_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new MySQLUser, copying all data from the given user
|
||||
* object.
|
||||
*
|
||||
* @param user The user object to copy.
|
||||
* @throws GuacamoleException If an error occurs while reading the user
|
||||
* data in the given object.
|
||||
*/
|
||||
public void init(User user) throws GuacamoleException {
|
||||
init(null, user.getUsername(), user.getPassword(), user.getPermissions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new MySQLUser initialized from the given data from the
|
||||
* database.
|
||||
*
|
||||
* @param userID The ID of the user in the database, if any.
|
||||
* @param username The username of this user.
|
||||
* @param password The password to assign to this user.
|
||||
* @param permissions The permissions to assign to this user, as
|
||||
* retrieved from the database.
|
||||
*/
|
||||
public void init(Integer userID, String username, String password,
|
||||
Set<Permission> permissions) {
|
||||
this.userID = userID;
|
||||
setUsername(username);
|
||||
setPassword(password);
|
||||
this.permissions.addAll(permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current set of permissions this user has.
|
||||
* @return the current set of permissions.
|
||||
*/
|
||||
public Set<Permission> getCurrentPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any new permissions that have yet to be inserted.
|
||||
* @return the new set of permissions.
|
||||
*/
|
||||
public Set<Permission> getNewPermissions() {
|
||||
return newPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any permissions that have not yet been deleted.
|
||||
* @return the permissions that need to be deleted.
|
||||
*/
|
||||
public Set<Permission> getRemovedPermissions() {
|
||||
return removedPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the new and removed permission sets after they are
|
||||
* no longer needed.
|
||||
*/
|
||||
public void resetPermissions() {
|
||||
newPermissions.clear();
|
||||
removedPermissions.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of this user in the database, if it exists.
|
||||
*
|
||||
* @return The ID of this user in the database, or null if this user
|
||||
* was not retrieved from the database.
|
||||
*/
|
||||
public Integer getUserID() {
|
||||
return userID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of this user to the given value.
|
||||
*
|
||||
* @param userID The ID to assign to this user.
|
||||
*/
|
||||
public void setUserID(Integer userID) {
|
||||
this.userID = userID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Permission> getPermissions() throws GuacamoleException {
|
||||
return Collections.unmodifiableSet(permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Permission permission) throws GuacamoleException {
|
||||
return permissions.contains(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPermission(Permission permission) throws GuacamoleException {
|
||||
permissions.add(permission);
|
||||
newPermissions.add(permission);
|
||||
removedPermissions.remove(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePermission(Permission permission) throws GuacamoleException {
|
||||
permissions.remove(permission);
|
||||
newPermissions.remove(permission);
|
||||
removedPermissions.add(permission);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.Connection;
|
||||
import net.sourceforge.guacamole.net.auth.Directory;
|
||||
import net.sourceforge.guacamole.net.auth.User;
|
||||
import net.sourceforge.guacamole.net.auth.UserContext;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||
|
||||
/**
|
||||
* The MySQL representation of a UserContext.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLUserContext implements UserContext {
|
||||
|
||||
/**
|
||||
* The ID of the user owning this context. The permissions of this user
|
||||
* dictate the access given via the user and connection directories.
|
||||
*/
|
||||
private int user_id;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Service for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Initializes the user and directories associated with this context.
|
||||
*
|
||||
* @param user_id The ID of the user owning this context.
|
||||
*/
|
||||
public void init(int user_id) {
|
||||
this.user_id = user_id;
|
||||
userDirectory.init(user_id);
|
||||
connectionDirectory.init(user_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User self() {
|
||||
return userService.retrieveUser(user_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<String, User> getUserDirectory() throws GuacamoleException {
|
||||
return userDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<String, Connection> getConnectionDirectory() throws GuacamoleException {
|
||||
return connectionDirectory;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,601 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleClientException;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.GuacamoleSecurityException;
|
||||
import net.sourceforge.guacamole.net.auth.Directory;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.ConnectionService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.PermissionCheckService;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.service.UserService;
|
||||
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.UserPermission;
|
||||
import org.mybatis.guice.transactional.Transactional;
|
||||
|
||||
/**
|
||||
* A MySQL based implementation of the User Directory.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class UserDirectory implements Directory<String, net.sourceforge.guacamole.net.auth.User> {
|
||||
|
||||
/**
|
||||
* The ID of the user who this user directory belongs to.
|
||||
* Access is based on his/her permission settings.
|
||||
*/
|
||||
private int user_id;
|
||||
|
||||
/**
|
||||
* Service for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Service for accessing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* DAO for accessing user permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private UserPermissionMapper userPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionPermissionMapper connectionPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing system permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private SystemPermissionMapper systemPermissionDAO;
|
||||
|
||||
/**
|
||||
* Service for checking various permissions, which will be injected.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Set the user for this directory.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions define the visibility
|
||||
* of other users in this directory.
|
||||
*/
|
||||
public void init(int user_id) {
|
||||
this.user_id = user_id;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public net.sourceforge.guacamole.net.auth.User get(String identifier)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Get user
|
||||
MySQLUser user = userService.retrieveUser(identifier);
|
||||
|
||||
// Verify access is granted
|
||||
permissionCheckService.verifyUserAccess(this.user_id,
|
||||
user.getUserID(),
|
||||
MySQLConstants.USER_READ);
|
||||
|
||||
// Return user
|
||||
return userService.retrieveUser(identifier);
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Set<String> getIdentifiers() throws GuacamoleException {
|
||||
return permissionCheckService.retrieveUsernames(user_id,
|
||||
MySQLConstants.USER_READ);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void add(net.sourceforge.guacamole.net.auth.User object)
|
||||
throws GuacamoleException {
|
||||
|
||||
String username = object.getUsername().trim();
|
||||
if(username.isEmpty())
|
||||
throw new GuacamoleClientException("The username cannot be blank.");
|
||||
|
||||
// Verify current user has permission to create users
|
||||
permissionCheckService.verifySystemAccess(this.user_id,
|
||||
MySQLConstants.SYSTEM_USER_CREATE);
|
||||
Preconditions.checkNotNull(object);
|
||||
|
||||
// Verify that no user already exists with this username.
|
||||
MySQLUser previousUser = userService.retrieveUser(username);
|
||||
if(previousUser != null)
|
||||
throw new GuacamoleClientException("That username is already in use.");
|
||||
|
||||
// Create new user
|
||||
MySQLUser user = userService.createUser(username, object.getPassword());
|
||||
|
||||
// Create permissions of new user in database
|
||||
createPermissions(user.getUserID(), object.getPermissions());
|
||||
|
||||
// Give the current user full access to the newly created user.
|
||||
UserPermissionKey newUserPermission = new UserPermissionKey();
|
||||
newUserPermission.setUser_id(this.user_id);
|
||||
newUserPermission.setAffected_user_id(user.getUserID());
|
||||
|
||||
// READ permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_READ);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
// UPDATE permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_UPDATE);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
// DELETE permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_DELETE);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
// ADMINISTER permission on new user
|
||||
newUserPermission.setPermission(MySQLConstants.USER_ADMINISTER);
|
||||
userPermissionDAO.insert(newUserPermission);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given permissions to the given user.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The permissions to add.
|
||||
* @throws GuacamoleException If an error occurs while updating the
|
||||
* permissions of the given user.
|
||||
*/
|
||||
private void createPermissions(int user_id, Set<Permission> permissions) throws GuacamoleException {
|
||||
|
||||
// Partition given permissions by permission type
|
||||
List<UserPermission> newUserPermissions = new ArrayList<UserPermission>();
|
||||
List<ConnectionPermission> newConnectionPermissions = new ArrayList<ConnectionPermission>();
|
||||
List<SystemPermission> newSystemPermissions = new ArrayList<SystemPermission>();
|
||||
|
||||
for (Permission permission : permissions) {
|
||||
|
||||
if (permission instanceof UserPermission)
|
||||
newUserPermissions.add((UserPermission) permission);
|
||||
|
||||
else if (permission instanceof ConnectionPermission)
|
||||
newConnectionPermissions.add((ConnectionPermission) permission);
|
||||
|
||||
else if (permission instanceof SystemPermission)
|
||||
newSystemPermissions.add((SystemPermission) permission);
|
||||
}
|
||||
|
||||
// Create the new permissions
|
||||
createUserPermissions(user_id, newUserPermissions);
|
||||
createConnectionPermissions(user_id, newConnectionPermissions);
|
||||
createSystemPermissions(user_id, newSystemPermissions);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given permissions from the given user.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The permissions to remove.
|
||||
* @throws GuacamoleException If an error occurs while updating the
|
||||
* permissions of the given user.
|
||||
*/
|
||||
private void removePermissions(int user_id, Set<Permission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Partition given permissions by permission type
|
||||
List<UserPermission> removedUserPermissions = new ArrayList<UserPermission>();
|
||||
List<ConnectionPermission> removedConnectionPermissions = new ArrayList<ConnectionPermission>();
|
||||
List<SystemPermission> removedSystemPermissions = new ArrayList<SystemPermission>();
|
||||
|
||||
for (Permission permission : permissions) {
|
||||
|
||||
if (permission instanceof UserPermission)
|
||||
removedUserPermissions.add((UserPermission) permission);
|
||||
|
||||
else if (permission instanceof ConnectionPermission)
|
||||
removedConnectionPermissions.add((ConnectionPermission) permission);
|
||||
|
||||
else if (permission instanceof SystemPermission)
|
||||
removedSystemPermissions.add((SystemPermission) permission);
|
||||
}
|
||||
|
||||
// Delete the removed permissions.
|
||||
deleteUserPermissions(user_id, removedUserPermissions);
|
||||
deleteConnectionPermissions(user_id, removedConnectionPermissions);
|
||||
deleteSystemPermissions(user_id, removedSystemPermissions);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the given user permissions for the given user.
|
||||
*
|
||||
* @param user_id The ID of the user to change the permissions of.
|
||||
* @param permissions The new permissions the given user should have when
|
||||
* this operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is denied.
|
||||
*/
|
||||
private void createUserPermissions(int user_id,
|
||||
Collection<UserPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable user IDs
|
||||
List<Integer> administerableUserIDs =
|
||||
permissionCheckService.retrieveUserIDs(this.user_id,
|
||||
MySQLConstants.USER_ADMINISTER);
|
||||
|
||||
// Get set of usernames corresponding to administerable users
|
||||
Map<String, Integer> administerableUsers =
|
||||
userService.translateUsernames(administerableUserIDs);
|
||||
|
||||
// Insert all given permissions
|
||||
for (UserPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer affected_id =
|
||||
administerableUsers.get(permission.getObjectIdentifier());
|
||||
|
||||
// Verify that the user actually has permission to administrate
|
||||
// every one of these users
|
||||
if (affected_id == null)
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + this.user_id
|
||||
+ " does not have permission to administrate user "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
// Create new permission
|
||||
UserPermissionKey newPermission = new UserPermissionKey();
|
||||
newPermission.setUser_id(user_id);
|
||||
newPermission.setPermission(MySQLConstants.getUserConstant(permission.getType()));
|
||||
newPermission.setAffected_user_id(affected_id);
|
||||
userPermissionDAO.insert(newPermission);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permissions having to do with users for a given user.
|
||||
*
|
||||
* @param user_id The ID of the user to change the permissions of.
|
||||
* @param permissions The permissions the given user should no longer have
|
||||
* when this operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is denied.
|
||||
*/
|
||||
private void deleteUserPermissions(int user_id,
|
||||
Collection<UserPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable user IDs
|
||||
List<Integer> administerableUserIDs =
|
||||
permissionCheckService.retrieveUserIDs(this.user_id,
|
||||
MySQLConstants.USER_ADMINISTER);
|
||||
|
||||
// Get set of usernames corresponding to administerable users
|
||||
Map<String, Integer> administerableUsers =
|
||||
userService.translateUsernames(administerableUserIDs);
|
||||
|
||||
// Delete requested permissions
|
||||
for (UserPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer affected_id =
|
||||
administerableUsers.get(permission.getObjectIdentifier());
|
||||
|
||||
// Verify that the user actually has permission to administrate
|
||||
// every one of these users
|
||||
if (affected_id == null)
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + this.user_id
|
||||
+ " does not have permission to administrate user "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
// Delete requested permission
|
||||
UserPermissionExample userPermissionExample = new UserPermissionExample();
|
||||
userPermissionExample.createCriteria()
|
||||
.andUser_idEqualTo(user_id)
|
||||
.andPermissionEqualTo(MySQLConstants.getUserConstant(permission.getType()))
|
||||
.andAffected_user_idEqualTo(affected_id);
|
||||
userPermissionDAO.deleteByExample(userPermissionExample);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create any new permissions having to do with connections for a given
|
||||
* user.
|
||||
*
|
||||
* @param user_id The ID of the user to assign or remove permissions from.
|
||||
* @param permissions The new permissions the user should have after this
|
||||
* operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is deniedD
|
||||
*/
|
||||
private void createConnectionPermissions(int user_id,
|
||||
Collection<ConnectionPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable connection IDs
|
||||
List<Integer> administerableConnectionIDs =
|
||||
permissionCheckService.retrieveConnectionIDs(this.user_id,
|
||||
MySQLConstants.CONNECTION_ADMINISTER);
|
||||
|
||||
// Get set of names corresponding to administerable connections
|
||||
Map<String, Integer> administerableConnections =
|
||||
connectionService.translateNames(administerableConnectionIDs);
|
||||
|
||||
// Insert all given permissions
|
||||
for (ConnectionPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer connection_id =
|
||||
administerableConnections.get(permission.getObjectIdentifier());
|
||||
|
||||
// Throw exception if permission to administer this connection
|
||||
// is not granted
|
||||
if (connection_id == null)
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + this.user_id
|
||||
+ " does not have permission to administrate connection "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
|
||||
// Create new permission
|
||||
ConnectionPermissionKey newPermission = new ConnectionPermissionKey();
|
||||
newPermission.setUser_id(user_id);
|
||||
newPermission.setPermission(MySQLConstants.getConnectionConstant(permission.getType()));
|
||||
newPermission.setConnection_id(connection_id);
|
||||
connectionPermissionDAO.insert(newPermission);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permissions having to do with connections for a given user.
|
||||
*
|
||||
* @param user_id The ID of the user to change the permissions of.
|
||||
* @param permissions The permissions the given user should no longer have
|
||||
* when this operation completes.
|
||||
* @throws GuacamoleException If permission to alter the access permissions
|
||||
* of affected objects is denied.
|
||||
*/
|
||||
private void deleteConnectionPermissions(int user_id,
|
||||
Collection<ConnectionPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Get list of administerable connection IDs
|
||||
List<Integer> administerableConnectionIDs =
|
||||
permissionCheckService.retrieveConnectionIDs(this.user_id,
|
||||
MySQLConstants.CONNECTION_ADMINISTER);
|
||||
|
||||
// Get set of names corresponding to administerable connections
|
||||
Map<String, Integer> administerableConnections =
|
||||
connectionService.translateNames(administerableConnectionIDs);
|
||||
|
||||
// Delete requested permissions
|
||||
for (ConnectionPermission permission : permissions) {
|
||||
|
||||
// Get original ID
|
||||
Integer connection_id =
|
||||
administerableConnections.get(permission.getObjectIdentifier());
|
||||
|
||||
// Verify that the user actually has permission to administrate
|
||||
// every one of these connections
|
||||
if (connection_id == null)
|
||||
throw new GuacamoleSecurityException(
|
||||
"User #" + this.user_id
|
||||
+ " does not have permission to administrate connection "
|
||||
+ permission.getObjectIdentifier());
|
||||
|
||||
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
|
||||
connectionPermissionExample.createCriteria()
|
||||
.andUser_idEqualTo(user_id)
|
||||
.andPermissionEqualTo(MySQLConstants.getConnectionConstant(permission.getType()))
|
||||
.andConnection_idEqualTo(connection_id);
|
||||
connectionPermissionDAO.deleteByExample(connectionPermissionExample);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create any new system permissions for a given user. All permissions in
|
||||
* the given list will be inserted.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The new system permissions that the given user should
|
||||
* have when this operation completes.
|
||||
* @throws GuacamoleException If permission to administer system permissions
|
||||
* is denied.
|
||||
*/
|
||||
private void createSystemPermissions(int user_id,
|
||||
Collection<SystemPermission> permissions) throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if(permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Only a system administrator can add system permissions.
|
||||
permissionCheckService.verifySystemAccess(
|
||||
this.user_id, SystemPermission.Type.ADMINISTER.name());
|
||||
|
||||
// Insert all requested permissions
|
||||
for (SystemPermission permission : permissions) {
|
||||
|
||||
// Insert permission
|
||||
SystemPermissionKey newSystemPermission = new SystemPermissionKey();
|
||||
newSystemPermission.setUser_id(user_id);
|
||||
newSystemPermission.setPermission(MySQLConstants.getSystemConstant(permission.getType()));
|
||||
systemPermissionDAO.insert(newSystemPermission);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete system permissions for a given user. All permissions in
|
||||
* the given list will be removed from the user.
|
||||
*
|
||||
* @param user_id The ID of the user whose permissions should be updated.
|
||||
* @param permissions The permissions the given user should no longer have
|
||||
* when this operation completes.
|
||||
* @throws GuacamoleException If the permissions specified could not be
|
||||
* removed due to system restrictions.
|
||||
*/
|
||||
private void deleteSystemPermissions(int user_id,
|
||||
Collection<SystemPermission> permissions)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If no permissions given, stop now
|
||||
if (permissions.isEmpty())
|
||||
return;
|
||||
|
||||
// Prevent self-de-adminifying
|
||||
if (user_id == this.user_id)
|
||||
throw new GuacamoleClientException("Removing your own administrative permissions is not allowed.");
|
||||
|
||||
// Build list of requested system permissions
|
||||
List<String> systemPermissionTypes = new ArrayList<String>();
|
||||
for (SystemPermission permission : permissions)
|
||||
systemPermissionTypes.add(MySQLConstants.getSystemConstant(permission.getType()));
|
||||
|
||||
// Delete the requested system permissions for this user
|
||||
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
|
||||
systemPermissionExample.createCriteria().andUser_idEqualTo(user_id)
|
||||
.andPermissionIn(systemPermissionTypes);
|
||||
systemPermissionDAO.deleteByExample(systemPermissionExample);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void update(net.sourceforge.guacamole.net.auth.User object)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If user not actually from this auth provider, we can't handle updated
|
||||
// permissions.
|
||||
if (!(object instanceof MySQLUser))
|
||||
throw new GuacamoleException("User not from database.");
|
||||
|
||||
MySQLUser mySQLUser = (MySQLUser) object;
|
||||
|
||||
// Validate permission to update this user is granted
|
||||
permissionCheckService.verifyUserAccess(this.user_id,
|
||||
mySQLUser.getUserID(),
|
||||
MySQLConstants.USER_UPDATE);
|
||||
|
||||
// Update the user in the database
|
||||
userService.updateUser(mySQLUser);
|
||||
|
||||
// Update permissions in database
|
||||
createPermissions(mySQLUser.getUserID(), mySQLUser.getNewPermissions());
|
||||
removePermissions(mySQLUser.getUserID(), mySQLUser.getRemovedPermissions());
|
||||
|
||||
// The appropriate permissions have been inserted and deleted, so
|
||||
// reset the new and removed permission sets.
|
||||
mySQLUser.resetPermissions();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(String identifier) throws GuacamoleException {
|
||||
|
||||
// Get user pending deletion
|
||||
MySQLUser user = userService.retrieveUser(identifier);
|
||||
|
||||
// Prevent self-deletion
|
||||
if (user.getUserID() == this.user_id)
|
||||
throw new GuacamoleClientException("Deleting your own user is not allowed.");
|
||||
|
||||
// Validate current user has permission to remove the specified user
|
||||
permissionCheckService.verifyUserAccess(this.user_id,
|
||||
user.getUserID(),
|
||||
MySQLConstants.USER_DELETE);
|
||||
|
||||
// Delete specified user
|
||||
userService.deleteUser(user.getUserID());
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
|
||||
/**
|
||||
* Base classes which support the MySQL authentication provider, including
|
||||
* the authentication provider itself.
|
||||
*/
|
||||
package net.sourceforge.guacamole.net.auth.mysql;
|
||||
|
@@ -0,0 +1,112 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
package net.sourceforge.guacamole.net.auth.mysql.properties;
|
||||
|
||||
import net.sourceforge.guacamole.properties.BooleanGuacamoleProperty;
|
||||
import net.sourceforge.guacamole.properties.IntegerGuacamoleProperty;
|
||||
import net.sourceforge.guacamole.properties.StringGuacamoleProperty;
|
||||
|
||||
/**
|
||||
* Properties used by the MySQL Authentication plugin.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class MySQLGuacamoleProperties {
|
||||
|
||||
/**
|
||||
* This class should not be instantiated.
|
||||
*/
|
||||
private MySQLGuacamoleProperties() {}
|
||||
|
||||
/**
|
||||
* The URL of the MySQL server hosting the guacamole authentication tables.
|
||||
*/
|
||||
public static final StringGuacamoleProperty MYSQL_HOSTNAME = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-hostname"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The port of the MySQL server hosting the guacamole authentication tables.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty MYSQL_PORT = new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-port"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The name of the MySQL database containing the guacamole authentication tables.
|
||||
*/
|
||||
public static final StringGuacamoleProperty MYSQL_DATABASE = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-database"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The username used to authenticate to the MySQL database containing the guacamole authentication tables.
|
||||
*/
|
||||
public static final StringGuacamoleProperty MYSQL_USERNAME = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-username"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The password used to authenticate to the MySQL database containing the guacamole authentication tables.
|
||||
*/
|
||||
public static final StringGuacamoleProperty MYSQL_PASSWORD = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-password"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether or not multiple users accessing the same connection at the same time should be disallowed.
|
||||
*/
|
||||
public static final BooleanGuacamoleProperty MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS = new BooleanGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "mysql-disallow-simultaneous-connections"; }
|
||||
|
||||
};
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
|
||||
/**
|
||||
* Properties which control the configuration of the MySQL authentication
|
||||
* provider.
|
||||
*/
|
||||
package net.sourceforge.guacamole.net.auth.mysql.properties;
|
||||
|
@@ -0,0 +1,456 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleClientException;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.InetGuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.ActiveConnectionSet;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnection;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConnectionRecord;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLGuacamoleSocket;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionHistoryMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionParameterMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.Connection;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistory;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionHistoryExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameter;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionParameterExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.properties.MySQLGuacamoleProperties;
|
||||
import net.sourceforge.guacamole.properties.GuacamoleProperties;
|
||||
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
|
||||
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating connections.
|
||||
*
|
||||
* @author Michael Jumper, James Muehlner
|
||||
*/
|
||||
public class ConnectionService {
|
||||
|
||||
/**
|
||||
* DAO for accessing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionMapper connectionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection parameters.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionParameterMapper connectionParameterDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing connection history.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionHistoryMapper connectionHistoryDAO;
|
||||
|
||||
/**
|
||||
* Provider which creates MySQLConnections.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLConnection> mySQLConnectionProvider;
|
||||
|
||||
/**
|
||||
* Provider which creates MySQLGuacamoleSockets.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLGuacamoleSocket> mySQLGuacamoleSocketProvider;
|
||||
|
||||
/**
|
||||
* Set of all currently active connections.
|
||||
*/
|
||||
@Inject
|
||||
private ActiveConnectionSet activeConnectionSet;
|
||||
|
||||
/**
|
||||
* Service managing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Retrieves the connection having the given name from the database.
|
||||
*
|
||||
* @param name The name of the connection to return.
|
||||
* @param userID The ID of the user who queried this connection.
|
||||
* @return The connection having the given name, or null if no such
|
||||
* connection could be found.
|
||||
*/
|
||||
public MySQLConnection retrieveConnection(String name, int userID) {
|
||||
|
||||
// Query connection by connection identifier (name)
|
||||
ConnectionExample example = new ConnectionExample();
|
||||
example.createCriteria().andConnection_nameEqualTo(name);
|
||||
List<Connection> connections =
|
||||
connectionDAO.selectByExample(example);
|
||||
|
||||
// If no connection found, return null
|
||||
if(connections.isEmpty())
|
||||
return null;
|
||||
|
||||
// Assert only one connection found
|
||||
assert connections.size() == 1 : "Multiple connections with same name.";
|
||||
|
||||
// Otherwise, return found connection
|
||||
return toMySQLConnection(connections.get(0), userID);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the connection having the given ID from the database.
|
||||
*
|
||||
* @param id The ID of the connection to retrieve.
|
||||
* @param userID The ID of the user who queried this connection.
|
||||
* @return The connection having the given ID, or null if no such
|
||||
* connection was found.
|
||||
*/
|
||||
public MySQLConnection retrieveConnection(int id, int userID) {
|
||||
|
||||
// Query connection by ID
|
||||
Connection connection = connectionDAO.selectByPrimaryKey(id);
|
||||
|
||||
// If no connection found, return null
|
||||
if(connection == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, return found connection
|
||||
return toMySQLConnection(connection, userID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a translation map of connection names to their corresponding
|
||||
* IDs.
|
||||
*
|
||||
* @param ids The IDs of the connections to retrieve the names of.
|
||||
* @return A map containing the names of all connections and their
|
||||
* corresponding IDs.
|
||||
*/
|
||||
public Map<String, Integer> translateNames(List<Integer> ids) {
|
||||
|
||||
// If no IDs given, just return empty map
|
||||
if (ids.isEmpty())
|
||||
return Collections.EMPTY_MAP;
|
||||
|
||||
// Map of all names onto their corresponding IDs.
|
||||
Map<String, Integer> names = new HashMap<String, Integer>();
|
||||
|
||||
// Get all connections having the given IDs
|
||||
ConnectionExample example = new ConnectionExample();
|
||||
example.createCriteria().andConnection_idIn(ids);
|
||||
List<Connection> connections = connectionDAO.selectByExample(example);
|
||||
|
||||
// Produce set of names
|
||||
for (Connection connection : connections)
|
||||
names.put(connection.getConnection_name(),
|
||||
connection.getConnection_id());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a map of all connection names for the given IDs.
|
||||
*
|
||||
* @param ids The IDs of the connections to retrieve the names of.
|
||||
* @return A map containing the names of all connections and their
|
||||
* corresponding IDs.
|
||||
*/
|
||||
public Map<Integer, String> retrieveNames(Collection<Integer> ids) {
|
||||
|
||||
// If no IDs given, just return empty map
|
||||
if (ids.isEmpty())
|
||||
return Collections.EMPTY_MAP;
|
||||
|
||||
// Map of all names onto their corresponding IDs.
|
||||
Map<Integer, String> names = new HashMap<Integer, String>();
|
||||
|
||||
// Get all connections having the given IDs
|
||||
ConnectionExample example = new ConnectionExample();
|
||||
example.createCriteria().andConnection_idIn(Lists.newArrayList(ids));
|
||||
List<Connection> connections = connectionDAO.selectByExample(example);
|
||||
|
||||
// Produce set of names
|
||||
for (Connection connection : connections)
|
||||
names.put(connection.getConnection_id(),
|
||||
connection.getConnection_name());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given database-retrieved Connection into a MySQLConnection.
|
||||
* The parameters of the given connection will be read and added to the
|
||||
* MySQLConnection in the process.
|
||||
*
|
||||
* @param connection The connection to convert.
|
||||
* @param userID The user who queried this connection.
|
||||
* @return A new MySQLConnection containing all data associated with the
|
||||
* specified connection.
|
||||
*/
|
||||
private MySQLConnection toMySQLConnection(Connection connection, int userID) {
|
||||
|
||||
// Build configuration
|
||||
GuacamoleConfiguration config = new GuacamoleConfiguration();
|
||||
|
||||
// Query parameters for configuration
|
||||
ConnectionParameterExample connectionParameterExample = new ConnectionParameterExample();
|
||||
connectionParameterExample.createCriteria().andConnection_idEqualTo(connection.getConnection_id());
|
||||
List<ConnectionParameter> connectionParameters =
|
||||
connectionParameterDAO.selectByExample(connectionParameterExample);
|
||||
|
||||
// Set protocol
|
||||
config.setProtocol(connection.getProtocol());
|
||||
|
||||
// Set all values for all parameters
|
||||
for (ConnectionParameter parameter : connectionParameters)
|
||||
config.setParameter(parameter.getParameter_name(),
|
||||
parameter.getParameter_value());
|
||||
|
||||
// Create new MySQLConnection from retrieved data
|
||||
MySQLConnection mySQLConnection = mySQLConnectionProvider.get();
|
||||
mySQLConnection.init(
|
||||
connection.getConnection_id(),
|
||||
connection.getConnection_name(),
|
||||
config,
|
||||
retrieveHistory(connection.getConnection_id()),
|
||||
userID
|
||||
);
|
||||
|
||||
return mySQLConnection;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the history of the connection having the given ID.
|
||||
*
|
||||
* @param connectionID The ID of the connection to retrieve the history of.
|
||||
* @return A list of MySQLConnectionRecord documenting the history of this
|
||||
* connection.
|
||||
*/
|
||||
public List<MySQLConnectionRecord> retrieveHistory(int connectionID) {
|
||||
|
||||
// Retrieve history records relating to given connection ID
|
||||
ConnectionHistoryExample example = new ConnectionHistoryExample();
|
||||
example.createCriteria().andConnection_idEqualTo(connectionID);
|
||||
|
||||
// We want to return the newest records first
|
||||
example.setOrderByClause("start_date DESC");
|
||||
|
||||
// Set the maximum number of history records returned to 100
|
||||
RowBounds rowBounds = new RowBounds(0, 100);
|
||||
|
||||
// Retrieve all connection history entries
|
||||
List<ConnectionHistory> connectionHistories =
|
||||
connectionHistoryDAO.selectByExampleWithRowbounds(example, rowBounds);
|
||||
|
||||
// Convert history entries to connection records
|
||||
List<MySQLConnectionRecord> connectionRecords = new ArrayList<MySQLConnectionRecord>();
|
||||
Set<Integer> userIDSet = new HashSet<Integer>();
|
||||
for(ConnectionHistory history : connectionHistories) {
|
||||
userIDSet.add(history.getUser_id());
|
||||
}
|
||||
|
||||
// Get all the usernames for the users who are in the history
|
||||
Map<Integer, String> usernameMap = userService.retrieveUsernames(userIDSet);
|
||||
|
||||
// Create the new ConnectionRecords
|
||||
for(ConnectionHistory history : connectionHistories) {
|
||||
Date startDate = history.getStart_date();
|
||||
Date endDate = history.getEnd_date();
|
||||
String username = usernameMap.get(history.getUser_id());
|
||||
MySQLConnectionRecord connectionRecord = new MySQLConnectionRecord(startDate, endDate, username);
|
||||
connectionRecords.add(connectionRecord);
|
||||
}
|
||||
|
||||
return connectionRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a MySQLGuacamoleSocket using the provided connection.
|
||||
*
|
||||
* @param connection The connection to use when connecting the socket.
|
||||
* @param info The information to use when performing the connection
|
||||
* handshake.
|
||||
* @param userID The ID of the user who is connecting to the socket.
|
||||
* @return The connected socket.
|
||||
* @throws GuacamoleException If an error occurs while connecting the
|
||||
* socket.
|
||||
*/
|
||||
public MySQLGuacamoleSocket connect(MySQLConnection connection,
|
||||
GuacamoleClientInformation info, int userID)
|
||||
throws GuacamoleException {
|
||||
|
||||
// If the given connection is active, and multiple simultaneous
|
||||
// connections are not allowed, disallow connection
|
||||
if(GuacamoleProperties.getProperty(
|
||||
MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false)
|
||||
&& activeConnectionSet.isActive(connection.getConnectionID()))
|
||||
throw new GuacamoleClientException("Cannot connect. This connection is in use.");
|
||||
|
||||
// Get guacd connection information
|
||||
String host = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_HOSTNAME);
|
||||
int port = GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_PORT);
|
||||
|
||||
// Get socket
|
||||
GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
|
||||
new InetGuacamoleSocket(host, port),
|
||||
connection.getConfiguration(), info
|
||||
);
|
||||
|
||||
// Mark this connection as active
|
||||
int historyID = activeConnectionSet.openConnection(connection.getConnectionID(), userID);
|
||||
|
||||
// Return new MySQLGuacamoleSocket
|
||||
MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
|
||||
mySQLGuacamoleSocket.init(socket, connection.getConnectionID(), historyID);
|
||||
return mySQLGuacamoleSocket;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection having the given name and protocol.
|
||||
*
|
||||
* @param name The name to assign to the new connection.
|
||||
* @param protocol The protocol to assign to the new connection.
|
||||
* @param userID The ID of the user who created this connection.
|
||||
* @return A new MySQLConnection containing the data of the newly created
|
||||
* connection.
|
||||
*/
|
||||
public MySQLConnection createConnection(String name, String protocol, int userID) {
|
||||
|
||||
// Initialize database connection
|
||||
Connection connection = new Connection();
|
||||
connection.setConnection_name(name);
|
||||
connection.setProtocol(protocol);
|
||||
|
||||
// Create connection
|
||||
connectionDAO.insert(connection);
|
||||
return toMySQLConnection(connection, userID);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the connection having the given ID from the database.
|
||||
* @param id The ID of the connection to delete.
|
||||
*/
|
||||
public void deleteConnection(int id) {
|
||||
connectionDAO.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the connection in the database corresponding to the given
|
||||
* MySQLConnection.
|
||||
*
|
||||
* @param mySQLConnection The MySQLConnection to update (save) to the
|
||||
* database. This connection must already exist.
|
||||
*/
|
||||
public void updateConnection(MySQLConnection mySQLConnection) {
|
||||
|
||||
// Populate connection
|
||||
Connection connection = new Connection();
|
||||
connection.setConnection_id(mySQLConnection.getConnectionID());
|
||||
connection.setConnection_name(mySQLConnection.getIdentifier());
|
||||
connection.setProtocol(mySQLConnection.getConfiguration().getProtocol());
|
||||
|
||||
// Update the connection in the database
|
||||
connectionDAO.updateByPrimaryKeySelective(connection);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of all the connections defined in the system.
|
||||
*
|
||||
* @return A Set of names of all the connections defined in the system.
|
||||
*/
|
||||
public Set<String> getAllConnectionNames() {
|
||||
|
||||
// Set of all present connection names
|
||||
Set<String> names = new HashSet<String>();
|
||||
|
||||
// Query all connection names
|
||||
List<Connection> connections =
|
||||
connectionDAO.selectByExample(new ConnectionExample());
|
||||
for (Connection connection : connections)
|
||||
names.add(connection.getConnection_name());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection IDs of all the connections defined in the system.
|
||||
*
|
||||
* @return A list of connection IDs of all the connections defined in the system.
|
||||
*/
|
||||
public List<Integer> getAllConnectionIDs() {
|
||||
|
||||
// Set of all present connection IDs
|
||||
List<Integer> connectionIDs = new ArrayList<Integer>();
|
||||
|
||||
// Query all connection IDs
|
||||
List<Connection> connections =
|
||||
connectionDAO.selectByExample(new ConnectionExample());
|
||||
for (Connection connection : connections)
|
||||
connectionIDs.add(connection.getConnection_id());
|
||||
|
||||
return connectionIDs;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* A service to perform password encryption and checking.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public interface PasswordEncryptionService {
|
||||
|
||||
/**
|
||||
* Checks whether the provided, unhashed password matches the given
|
||||
* hash/salt pair.
|
||||
*
|
||||
* @param password The unhashed password to validate.
|
||||
* @param hashedPassword The hashed password to compare the given password
|
||||
* against.
|
||||
* @param salt The salt used when the hashed password given was created.
|
||||
* @return true if the provided credentials match the values given, false
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean checkPassword(String password, byte[] hashedPassword,
|
||||
byte[] salt);
|
||||
|
||||
/**
|
||||
* 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,497 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleSecurityException;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLConstants;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.ConnectionPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.SystemPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserPermissionMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.ConnectionPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.SystemPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserPermissionKey;
|
||||
import net.sourceforge.guacamole.net.auth.permission.ConnectionPermission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.Permission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.SystemPermission;
|
||||
import net.sourceforge.guacamole.net.auth.permission.UserPermission;
|
||||
|
||||
/**
|
||||
* A service to retrieve information about what objects a user has permission to.
|
||||
* @author James Muehlner
|
||||
*/
|
||||
public class PermissionCheckService {
|
||||
|
||||
/**
|
||||
* Service for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Service for accessing connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to users.
|
||||
*/
|
||||
@Inject
|
||||
private UserPermissionMapper userPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to connections.
|
||||
*/
|
||||
@Inject
|
||||
private ConnectionPermissionMapper connectionPermissionDAO;
|
||||
|
||||
/**
|
||||
* DAO for accessing permissions related to the system as a whole.
|
||||
*/
|
||||
@Inject
|
||||
private SystemPermissionMapper systemPermissionDAO;
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the given other
|
||||
* user. If permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param affectedUserID The user that would be affected by the operation
|
||||
* if permission is granted.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @throws GuacamoleSecurityException If the specified permission is not
|
||||
* granted.
|
||||
*/
|
||||
public void verifyUserAccess(int userID, int affectedUserID,
|
||||
String permissionType) throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkUserAccess(userID, affectedUserID, permissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the user has the specified access to the given connection.
|
||||
* If permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param affectedConnectionID The connection that would be affected by the
|
||||
* operation if permission is granted.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @throws GuacamoleSecurityException If the specified permission is not
|
||||
* granted.
|
||||
*/
|
||||
public void verifyConnectionAccess(int userID, int affectedConnectionID, String permissionType) throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkConnectionAccess(userID, affectedConnectionID, permissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
/**
|
||||
* Verifies that the user has the specified access to the system. If
|
||||
* permission is denied, a GuacamoleSecurityException is thrown.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param systemPermissionType The type of permission to check for.
|
||||
* @throws GuacamoleSecurityException If the specified permission is not
|
||||
* granted.
|
||||
*/
|
||||
public void verifySystemAccess(int userID, String systemPermissionType)
|
||||
throws GuacamoleSecurityException {
|
||||
|
||||
// If permission does not exist, throw exception
|
||||
if(!checkSystemAccess(userID, systemPermissionType))
|
||||
throw new GuacamoleSecurityException("Permission denied.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the affected
|
||||
* user.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param affectedUserID The user that would be affected by the operation
|
||||
* if permission is granted.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @return true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
public boolean checkUserAccess(int userID, Integer affectedUserID, String permissionType) {
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
UserPermissionExample example = new UserPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).andAffected_user_idEqualTo(affectedUserID).andPermissionEqualTo(permissionType);
|
||||
return userPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the affected
|
||||
* connection.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param affectedConnectionID The connection that would be affected by the
|
||||
* operation if permission is granted.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @return true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
public boolean checkConnectionAccess(int userID, Integer affectedConnectionID, String permissionType) {
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
ConnectionPermissionExample example = new ConnectionPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).andConnection_idEqualTo(affectedConnectionID).andPermissionEqualTo(permissionType);
|
||||
return connectionPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user has the specified type of access to the system.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param systemPermissionType The type of permission to check for.
|
||||
* @return true if the specified permission is granted, false otherwise.
|
||||
*/
|
||||
private boolean checkSystemAccess(int userID, String systemPermissionType) {
|
||||
|
||||
// A system administrator has full access to everything.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return true;
|
||||
|
||||
// Check existence of requested permission
|
||||
SystemPermissionExample example = new SystemPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(systemPermissionType);
|
||||
return systemPermissionDAO.countByExample(example) > 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a user has system administrator access to the system.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @return true if the system administrator access exists, false otherwise.
|
||||
*/
|
||||
private boolean checkSystemAdministratorAccess(int userID) {
|
||||
|
||||
// Check existence of system administrator permission
|
||||
SystemPermissionExample example = new SystemPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).
|
||||
andPermissionEqualTo(MySQLConstants.SYSTEM_ADMINISTER);
|
||||
return systemPermissionDAO.countByExample(example) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all users a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @return A list of all user IDs this user has the specified access to.
|
||||
*/
|
||||
public List<Integer> retrieveUserIDs(int userID, String permissionType) {
|
||||
|
||||
// A system administrator has access to all users.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return userService.getAllUserIDs();
|
||||
|
||||
// Query all user permissions for the given user and permission type
|
||||
UserPermissionExample example = new UserPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType);
|
||||
example.setDistinct(true);
|
||||
List<UserPermissionKey> userPermissions =
|
||||
userPermissionDAO.selectByExample(example);
|
||||
|
||||
// Convert result into list of IDs
|
||||
List<Integer> userIDs = new ArrayList<Integer>(userPermissions.size());
|
||||
for(UserPermissionKey permission : userPermissions)
|
||||
userIDs.add(permission.getAffected_user_id());
|
||||
|
||||
return userIDs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of the IDs of all connections a user has permission to.
|
||||
* The access type is defined by permissionType.
|
||||
*
|
||||
* @param userID The ID of the user to check.
|
||||
* @param permissionType The type of permission to check for.
|
||||
* @return A list of all connection IDs this user has the specified access
|
||||
* to.
|
||||
*/
|
||||
public List<Integer> retrieveConnectionIDs(int userID,
|
||||
String permissionType) {
|
||||
|
||||
// A system administrator has access to all connections.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return connectionService.getAllConnectionIDs();
|
||||
|
||||
// Query all connection permissions for the given user and permission type
|
||||
ConnectionPermissionExample example = new ConnectionPermissionExample();
|
||||
example.createCriteria().andUser_idEqualTo(userID).andPermissionEqualTo(permissionType);
|
||||
example.setDistinct(true);
|
||||
List<ConnectionPermissionKey> connectionPermissions =
|
||||
connectionPermissionDAO.selectByExample(example);
|
||||
|
||||
// Convert result into list of IDs
|
||||
List<Integer> connectionIDs = new ArrayList<Integer>(connectionPermissions.size());
|
||||
for(ConnectionPermissionKey permission : connectionPermissions)
|
||||
connectionIDs.add(permission.getConnection_id());
|
||||
|
||||
return connectionIDs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all existing usernames that the given user has permission to
|
||||
* perform the given operation upon.
|
||||
*
|
||||
* @param userID The user whose permissions should be checked.
|
||||
* @param permissionType The permission to check.
|
||||
* @return A set of all usernames for which the given user has the given
|
||||
* permission.
|
||||
*/
|
||||
public Set<String> retrieveUsernames(int userID, String permissionType) {
|
||||
|
||||
// A system administrator has access to all users.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return userService.getAllUsernames();
|
||||
|
||||
// List of all user IDs for which this user has read access
|
||||
List<Integer> userIDs =
|
||||
retrieveUserIDs(userID, MySQLConstants.USER_READ);
|
||||
|
||||
// Query all associated users
|
||||
return userService.translateUsernames(userIDs).keySet();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all existing connection names that the given user has permission
|
||||
* to perform the given operation upon.
|
||||
*
|
||||
* @param userID The user whose permissions should be checked.
|
||||
* @param permissionType The permission to check.
|
||||
* @return A set of all connection names for which the given user has the
|
||||
* given permission.
|
||||
*/
|
||||
public Set<String> retrieveConnectionNames(int userID, String permissionType) {
|
||||
|
||||
// A system administrator has access to all connections.
|
||||
if(checkSystemAdministratorAccess(userID))
|
||||
return connectionService.getAllConnectionNames();
|
||||
|
||||
// List of all connection IDs for which this connection has read access
|
||||
List<Integer> connectionIDs =
|
||||
retrieveConnectionIDs(userID, MySQLConstants.CONNECTION_READ);
|
||||
|
||||
// Query all associated connections
|
||||
return connectionService.translateNames(connectionIDs).keySet();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all user permissions granted to the user having the given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all user permissions granted to the user having the
|
||||
* given ID.
|
||||
*/
|
||||
public Set<UserPermission> retrieveUserPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<UserPermission> permissions = new HashSet<UserPermission>();
|
||||
|
||||
// Query all user permissions
|
||||
UserPermissionExample userPermissionExample = new UserPermissionExample();
|
||||
userPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<UserPermissionKey> userPermissions =
|
||||
userPermissionDAO.selectByExample(userPermissionExample);
|
||||
|
||||
// Get list of affected user IDs
|
||||
List<Integer> affectedUserIDs = new ArrayList<Integer>();
|
||||
for(UserPermissionKey userPermission : userPermissions)
|
||||
affectedUserIDs.add(userPermission.getAffected_user_id());
|
||||
|
||||
// Get corresponding usernames
|
||||
Map<Integer, String> affectedUsers =
|
||||
userService.retrieveUsernames(affectedUserIDs);
|
||||
|
||||
// Add user permissions
|
||||
for(UserPermissionKey userPermission : userPermissions) {
|
||||
|
||||
// Construct permission from data
|
||||
UserPermission permission = new UserPermission(
|
||||
UserPermission.Type.valueOf(userPermission.getPermission()),
|
||||
affectedUsers.get(userPermission.getAffected_user_id())
|
||||
);
|
||||
|
||||
// Add to set
|
||||
permissions.add(permission);
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all connection permissions granted to the user having the
|
||||
* given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all connection permissions granted to the user having
|
||||
* the given ID.
|
||||
*/
|
||||
public Set<ConnectionPermission> retrieveConnectionPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<ConnectionPermission> permissions = new HashSet<ConnectionPermission>();
|
||||
|
||||
// Query all connection permissions
|
||||
ConnectionPermissionExample connectionPermissionExample = new ConnectionPermissionExample();
|
||||
connectionPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<ConnectionPermissionKey> connectionPermissions =
|
||||
connectionPermissionDAO.selectByExample(connectionPermissionExample);
|
||||
|
||||
// Get list of affected connection IDs
|
||||
List<Integer> connectionIDs = new ArrayList<Integer>();
|
||||
for(ConnectionPermissionKey connectionPermission : connectionPermissions)
|
||||
connectionIDs.add(connectionPermission.getConnection_id());
|
||||
|
||||
// Get corresponding names
|
||||
Map<Integer, String> affectedConnections =
|
||||
connectionService.retrieveNames(connectionIDs);
|
||||
|
||||
// Add connection permissions
|
||||
for(ConnectionPermissionKey connectionPermission : connectionPermissions) {
|
||||
|
||||
// Construct permission from data
|
||||
ConnectionPermission permission = new ConnectionPermission(
|
||||
ConnectionPermission.Type.valueOf(connectionPermission.getPermission()),
|
||||
affectedConnections.get(connectionPermission.getConnection_id())
|
||||
);
|
||||
|
||||
// Add to set
|
||||
permissions.add(permission);
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all system permissions granted to the user having the
|
||||
* given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all system permissions granted to the user having the
|
||||
* given ID.
|
||||
*/
|
||||
public Set<SystemPermission> retrieveSystemPermissions(int userID) {
|
||||
|
||||
// Set of all permissions
|
||||
Set<SystemPermission> permissions = new HashSet<SystemPermission>();
|
||||
|
||||
// And finally, system permissions
|
||||
SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
|
||||
systemPermissionExample.createCriteria().andUser_idEqualTo(userID);
|
||||
List<SystemPermissionKey> systemPermissions =
|
||||
systemPermissionDAO.selectByExample(systemPermissionExample);
|
||||
for(SystemPermissionKey systemPermission : systemPermissions) {
|
||||
|
||||
// User creation permission
|
||||
if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_USER_CREATE))
|
||||
permissions.add(new SystemPermission(SystemPermission.Type.CREATE_USER));
|
||||
|
||||
// System creation permission
|
||||
else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_CONNECTION_CREATE))
|
||||
permissions.add(new SystemPermission(SystemPermission.Type.CREATE_CONNECTION));
|
||||
|
||||
// System administration permission
|
||||
else if(systemPermission.getPermission().equals(MySQLConstants.SYSTEM_ADMINISTER))
|
||||
permissions.add(new SystemPermission(SystemPermission.Type.ADMINISTER));
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all permissions granted to the user having the given ID.
|
||||
*
|
||||
* @param userID The ID of the user to retrieve permissions of.
|
||||
* @return A set of all permissions granted to the user having the given
|
||||
* ID.
|
||||
*/
|
||||
public Set<Permission> retrieveAllPermissions(int userID) {
|
||||
|
||||
// Set which will contain all permissions
|
||||
Set<Permission> allPermissions = new HashSet<Permission>();
|
||||
|
||||
// Add user permissions
|
||||
allPermissions.addAll(retrieveUserPermissions(userID));
|
||||
|
||||
// Add connection permissions
|
||||
allPermissions.addAll(retrieveConnectionPermissions(userID));
|
||||
|
||||
// Add system permissions
|
||||
allPermissions.addAll(retrieveSystemPermissions(userID));
|
||||
|
||||
return allPermissions;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
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 boolean checkPassword(String password, byte[] hashedPassword,
|
||||
byte[] salt) {
|
||||
|
||||
// Compare bytes of password in credentials against hashed password
|
||||
byte[] passwordBytes = createPasswordHash(password, salt);
|
||||
return Arrays.equals(passwordBytes, hashedPassword);
|
||||
|
||||
}
|
||||
|
||||
@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,48 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
/**
|
||||
* 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,60 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
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,381 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is guacamole-auth-mysql.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* James Muehlner.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.sourceforge.guacamole.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.auth.Credentials;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.MySQLUser;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.dao.UserMapper;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.User;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserExample;
|
||||
import net.sourceforge.guacamole.net.auth.mysql.model.UserWithBLOBs;
|
||||
|
||||
/**
|
||||
* Service which provides convenience methods for creating, retrieving, and
|
||||
* manipulating users.
|
||||
*
|
||||
* @author Michael Jumper, James Muehlner
|
||||
*/
|
||||
public class UserService {
|
||||
|
||||
/**
|
||||
* DAO for accessing users.
|
||||
*/
|
||||
@Inject
|
||||
private UserMapper userDAO;
|
||||
|
||||
/**
|
||||
* Provider for creating users.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<MySQLUser> mySQLUserProvider;
|
||||
|
||||
/**
|
||||
* Service for checking permissions.
|
||||
*/
|
||||
@Inject
|
||||
private PermissionCheckService permissionCheckService;
|
||||
|
||||
/**
|
||||
* Service for encrypting passwords.
|
||||
*/
|
||||
@Inject
|
||||
private PasswordEncryptionService passwordService;
|
||||
|
||||
/**
|
||||
* Service for generating random salts.
|
||||
*/
|
||||
@Inject
|
||||
private SaltService saltService;
|
||||
|
||||
/**
|
||||
* Create a new MySQLUser based on the provided User.
|
||||
*
|
||||
* @param user The User to use when populating the data of the given
|
||||
* MySQLUser.
|
||||
* @return A new MySQLUser object, populated with the data of the given
|
||||
* user.
|
||||
*
|
||||
* @throws GuacamoleException If an error occurs while reading the data
|
||||
* of the provided User.
|
||||
*/
|
||||
public MySQLUser toMySQLUser(net.sourceforge.guacamole.net.auth.User user) throws GuacamoleException {
|
||||
MySQLUser mySQLUser = mySQLUserProvider.get();
|
||||
mySQLUser.init(user);
|
||||
return mySQLUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MySQLUser based on the provided database record.
|
||||
*
|
||||
* @param user The database record describing the user.
|
||||
* @return A new MySQLUser object, populated with the data of the given
|
||||
* database record.
|
||||
*/
|
||||
private MySQLUser toMySQLUser(UserWithBLOBs user) {
|
||||
|
||||
// Retrieve user from provider
|
||||
MySQLUser mySQLUser = mySQLUserProvider.get();
|
||||
|
||||
// Init with data from given database user
|
||||
mySQLUser.init(
|
||||
user.getUser_id(),
|
||||
user.getUsername(),
|
||||
null,
|
||||
permissionCheckService.retrieveAllPermissions(user.getUser_id())
|
||||
);
|
||||
|
||||
// Return new user
|
||||
return mySQLUser;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the user having the given ID from the database.
|
||||
*
|
||||
* @param id The ID of the user to retrieve.
|
||||
* @return The existing MySQLUser object if found, null otherwise.
|
||||
*/
|
||||
public MySQLUser retrieveUser(int id) {
|
||||
|
||||
// Query user by ID
|
||||
UserWithBLOBs user = userDAO.selectByPrimaryKey(id);
|
||||
|
||||
// If no user found, return null
|
||||
if(user == null)
|
||||
return null;
|
||||
|
||||
// Otherwise, return found user
|
||||
return toMySQLUser(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the user having the given username from the database.
|
||||
*
|
||||
* @param name The username of the user to retrieve.
|
||||
* @return The existing MySQLUser object if found, null otherwise.
|
||||
*/
|
||||
public MySQLUser retrieveUser(String name) {
|
||||
|
||||
// Query user by ID
|
||||
UserExample example = new UserExample();
|
||||
example.createCriteria().andUsernameEqualTo(name);
|
||||
List<UserWithBLOBs> users = userDAO.selectByExampleWithBLOBs(example);
|
||||
|
||||
// If no user found, return null
|
||||
if(users.isEmpty())
|
||||
return null;
|
||||
|
||||
// Otherwise, return found user
|
||||
return toMySQLUser(users.get(0));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
// No null users in database
|
||||
if (credentials.getUsername() == null)
|
||||
return null;
|
||||
|
||||
// Query user
|
||||
UserExample userExample = new UserExample();
|
||||
userExample.createCriteria().andUsernameEqualTo(credentials.getUsername());
|
||||
List<UserWithBLOBs> users = userDAO.selectByExampleWithBLOBs(userExample);
|
||||
|
||||
// Check that a user was found
|
||||
if (users.isEmpty())
|
||||
return null;
|
||||
|
||||
// Assert only one user found
|
||||
assert users.size() == 1 : "Multiple users with same username.";
|
||||
|
||||
// Get first (and only) user
|
||||
UserWithBLOBs user = users.get(0);
|
||||
|
||||
// Check password, if invalid return null
|
||||
if (!passwordService.checkPassword(credentials.getPassword(),
|
||||
user.getPassword_hash(), user.getPassword_salt()))
|
||||
return null;
|
||||
|
||||
// Return found user
|
||||
return toMySQLUser(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a translation map of usernames to their corresponding IDs.
|
||||
*
|
||||
* @param ids The IDs of the users to retrieve the usernames of.
|
||||
* @return A map containing the names of all users and their corresponding
|
||||
* IDs.
|
||||
*/
|
||||
public Map<String, Integer> translateUsernames(List<Integer> ids) {
|
||||
|
||||
// If no IDs given, just return empty map
|
||||
if (ids.isEmpty())
|
||||
return Collections.EMPTY_MAP;
|
||||
|
||||
// Map of all names onto their corresponding IDs
|
||||
Map<String, Integer> names = new HashMap<String, Integer>();
|
||||
|
||||
// Get all users having the given IDs
|
||||
UserExample example = new UserExample();
|
||||
example.createCriteria().andUser_idIn(ids);
|
||||
List<User> users =
|
||||
userDAO.selectByExample(example);
|
||||
|
||||
// Produce set of names
|
||||
for (User user : users)
|
||||
names.put(user.getUsername(), user.getUser_id());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a map of all usernames for the given IDs.
|
||||
*
|
||||
* @param ids The IDs of the users to retrieve the usernames of.
|
||||
* @return A map containing the names of all users and their corresponding
|
||||
* IDs.
|
||||
*/
|
||||
public Map<Integer, String> retrieveUsernames(Collection<Integer> ids) {
|
||||
|
||||
// If no IDs given, just return empty map
|
||||
if (ids.isEmpty())
|
||||
return Collections.EMPTY_MAP;
|
||||
|
||||
// Map of all names onto their corresponding IDs
|
||||
Map<Integer, String> names = new HashMap<Integer, String>();
|
||||
|
||||
// Get all users having the given IDs
|
||||
UserExample example = new UserExample();
|
||||
example.createCriteria().andUser_idIn(Lists.newArrayList(ids));
|
||||
List<User> users =
|
||||
userDAO.selectByExample(example);
|
||||
|
||||
// Produce set of names
|
||||
for (User user : users)
|
||||
names.put(user.getUser_id(), user.getUsername());
|
||||
|
||||
return names;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user having the given username and password.
|
||||
*
|
||||
* @param username The username to assign to the new user.
|
||||
* @param password The password to assign to the new user.
|
||||
* @return A new MySQLUser containing the data of the newly created
|
||||
* user.
|
||||
*/
|
||||
public MySQLUser createUser(String username, String password) {
|
||||
|
||||
// Initialize database user
|
||||
UserWithBLOBs user = new UserWithBLOBs();
|
||||
user.setUsername(username);
|
||||
|
||||
// Set password if specified
|
||||
if (password != null) {
|
||||
byte[] salt = saltService.generateSalt();
|
||||
user.setPassword_salt(salt);
|
||||
user.setPassword_hash(
|
||||
passwordService.createPasswordHash(password, salt));
|
||||
}
|
||||
|
||||
// Create user
|
||||
userDAO.insert(user);
|
||||
return toMySQLUser(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the user having the given ID from the database.
|
||||
* @param user_id The ID of the user to delete.
|
||||
*/
|
||||
public void deleteUser(int user_id) {
|
||||
userDAO.deleteByPrimaryKey(user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user in the database corresponding to the given MySQLUser.
|
||||
*
|
||||
* @param mySQLUser The MySQLUser to update (save) to the database. This
|
||||
* user must already exist.
|
||||
*/
|
||||
public void updateUser(MySQLUser mySQLUser) {
|
||||
|
||||
UserWithBLOBs user = new UserWithBLOBs();
|
||||
user.setUser_id(mySQLUser.getUserID());
|
||||
user.setUsername(mySQLUser.getUsername());
|
||||
|
||||
// Set password if specified
|
||||
if (mySQLUser.getPassword() != null) {
|
||||
byte[] salt = saltService.generateSalt();
|
||||
user.setPassword_salt(salt);
|
||||
user.setPassword_hash(
|
||||
passwordService.createPasswordHash(mySQLUser.getPassword(), salt));
|
||||
}
|
||||
|
||||
// Update the user in the database
|
||||
userDAO.updateByPrimaryKeySelective(user);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the usernames of all the users defined in the system.
|
||||
*
|
||||
* @return A Set of usernames of all the users defined in the system.
|
||||
*/
|
||||
public Set<String> getAllUsernames() {
|
||||
|
||||
// Set of all present usernames
|
||||
Set<String> usernames = new HashSet<String>();
|
||||
|
||||
// Query all usernames
|
||||
List<User> users =
|
||||
userDAO.selectByExample(new UserExample());
|
||||
for (User user : users)
|
||||
usernames.add(user.getUsername());
|
||||
|
||||
return usernames;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user IDs of all the users defined in the system.
|
||||
*
|
||||
* @return A list of user IDs of all the users defined in the system.
|
||||
*/
|
||||
public List<Integer> getAllUserIDs() {
|
||||
|
||||
// Set of all present user IDs
|
||||
List<Integer> userIDs = new ArrayList<Integer>();
|
||||
|
||||
// Query all user IDs
|
||||
List<User> users =
|
||||
userDAO.selectByExample(new UserExample());
|
||||
for (User user : users)
|
||||
userIDs.add(user.getUser_id());
|
||||
|
||||
return userIDs;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
|
||||
/**
|
||||
* Service classes which help fill the needs of the MySQL authentication
|
||||
* provider.
|
||||
*/
|
||||
package net.sourceforge.guacamole.net.auth.mysql.service;
|
||||
|
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE generatorConfiguration
|
||||
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
|
||||
|
||||
<generatorConfiguration>
|
||||
<context id="guacamoleTables" targetRuntime="MyBatis3">
|
||||
|
||||
<!-- Allow selectByExample with RowBounds -->
|
||||
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>
|
||||
|
||||
<!-- MySQL JDBC driver class. -->
|
||||
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
|
||||
connectionURL="jdbc:mysql://127.0.0.1:3306"
|
||||
userId="${guacamole.database.user}"
|
||||
password="${guacamole.database.password}"/>
|
||||
|
||||
<javaModelGenerator
|
||||
targetPackage="net.sourceforge.guacamole.net.auth.mysql.model"
|
||||
targetProject="MAVEN"/>
|
||||
|
||||
<sqlMapGenerator
|
||||
targetPackage="net.sourceforge.guacamole.net.auth.mysql.dao"
|
||||
targetProject="MAVEN"/>
|
||||
|
||||
<javaClientGenerator type="XMLMAPPER"
|
||||
targetPackage="net.sourceforge.guacamole.net.auth.mysql.dao"
|
||||
targetProject="MAVEN"/>
|
||||
|
||||
<!-- TABLES -->
|
||||
|
||||
<table tableName="guacamole_connection"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="Connection" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
<generatedKey column="connection_id" identity="true"
|
||||
sqlStatement="SELECT LAST_INSERT_ID()"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_parameter"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionParameter" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_system_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="SystemPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_user"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="User" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
<generatedKey column="user_id" identity="true"
|
||||
sqlStatement="SELECT LAST_INSERT_ID()"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_user_permission"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="UserPermission" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
</table>
|
||||
|
||||
<table tableName="guacamole_connection_history"
|
||||
catalog="${guacamole.database.catalog}"
|
||||
schema="${guacamole.database.schema}"
|
||||
domainObjectName="ConnectionHistory" >
|
||||
<property name="useActualColumnNames" value="true"/>
|
||||
<property name="ignoreQualifiersAtRuntime" value="true"/>
|
||||
<generatedKey column="history_id" identity="true"
|
||||
sqlStatement="SELECT LAST_INSERT_ID()"/>
|
||||
</table>
|
||||
|
||||
</context>
|
||||
</generatorConfiguration>
|
||||
|
Reference in New Issue
Block a user