You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by mj...@apache.org on 2017/10/01 02:10:14 UTC
[02/28] incubator-guacamole-client git commit: GUACAMOLE-363: Initial
commit of SQLServer authentication module for JDBC.
GUACAMOLE-363: Initial commit of SQLServer authentication module for JDBC.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/b6e88d33
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/b6e88d33
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/b6e88d33
Branch: refs/heads/master
Commit: b6e88d33b3967b42020aa8dbc8429f41f2a0afb8
Parents: 81ffa5c
Author: Nick Couchman <vn...@apache.org>
Authored: Mon Aug 14 22:14:15 2017 -0400
Committer: Nick Couchman <vn...@apache.org>
Committed: Thu Sep 28 07:00:51 2017 -0400
----------------------------------------------------------------------
.../guacamole-auth-jdbc-sqlserver/.gitignore | 2 +
.../guacamole-auth-jdbc-sqlserver/pom.xml | 128 ++++++++
.../schema/001-create-schema.sql | Bin 0 -> 35118 bytes
.../schema/002-create-admin-user.sql | 43 +++
.../SQLServerAuthenticationProvider.java | 50 +++
.../SQLServerAuthenticationProviderModule.java | 91 ++++++
.../auth/sqlserver/SQLServerEnvironment.java | 306 +++++++++++++++++++
.../sqlserver/SQLServerGuacamoleProperties.java | 200 ++++++++++++
.../sqlserver/SQLServerInjectorProvider.java | 49 +++
.../auth/sqlserver/SQLServerPasswordPolicy.java | 194 ++++++++++++
.../SQLServerSharedAuthenticationProvider.java | 50 +++
.../guacamole/auth/sqlserver/package-info.java | 23 ++
.../src/main/resources/guac-manifest.json | 28 ++
.../auth/jdbc/connection/ConnectionMapper.xml | 235 ++++++++++++++
.../connection/ConnectionParameterMapper.xml | 68 +++++
.../jdbc/connection/ConnectionRecordMapper.xml | 216 +++++++++++++
.../connectiongroup/ConnectionGroupMapper.xml | 232 ++++++++++++++
.../ConnectionGroupPermissionMapper.xml | 130 ++++++++
.../permission/ConnectionPermissionMapper.xml | 130 ++++++++
.../SharingProfilePermissionMapper.xml | 130 ++++++++
.../jdbc/permission/SystemPermissionMapper.xml | 101 ++++++
.../jdbc/permission/UserPermissionMapper.xml | 137 +++++++++
.../sharingprofile/SharingProfileMapper.xml | 126 ++++++++
.../SharingProfileParameterMapper.xml | 68 +++++
.../auth/jdbc/user/PasswordRecordMapper.xml | 79 +++++
.../guacamole/auth/jdbc/user/UserMapper.xml | 216 +++++++++++++
extensions/guacamole-auth-jdbc/pom.xml | 1 +
27 files changed, 3033 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore
new file mode 100644
index 0000000..42f4a1a
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore
@@ -0,0 +1,2 @@
+target/
+*~
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml
new file mode 100644
index 0000000..82776f7
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.guacamole</groupId>
+ <artifactId>guacamole-auth-jdbc-sqlserver</artifactId>
+ <packaging>jar</packaging>
+ <name>guacamole-auth-jdbc-sqlserver</name>
+ <url>http://guacamole.incubator.apache.org/</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <parent>
+ <groupId>org.apache.guacamole</groupId>
+ <artifactId>guacamole-auth-jdbc</artifactId>
+ <version>0.9.13-incubating</version>
+ <relativePath>../../</relativePath>
+ </parent>
+
+ <build>
+ <plugins>
+
+ <!-- Written for 1.6 -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ <compilerArgs>
+ <arg>-Xlint:all</arg>
+ <arg>-Werror</arg>
+ </compilerArgs>
+ <fork>true</fork>
+ </configuration>
+ </plugin>
+
+ <!-- Copy dependencies prior to packaging -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.10</version>
+ <executions>
+ <execution>
+ <id>unpack-dependencies</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeScope>runtime</includeScope>
+ <outputDirectory>${project.build.directory}/classes</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Verify format using Apache RAT -->
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <version>0.12</version>
+
+ <configuration>
+ <excludes>
+ <exclude>**/*.json</exclude>
+ </excludes>
+ </configuration>
+
+ <!-- Bind RAT to validate phase -->
+ <executions>
+ <execution>
+ <id>validate</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <dependencies>
+
+ <!-- Guacamole Extension API -->
+ <dependency>
+ <groupId>org.apache.guacamole</groupId>
+ <artifactId>guacamole-ext</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Guacamole JDBC Authentication -->
+ <dependency>
+ <groupId>org.apache.guacamole</groupId>
+ <artifactId>guacamole-auth-jdbc-base</artifactId>
+ <version>0.9.13-incubating</version>
+ </dependency>
+
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql
new file mode 100644
index 0000000..df95800
Binary files /dev/null and b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql differ
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql
new file mode 100644
index 0000000..08cce3f
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+INSERT INTO [guacamole].[user] (username, password_hash, password_salt, password_date)
+VALUES ('guacadmin', 0xCA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960,
+0xCA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960, getdate());
+
+INSERT INTO [guacamole].[system_permission]
+SELECT user_id, permission
+FROM (
+ SELECT 'guacadmin' AS username, 'CREATE_CONNECTION' AS permission
+ UNION SELECT 'guacadmin' AS username, 'CREATE_CONNECTION_GROUP' AS permission
+ UNION SELECT 'guacadmin' AS username, 'CREATE_SHARING_PROFILE' AS permission
+ UNION SELECT 'guacadmin' AS username, 'CREATE_USER' AS permission
+ UNION SELECT 'guacadmin' AS username, 'ADMINISTER' AS permission)
+ permissions
+ JOIN [guacamole].[user] ON permissions.username = [guacamole].[user].[username];
+
+INSERT INTO [guacamole].[user_permission]
+SELECT [guacamole].[user].[user_id], [affected].[user_id], permission
+FROM (
+ SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'READ' AS permission
+ UNION SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'UPDATE' AS permission
+ UNION SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'ADMINISTER' AS permission)
+ permissions
+ JOIN [guacamole].[user] ON permissions.username = [guacamole].[user].[username]
+ JOIN [guacamole].[user] affected ON permissions.affected_username = affected.username;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java
new file mode 100644
index 0000000..ef5d61d
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.sqlserver;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.InjectedAuthenticationProvider;
+import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderService;
+
+/**
+ * Provides a SQLServer-based implementation of the AuthenticationProvider
+ * functionality.
+ */
+public class SQLServerAuthenticationProvider extends InjectedAuthenticationProvider {
+
+ /**
+ * Creates a new SQLServerAuthenticationProvider that reads and writes
+ * authentication data to a SQLServer database defined by properties in
+ * guacamole.properties.
+ *
+ * @throws GuacamoleException
+ * If a required property is missing, or an error occurs while parsing
+ * a property.
+ */
+ public SQLServerAuthenticationProvider() throws GuacamoleException {
+ super(new SQLServerInjectorProvider(), JDBCAuthenticationProviderService.class);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return "sqlserver";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java
new file mode 100644
index 0000000..ebb1a06
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.sqlserver;
+
+import com.google.inject.Binder;
+import com.google.inject.Module;
+import com.google.inject.name.Names;
+import java.util.Properties;
+import org.apache.guacamole.GuacamoleException;
+import org.mybatis.guice.datasource.helper.JdbcHelper;
+
+/**
+ * Guice module which configures SQLServer-specific injections.
+ */
+public class SQLServerAuthenticationProviderModule implements Module {
+
+ /**
+ * MyBatis-specific configuration properties.
+ */
+ private final Properties myBatisProperties = new Properties();
+
+ /**
+ * SQLServer-specific driver configuration properties.
+ */
+ private final Properties driverProperties = new Properties();
+
+ /**
+ * Creates a new SQLServer authentication provider module that configures
+ * driver and MyBatis properties using the given environment.
+ *
+ * @param environment
+ * The environment to use when configuring MyBatis and the underlying
+ * JDBC driver.
+ *
+ * @throws GuacamoleException
+ * If a required property is missing, or an error occurs while parsing
+ * a property.
+ */
+ public SQLServerAuthenticationProviderModule(SQLServerEnvironment environment)
+ throws GuacamoleException {
+
+ // Set the SQLServer-specific properties for MyBatis.
+ myBatisProperties.setProperty("mybatis.environment.id", "guacamole");
+ myBatisProperties.setProperty("JDBC.host", environment.getSQLServerHostname());
+ myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getSQLServerPort()));
+ myBatisProperties.setProperty("JDBC.schema", environment.getSQLServerDatabase());
+ myBatisProperties.setProperty("JDBC.username", environment.getSQLServerUsername());
+ myBatisProperties.setProperty("JDBC.password", environment.getSQLServerPassword());
+ myBatisProperties.setProperty("JDBC.autoCommit", "false");
+ myBatisProperties.setProperty("mybatis.pooled.pingEnabled", "true");
+ myBatisProperties.setProperty("mybatis.pooled.pingQuery", "SELECT 1");
+
+ // Use UTF-8 in database
+ driverProperties.setProperty("characterEncoding", "UTF-8");
+
+ }
+
+ @Override
+ public void configure(Binder binder) {
+
+ // Bind SQLServer-specific properties
+ JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder);
+
+ // Bind MyBatis properties
+ Names.bindProperties(binder, myBatisProperties);
+
+ // Bind JDBC driver properties
+ binder.bind(Properties.class)
+ .annotatedWith(Names.named("JDBC.driverProperties"))
+ .toInstance(driverProperties);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java
new file mode 100644
index 0000000..67d8827
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.sqlserver;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.guacamole.auth.jdbc.security.PasswordPolicy;
+
+/**
+ * A SQLServer-specific implementation of JDBCEnvironment provides database
+ * properties specifically for SQLServer.
+ */
+public class SQLServerEnvironment extends JDBCEnvironment {
+
+ /**
+ * Logger for this class.
+ */
+ private static final Logger logger = LoggerFactory.getLogger(SQLServerEnvironment.class);
+
+ /**
+ * The default host to connect to, if SQLSERVER_HOSTNAME is not specified.
+ */
+ private static final String DEFAULT_HOSTNAME = "localhost";
+
+ /**
+ * The default port to connect to, if SQLSERVER_PORT is not specified.
+ */
+ private static final int DEFAULT_PORT = 1433;
+
+ /**
+ * Whether a database user account is required by default for authentication
+ * to succeed.
+ */
+ private static final boolean DEFAULT_USER_REQUIRED = true;
+
+ /**
+ * The default value for the maximum number of connections to be
+ * allowed to the Guacamole server overall.
+ */
+ private final int DEFAULT_ABSOLUTE_MAX_CONNECTIONS = 0;
+
+ /**
+ * The default value for the default maximum number of connections to be
+ * allowed per user to any one connection. Note that, as long as the
+ * legacy "disallow duplicate" and "disallow simultaneous" properties are
+ * still supported, these cannot be constants, as the legacy properties
+ * dictate the values that should be used in the absence of the correct
+ * properties.
+ */
+ private int DEFAULT_MAX_CONNECTIONS_PER_USER = 1;
+
+ /**
+ * The default value for the default maximum number of connections to be
+ * allowed per user to any one connection group. Note that, as long as the
+ * legacy "disallow duplicate" and "disallow simultaneous" properties are
+ * still supported, these cannot be constants, as the legacy properties
+ * dictate the values that should be used in the absence of the correct
+ * properties.
+ */
+ private int DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 1;
+
+ /**
+ * The default value for the default maximum number of connections to be
+ * allowed to any one connection. Note that, as long as the legacy
+ * "disallow duplicate" and "disallow simultaneous" properties are still
+ * supported, these cannot be constants, as the legacy properties dictate
+ * the values that should be used in the absence of the correct properties.
+ */
+ private int DEFAULT_MAX_CONNECTIONS = 0;
+
+ /**
+ * The default value for the default maximum number of connections to be
+ * allowed to any one connection group. Note that, as long as the legacy
+ * "disallow duplicate" and "disallow simultaneous" properties are still
+ * supported, these cannot be constants, as the legacy properties dictate
+ * the values that should be used in the absence of the correct properties.
+ */
+ private int DEFAULT_MAX_GROUP_CONNECTIONS = 0;
+
+ /**
+ * Constructs a new SQLServerEnvironment, providing access to SQLServer-specific
+ * configuration options.
+ *
+ * @throws GuacamoleException
+ * If an error occurs while setting up the underlying JDBCEnvironment
+ * or while parsing legacy SQLServer configuration options.
+ */
+ public SQLServerEnvironment() throws GuacamoleException {
+
+ // Init underlying JDBC environment
+ super();
+
+ // Read legacy concurrency-related property
+ Boolean disallowSimultaneous = getProperty(SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS);
+ Boolean disallowDuplicate = getProperty(SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS);
+
+ // Legacy "simultaneous" property dictates only the maximum number of
+ // connections per connection
+ if (disallowSimultaneous != null) {
+
+ // Translate legacy property
+ if (disallowSimultaneous) {
+ DEFAULT_MAX_CONNECTIONS = 1;
+ DEFAULT_MAX_GROUP_CONNECTIONS = 0;
+ }
+ else {
+ DEFAULT_MAX_CONNECTIONS = 0;
+ DEFAULT_MAX_GROUP_CONNECTIONS = 0;
+ }
+
+ // Warn of deprecation
+ logger.warn("The \"{}\" property is deprecated. Use \"{}\" and \"{}\" instead.",
+ SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(),
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS.getName(),
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS.getName());
+
+ // Inform of new equivalent
+ logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".",
+ SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(), disallowSimultaneous,
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS.getName(), DEFAULT_MAX_CONNECTIONS,
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS.getName(), DEFAULT_MAX_GROUP_CONNECTIONS);
+
+ }
+
+ // Legacy "duplicate" property dictates whether connections and groups
+ // may be used concurrently only by different users
+ if (disallowDuplicate != null) {
+
+ // Translate legacy property
+ if (disallowDuplicate) {
+ DEFAULT_MAX_CONNECTIONS_PER_USER = 1;
+ DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 1;
+ }
+ else {
+ DEFAULT_MAX_CONNECTIONS_PER_USER = 0;
+ DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 0;
+ }
+
+ // Warn of deprecation
+ logger.warn("The \"{}\" property is deprecated. Use \"{}\" and \"{}\" instead.",
+ SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS.getName(),
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(),
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS.getName());
+
+ // Inform of new equivalent
+ logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".",
+ SQLServerGuacamoleProperties.SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS.getName(), disallowDuplicate,
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(), DEFAULT_MAX_CONNECTIONS_PER_USER,
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER.getName(), DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER);
+
+ }
+
+ }
+
+ @Override
+ public boolean isUserRequired() throws GuacamoleException {
+ return getProperty(
+ SQLServerGuacamoleProperties.SQLSERVER_USER_REQUIRED,
+ DEFAULT_USER_REQUIRED
+ );
+ }
+
+ @Override
+ public int getAbsoluteMaxConnections() throws GuacamoleException {
+ return getProperty(SQLServerGuacamoleProperties.SQLSERVER_ABSOLUTE_MAX_CONNECTIONS,
+ DEFAULT_ABSOLUTE_MAX_CONNECTIONS
+ );
+ }
+
+ @Override
+ public int getDefaultMaxConnections() throws GuacamoleException {
+ return getProperty(
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS,
+ DEFAULT_MAX_CONNECTIONS
+ );
+ }
+
+ @Override
+ public int getDefaultMaxGroupConnections() throws GuacamoleException {
+ return getProperty(
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS,
+ DEFAULT_MAX_GROUP_CONNECTIONS
+ );
+ }
+
+ @Override
+ public int getDefaultMaxConnectionsPerUser() throws GuacamoleException {
+ return getProperty(
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER,
+ DEFAULT_MAX_CONNECTIONS_PER_USER
+ );
+ }
+
+ @Override
+ public int getDefaultMaxGroupConnectionsPerUser() throws GuacamoleException {
+ return getProperty(
+ SQLServerGuacamoleProperties.SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER,
+ DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER
+ );
+ }
+
+ @Override
+ public PasswordPolicy getPasswordPolicy() {
+ return new SQLServerPasswordPolicy(this);
+ }
+
+ /**
+ * Returns the hostname of the SQLServer server hosting the Guacamole
+ * authentication tables. If unspecified, this will be "localhost".
+ *
+ * @return
+ * The URL of the SQLServer server.
+ *
+ * @throws GuacamoleException
+ * If an error occurs while retrieving the property value.
+ */
+ public String getSQLServerHostname() throws GuacamoleException {
+ return getProperty(
+ SQLServerGuacamoleProperties.SQLSERVER_HOSTNAME,
+ DEFAULT_HOSTNAME
+ );
+ }
+
+ /**
+ * Returns the port number of the SQLServer server hosting the Guacamole
+ * authentication tables. If unspecified, this will be the default
+ * SQLServer port of 5432.
+ *
+ * @return
+ * The port number of the SQLServer server.
+ *
+ * @throws GuacamoleException
+ * If an error occurs while retrieving the property value.
+ */
+ public int getSQLServerPort() throws GuacamoleException {
+ return getProperty(
+ SQLServerGuacamoleProperties.SQLSERVER_PORT,
+ DEFAULT_PORT
+ );
+ }
+
+ /**
+ * Returns the name of the SQLServer database containing the Guacamole
+ * authentication tables.
+ *
+ * @return
+ * The name of the SQLServer database.
+ *
+ * @throws GuacamoleException
+ * If an error occurs while retrieving the property value, or if the
+ * value was not set, as this property is required.
+ */
+ public String getSQLServerDatabase() throws GuacamoleException {
+ return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_DATABASE);
+ }
+
+ /**
+ * Returns the username that should be used when authenticating with the
+ * SQLServer database containing the Guacamole authentication tables.
+ *
+ * @return
+ * The username for the SQLServer database.
+ *
+ * @throws GuacamoleException
+ * If an error occurs while retrieving the property value, or if the
+ * value was not set, as this property is required.
+ */
+ public String getSQLServerUsername() throws GuacamoleException {
+ return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_USERNAME);
+ }
+
+ /**
+ * Returns the password that should be used when authenticating with the
+ * SQLServer database containing the Guacamole authentication tables.
+ *
+ * @return
+ * The password for the SQLServer database.
+ *
+ * @throws GuacamoleException
+ * If an error occurs while retrieving the property value, or if the
+ * value was not set, as this property is required.
+ */
+ public String getSQLServerPassword() throws GuacamoleException {
+ return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_PASSWORD);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java
new file mode 100644
index 0000000..e45f502
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.sqlserver;
+
+import org.apache.guacamole.properties.BooleanGuacamoleProperty;
+import org.apache.guacamole.properties.IntegerGuacamoleProperty;
+import org.apache.guacamole.properties.StringGuacamoleProperty;
+
+/**
+ * Properties used by the SQLServer Authentication plugin.
+ */
+public class SQLServerGuacamoleProperties {
+
+ /**
+ * This class should not be instantiated.
+ */
+ private SQLServerGuacamoleProperties() {}
+
+ /**
+ * The URL of the SQLServer server hosting the Guacamole authentication tables.
+ */
+ public static final StringGuacamoleProperty SQLSERVER_HOSTNAME =
+ new StringGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-hostname"; }
+
+ };
+
+ /**
+ * The port of the SQLServer server hosting the Guacamole authentication
+ * tables.
+ */
+ public static final IntegerGuacamoleProperty SQLSERVER_PORT =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-port"; }
+
+ };
+
+ /**
+ * The name of the SQLServer database containing the Guacamole
+ * authentication tables.
+ */
+ public static final StringGuacamoleProperty SQLSERVER_DATABASE =
+ new StringGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-database"; }
+
+ };
+
+ /**
+ * The username used to authenticate to the SQLServer database containing
+ * the Guacamole authentication tables.
+ */
+ public static final StringGuacamoleProperty SQLSERVER_USERNAME =
+ new StringGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-username"; }
+
+ };
+
+ /**
+ * The password used to authenticate to the SQLServer database containing
+ * the Guacamole authentication tables.
+ */
+ public static final StringGuacamoleProperty SQLSERVER_PASSWORD =
+ new StringGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-password"; }
+
+ };
+
+ /**
+ * Whether a user account within the database is required for authentication
+ * to succeed, even if the user has been authenticated via another
+ * authentication provider.
+ */
+ public static final BooleanGuacamoleProperty
+ SQLSERVER_USER_REQUIRED = new BooleanGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-required"; }
+
+ };
+
+ /**
+ * Whether or not multiple users accessing the same connection at the same
+ * time should be disallowed.
+ */
+ public static final BooleanGuacamoleProperty
+ SQLSERVER_DISALLOW_SIMULTANEOUS_CONNECTIONS =
+ new BooleanGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-disallow-simultaneous-connections"; }
+
+ };
+
+ /**
+ * Whether or not the same user accessing the same connection or connection
+ * group at the same time should be disallowed.
+ */
+ public static final BooleanGuacamoleProperty
+ SQLSERVER_DISALLOW_DUPLICATE_CONNECTIONS =
+ new BooleanGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-disallow-duplicate-connections"; }
+
+ };
+
+ /**
+ * The maximum number of concurrent connections to allow overall. Zero
+ * denotes unlimited.
+ */
+ public static final IntegerGuacamoleProperty
+ SQLSERVER_ABSOLUTE_MAX_CONNECTIONS =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-absolute-max-connections"; }
+
+ };
+
+ /**
+ * The maximum number of concurrent connections to allow to any one
+ * connection. Zero denotes unlimited.
+ */
+ public static final IntegerGuacamoleProperty
+ SQLSERVER_DEFAULT_MAX_CONNECTIONS =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-default-max-connections"; }
+
+ };
+
+ /**
+ * The maximum number of concurrent connections to allow to any one
+ * connection group. Zero denotes unlimited.
+ */
+ public static final IntegerGuacamoleProperty
+ SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-default-max-group-connections"; }
+
+ };
+
+ /**
+ * The maximum number of concurrent connections to allow to any one
+ * connection by an individual user. Zero denotes unlimited.
+ */
+ public static final IntegerGuacamoleProperty
+ SQLSERVER_DEFAULT_MAX_CONNECTIONS_PER_USER =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-default-max-connections-per-user"; }
+
+ };
+
+ /**
+ * The maximum number of concurrent connections to allow to any one
+ * connection group by an individual user. Zero denotes
+ * unlimited.
+ */
+ public static final IntegerGuacamoleProperty
+ SQLSERVER_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-default-max-group-connections-per-user"; }
+
+ };
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java
new file mode 100644
index 0000000..32d12f6
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.sqlserver;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.JDBCAuthenticationProviderModule;
+import org.apache.guacamole.auth.jdbc.JDBCInjectorProvider;
+
+/**
+ * JDBCInjectorProvider implementation which configures Guice injections for
+ * connecting to a SQLServer database based on SQLServer-specific options
+ * provided via guacamole.properties.
+ */
+public class SQLServerInjectorProvider extends JDBCInjectorProvider {
+
+ @Override
+ protected Injector create() throws GuacamoleException {
+
+ // Get local environment
+ SQLServerEnvironment environment = new SQLServerEnvironment();
+
+ // Set up Guice injector
+ return Guice.createInjector(
+ new JDBCAuthenticationProviderModule(environment),
+ new SQLServerAuthenticationProviderModule(environment)
+ );
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java
new file mode 100644
index 0000000..f30b180
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.sqlserver;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
+import org.apache.guacamole.auth.jdbc.security.PasswordPolicy;
+import org.apache.guacamole.properties.BooleanGuacamoleProperty;
+import org.apache.guacamole.properties.IntegerGuacamoleProperty;
+
+/**
+ * PasswordPolicy implementation which reads the details of the policy from
+ * SQLServer-specific properties in guacamole.properties.
+ */
+public class SQLServerPasswordPolicy implements PasswordPolicy {
+
+ /**
+ * The property which specifies the minimum length required of all user
+ * passwords. By default, this will be zero.
+ */
+ private static final IntegerGuacamoleProperty MIN_LENGTH =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-min-length"; }
+
+ };
+
+ /**
+ * The property which specifies the minimum number of days which must
+ * elapse before a user may reset their password. If set to zero, the
+ * default, then this restriction does not apply.
+ */
+ private static final IntegerGuacamoleProperty MIN_AGE =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-min-age"; }
+
+ };
+
+ /**
+ * The property which specifies the maximum number of days which may
+ * elapse before a user is required to reset their password. If set to zero,
+ * the default, then this restriction does not apply.
+ */
+ private static final IntegerGuacamoleProperty MAX_AGE =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-max-age"; }
+
+ };
+
+ /**
+ * The property which specifies the number of previous passwords remembered
+ * for each user. If set to zero, the default, then this restriction does
+ * not apply.
+ */
+ private static final IntegerGuacamoleProperty HISTORY_SIZE =
+ new IntegerGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-history-size"; }
+
+ };
+
+ /**
+ * The property which specifies whether all user passwords must have at
+ * least one lowercase character and one uppercase character. By default,
+ * no such restriction is imposed.
+ */
+ private static final BooleanGuacamoleProperty REQUIRE_MULTIPLE_CASE =
+ new BooleanGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-require-multiple-case"; }
+
+ };
+
+ /**
+ * The property which specifies whether all user passwords must have at
+ * least one numeric character (digit). By default, no such restriction is
+ * imposed.
+ */
+ private static final BooleanGuacamoleProperty REQUIRE_DIGIT =
+ new BooleanGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-require-digit"; }
+
+ };
+
+ /**
+ * The property which specifies whether all user passwords must have at
+ * least one non-alphanumeric character (symbol). By default, no such
+ * restriction is imposed.
+ */
+ private static final BooleanGuacamoleProperty REQUIRE_SYMBOL =
+ new BooleanGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-require-symbol"; }
+
+ };
+
+ /**
+ * The property which specifies whether users are prohibited from including
+ * their own username in their password. By default, no such restriction is
+ * imposed.
+ */
+ private static final BooleanGuacamoleProperty PROHIBIT_USERNAME =
+ new BooleanGuacamoleProperty() {
+
+ @Override
+ public String getName() { return "sqlserver-user-password-prohibit-username"; }
+
+ };
+
+ /**
+ * The Guacamole server environment.
+ */
+ private final JDBCEnvironment environment;
+
+ /**
+ * Creates a new SQLServerPasswordPolicy which reads the details of the
+ * policy from the properties exposed by the given environment.
+ *
+ * @param environment
+ * The environment from which password policy properties should be
+ * read.
+ */
+ public SQLServerPasswordPolicy(JDBCEnvironment environment) {
+ this.environment = environment;
+ }
+
+ @Override
+ public int getMinimumLength() throws GuacamoleException {
+ return environment.getProperty(MIN_LENGTH, 0);
+ }
+
+ @Override
+ public int getMinimumAge() throws GuacamoleException {
+ return environment.getProperty(MIN_AGE, 0);
+ }
+
+ @Override
+ public int getMaximumAge() throws GuacamoleException {
+ return environment.getProperty(MAX_AGE, 0);
+ }
+
+ @Override
+ public int getHistorySize() throws GuacamoleException {
+ return environment.getProperty(HISTORY_SIZE, 0);
+ }
+
+ @Override
+ public boolean isMultipleCaseRequired() throws GuacamoleException {
+ return environment.getProperty(REQUIRE_MULTIPLE_CASE, false);
+ }
+
+ @Override
+ public boolean isNumericRequired() throws GuacamoleException {
+ return environment.getProperty(REQUIRE_DIGIT, false);
+ }
+
+ @Override
+ public boolean isNonAlphanumericRequired() throws GuacamoleException {
+ return environment.getProperty(REQUIRE_SYMBOL, false);
+ }
+
+ @Override
+ public boolean isUsernameProhibited() throws GuacamoleException {
+ return environment.getProperty(PROHIBIT_USERNAME, false);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java
new file mode 100644
index 0000000..0a3c8d3
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.auth.sqlserver;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.InjectedAuthenticationProvider;
+import org.apache.guacamole.auth.jdbc.sharing.SharedAuthenticationProviderService;
+
+/**
+ * Provides a implementation of AuthenticationProvider which interacts with the
+ * SQLServer AuthenticationProvider, accepting share keys as credentials and
+ * providing access to the shared connections.
+ */
+public class SQLServerSharedAuthenticationProvider extends InjectedAuthenticationProvider {
+
+ /**
+ * Creates a new SQLServerSharedAuthenticationProvider that provides access
+ * to shared connections exposed by the SQLServerAuthenticationProvider.
+ *
+ * @throws GuacamoleException
+ * If a required property is missing, or an error occurs while parsing
+ * a property.
+ */
+ public SQLServerSharedAuthenticationProvider() throws GuacamoleException {
+ super(new SQLServerInjectorProvider(), SharedAuthenticationProviderService.class);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return "sqlserver-shared";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java
new file mode 100644
index 0000000..7bbe1b2
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * The SQLServer authentication provider.
+ */
+package org.apache.guacamole.auth.sqlserver;
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json
new file mode 100644
index 0000000..ee61ab5
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json
@@ -0,0 +1,28 @@
+{
+
+ "guacamoleVersion" : "0.9.13-incubating",
+
+ "name" : "SQLServer Authentication",
+ "namespace" : "guac-sqlserver",
+
+ "authProviders" : [
+ "org.apache.guacamole.auth.sqlserver.SQLServerAuthenticationProvider",
+ "org.apache.guacamole.auth.sqlserver.SQLServerSharedAuthenticationProvider"
+ ],
+
+ "css" : [
+ "styles/jdbc.css"
+ ],
+
+ "html" : [
+ "html/shared-connection.html"
+ ],
+
+ "translations" : [
+ "translations/en.json",
+ "translations/fr.json",
+ "translations/ru.json"
+ ]
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml
new file mode 100644
index 0000000..24008fc
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<mapper namespace="org.apache.guacamole.auth.jdbc.connection.ConnectionMapper" >
+
+ <!-- Result mapper for connection objects -->
+ <resultMap id="ConnectionResultMap" type="org.apache.guacamole.auth.jdbc.connection.ConnectionModel" >
+
+ <!-- Connection properties -->
+ <id column="connection_id" property="objectID" jdbcType="INTEGER"/>
+ <result column="connection_name" property="name" jdbcType="VARCHAR"/>
+ <result column="parent_id" property="parentIdentifier" jdbcType="INTEGER"/>
+ <result column="protocol" property="protocol" jdbcType="VARCHAR"/>
+ <result column="max_connections" property="maxConnections" jdbcType="INTEGER"/>
+ <result column="max_connections_per_user" property="maxConnectionsPerUser" jdbcType="INTEGER"/>
+ <result column="proxy_hostname" property="proxyHostname" jdbcType="VARCHAR"/>
+ <result column="proxy_port" property="proxyPort" jdbcType="INTEGER"/>
+ <result column="proxy_encryption_method" property="proxyEncryptionMethod" jdbcType="VARCHAR"
+ javaType="org.apache.guacamole.net.auth.GuacamoleProxyConfiguration$EncryptionMethod"/>
+ <result column="connection_weight" property="connectionWeight" jdbcType="INTEGER"/>
+ <result column="failover_only" property="failoverOnly" jdbcType="BOOLEAN"/>
+
+ <!-- Associated sharing profiles -->
+ <collection property="sharingProfileIdentifiers" resultSet="sharingProfiles" ofType="java.lang.String"
+ column="connection_id" foreignColumn="primary_connection_id">
+ <result column="sharing_profile_id"/>
+ </collection>
+
+ </resultMap>
+
+ <!-- Select all connection identifiers -->
+ <select id="selectIdentifiers" resultType="string">
+ SELECT connection_id
+ FROM [guacamole].[connection]
+ </select>
+
+ <!-- Select identifiers of all readable connections -->
+ <select id="selectReadableIdentifiers" resultType="string">
+ SELECT connection_id
+ FROM [guacamole].[connection_permission]
+ WHERE
+ user_id = #{user.objectID,jdbcType=INTEGER}
+ AND permission = 'READ'
+ </select>
+
+ <!-- Select all connection identifiers within a particular connection group -->
+ <select id="selectIdentifiersWithin" resultType="string">
+ SELECT connection_id
+ FROM [guacamole].[connection]
+ WHERE
+ <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}</if>
+ <if test="parentIdentifier == null">parent_id IS NULL</if>
+ </select>
+
+ <!-- Select identifiers of all readable connections within a particular connection group -->
+ <select id="selectReadableIdentifiersWithin" resultType="string">
+ SELECT [guacamole].[connection].connection_id
+ FROM [guacamole].[connection]
+ JOIN [guacamole].[connection_permission] ON [guacamole].[connection_permission].connection_id = [guacamole].[connection].connection_id
+ WHERE
+ <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}</if>
+ <if test="parentIdentifier == null">parent_id IS NULL</if>
+ AND user_id = #{user.objectID,jdbcType=INTEGER}
+ AND permission = 'READ'
+ </select>
+
+ <!-- Select multiple connections by identifier -->
+ <select id="select" resultMap="ConnectionResultMap"
+ resultSets="connections,sharingProfiles">
+
+ SELECT
+ connection_id,
+ connection_name,
+ parent_id,
+ protocol,
+ max_connections,
+ max_connections_per_user,
+ proxy_hostname,
+ proxy_port,
+ proxy_encryption_method,
+ connection_weight,
+ failover_only
+ FROM [guacamole].[connection]
+ WHERE connection_id IN
+ <foreach collection="identifiers" item="identifier"
+ open="(" separator="," close=")">
+ #{identifier,jdbcType=INTEGER}
+ </foreach>;
+
+ SELECT primary_connection_id, sharing_profile_id
+ FROM [guacamole].[sharing_profile]
+ WHERE primary_connection_id IN
+ <foreach collection="identifiers" item="identifier"
+ open="(" separator="," close=")">
+ #{identifier,jdbcType=INTEGER}
+ </foreach>;
+
+ </select>
+
+ <!-- Select multiple connections by identifier only if readable -->
+ <select id="selectReadable" resultMap="ConnectionResultMap"
+ resultSets="connections,sharingProfiles">
+
+ SELECT
+ [guacamole].[connection].connection_id,
+ connection_name,
+ parent_id,
+ protocol,
+ max_connections,
+ max_connections_per_user,
+ proxy_hostname,
+ proxy_port,
+ proxy_encryption_method,
+ connection_weight,
+ failover_only
+ FROM [guacamole].[connection]
+ JOIN [guacamole].[connection_permission] ON [guacamole].[connection_permission].connection_id = [guacamole].[connection].connection_id
+ WHERE [guacamole].[connection].connection_id IN
+ <foreach collection="identifiers" item="identifier"
+ open="(" separator="," close=")">
+ #{identifier,jdbcType=INTEGER}
+ </foreach>
+ AND user_id = #{user.objectID,jdbcType=INTEGER}
+ AND permission = 'READ';
+
+ SELECT primary_connection_id, [guacamole].[sharing_profile].sharing_profile_id
+ FROM [guacamole].[sharing_profile]
+ JOIN [guacamole].[sharing_profile_permission] ON [guacamole].[sharing_profile_permission].sharing_profile_id = [guacamole].[sharing_profile].sharing_profile_id
+ WHERE primary_connection_id IN
+ <foreach collection="identifiers" item="identifier"
+ open="(" separator="," close=")">
+ #{identifier,jdbcType=INTEGER}
+ </foreach>
+ AND user_id = #{user.objectID,jdbcType=INTEGER}
+ AND permission = 'READ';
+
+ </select>
+
+ <!-- Select single connection by name -->
+ <select id="selectOneByName" resultMap="ConnectionResultMap">
+
+ SELECT
+ connection_id,
+ connection_name,
+ parent_id,
+ protocol,
+ max_connections,
+ max_connections_per_user,
+ proxy_hostname,
+ proxy_port,
+ proxy_encryption_method,
+ connection_weight,
+ failover_only
+ FROM [guacamole].[connection]
+ WHERE
+ <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}</if>
+ <if test="parentIdentifier == null">parent_id IS NULL</if>
+ AND connection_name = #{name,jdbcType=VARCHAR}
+
+ </select>
+
+ <!-- Delete single connection by identifier -->
+ <delete id="delete">
+ DELETE FROM [guacamole].[connection]
+ WHERE connection_id = #{identifier,jdbcType=INTEGER}
+ </delete>
+
+ <!-- Insert single connection -->
+ <insert id="insert" useGeneratedKeys="true" keyProperty="object.objectID"
+ parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionModel">
+
+ INSERT INTO [guacamole].[connection] (
+ connection_name,
+ parent_id,
+ protocol,
+ max_connections,
+ max_connections_per_user,
+ proxy_hostname,
+ proxy_port,
+ proxy_encryption_method,
+ connection_weight,
+ failover_only
+ )
+ VALUES (
+ #{object.name,jdbcType=VARCHAR},
+ #{object.parentIdentifier,jdbcType=INTEGER},
+ #{object.protocol,jdbcType=VARCHAR},
+ #{object.maxConnections,jdbcType=INTEGER},
+ #{object.maxConnectionsPerUser,jdbcType=INTEGER},
+ #{object.proxyHostname,jdbcType=VARCHAR},
+ #{object.proxyPort,jdbcType=INTEGER},
+ #{object.proxyEncryptionMethod,jdbcType=VARCHAR},
+ #{object.connectionWeight,jdbcType=INTEGER},
+ #{object.failoverOnly,jdbcType=INTEGER}
+ )
+
+ </insert>
+
+ <!-- Update single connection -->
+ <update id="update" parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionModel">
+ UPDATE [guacamole].[connection]
+ SET connection_name = #{object.name,jdbcType=VARCHAR},
+ parent_id = #{object.parentIdentifier,jdbcType=INTEGER},
+ protocol = #{object.protocol,jdbcType=VARCHAR},
+ max_connections = #{object.maxConnections,jdbcType=INTEGER},
+ max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER},
+ proxy_hostname = #{object.proxyHostname,jdbcType=VARCHAR},
+ proxy_port = #{object.proxyPort,jdbcType=INTEGER},
+ proxy_encryption_method = #{object.proxyEncryptionMethod,jdbcType=VARCHAR},
+ connection_weight = #{object.connectionWeight,jdbcType=INTEGER},
+ failover_only = #{object.failoverOnly,jdbcType=INTEGER}
+ WHERE connection_id = #{object.objectID,jdbcType=INTEGER}
+ </update>
+
+</mapper>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml
new file mode 100644
index 0000000..de1ab97
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<mapper namespace="org.apache.guacamole.auth.jdbc.connection.ConnectionParameterMapper">
+
+ <!-- Result mapper for connection parameters -->
+ <resultMap id="ParameterResultMap" type="org.apache.guacamole.auth.jdbc.connection.ConnectionParameterModel">
+ <result column="connection_id" property="connectionIdentifier" jdbcType="INTEGER"/>
+ <result column="parameter_name" property="name" jdbcType="VARCHAR"/>
+ <result column="parameter_value" property="value" jdbcType="VARCHAR"/>
+ </resultMap>
+
+ <!-- Select all parameters of a given connection -->
+ <select id="select" resultMap="ParameterResultMap">
+ SELECT
+ connection_id,
+ parameter_name,
+ parameter_value
+ FROM [guacamole].[connection_parameter]
+ WHERE
+ connection_id = #{identifier,jdbcType=INTEGER}
+ </select>
+
+ <!-- Delete all parameters of a given connection -->
+ <delete id="delete">
+ DELETE FROM [guacamole].[connection_parameter]
+ WHERE connection_id = #{identifier,jdbcType=INTEGER}
+ </delete>
+
+ <!-- Insert all given parameters -->
+ <insert id="insert" parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionParameterModel">
+
+ INSERT INTO [guacamole].[connection_parameter] (
+ connection_id,
+ parameter_name,
+ parameter_value
+ )
+ VALUES
+ <foreach collection="parameters" item="parameter" separator=",">
+ (#{parameter.connectionIdentifier,jdbcType=INTEGER},
+ #{parameter.name,jdbcType=VARCHAR},
+ #{parameter.value,jdbcType=VARCHAR})
+ </foreach>
+
+ </insert>
+
+
+</mapper>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/b6e88d33/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
new file mode 100644
index 0000000..ec077db
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<mapper namespace="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordMapper" >
+
+ <!-- Result mapper for system permissions -->
+ <resultMap id="ConnectionRecordResultMap" type="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel">
+ <result column="connection_id" property="connectionIdentifier" jdbcType="INTEGER"/>
+ <result column="connection_name" property="connectionName" jdbcType="VARCHAR"/>
+ <result column="remote_host" property="remoteHost" jdbcType="VARCHAR"/>
+ <result column="sharing_profile_id" property="sharingProfileIdentifier" jdbcType="INTEGER"/>
+ <result column="sharing_profile_name" property="sharingProfileName" jdbcType="VARCHAR"/>
+ <result column="user_id" property="userID" jdbcType="INTEGER"/>
+ <result column="username" property="username" jdbcType="VARCHAR"/>
+ <result column="start_date" property="startDate" jdbcType="TIMESTAMP"/>
+ <result column="end_date" property="endDate" jdbcType="TIMESTAMP"/>
+ </resultMap>
+
+ <!-- Select all connection records from a given connection -->
+ <select id="select" resultMap="ConnectionRecordResultMap">
+
+ SELECT
+ [guacamole].[connection_history].connection_id,
+ [guacamole].[connection_history].connection_name,
+ [guacamole].[connection_history].remote_host,
+ [guacamole].[connection_history].sharing_profile_id,
+ [guacamole].[connection_history].sharing_profile_name,
+ [guacamole].[connection_history].user_id,
+ [guacamole].[connection_history].username,
+ [guacamole].[connection_history].start_date,
+ [guacamole].[connection_history].end_date
+ FROM [guacamole].[connection_history]
+ WHERE
+ [guacamole].[connection_history].connection_id = #{identifier,jdbcType=INTEGER}
+ ORDER BY
+ [guacamole].[connection_history].start_date DESC,
+ [guacamole].[connection_history].end_date DESC
+
+ </select>
+
+ <!-- Insert the given connection record -->
+ <insert id="insert" parameterType="org.apache.guacamole.auth.jdbc.connection.ConnectionRecordModel">
+
+ INSERT INTO [guacamole].[connection_history] (
+ connection_id,
+ connection_name,
+ remote_host,
+ sharing_profile_id,
+ sharing_profile_name,
+ user_id,
+ username,
+ start_date,
+ end_date
+ )
+ VALUES (
+ #{record.connectionIdentifier,jdbcType=INTEGER},
+ #{record.connectionName,jdbcType=VARCHAR},
+ #{record.remoteHost,jdbcType=VARCHAR},
+ #{record.sharingProfileIdentifier,jdbcType=INTEGER},
+ #{record.sharingProfileName,jdbcType=VARCHAR},
+ (SELECT user_id FROM [guacamole].[user]
+ WHERE username = #{record.username,jdbcType=VARCHAR}),
+ #{record.username,jdbcType=VARCHAR},
+ #{record.startDate,jdbcType=TIMESTAMP},
+ #{record.endDate,jdbcType=TIMESTAMP}
+ )
+
+ </insert>
+
+ <!-- Search for specific connection records -->
+ <select id="search" resultMap="ConnectionRecordResultMap">
+
+ SELECT
+ [guacamole].[connection_history].connection_id,
+ [guacamole].[connection_history].connection_name,
+ [guacamole].[connection_history].remote_host,
+ [guacamole].[connection_history].sharing_profile_id,
+ [guacamole].[connection_history].sharing_profile_name,
+ [guacamole].[connection_history].user_id,
+ [guacamole].[connection_history].username,
+ [guacamole].[connection_history].start_date,
+ [guacamole].[connection_history].end_date
+ FROM [guacamole].[connection_history]
+
+ <!-- Search terms -->
+ <foreach collection="terms" item="term"
+ open="WHERE " separator=" AND ">
+ (
+
+ [guacamole].[connection_history].user_id IN (
+ SELECT user_id
+ FROM [guacamole].[user]
+ WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0
+ )
+
+ OR [guacamole].[connection_history].connection_id IN (
+ SELECT connection_id
+ FROM [guacamole].[connection]
+ WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
+ )
+
+ <if test="term.startDate != null and term.endDate != null">
+ OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
+ </if>
+
+ )
+ </foreach>
+
+ <!-- Bind sort property enum values for sake of readability -->
+ <bind name="START_DATE" value="@org.apache.guacamole.net.auth.ConnectionRecordSet$SortableProperty@START_DATE"/>
+
+ <!-- Sort predicates -->
+ <foreach collection="sortPredicates" item="sortPredicate"
+ open="ORDER BY " separator=", ">
+ <choose>
+ <when test="sortPredicate.property == START_DATE">[guacamole].[connection_history].start_date</when>
+ <otherwise>1</otherwise>
+ </choose>
+ <if test="sortPredicate.descending">DESC</if>
+ </foreach>
+
+ LIMIT #{limit,jdbcType=INTEGER}
+
+ </select>
+
+ <!-- Search for specific connection records -->
+ <select id="searchReadable" resultMap="ConnectionRecordResultMap">
+
+ SELECT
+ [guacamole].[connection_history].connection_id,
+ [guacamole].[connection_history].connection_name,
+ [guacamole].[connection_history].remote_host,
+ [guacamole].[connection_history].sharing_profile_id,
+ [guacamole].[connection_history].sharing_profile_name,
+ [guacamole].[connection_history].user_id,
+ [guacamole].[connection_history].username,
+ [guacamole].[connection_history].start_date,
+ [guacamole].[connection_history].end_date
+ FROM [guacamole].[connection_history]
+ LEFT JOIN [guacamole].[connection] ON [guacamole].[connection_history].connection_id = [guacamole].[connection].connection_id
+ LEFT JOIN [guacamole].[user] ON [guacamole].[connection_history].user_id = [guacamole].[user].user_id
+
+ <!-- Restrict to readable connections -->
+ JOIN [guacamole].[connection_permission] ON
+ [guacamole].[connection_history].connection_id = [guacamole].[connection_permission].connection_id
+ AND [guacamole].[connection_permission].user_id = #{user.objectID,jdbcType=INTEGER}
+ AND [guacamole].[connection_permission].permission = 'READ'
+
+ <!-- Restrict to readable users -->
+ JOIN [guacamole].[user_permission] ON
+ [guacamole].[connection_history].user_id = [guacamole].[user_permission].affected_user_id
+ AND [guacamole].[user_permission].user_id = #{user.objectID,jdbcType=INTEGER}
+ AND [guacamole].[user_permission].permission = 'READ'
+
+ <!-- Search terms -->
+ <foreach collection="terms" item="term"
+ open="WHERE " separator=" AND ">
+ (
+
+ [guacamole].[connection_history].user_id IN (
+ SELECT user_id
+ FROM [guacamole].[user]
+ WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0
+ )
+
+ OR [guacamole].[connection_history].connection_id IN (
+ SELECT connection_id
+ FROM [guacamole].[connection]
+ WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0
+ )
+
+ <if test="term.startDate != null and term.endDate != null">
+ OR start_date BETWEEN #{term.startDate,jdbcType=TIMESTAMP} AND #{term.endDate,jdbcType=TIMESTAMP}
+ </if>
+
+ )
+ </foreach>
+
+ <!-- Bind sort property enum values for sake of readability -->
+ <bind name="START_DATE" value="@org.apache.guacamole.net.auth.ConnectionRecordSet$SortableProperty@START_DATE"/>
+
+ <!-- Sort predicates -->
+ <foreach collection="sortPredicates" item="sortPredicate"
+ open="ORDER BY " separator=", ">
+ <choose>
+ <when test="sortPredicate.property == START_DATE">[guacamole].[connection_history].start_date</when>
+ <otherwise>1</otherwise>
+ </choose>
+ <if test="sortPredicate.descending">DESC</if>
+ </foreach>
+
+ LIMIT #{limit,jdbcType=INTEGER}
+
+ </select>
+
+</mapper>