GUACAMOLE-1: Remove BasicGuacamoleProperties. Finally remove support for "auth-provider" and "lib-directory" properties.

This commit is contained in:
Michael Jumper
2016-03-22 15:20:48 -07:00
parent 8590a0a492
commit c7a5f0bcd6
6 changed files with 31 additions and 392 deletions

View File

@@ -1,185 +0,0 @@
/*
* Copyright (C) 2013 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.apache.guacamole;
import java.io.File;
import java.io.FilenameFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.environment.LocalEnvironment;
import org.apache.guacamole.properties.BasicGuacamoleProperties;
/**
* A ClassLoader implementation which finds classes within a configurable
* directory. This directory is set within guacamole.properties. This class
* is deprecated in favor of DirectoryClassLoader, which is automatically
* configured based on the presence/absence of GUACAMOLE_HOME/lib.
*
* @author Michael Jumper
*/
@Deprecated
public class GuacamoleClassLoader extends ClassLoader {
/**
* Class loader which will load classes from the classpath specified
* in guacamole.properties.
*/
private URLClassLoader classLoader = null;
/**
* Any exception that occurs while the class loader is being instantiated.
*/
private static GuacamoleException exception = null;
/**
* Singleton instance of the GuacamoleClassLoader.
*/
private static GuacamoleClassLoader instance = null;
static {
try {
// Attempt to create singleton classloader which loads classes from
// all .jar's in the lib directory defined in guacamole.properties
instance = AccessController.doPrivileged(new PrivilegedExceptionAction<GuacamoleClassLoader>() {
@Override
public GuacamoleClassLoader run() throws GuacamoleException {
// TODONT: This should be injected, but GuacamoleClassLoader will be removed soon.
Environment environment = new LocalEnvironment();
return new GuacamoleClassLoader(
environment.getProperty(BasicGuacamoleProperties.LIB_DIRECTORY)
);
}
});
}
catch (PrivilegedActionException e) {
// On error, record exception
exception = (GuacamoleException) e.getException();
}
}
/**
* Creates a new GuacamoleClassLoader which reads classes from the given
* directory.
*
* @param libDirectory The directory to load classes from.
* @throws GuacamoleException If the file given is not a director, or if
* an error occurs while constructing the URL
* for the backing classloader.
*/
private GuacamoleClassLoader(File libDirectory) throws GuacamoleException {
// If no directory provided, just direct requests to parent classloader
if (libDirectory == null)
return;
// Validate directory is indeed a directory
if (!libDirectory.isDirectory())
throw new GuacamoleException(libDirectory + " is not a directory.");
// Get list of URLs for all .jar's in the lib directory
Collection<URL> jarURLs = new ArrayList<URL>();
File[] files = libDirectory.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// If it ends with .jar, accept the file
return name.endsWith(".jar");
}
});
// Verify directory was successfully read
if (files == null)
throw new GuacamoleException("Unable to read contents of directory " + libDirectory);
// Add the URL for each .jar to the jar URL list
for (File file : files) {
try {
jarURLs.add(file.toURI().toURL());
}
catch (MalformedURLException e) {
throw new GuacamoleException(e);
}
}
// Set delegate classloader to new URLClassLoader which loads from the
// .jars found above.
URL[] urls = new URL[jarURLs.size()];
classLoader = new URLClassLoader(
jarURLs.toArray(urls),
getClass().getClassLoader()
);
}
/**
* Returns an instance of a GuacamoleClassLoader which finds classes
* within the directory configured in guacamole.properties.
*
* @return An instance of a GuacamoleClassLoader.
* @throws GuacamoleException If no instance could be returned due to an
* error.
*/
public static GuacamoleClassLoader getInstance() throws GuacamoleException {
// If instance could not be created, rethrow original exception
if (exception != null) throw exception;
return instance;
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
// If no classloader, use default loader
if (classLoader == null)
return Class.forName(name);
// Otherwise, delegate
return classLoader.loadClass(name);
}
}

View File

