diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java b/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java index 9855cd6fd..87e9e39d3 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java @@ -23,6 +23,7 @@ import java.util.Set; import java.util.UUID; import org.apache.guacamole.GuacamoleClientException; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.environment.Environment; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Credentials; @@ -71,6 +72,9 @@ public class AuthenticationProviderFacade implements AuthenticationProvider { * facade will still succeed, but its use will result in errors being * logged, and all authentication attempts will fail. * + * @param environment + * The Guacamole server environment. + * * @param authProviderClass * The AuthenticationProvider subclass to instantiate. * @@ -83,12 +87,12 @@ public class AuthenticationProviderFacade implements AuthenticationProvider { * attempt. By default, errors during authentication halt the * authentication process entirely. */ - public AuthenticationProviderFacade( + public AuthenticationProviderFacade(Environment environment, Class authProviderClass, Set tolerateFailures) { this.tolerateFailures = tolerateFailures; - this.authProvider = ProviderFactory.newInstance("authentication provider", - authProviderClass); + this.authProvider = ProviderFactory.newInstance(environment, + "authentication provider", authProviderClass); } @Override diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java index 58f124e6a..d7e266d2a 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java @@ -199,7 +199,7 @@ public class ExtensionModule extends ServletModule { logger.debug("[{}] Binding AuthenticationProvider \"{}\".", boundAuthenticationProviders.size(), authenticationProvider.getName()); boundAuthenticationProviders.add(new AuthenticationProviderFacade( - authenticationProvider, tolerateFailures)); + environment, authenticationProvider, tolerateFailures)); } @@ -255,7 +255,7 @@ public class ExtensionModule extends ServletModule { logger.debug("[{}] Binding listener \"{}\".", boundListeners.size(), providerClass.getName()); - boundListeners.addAll(ListenerFactory.createListeners(providerClass)); + boundListeners.addAll(ListenerFactory.createListeners(environment, providerClass)); } diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java index 8aa6babb4..ef8d22d5b 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java @@ -30,6 +30,7 @@ import org.apache.guacamole.net.event.listener.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.apache.guacamole.environment.Environment; /** * A factory that reflectively instantiates Listener objects for a given @@ -44,15 +45,20 @@ class ListenerFactory { * only listener type that will be returned. Otherwise, a list of Listener * objects that adapt the legacy listener interfaces will be returned. * + * @param environment + * The Environment instance that should be passed to the constructor + * of the given class, if a constructor accepting an Environment + * instance is defined. + * * @param providerClass * A class that represents a listener. * * @return * The list of listeners represented by the given provider class. */ - static List createListeners(Class providerClass) { + static List createListeners(Environment environment, Class providerClass) { - Object provider = ProviderFactory.newInstance("listener", providerClass); + Object provider = ProviderFactory.newInstance(environment, "listener", providerClass); if (provider instanceof Listener) { return Collections.singletonList((Listener) provider); diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java b/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java index 01fda5719..8f85093bd 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java @@ -24,6 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationTargetException; +import org.apache.guacamole.environment.Environment; /** * A utility for creating provider instances and logging unexpected outcomes @@ -37,10 +38,18 @@ class ProviderFactory { private static final Logger logger = LoggerFactory.getLogger(ProviderFactory.class); /** - * Creates an instance of the specified provider class using the no-arg constructor. + * Creates an instance of the specified provider class using either the + * constructor accepting an instance of the Environment interface or, if no + * such constructor is defined, the no-arg constructor. + * + * @param environment + * The Environment instance that should be passed to the constructor + * of the given class, if a constructor accepting an Environment + * instance is defined. * * @param typeName - * The provider type name used for log messages; e.g. "authentication provider". + * The provider type name used for log messages; e.g. "authentication + * provider". * * @param providerClass * The provider class to instantiate. @@ -51,19 +60,33 @@ class ProviderFactory { * @return * A provider instance or null if no instance was created due to error. */ - static T newInstance(String typeName, Class providerClass) { + static T newInstance(Environment environment, String typeName, + Class providerClass) { T instance = null; try { - // Attempt to instantiate the provider - instance = providerClass.getConstructor().newInstance(); + + // Attempt to instantiate the provider while providing the + // Guacamole server's environment + try { + instance = providerClass.getConstructor(Environment.class).newInstance(environment); + } + + // Fall back to no-arg constructor if no constructor accepts + // Environment + catch (NoSuchMethodException e) { + logger.debug("{} does not provide a constructor accepting " + + "Environment. Falling back to no-arg constructor.", + providerClass.getName()); + instance = providerClass.getConstructor().newInstance(); + } + } catch (NoSuchMethodException e) { logger.error("The {} extension in use is not properly defined. " + "Please contact the developers of the extension or, if you " + "are the developer, turn on debug-level logging.", typeName); - logger.debug("{} is missing a default constructor.", - providerClass.getName(), e); + logger.debug("{} is missing a usable constructor.", providerClass.getName(), e); } catch (SecurityException e) { logger.error("The Java security manager is preventing extensions "