diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java index db0fe1b08..602784bae 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProvider.java @@ -29,11 +29,8 @@ import org.glyptodon.guacamole.net.auth.AuthenticationProvider; import org.glyptodon.guacamole.net.auth.Credentials; import org.glyptodon.guacamole.net.auth.UserContext; import org.glyptodon.guacamole.auth.jdbc.JDBCAuthenticationProviderModule; -import org.glyptodon.guacamole.auth.jdbc.tunnel.ConfigurableGuacamoleTunnelService; -import org.glyptodon.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; +import org.glyptodon.guacamole.auth.jdbc.JDBCEnvironment; import org.glyptodon.guacamole.auth.jdbc.user.AuthenticationProviderService; -import org.glyptodon.guacamole.environment.Environment; -import org.glyptodon.guacamole.environment.LocalEnvironment; import org.glyptodon.guacamole.net.auth.AuthenticatedUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,112 +55,6 @@ public class PostgreSQLAuthenticationProvider implements AuthenticationProvider */ private final Injector injector; - /** - * Returns the appropriate tunnel service given the Guacamole environment. - * The service is configured based on configuration options that dictate - * the default concurrent usage policy. - * - * @param environment - * The environment of the Guacamole server. - * - * @return - * A tunnel service implementation configured according to the - * concurrent usage policy options set in the Guacamole environment. - * - * @throws GuacamoleException - * If an error occurs while reading the configuration options. - */ - private GuacamoleTunnelService getTunnelService(Environment environment) - throws GuacamoleException { - - // Tunnel service default configuration - int connectionDefaultMaxConnections; - int connectionDefaultMaxConnectionsPerUser; - int connectionGroupDefaultMaxConnections; - int connectionGroupDefaultMaxConnectionsPerUser; - - // Read legacy concurrency-related properties - Boolean disallowSimultaneous = environment.getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_SIMULTANEOUS_CONNECTIONS); - Boolean disallowDuplicate = environment.getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_DUPLICATE_CONNECTIONS); - - // Legacy "simultaneous" property dictates only the maximum number of - // connections per connection - if (disallowSimultaneous != null) { - - // Translate legacy property - if (disallowSimultaneous) { - connectionDefaultMaxConnections = 1; - connectionGroupDefaultMaxConnections = 0; - } - else { - connectionDefaultMaxConnections = 0; - connectionGroupDefaultMaxConnections = 0; - } - - // Warn of deprecation - logger.warn("The \"{}\" property is deprecated. Use \"{}\" and \"{}\" instead.", - PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(), - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS.getName(), - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS.getName()); - - // Inform of new equivalent - logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".", - PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(), disallowSimultaneous, - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS.getName(), connectionDefaultMaxConnections, - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS.getName(), connectionGroupDefaultMaxConnections); - - } - - // If legacy property is not specified, use new property - else { - connectionDefaultMaxConnections = environment.getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS, 0); - connectionGroupDefaultMaxConnections = environment.getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS, 0); - } - - // Legacy "duplicate" property dictates whether connections and groups - // may be used concurrently only by different users - if (disallowDuplicate != null) { - - // Translate legacy property - if (disallowDuplicate) { - connectionDefaultMaxConnectionsPerUser = 1; - connectionGroupDefaultMaxConnectionsPerUser = 1; - } - else { - connectionDefaultMaxConnectionsPerUser = 0; - connectionGroupDefaultMaxConnectionsPerUser = 0; - } - - // Warn of deprecation - logger.warn("The \"{}\" property is deprecated. Use \"{}\" and \"{}\" instead.", - PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_DUPLICATE_CONNECTIONS.getName(), - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(), - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS.getName()); - - // Inform of new equivalent - logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".", - PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_DUPLICATE_CONNECTIONS.getName(), disallowDuplicate, - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(), connectionDefaultMaxConnectionsPerUser, - PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER.getName(), connectionGroupDefaultMaxConnectionsPerUser); - - } - - // If legacy property is not specified, use new property - else { - connectionDefaultMaxConnectionsPerUser = environment.getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS_PER_USER, 1); - connectionGroupDefaultMaxConnectionsPerUser = environment.getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER, 1); - } - - // Return service configured for specified default limits - return new ConfigurableGuacamoleTunnelService( - connectionDefaultMaxConnections, - connectionDefaultMaxConnectionsPerUser, - connectionGroupDefaultMaxConnections, - connectionGroupDefaultMaxConnectionsPerUser - ); - - } - /** * Creates a new PostgreSQLAuthenticationProvider that reads and writes * authentication data to a PostgreSQL database defined by properties in @@ -176,7 +67,7 @@ public class PostgreSQLAuthenticationProvider implements AuthenticationProvider public PostgreSQLAuthenticationProvider() throws GuacamoleException { // Get local environment - Environment environment = new LocalEnvironment(); + PostgreSQLEnvironment environment = new PostgreSQLEnvironment(); // Set up Guice injector. injector = Guice.createInjector( @@ -185,8 +76,7 @@ public class PostgreSQLAuthenticationProvider implements AuthenticationProvider new PostgreSQLAuthenticationProviderModule(environment), // Configure JDBC authentication core - new JDBCAuthenticationProviderModule(this, environment, - getTunnelService(environment)) + new JDBCAuthenticationProviderModule(this, environment) ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProviderModule.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProviderModule.java index 2decdf9a6..efd7b9f4f 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLAuthenticationProviderModule.java @@ -27,7 +27,6 @@ import com.google.inject.Module; import com.google.inject.name.Names; import java.util.Properties; import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.environment.Environment; import org.mybatis.guice.datasource.helper.JdbcHelper; /** @@ -60,16 +59,16 @@ public class PostgreSQLAuthenticationProviderModule implements Module { * If a required property is missing, or an error occurs while parsing * a property. */ - public PostgreSQLAuthenticationProviderModule(Environment environment) + public PostgreSQLAuthenticationProviderModule(PostgreSQLEnvironment environment) throws GuacamoleException { // Set the PostgreSQL-specific properties for MyBatis. myBatisProperties.setProperty("mybatis.environment.id", "guacamole"); - myBatisProperties.setProperty("JDBC.host", environment.getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_HOSTNAME)); - myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_PORT))); - myBatisProperties.setProperty("JDBC.schema", environment.getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DATABASE)); - myBatisProperties.setProperty("JDBC.username", environment.getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_USERNAME)); - myBatisProperties.setProperty("JDBC.password", environment.getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_PASSWORD)); + myBatisProperties.setProperty("JDBC.host", environment.getPostgreSQLHostname()); + myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getPostgreSQLPort())); + myBatisProperties.setProperty("JDBC.schema", environment.getPostgreSQLDatabase()); + myBatisProperties.setProperty("JDBC.username", environment.getPostgreSQLUsername()); + myBatisProperties.setProperty("JDBC.password", environment.getPostgreSQLPassword()); myBatisProperties.setProperty("JDBC.autoCommit", "false"); myBatisProperties.setProperty("mybatis.pooled.pingEnabled", "true"); myBatisProperties.setProperty("mybatis.pooled.pingQuery", "SELECT 1"); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLEnvironment.java new file mode 100644 index 000000000..83c139ec5 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/glyptodon/guacamole/auth/postgresql/PostgreSQLEnvironment.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.glyptodon.guacamole.auth.postgresql; + +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.auth.jdbc.JDBCEnvironment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A PostgreSQL-specific implementation of JDBCEnvironment provides database + * properties specifically for PostgreSQL. + * + * @author Michael Jumper + */ +public class PostgreSQLEnvironment extends JDBCEnvironment { + + /** + * Logger for this class. + */ + private static final Logger logger = LoggerFactory.getLogger(PostgreSQLEnvironment.class); + + /** + * The default host to connect to, if POSTGRESQL_HOSTNAME is not specified. + */ + private static final String DEFAULT_HOSTNAME = "localhost"; + + /** + * The default port to connect to, if POSTGRESQL_PORT is not specified. + */ + private static final int DEFAULT_PORT = 5432; + + /** + * 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 PostgreSQLEnvironment, providing access to PostgreSQL-specific + * configuration options. + * + * @throws GuacamoleException + * If an error occurs while setting up the underlying JDBCEnvironment + * or while parsing legacy PostgreSQL configuration options. + */ + public PostgreSQLEnvironment() throws GuacamoleException { + + // Init underlying JDBC environment + super(); + + // Read legacy concurrency-related property + Boolean disallowSimultaneous = getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_SIMULTANEOUS_CONNECTIONS); + Boolean disallowDuplicate = getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_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.", + PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(), + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS.getName(), + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS.getName()); + + // Inform of new equivalent + logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".", + PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_SIMULTANEOUS_CONNECTIONS.getName(), disallowSimultaneous, + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS.getName(), DEFAULT_MAX_CONNECTIONS, + PostgreSQLGuacamoleProperties.POSTGRESQL_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.", + PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_DUPLICATE_CONNECTIONS.getName(), + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(), + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS.getName()); + + // Inform of new equivalent + logger.info("To achieve the same result of setting \"{}\" to \"{}\", set \"{}\" to \"{}\" and \"{}\" to \"{}\".", + PostgreSQLGuacamoleProperties.POSTGRESQL_DISALLOW_DUPLICATE_CONNECTIONS.getName(), disallowDuplicate, + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS_PER_USER.getName(), DEFAULT_MAX_CONNECTIONS_PER_USER, + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER.getName(), DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER); + + } + + } + + @Override + public int getDefaultMaxConnections() throws GuacamoleException { + return getProperty( + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS, + DEFAULT_MAX_CONNECTIONS + ); + } + + @Override + public int getDefaultMaxGroupConnections() throws GuacamoleException { + return getProperty( + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS, + DEFAULT_MAX_GROUP_CONNECTIONS + ); + } + + @Override + public int getDefaultMaxConnectionsPerUser() throws GuacamoleException { + return getProperty( + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_CONNECTIONS_PER_USER, + DEFAULT_MAX_CONNECTIONS_PER_USER + ); + } + + @Override + public int getDefaultMaxGroupConnectionsPerUser() throws GuacamoleException { + return getProperty( + PostgreSQLGuacamoleProperties.POSTGRESQL_DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER, + DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER + ); + } + + /** + * Returns the hostname of the PostgreSQL server hosting the Guacamole + * authentication tables. If unspecified, this will be "localhost". + * + * @return + * The URL of the PostgreSQL server. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value. + */ + public String getPostgreSQLHostname() throws GuacamoleException { + return getProperty( + PostgreSQLGuacamoleProperties.POSTGRESQL_HOSTNAME, + DEFAULT_HOSTNAME + ); + } + + /** + * Returns the port number of the PostgreSQL server hosting the Guacamole + * authentication tables. If unspecified, this will be the default + * PostgreSQL port of 5432. + * + * @return + * The port number of the PostgreSQL server. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value. + */ + public int getPostgreSQLPort() throws GuacamoleException { + return getProperty( + PostgreSQLGuacamoleProperties.POSTGRESQL_PORT, + DEFAULT_PORT + ); + } + + /** + * Returns the name of the PostgreSQL database containing the Guacamole + * authentication tables. + * + * @return + * The name of the PostgreSQL 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 getPostgreSQLDatabase() throws GuacamoleException { + return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DATABASE); + } + + /** + * Returns the username that should be used when authenticating with the + * PostgreSQL database containing the Guacamole authentication tables. + * + * @return + * The username for the PostgreSQL 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 getPostgreSQLUsername() throws GuacamoleException { + return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_USERNAME); + } + + /** + * Returns the password that should be used when authenticating with the + * PostgreSQL database containing the Guacamole authentication tables. + * + * @return + * The password for the PostgreSQL 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 getPostgreSQLPassword() throws GuacamoleException { + return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_PASSWORD); + } + +}