@@ -37,7 +37,6 @@ import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleServerException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.properties.BasicGuacamoleProperties;
import org.apache.guacamole.resource.Resource;
import org.apache.guacamole.resource.ResourceServlet;
import org.apache.guacamole.resource.SequenceResource;
@@ -148,42 +147,6 @@ public class ExtensionModule extends ServletModule {
this.patchResourceService = new PatchResourceService();
}
/**
* Reads the value of the now-deprecated "auth-provider" property from
* guacamole.properties, returning the corresponding AuthenticationProvider
* class. If no authentication provider could be read, or the property is
* not present, null is returned.
*
* As this property is deprecated, this function will also log warning
* messages if the property is actually specified.
*
* @return
* The value of the deprecated "auth-provider" property, or null if the
* property is not present.
*/
@SuppressWarnings("deprecation") // We must continue to use this property until it is truly no longer supported
private Class<AuthenticationProvider> getAuthProviderProperty() {
// Get and bind auth provider instance, if defined via property
try {
// Use "auth-provider" property if present, but warn about deprecation
Class<AuthenticationProvider> authenticationProvider = environment.getProperty(BasicGuacamoleProperties.AUTH_PROVIDER);
if (authenticationProvider != null)
logger.warn("The \"auth-provider\" and \"lib-directory\" properties are now deprecated. Please use the \"extensions\" and \"lib\" directories within GUACAMOLE_HOME instead.");
return authenticationProvider;
}
catch (GuacamoleException e) {
logger.warn("Value of deprecated \"auth-provider\" property within guacamole.properties is not valid: {}", e.getMessage());
logger.debug("Error reading authentication provider from guacamole.properties.", e);
}
return null;
}
/**
* Binds the given AuthenticationProvider class such that any service
* requiring access to the AuthenticationProvider can obtain it via
@@ -410,11 +373,6 @@ public class ExtensionModule extends ServletModule {
// Load initial language resources from servlet context
languageResourceService.addLanguageResources(getServletContext());
// Load authentication provider from guacamole.properties for sake of backwards compatibility
Class<AuthenticationProvider> authProviderProperty = getAuthProviderProperty();
if (authProviderProperty != null)
bindAuthenticationProvider(authProviderProperty);
// Init JavaScript resources with base guacamole.min.js
Collection<Resource> javaScriptResources = new ArrayList<Resource>();
javaScriptResources.add(new WebApplicationResource(getServletContext(), "/guacamole.min.js"));

View File

@@ -38,7 +38,7 @@ import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.ObjectNode;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.properties.BasicGuacamoleProperties;
import org.apache.guacamole.properties.StringSetProperty;
import org.apache.guacamole.resource.ByteArrayResource;
import org.apache.guacamole.resource.Resource;
import org.apache.guacamole.resource.WebApplicationResource;
@@ -79,6 +79,19 @@ public class LanguageResourceService {
*/
private static final Pattern LANGUAGE_KEY_PATTERN = Pattern.compile(".*/([a-z]+(_[A-Z]+)?)\\.json");
/**
* Comma-separated list of all allowed languages, where each language is
* represented by a language key, such as "en" or "en_US". If specified,
* only languages within this list will be listed as available by the REST
* service.
*/
public final StringSetProperty ALLOWED_LANGUAGES = new StringSetProperty() {
@Override
public String getName() { return "allowed-languages"; }
};
/**
* The set of all language keys which are explicitly listed as allowed
* within guacamole.properties, or null if all defined languages should be
@@ -110,7 +123,7 @@ public class LanguageResourceService {
// Parse list of available languages from properties
try {
parsedAllowedLanguages = environment.getProperty(BasicGuacamoleProperties.ALLOWED_LANGUAGES);
parsedAllowedLanguages = environment.getProperty(ALLOWED_LANGUAGES);
logger.debug("Available languages will be restricted to: {}", parsedAllowedLanguages);
}

View File

@@ -1,68 +0,0 @@
/*
* 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.apache.guacamole.properties;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.properties.GuacamoleProperty;
/**
* A GuacamoleProperty whose value is the name of a class to use to
* authenticate users. This class must implement AuthenticationProvider. Use
* of this property type is deprecated in favor of the
* GUACAMOLE_HOME/extensions directory.
*
* @author Michael Jumper
*/
@Deprecated
public abstract class AuthenticationProviderProperty implements GuacamoleProperty<Class<AuthenticationProvider>> {
@Override
@SuppressWarnings("unchecked") // Explicitly checked within by isAssignableFrom()
public Class<AuthenticationProvider> parseValue(String authProviderClassName) throws GuacamoleException {
// If no property provided, return null.
if (authProviderClassName == null)
return null;
// Get auth provider instance
try {
// Get authentication provider class
Class<?> authProviderClass = org.apache.guacamole.GuacamoleClassLoader.getInstance().loadClass(authProviderClassName);
// Verify the located class is actually a subclass of AuthenticationProvider
if (!AuthenticationProvider.class.isAssignableFrom(authProviderClass))
throw new GuacamoleException("Specified authentication provider class is not a AuthenticationProvider.");
// Return located class
return (Class<AuthenticationProvider>) authProviderClass;
}
catch (ClassNotFoundException e) {
throw new GuacamoleException("Authentication provider class not found", e);
}
}
}

View File

@@ -1,90 +0,0 @@
/*
* Copyright (C) 2013 Glyptodon LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.apache.guacamole.properties;
import org.apache.guacamole.properties.FileGuacamoleProperty;
import org.apache.guacamole.properties.IntegerGuacamoleProperty;
import org.apache.guacamole.properties.StringGuacamoleProperty;
/**
* Properties used by the default Guacamole web application.
*
* @author Michael Jumper
*/
public class BasicGuacamoleProperties {
/**
* This class should not be instantiated.
*/
private BasicGuacamoleProperties() {}
/**
* The authentication provider to user when retrieving the authorized
* configurations of a user. This property is currently supported, but
* deprecated in favor of the GUACAMOLE_HOME/extensions directory.
*/
@Deprecated
public static final AuthenticationProviderProperty AUTH_PROVIDER = new AuthenticationProviderProperty() {
@Override
public String getName() { return "auth-provider"; }
};
/**
* The directory to search for authentication provider classes. This
* property is currently supported, but deprecated in favor of the
* GUACAMOLE_HOME/lib directory.
*/
@Deprecated
public static final FileGuacamoleProperty LIB_DIRECTORY = new FileGuacamoleProperty() {
@Override
public String getName() { return "lib-directory"; }
};
/**
* The session timeout for the API, in minutes.
*/
public static final IntegerGuacamoleProperty API_SESSION_TIMEOUT = new IntegerGuacamoleProperty() {
@Override
public String getName() { return "api-session-timeout"; }
};
/**
* Comma-separated list of all allowed languages, where each language is
* represented by a language key, such as "en" or "en_US". If specified,
* only languages within this list will be listed as available by the REST
* service.
*/
public static final StringSetProperty ALLOWED_LANGUAGES = new StringSetProperty() {
@Override
public String getName() { return "allowed-languages"; }
};
}

View File

@@ -32,14 +32,14 @@ import java.util.concurrent.TimeUnit;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.GuacamoleSession;
import org.apache.guacamole.properties.BasicGuacamoleProperties;
import org.apache.guacamole.properties.IntegerGuacamoleProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A basic, HashMap-based implementation of the TokenSessionMap with support
* for session timeouts.
*
* A HashMap-based implementation of the TokenSessionMap with support for
* session timeouts.
*
* @author James Muehlner
*/
public class BasicTokenSessionMap implements TokenSessionMap {
@@ -60,6 +60,17 @@ public class BasicTokenSessionMap implements TokenSessionMap {
private final ConcurrentMap<String, GuacamoleSession> sessionMap =
new ConcurrentHashMap<String, GuacamoleSession>();
/**
* The session timeout for the Guacamole REST API, in minutes.
*/
private final IntegerGuacamoleProperty API_SESSION_TIMEOUT =
new IntegerGuacamoleProperty() {
@Override
public String getName() { return "api-session-timeout"; }
};
/**
* Create a new BasicTokenGuacamoleSessionMap configured using the given
* environment.
@@ -73,7 +84,7 @@ public class BasicTokenSessionMap implements TokenSessionMap {
// Read session timeout from guacamole.properties
try {
sessionTimeoutValue = environment.getProperty(BasicGuacamoleProperties.API_SESSION_TIMEOUT, 60);
sessionTimeoutValue = environment.getProperty(API_SESSION_TIMEOUT, 60);
}
catch (GuacamoleException e) {
logger.error("Unable to read guacamole.properties: {}", e.getMessage());