From 252c4478b47ac85a290b453815c56f048473168d Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Fri, 11 Aug 2017 12:57:41 -0400 Subject: [PATCH 01/94] GUACAMOLE-358: Allow settings page to load even if permissions cannot be loaded. --- .../webapp/app/settings/directives/guacSettingsPreferences.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js index 0a3ed6e9d..d906c3dc0 100644 --- a/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js +++ b/guacamole/src/main/webapp/app/settings/directives/guacSettingsPreferences.js @@ -192,6 +192,9 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe $scope.canChangePassword = PermissionSet.hasUserPermission(permissions, PermissionSet.ObjectPermissionType.UPDATE, username); + }) + .error(function permissionsFailed(error) { + $scope.canChangePassword = false; }); /** From 287ab56f0f793190522e9d173f3fbd61c9155919 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Wed, 16 Aug 2017 06:52:10 -0400 Subject: [PATCH 02/94] GUACAMOLE-364: factor out common provider class instantiation support This will allow the same error and debug logging to be used both for the AuthenticationProviderFacade and a new ListenerFacade. --- .../AuthenticationProviderFacade.java | 55 +--------- .../guacamole/extension/ProviderFactory.java | 102 ++++++++++++++++++ 2 files changed, 104 insertions(+), 53 deletions(-) create mode 100644 guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java 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 e1ed5ff68..cb65909a0 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java @@ -19,7 +19,6 @@ package org.apache.guacamole.extension; -import java.lang.reflect.InvocationTargetException; import java.util.UUID; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.auth.AuthenticatedUser; @@ -66,58 +65,8 @@ public class AuthenticationProviderFacade implements AuthenticationProvider { * The AuthenticationProvider subclass to instantiate. */ public AuthenticationProviderFacade(Class authProviderClass) { - - AuthenticationProvider instance = null; - - try { - // Attempt to instantiate the authentication provider - instance = authProviderClass.getConstructor().newInstance(); - } - catch (NoSuchMethodException e) { - logger.error("The authentication 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."); - logger.debug("AuthenticationProvider is missing a default constructor.", e); - } - catch (SecurityException e) { - logger.error("The Java security mananager is preventing authentication extensions " - + "from being loaded. Please check the configuration of Java or your " - + "servlet container."); - logger.debug("Creation of AuthenticationProvider disallowed by security manager.", e); - } - catch (InstantiationException e) { - logger.error("The authentication 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."); - logger.debug("AuthenticationProvider cannot be instantiated.", e); - } - catch (IllegalAccessException e) { - logger.error("The authentication 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."); - logger.debug("Default constructor of AuthenticationProvider is not public.", e); - } - catch (IllegalArgumentException e) { - logger.error("The authentication 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."); - logger.debug("Default constructor of AuthenticationProvider cannot accept zero arguments.", e); - } - catch (InvocationTargetException e) { - - // Obtain causing error - create relatively-informative stub error if cause is unknown - Throwable cause = e.getCause(); - if (cause == null) - cause = new GuacamoleException("Error encountered during initialization."); - - logger.error("Authentication extension failed to start: {}", cause.getMessage()); - logger.debug("AuthenticationProvider instantiation failed.", e); - - } - - // Associate instance, if any - authProvider = instance; - + authProvider = ProviderFactory.newInstance("authentication provider", + authProviderClass); } @Override diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java b/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java new file mode 100644 index 000000000..0620b4da8 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java @@ -0,0 +1,102 @@ +/* + * 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.extension; + +import org.apache.guacamole.GuacamoleException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationTargetException; + +/** + * Static factory method for creating provider instances and logging unexpected outcomes + * with sufficient detail to allow user/developer debugging. + */ +class ProviderFactory { + + private static final Logger logger = LoggerFactory.getLogger(ProviderFactory.class); + + /** + * Creates an instance of the specified provider class using the no-arg constructor. + * + * @param typeName + * The provider type name used for log messages (e.g. "authentication provider") + * @param providerClass + * The provider class to instantiate + * @param + * The provider type + * @return + * A provider instance or null if no instance was created due to error + */ + static T newInstance(String typeName, Class providerClass) { + T instance = null; + + try { + // Attempt to instantiate the provider + 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); + } + catch (SecurityException e) { + logger.error("The Java security manager is preventing extensions " + + "from being loaded. Please check the configuration of Java or your " + + "servlet container."); + logger.debug("Creation of {} disallowed by security manager.", + providerClass.getName(), e); + } + catch (InstantiationException 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("{} cannot be instantiated.", providerClass.getName(), e); + } + catch (IllegalAccessException 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."); + logger.debug("Default constructor of {} is not public.", typeName, e); + } + catch (IllegalArgumentException 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("Default constructor of {} cannot accept zero arguments.", + providerClass.getName(), e); + } + catch (InvocationTargetException e) { + // Obtain causing error - create relatively-informative stub error if cause is unknown + Throwable cause = e.getCause(); + if (cause == null) + cause = new GuacamoleException("Error encountered during initialization."); + + logger.error("{} extension failed to start: {}", typeName, cause.getMessage()); + logger.debug("{} instantiation failed.", providerClass.getName(), e); + } + + return instance; + } + +} From 6f89a0b53047dd1cc9fac8264639c30067bf6cb6 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Wed, 16 Aug 2017 06:54:16 -0400 Subject: [PATCH 03/94] GUACAMOLE-364: listener interfaces now extend a common marker interface --- .../AuthenticationFailureListener.java | 3 +- .../AuthenticationSuccessListener.java | 2 +- .../net/event/listener/Listener.java | 29 +++++++++++++++++++ .../event/listener/TunnelCloseListener.java | 4 +-- .../event/listener/TunnelConnectListener.java | 2 +- 5 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java index 5fcd27b67..7fa619042 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java @@ -27,8 +27,7 @@ import org.apache.guacamole.net.event.AuthenticationFailureEvent; * after a user's authentication attempt fails. Note that this hook cannot * be used to cancel the authentication failure. */ -public interface AuthenticationFailureListener { - +public interface AuthenticationFailureListener extends Listener { /** * Event hook which fires immediately after a user's authentication attempt * fails. diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java index 7db072c36..cc5e01d57 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java @@ -28,7 +28,7 @@ import org.apache.guacamole.net.event.AuthenticationSuccessEvent; * the authenticationSucceeded() hook has the opportunity to cancel the * authentication and force it to fail. */ -public interface AuthenticationSuccessListener { +public interface AuthenticationSuccessListener extends Listener { /** * Event hook which fires immediately after a user's authentication attempt diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java new file mode 100644 index 000000000..72f859db1 --- /dev/null +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java @@ -0,0 +1,29 @@ +/* + * 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.net.event.listener; + +/** + * A marker interface extended by all listener types. This interface is used + * simply to validate that a listener class identified in an extension + * actually implements some listener interface. + */ +public interface Listener { +} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java index 784e4e932..99f2c04de 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java @@ -26,10 +26,10 @@ import org.apache.guacamole.net.event.TunnelCloseEvent; * A listener whose tunnelClosed() hook will fire immediately after an * existing tunnel is closed. */ -public interface TunnelCloseListener { +public interface TunnelCloseListener extends Listener { /** - * Event hook which fires immediately after an existing tunnel is closed. + * Event hook which fires immediately before an existing tunnel is closed. * The return value of this hook dictates whether the tunnel is allowed to * be closed. * diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java index da14fe277..7ac47e189 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java @@ -26,7 +26,7 @@ import org.apache.guacamole.net.event.TunnelConnectEvent; * A listener whose tunnelConnected() hook will fire immediately after a new * tunnel is connected. */ -public interface TunnelConnectListener { +public interface TunnelConnectListener extends Listener { /** * Event hook which fires immediately after a new tunnel is connected. From dca7862351fd4c27e82ecaf1cf540180501f48ec Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Wed, 16 Aug 2017 06:54:55 -0400 Subject: [PATCH 04/94] GUACAMOLE-364: add facade used to wrap extension listeners --- .../guacamole/extension/ListenerFacade.java | 135 ++++++++++++++++++ .../guacamole/extension/ListenerProvider.java | 37 +++++ 2 files changed, 172 insertions(+) create mode 100644 guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java create mode 100644 guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java new file mode 100644 index 000000000..278b2a934 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java @@ -0,0 +1,135 @@ +/* + * 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.extension; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.net.event.AuthenticationFailureEvent; +import org.apache.guacamole.net.event.AuthenticationSuccessEvent; +import org.apache.guacamole.net.event.TunnelCloseEvent; +import org.apache.guacamole.net.event.TunnelConnectEvent; +import org.apache.guacamole.net.event.listener.*; + +/** + * Provides a wrapper around a Listener subclass, allowing listener + * extensions to be bound without regard for which specific listener interfaces + * are implemented. + */ +class ListenerFacade implements ListenerProvider { + + private final Listener delegate; + + /** + * Creates a new ListenerFacade which delegates all listener methods + * calls to an instance of the given Listener subclass. If + * an instance of the given class cannot be created, creation of this + * facade will still succeed. Errors will be logged at the time listener + * creation fails, but subsequent events directed to the listener will be + * silently dropped. + * + * @param listenerClass + * The Listener subclass to instantiate. + */ + public ListenerFacade(Class listenerClass) { + delegate = ProviderFactory.newInstance("listener", listenerClass); + } + + /** + * Notifies the delegate listener of an authentication success event, if the + * listener implements the AuthenticationSuccessListener interface. + * + * @param + * e The AuthenticationSuccessEvent describing the authentication + * success that just occurred. + * @return + * false if the delegate listener rejects the successful authentication, + * else true + * + * @throws GuacamoleException + * if the delegate listener throws this exception + */ + @Override + public boolean authenticationSucceeded(AuthenticationSuccessEvent e) + throws GuacamoleException { + return !(delegate instanceof AuthenticationSuccessListener) + || ((AuthenticationSuccessListener) delegate).authenticationSucceeded(e); + } + + /** + * Notifies the delegate listener of an authentication failure event, if the + * listener implements the AuthenticationSuccessListener interface. + * + * @param + * e The AuthenticationFailureEvent describing the authentication + * failure that just occurred. + * + * @throws GuacamoleException + * if the delegate listener throws this exception + */ + @Override + public void authenticationFailed(AuthenticationFailureEvent e) + throws GuacamoleException { + if (delegate instanceof AuthenticationFailureListener) { + ((AuthenticationFailureListener) delegate).authenticationFailed(e); + } + } + + /** + * Notifies the delegate listener of a tunnel connected event, if the + * listener implements the TunnelConnectListener interface. + * + * @param + * e The TunnelConnectEvent describing the tunnel that was just connected + + * @return + * false if the delegate listener rejects the tunnel connection, + * else true + * + * @throws GuacamoleException + * if the delegate listener throws this exception + */ + @Override + public boolean tunnelConnected(TunnelConnectEvent e) + throws GuacamoleException { + return !(delegate instanceof TunnelConnectListener) + || ((TunnelConnectListener) delegate).tunnelConnected(e); + } + + /** + * Notifies the delegate listener of a tunnel close event, if the + * listener implements the TunnelCloseListener interface. + * + * @param + * e The TunnelCloseEvent describing the tunnel that is to be close + + * @return + * false if the delegate listener rejects the tunnel close request, + * else true + * + * @throws GuacamoleException + * if the delegate listener throws this exception + */ + @Override + public boolean tunnelClosed(TunnelCloseEvent e) throws GuacamoleException { + return !(delegate instanceof TunnelCloseListener) + || ((TunnelCloseListener) delegate).tunnelClosed(e); + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java new file mode 100644 index 000000000..0b3a7473d --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java @@ -0,0 +1,37 @@ +/* + * 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.extension; + +import org.apache.guacamole.net.event.listener.AuthenticationFailureListener; +import org.apache.guacamole.net.event.listener.AuthenticationSuccessListener; +import org.apache.guacamole.net.event.listener.TunnelCloseListener; +import org.apache.guacamole.net.event.listener.TunnelConnectListener; + +/** + * A provider of an event listener. While an implementation of this interface + * must implement all of the specified listener interfaces, an implementation + * may selectively deliver event notifications to an underlying delegate based + * on the specific listener interfaces implemented by the delegate. + */ +public interface ListenerProvider extends AuthenticationSuccessListener, + AuthenticationFailureListener, TunnelConnectListener, + TunnelCloseListener { +} From 109d57ecb372c3fc8114792086f339e9269eaf98 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Wed, 16 Aug 2017 06:55:28 -0400 Subject: [PATCH 05/94] GUACAMOLE-364: add extension module support for event listeners --- .../apache/guacamole/extension/Extension.java | 95 +++++++++++++++++++ .../extension/ExtensionManifest.java | 31 ++++++ .../guacamole/extension/ExtensionModule.java | 53 +++++++++++ 3 files changed, 179 insertions(+) diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java b/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java index 3183fa21c..ac58676ec 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java @@ -35,6 +35,8 @@ import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; + +import org.apache.guacamole.net.event.listener.Listener; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.ObjectMapper; import org.apache.guacamole.GuacamoleException; @@ -109,6 +111,11 @@ public class Extension { */ private final Collection> authenticationProviderClasses; + /** + * The collection of all Listener classes defined within the extension. + */ + private final Collection> listenerClasses; + /** * The resource for the small favicon for the extension. If provided, this * will replace the default Guacamole icon. @@ -265,6 +272,80 @@ public class Extension { } + /** + * Retrieve the Listener subclass having the given name. If + * the class having the given name does not exist or isn't actually a + * subclass of Listener, an exception will be thrown. + * + * @param name + * The name of the Listener class to retrieve. + * + * @return + * The subclass of Listener having the given name. + * + * @throws GuacamoleException + * If no such class exists, or if the class with the given name is not + * a subclass of Listener. + */ + @SuppressWarnings("unchecked") // We check this ourselves with isAssignableFrom() + private Class getListenerClass(String name) + throws GuacamoleException { + + try { + + // Get listener class + Class listenerClass = classLoader.loadClass(name); + + // Verify the located class is actually a subclass of Listener + if (!Listener.class.isAssignableFrom(listenerClass)) + throw new GuacamoleServerException("Listeners MUST implement a Listener subclass."); + + // Return located class + return (Class) listenerClass; + + } + catch (ClassNotFoundException e) { + throw new GuacamoleException("Listener class not found.", e); + } + catch (LinkageError e) { + throw new GuacamoleException("Listener class cannot be loaded (wrong version of API?).", e); + } + + } + + /** + * Returns a new collection of all Listener subclasses having the given names. + * If any class does not exist or isn't actually subclass of Listener, an + * exception will be thrown, an no further Listener classes will be loaded. + * + * @param names + * The names of the AuthenticationProvider classes to retrieve. + * + * @return + * A new collection of all AuthenticationProvider subclasses having the + * given names. + * + * @throws GuacamoleException + * If any given class does not exist, or if any given class is not a + * subclass of AuthenticationProvider. + */ + private Collection> getListenerClasses(Collection names) + throws GuacamoleException { + + // If no classnames are provided, just return an empty list + if (names == null) + return Collections.>emptyList(); + + // Define all auth provider classes + Collection> classes = new ArrayList>(names.size()); + for (String name : names) + classes.add(getListenerClass(name)); + + // Callers should not rely on modifying the result + return Collections.unmodifiableCollection(classes); + } + + /** * Loads the given file as an extension, which must be a .jar containing * a guac-manifest.json file describing its contents. @@ -363,6 +444,9 @@ public class Extension { // Define authentication providers authenticationProviderClasses = getAuthenticationProviderClasses(manifest.getAuthProviders()); + // Define listeners + listenerClasses = getListenerClasses(manifest.getListeners()); + // Get small icon resource if provided if (manifest.getSmallIcon() != null) smallIcon = new ClassPathResource(classLoader, "image/png", manifest.getSmallIcon()); @@ -488,6 +572,17 @@ public class Extension { return authenticationProviderClasses; } + /** + * Returns all declared listener classes associated wit this extension. Listeners are + * declared within the extension manifest. + * + * @return + * All declared listener classes with this extension. + */ + public Collection> getListenerClasses() { + return listenerClasses; + } + /** * Returns the resource for the small favicon for the extension. If * provided, this will replace the default Guacamole icon. diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java index 9b9bd9bee..1636b0350 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java @@ -87,6 +87,11 @@ public class ExtensionManifest { */ private Collection authProviders; + /** + * The names of all listener classes within this extension, if any. + */ + private Collection listeners; + /** * The path to the small favicon. If provided, this will replace the default * Guacamole icon. @@ -355,6 +360,32 @@ public class ExtensionManifest { this.authProviders = authProviders; } + /** + * Returns the classnames of all listener classes within the extension. + * These classnames are defined within the manifest by the "listeners" + * property as an array of strings, where each string is a listener + * class name. + * + * @return + * a collection of classnames for all listeners within the extension + */ + public Collection getListeners() { + return listeners; + } + + /** + * Sets the classnames of all listener classes within the extension. + * These classnames are defined within the manifest by the "listeners" + * property as an array of strings, where each string is a listener + * class name. + * + * @param listeners + * a collection of classnames for all listeners within the extension + */ + public void setListeners(Collection listeners) { + this.listeners = listeners; + } + /** * Returns the path to the small favicon, relative to the root of the * extension. 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 792066c87..1e1a85452 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java @@ -34,6 +34,7 @@ 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.net.event.listener.Listener; import org.apache.guacamole.resource.Resource; import org.apache.guacamole.resource.ResourceServlet; import org.apache.guacamole.resource.SequenceResource; @@ -91,6 +92,12 @@ public class ExtensionModule extends ServletModule { private final List boundAuthenticationProviders = new ArrayList(); + /** + * All currently-bound authentication providers, if any. + */ + private final List boundListenerProviders = + new ArrayList(); + /** * Service for adding and retrieving language resources. */ @@ -187,6 +194,49 @@ public class ExtensionModule extends ServletModule { return Collections.unmodifiableList(boundAuthenticationProviders); } + /** + * Binds the given Listener class such that any service + * requiring access to the Listener can obtain it via + * injection, along with any other bound Listener. + * + * @param listenerClass + * The Listener class to bind. + */ + private void bindListenerProvider(Class listenerClass) { + + // Bind listener + logger.debug("[{}] Binding Listener \"{}\".", + boundListenerProviders.size(), listenerClass.getName()); + boundListenerProviders.add(new ListenerFacade(listenerClass)); + } + + /** + * Binds each of the the given Listener classes such that any + * service requiring access to the Listener can obtain it via + * injection. + * + * @param listeners + * The Listener classes to bind. + */ + private void bindListenerProviders(Collection> listeners) { + + // Bind each listener within extension + for (Class listener : listeners) + bindListenerProvider(listener); + } + + /** + * Returns a list of all currently-bound ListenerProvider instances. + * + * @return + * A List of all currently-bound ListenerProvider instances. The List is + * not modifiable. + */ + @Provides + public List getListenerProviders() { + return Collections.unmodifiableList(boundListenerProviders); + } + /** * Serves each of the given resources as a language resource. Language * resources are served from within the "/translations" directory as JSON @@ -327,6 +377,9 @@ public class ExtensionModule extends ServletModule { // Attempt to load all authentication providers bindAuthenticationProviders(extension.getAuthenticationProviderClasses()); + // Attempt to load all listeners + bindListenerProviders(extension.getListenerClasses()); + // Add any translation resources serveLanguageResources(extension.getTranslationResources()); From cfb879b763b4254ba1c44b38d7fb5993b3e62187 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Wed, 16 Aug 2017 06:57:16 -0400 Subject: [PATCH 06/94] GUACAMOLE-364: add injectable ListenerService --- .../guacamole/rest/RESTServiceModule.java | 2 + .../guacamole/rest/event/ListenerService.java | 142 ++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java index cab4d973b..587d8338e 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java @@ -19,6 +19,7 @@ package org.apache.guacamole.rest; +import org.apache.guacamole.rest.event.ListenerService; import org.apache.guacamole.rest.session.UserContextResourceFactory; import org.apache.guacamole.rest.session.SessionRESTService; import com.google.inject.Scopes; @@ -76,6 +77,7 @@ public class RESTServiceModule extends ServletModule { bind(TokenSessionMap.class).toInstance(tokenSessionMap); // Bind low-level services + bind(ListenerService.class); bind(AuthenticationService.class); bind(AuthTokenGenerator.class).to(SecureRandomAuthTokenGenerator.class); diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java new file mode 100644 index 000000000..3b1a00f56 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java @@ -0,0 +1,142 @@ +/* + * 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.rest.event; + +import com.google.inject.Inject; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.extension.ListenerProvider; +import org.apache.guacamole.net.event.AuthenticationFailureEvent; +import org.apache.guacamole.net.event.AuthenticationSuccessEvent; +import org.apache.guacamole.net.event.TunnelCloseEvent; +import org.apache.guacamole.net.event.TunnelConnectEvent; +import org.apache.guacamole.net.event.listener.AuthenticationFailureListener; +import org.apache.guacamole.net.event.listener.AuthenticationSuccessListener; +import org.apache.guacamole.net.event.listener.TunnelCloseListener; +import org.apache.guacamole.net.event.listener.TunnelConnectListener; + +import java.util.List; + +/** + * A service used to notify listeners registered by extensions when events of + * interest occur. + * + * @author Carl Harris + */ +public class ListenerService implements ListenerProvider { + + @Inject + private List listeners; + + /** + * Notifies all bound listeners of an authentication success event. Listeners + * are allowed to veto a successful authentication by returning false from the + * listener method. Regardless of whether a particular listener rejects the + * successful authentication, all listeners are notified. + * @param e + * The AuthenticationSuccessEvent describing the successful authentication + * that just occurred. + * + * @return + * false if any bound listener returns false, else true + * + * @throws GuacamoleException + * If any bound listener throws this exception. If a listener throws an exception + * some listeners may not receive the authentication success event notification. + */ + @Override + public boolean authenticationSucceeded(AuthenticationSuccessEvent e) + throws GuacamoleException { + boolean result = true; + for (AuthenticationSuccessListener listener : listeners) { + result = result && listener.authenticationSucceeded(e); + } + return result; + } + + /** + * Notifies all bound listeners of an authentication failure event. + * + * @param e + * The AuthenticationSuccessEvent describing the authentication failure + * that just occurred. + * + * @throws GuacamoleException + * If any bound listener throws this exception. If a listener throws an exception + * some listeners may not receive the authentication failure event notification. + */ + @Override + public void authenticationFailed(AuthenticationFailureEvent e) + throws GuacamoleException { + for (AuthenticationFailureListener listener : listeners) { + listener.authenticationFailed(e); + } + } + + /** + * Notifies all bound listeners of an tunnel connected event. Listeners + * are allowed to veto a tunnel connection by returning false from the + * listener method. Regardless of whether a particular listener rejects the + * tunnel connection, all listeners are notified. + * @param e + * The TunnelConnectedEvent describing the tunnel that was just connected + * + * @return + * false if any bound listener returns false, else true + * + * @throws GuacamoleException + * If any bound listener throws this exception. If a listener throws an exception + * some listeners may not receive the tunnel connected event notification. + */ + @Override + public boolean tunnelConnected(TunnelConnectEvent e) + throws GuacamoleException { + boolean result = true; + for (TunnelConnectListener listener : listeners) { + result = result && listener.tunnelConnected(e); + } + return result; + } + + /** + * Notifies all bound listeners of an tunnel close event. Listeners + * are allowed to veto the request to close a tunnel by returning false from + * the listener method. Regardless of whether a particular listener rejects the + * tunnel close request, all listeners are notified. + * @param e + * The TunnelCloseEvent describing the tunnel that is to be closed + * + * @return + * false if any bound listener returns false, else true + * + * @throws GuacamoleException + * If any bound listener throws this exception. If a listener throws an exception + * some listeners may not receive the tunnel close event notification. + */ + @Override + public boolean tunnelClosed(TunnelCloseEvent e) throws GuacamoleException { + boolean result = true; + for (TunnelCloseListener listener : listeners) { + result = result && listener.tunnelClosed(e); + } + return result; + } + +} From 5a232f6825deb9b73f89473f941d92d012e36f67 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Wed, 16 Aug 2017 06:58:18 -0400 Subject: [PATCH 07/94] GUACAMOLE-364: notify authentication listeners in AuthenticationService --- ...camoleAuthenticationRejectedException.java | 34 +++++++++ .../rest/auth/AuthenticationService.java | 70 +++++++++++++++++-- 2 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java new file mode 100644 index 000000000..7d7bfa870 --- /dev/null +++ b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java @@ -0,0 +1,34 @@ +/* + * 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; + +/** + * An exception thrown when a successful authentication is rejected by a + * AuthenticationSuccessListener in an extension. + */ +public class GuacamoleAuthenticationRejectedException + extends GuacamoleSecurityException { + + public GuacamoleAuthenticationRejectedException() { + super("authentication rejected by listener extension"); + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java index 31abee5f5..b6bf5b20e 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java @@ -24,9 +24,11 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; +import org.apache.guacamole.GuacamoleAuthenticationRejectedException; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleUnauthorizedException; +import org.apache.guacamole.GuacamoleSession; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticationProvider; @@ -35,7 +37,9 @@ import org.apache.guacamole.net.auth.UserContext; import org.apache.guacamole.net.auth.credentials.CredentialsInfo; import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException; import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; -import org.apache.guacamole.GuacamoleSession; +import org.apache.guacamole.net.event.AuthenticationFailureEvent; +import org.apache.guacamole.net.event.AuthenticationSuccessEvent; +import org.apache.guacamole.rest.event.ListenerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,6 +78,12 @@ public class AuthenticationService { @Inject private AuthTokenGenerator authTokenGenerator; + /** + * The service to use to notify registered authentication listeners + */ + @Inject + private ListenerService listenerService; + /** * Regular expression which matches any IPv4 address. */ @@ -207,6 +217,50 @@ public class AuthenticationService { } + /** + * Notify all bound AuthenticationSuccessListeners that a successful authentication + * has occurred. If any of the bound listeners returns false (indicating that the + * authentication should be rejected) a GuacamoleRejectedAuthenticationException is + * thrown. + * + * @param authenticatedUser + * The user that was successfully authenticated + * @param session + * Existing session for the user (if any) + * @throws GuacamoleException + * If a filter throws an exception or if any filter rejects the authentication + */ + private void notifyAuthenticationSuccessListeners( + AuthenticatedUser authenticatedUser, GuacamoleSession session) + throws GuacamoleException { + UserContext userContext = null; + if (session != null) { + userContext = session.getUserContext( + authenticatedUser.getAuthenticationProvider().getIdentifier()); + } + + AuthenticationSuccessEvent event = new AuthenticationSuccessEvent( + userContext, authenticatedUser.getCredentials()); + + boolean ok = listenerService.authenticationSucceeded(event); + if (!ok) { + throw new GuacamoleAuthenticationRejectedException(); + } + } + + /** + * Notify all bound AuthenticationFailureListeners that an authentication has failed. + * + * @param credentials + * The credentials that failed to authenticate + * @throws GuacamoleException + * If a filter throws an exception + */ + private void notifyAuthenticationFailureListeners(Credentials credentials) + throws GuacamoleException { + listenerService.authenticationFailed(new AuthenticationFailureEvent(credentials)); + } + /** * Returns the AuthenticatedUser associated with the given session and * credentials, performing a fresh authentication and creating a new @@ -232,11 +286,17 @@ public class AuthenticationService { try { // Re-authenticate user if session exists - if (existingSession != null) - return updateAuthenticatedUser(existingSession.getAuthenticatedUser(), credentials); + if (existingSession != null) { + AuthenticatedUser updatedUser = updateAuthenticatedUser( + existingSession.getAuthenticatedUser(), credentials); + notifyAuthenticationSuccessListeners(updatedUser, existingSession); + return updatedUser; + } // Otherwise, attempt authentication as a new user - AuthenticatedUser authenticatedUser = AuthenticationService.this.authenticateUser(credentials); + AuthenticatedUser authenticatedUser = authenticateUser(credentials); + notifyAuthenticationSuccessListeners(authenticatedUser, null); + if (logger.isInfoEnabled()) logger.info("User \"{}\" successfully authenticated from {}.", authenticatedUser.getIdentifier(), @@ -249,6 +309,8 @@ public class AuthenticationService { // Log and rethrow any authentication errors catch (GuacamoleException e) { + notifyAuthenticationFailureListeners(credentials); + // Get request and username for sake of logging HttpServletRequest request = credentials.getRequest(); String username = credentials.getUsername(); From 6b6340ac464e03cc2a7bb8e9f72f8044e79beed6 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Wed, 16 Aug 2017 06:59:12 -0400 Subject: [PATCH 08/94] GUACAMOLE-364: notify tunnel listeners in TunnelRequestService --- .../GuacamoleTunnelConnectedException.java | 33 ++++++++ .../GuacamoleTunnelRejectedException.java | 33 ++++++++ .../tunnel/TunnelRequestService.java | 84 ++++++++++++++++++- 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java create mode 100644 guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java new file mode 100644 index 000000000..96693a483 --- /dev/null +++ b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java @@ -0,0 +1,33 @@ +/* + * 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; + +/** + * An exception thrown when a request to close a tunnel is vetoed by a + * TunnelCloseListener in an extension. + */ +public class GuacamoleTunnelConnectedException extends GuacamoleClientException { + + public GuacamoleTunnelConnectedException() { + super("tunnel close vetoed by listener extension"); + } + +} diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java new file mode 100644 index 000000000..c2e09f927 --- /dev/null +++ b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java @@ -0,0 +1,33 @@ +/* + * 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; + +/** + * An exception thrown when a successful tunnel connection is rejected by a + * TunnelConnectListener in an extension. + */ +public class GuacamoleTunnelRejectedException extends GuacamoleClientException { + + public GuacamoleTunnelRejectedException() { + super("tunnel connection rejected by listener extension"); + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java index 628386916..823ac1b9f 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java @@ -25,14 +25,20 @@ import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleSession; +import org.apache.guacamole.GuacamoleTunnelConnectedException; +import org.apache.guacamole.GuacamoleTunnelRejectedException; import org.apache.guacamole.GuacamoleUnauthorizedException; import org.apache.guacamole.net.GuacamoleTunnel; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionGroup; +import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.net.event.TunnelCloseEvent; +import org.apache.guacamole.net.event.TunnelConnectEvent; import org.apache.guacamole.rest.auth.AuthenticationService; import org.apache.guacamole.protocol.GuacamoleClientInformation; +import org.apache.guacamole.rest.event.ListenerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,6 +63,74 @@ public class TunnelRequestService { @Inject private AuthenticationService authenticationService; + /** + * A service for notifying listeners about tunnel connect/closed events. + */ + @Inject + private ListenerService listenerService; + + /** + * Notifies bound TunnelConnectListeners that a new tunnel has been connected. + * Listeners are allowed to veto a connected tunnel by returning false from the + * listener method. If the ListenerService indicates that any listener rejected + * the tunnel, the tunnel is closed an GuacamoleTunnelRejectedException is thrown. + * + * @param userContext + * The UserContext associated with the user for whom the tunnel is + * being created. + * + * @param credentials + * Credentials that authenticate the user + * + * @param tunnel + * The tunnel that was connected + * + * @throws GuacamoleException + * If thrown by a listener or if any listener vetoes the connected tunnel + */ + private void notifyTunnelConnectListeners(UserContext userContext, + Credentials credentials, GuacamoleTunnel tunnel) throws GuacamoleException { + TunnelConnectEvent event = new TunnelConnectEvent(userContext, credentials, tunnel); + boolean ok = listenerService.tunnelConnected(event); + if (!ok) { + try { + tunnel.close(); + } + catch (GuacamoleException closeEx) { + logger.warn("Error closing rejected tunnel connection: {}", closeEx.getMessage()); + } + throw new GuacamoleTunnelRejectedException(); + } + } + + /** + * Notifies bound TunnelCloseListeners that a tunnel is to be closed. + * Listeners are allowed to veto a request to close a tunnel by returning false from + * the listener method. If the ListenerService indicates that any listener vetoed the + * request to the close the tunnel, a GuacamoleTunnelConnectedException is thrown. + * + * @param userContext + * The UserContext associated with the user for whom the tunnel is + * being created. + * + * @param credentials + * Credentials that authenticate the user + * + * @param tunnel + * The tunnel that was connected + * + * @throws GuacamoleException + * If thrown by a listener or if any listener vetoes the request to close the tunnel + */ + private void notifyTunnelCloseListeners(UserContext userContext, + Credentials credentials, GuacamoleTunnel tunnel) + throws GuacamoleException { + TunnelCloseEvent event = new TunnelCloseEvent(userContext, credentials, tunnel); + if (listenerService.tunnelClosed(event)) { + throw new GuacamoleTunnelConnectedException(); + } + } + /** * Reads and returns the client information provided within the given * request. @@ -226,7 +300,7 @@ public class TunnelRequestService { * @throws GuacamoleException * If an error occurs while obtaining the tunnel. */ - protected GuacamoleTunnel createAssociatedTunnel(GuacamoleTunnel tunnel, + protected GuacamoleTunnel createAssociatedTunnel(final GuacamoleTunnel tunnel, final String authToken, final GuacamoleSession session, final UserContext context, final TunnelRequest.Type type, final String id) throws GuacamoleException { @@ -243,6 +317,10 @@ public class TunnelRequestService { @Override public void close() throws GuacamoleException { + // notify listeners to allow close request to be vetoed + notifyTunnelCloseListeners(context, + session.getAuthenticatedUser().getCredentials(), tunnel); + long connectionEndTime = System.currentTimeMillis(); long duration = connectionEndTime - connectionStartTime; @@ -328,6 +406,10 @@ public class TunnelRequestService { // Create connected tunnel using provided connection ID and client information GuacamoleTunnel tunnel = createConnectedTunnel(userContext, type, id, info); + // Notify listeners to allow connection to be vetoed + notifyTunnelConnectListeners(userContext, + session.getAuthenticatedUser().getCredentials(), tunnel); + // Associate tunnel with session return createAssociatedTunnel(tunnel, authToken, session, userContext, type, id); From 059cb75f0fd47b8a4c02491710e83695f26456bf Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Thu, 17 Aug 2017 05:10:32 -0400 Subject: [PATCH 09/94] GUACAMOLE-364: address style consistency issues --- ...camoleAuthenticationRejectedException.java | 1 - .../GuacamoleTunnelConnectedException.java | 1 - .../GuacamoleTunnelRejectedException.java | 1 - .../AuthenticationFailureListener.java | 1 + .../net/event/listener/Listener.java | 1 - .../apache/guacamole/extension/Extension.java | 1 - .../guacamole/extension/ListenerFacade.java | 25 +++++++------- .../guacamole/extension/ListenerProvider.java | 1 - .../guacamole/extension/ProviderFactory.java | 1 - .../rest/auth/AuthenticationService.java | 2 ++ .../guacamole/rest/event/ListenerService.java | 33 +++++++++---------- 11 files changed, 30 insertions(+), 38 deletions(-) diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java index 7d7bfa870..907e0c947 100644 --- a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java +++ b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java @@ -15,7 +15,6 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole; diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java index 96693a483..c7d21cf1d 100644 --- a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java +++ b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java @@ -15,7 +15,6 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole; diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java index c2e09f927..b9367c180 100644 --- a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java +++ b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java @@ -15,7 +15,6 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole; diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java index 7fa619042..86122bad2 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java @@ -28,6 +28,7 @@ import org.apache.guacamole.net.event.AuthenticationFailureEvent; * be used to cancel the authentication failure. */ public interface AuthenticationFailureListener extends Listener { + /** * Event hook which fires immediately after a user's authentication attempt * fails. diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java index 72f859db1..58499934e 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java @@ -15,7 +15,6 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole.net.event.listener; diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java b/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java index ac58676ec..697002d42 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java @@ -35,7 +35,6 @@ import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; - import org.apache.guacamole.net.event.listener.Listener; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.ObjectMapper; diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java index 278b2a934..ab0b7c85d 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java @@ -15,7 +15,6 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole.extension; @@ -56,7 +55,7 @@ class ListenerFacade implements ListenerProvider { * listener implements the AuthenticationSuccessListener interface. * * @param - * e The AuthenticationSuccessEvent describing the authentication + * event The AuthenticationSuccessEvent describing the authentication * success that just occurred. * @return * false if the delegate listener rejects the successful authentication, @@ -66,10 +65,10 @@ class ListenerFacade implements ListenerProvider { * if the delegate listener throws this exception */ @Override - public boolean authenticationSucceeded(AuthenticationSuccessEvent e) + public boolean authenticationSucceeded(AuthenticationSuccessEvent event) throws GuacamoleException { return !(delegate instanceof AuthenticationSuccessListener) - || ((AuthenticationSuccessListener) delegate).authenticationSucceeded(e); + || ((AuthenticationSuccessListener) delegate).authenticationSucceeded(event); } /** @@ -77,17 +76,17 @@ class ListenerFacade implements ListenerProvider { * listener implements the AuthenticationSuccessListener interface. * * @param - * e The AuthenticationFailureEvent describing the authentication + * event The AuthenticationFailureEvent describing the authentication * failure that just occurred. * * @throws GuacamoleException * if the delegate listener throws this exception */ @Override - public void authenticationFailed(AuthenticationFailureEvent e) + public void authenticationFailed(AuthenticationFailureEvent event) throws GuacamoleException { if (delegate instanceof AuthenticationFailureListener) { - ((AuthenticationFailureListener) delegate).authenticationFailed(e); + ((AuthenticationFailureListener) delegate).authenticationFailed(event); } } @@ -96,7 +95,7 @@ class ListenerFacade implements ListenerProvider { * listener implements the TunnelConnectListener interface. * * @param - * e The TunnelConnectEvent describing the tunnel that was just connected + * event The TunnelConnectEvent describing the tunnel that was just connected * @return * false if the delegate listener rejects the tunnel connection, @@ -106,10 +105,10 @@ class ListenerFacade implements ListenerProvider { * if the delegate listener throws this exception */ @Override - public boolean tunnelConnected(TunnelConnectEvent e) + public boolean tunnelConnected(TunnelConnectEvent event) throws GuacamoleException { return !(delegate instanceof TunnelConnectListener) - || ((TunnelConnectListener) delegate).tunnelConnected(e); + || ((TunnelConnectListener) delegate).tunnelConnected(event); } /** @@ -117,7 +116,7 @@ class ListenerFacade implements ListenerProvider { * listener implements the TunnelCloseListener interface. * * @param - * e The TunnelCloseEvent describing the tunnel that is to be close + * event The TunnelCloseEvent describing the tunnel that is to be close * @return * false if the delegate listener rejects the tunnel close request, @@ -127,9 +126,9 @@ class ListenerFacade implements ListenerProvider { * if the delegate listener throws this exception */ @Override - public boolean tunnelClosed(TunnelCloseEvent e) throws GuacamoleException { + public boolean tunnelClosed(TunnelCloseEvent event) throws GuacamoleException { return !(delegate instanceof TunnelCloseListener) - || ((TunnelCloseListener) delegate).tunnelClosed(e); + || ((TunnelCloseListener) delegate).tunnelClosed(event); } } diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java index 0b3a7473d..1d8afc10c 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java @@ -15,7 +15,6 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole.extension; 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 0620b4da8..376b213d6 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java @@ -15,7 +15,6 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole.extension; diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java index b6bf5b20e..4fed42aeb 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java @@ -233,6 +233,7 @@ public class AuthenticationService { private void notifyAuthenticationSuccessListeners( AuthenticatedUser authenticatedUser, GuacamoleSession session) throws GuacamoleException { + UserContext userContext = null; if (session != null) { userContext = session.getUserContext( @@ -258,6 +259,7 @@ public class AuthenticationService { */ private void notifyAuthenticationFailureListeners(Credentials credentials) throws GuacamoleException { + listenerService.authenticationFailed(new AuthenticationFailureEvent(credentials)); } diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java index 3b1a00f56..30c4357df 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java @@ -15,30 +15,26 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - * */ package org.apache.guacamole.rest.event; +import java.util.List; import com.google.inject.Inject; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.extension.ListenerProvider; import org.apache.guacamole.net.event.AuthenticationFailureEvent; import org.apache.guacamole.net.event.AuthenticationSuccessEvent; -import org.apache.guacamole.net.event.TunnelCloseEvent; import org.apache.guacamole.net.event.TunnelConnectEvent; +import org.apache.guacamole.net.event.TunnelCloseEvent; import org.apache.guacamole.net.event.listener.AuthenticationFailureListener; import org.apache.guacamole.net.event.listener.AuthenticationSuccessListener; import org.apache.guacamole.net.event.listener.TunnelCloseListener; import org.apache.guacamole.net.event.listener.TunnelConnectListener; -import java.util.List; - /** * A service used to notify listeners registered by extensions when events of * interest occur. - * - * @author Carl Harris */ public class ListenerService implements ListenerProvider { @@ -50,7 +46,8 @@ public class ListenerService implements ListenerProvider { * are allowed to veto a successful authentication by returning false from the * listener method. Regardless of whether a particular listener rejects the * successful authentication, all listeners are notified. - * @param e + * + * @param event * The AuthenticationSuccessEvent describing the successful authentication * that just occurred. * @@ -62,11 +59,11 @@ public class ListenerService implements ListenerProvider { * some listeners may not receive the authentication success event notification. */ @Override - public boolean authenticationSucceeded(AuthenticationSuccessEvent e) + public boolean authenticationSucceeded(AuthenticationSuccessEvent event) throws GuacamoleException { boolean result = true; for (AuthenticationSuccessListener listener : listeners) { - result = result && listener.authenticationSucceeded(e); + result = result && listener.authenticationSucceeded(event); } return result; } @@ -74,7 +71,7 @@ public class ListenerService implements ListenerProvider { /** * Notifies all bound listeners of an authentication failure event. * - * @param e + * @param event * The AuthenticationSuccessEvent describing the authentication failure * that just occurred. * @@ -83,10 +80,10 @@ public class ListenerService implements ListenerProvider { * some listeners may not receive the authentication failure event notification. */ @Override - public void authenticationFailed(AuthenticationFailureEvent e) + public void authenticationFailed(AuthenticationFailureEvent event) throws GuacamoleException { for (AuthenticationFailureListener listener : listeners) { - listener.authenticationFailed(e); + listener.authenticationFailed(event); } } @@ -95,7 +92,7 @@ public class ListenerService implements ListenerProvider { * are allowed to veto a tunnel connection by returning false from the * listener method. Regardless of whether a particular listener rejects the * tunnel connection, all listeners are notified. - * @param e + * @param event * The TunnelConnectedEvent describing the tunnel that was just connected * * @return @@ -106,11 +103,11 @@ public class ListenerService implements ListenerProvider { * some listeners may not receive the tunnel connected event notification. */ @Override - public boolean tunnelConnected(TunnelConnectEvent e) + public boolean tunnelConnected(TunnelConnectEvent event) throws GuacamoleException { boolean result = true; for (TunnelConnectListener listener : listeners) { - result = result && listener.tunnelConnected(e); + result = result && listener.tunnelConnected(event); } return result; } @@ -120,7 +117,7 @@ public class ListenerService implements ListenerProvider { * are allowed to veto the request to close a tunnel by returning false from * the listener method. Regardless of whether a particular listener rejects the * tunnel close request, all listeners are notified. - * @param e + * @param event * The TunnelCloseEvent describing the tunnel that is to be closed * * @return @@ -131,10 +128,10 @@ public class ListenerService implements ListenerProvider { * some listeners may not receive the tunnel close event notification. */ @Override - public boolean tunnelClosed(TunnelCloseEvent e) throws GuacamoleException { + public boolean tunnelClosed(TunnelCloseEvent event) throws GuacamoleException { boolean result = true; for (TunnelCloseListener listener : listeners) { - result = result && listener.tunnelClosed(e); + result = result && listener.tunnelClosed(event); } return result; } From 10bc443864dfda50e6277ab65d92e2dffbce8f8c Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Thu, 17 Aug 2017 05:24:10 -0400 Subject: [PATCH 10/94] GUACAMOLE-364: eliminate unnecessary local variable --- .../org/apache/guacamole/rest/auth/AuthenticationService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java index 4fed42aeb..8760b7363 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java @@ -243,8 +243,7 @@ public class AuthenticationService { AuthenticationSuccessEvent event = new AuthenticationSuccessEvent( userContext, authenticatedUser.getCredentials()); - boolean ok = listenerService.authenticationSucceeded(event); - if (!ok) { + if (!listenerService.authenticationSucceeded(event)) { throw new GuacamoleAuthenticationRejectedException(); } } From beac46bff5e3070d931e5f5577a095f8edcdb070 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Thu, 17 Aug 2017 05:25:51 -0400 Subject: [PATCH 11/94] GUACAMOLE-364: revert unnecessary code simplification This change isn't necessary to the stated issue. The expression here is unnecessarily complex but that should be addressed in another issue. --- .../org/apache/guacamole/rest/auth/AuthenticationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java index 8760b7363..cca284524 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java @@ -295,7 +295,7 @@ public class AuthenticationService { } // Otherwise, attempt authentication as a new user - AuthenticatedUser authenticatedUser = authenticateUser(credentials); + AuthenticatedUser authenticatedUser = AuthenticationService.this.authenticateUser(credentials); notifyAuthenticationSuccessListeners(authenticatedUser, null); if (logger.isInfoEnabled()) From 2062f1ccc54fc6435b9d10d4607c56a1fa4ac164 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Thu, 17 Aug 2017 05:28:47 -0400 Subject: [PATCH 12/94] GUACAMOLE-364: eliminate unnecessary local variable --- .../java/org/apache/guacamole/tunnel/TunnelRequestService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java index 823ac1b9f..56cf82a59 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java @@ -91,8 +91,7 @@ public class TunnelRequestService { private void notifyTunnelConnectListeners(UserContext userContext, Credentials credentials, GuacamoleTunnel tunnel) throws GuacamoleException { TunnelConnectEvent event = new TunnelConnectEvent(userContext, credentials, tunnel); - boolean ok = listenerService.tunnelConnected(event); - if (!ok) { + if (!listenerService.tunnelConnected(event)) { try { tunnel.close(); } From 535b70fdce8ff5df2405e23b30897f65ecda66bf Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 29 Aug 2017 11:38:05 -0700 Subject: [PATCH 13/94] GUACAMOLE-310: Switch clipboard service back to using textarea for contents. --- .../webapp/app/clipboard/services/clipboardService.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js index f0529d8b8..ff626ea4f 100644 --- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js +++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js @@ -57,10 +57,9 @@ angular.module('clipboard').factory('clipboardService', ['$injector', * * @type Element */ - var clipboardContent = document.createElement('div'); + var clipboardContent = document.createElement('textarea'); // Ensure clipboard target is selectable but not visible - clipboardContent.setAttribute('contenteditable', 'true'); clipboardContent.className = 'clipboard-service-target'; // Add clipboard target to DOM @@ -167,7 +166,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector', // Copy the given value into the clipboard DOM element if (typeof data.data === 'string') - clipboardContent.textContent = data.data; + clipboardContent.value = data.data; else { clipboardContent.innerHTML = ''; var img = document.createElement('img'); @@ -400,7 +399,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector', pushSelection(); // Clear and select the clipboard DOM element - clipboardContent.innerHTML = ''; + clipboardContent.value = ''; clipboardContent.focus(); selectAll(clipboardContent); @@ -431,7 +430,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector', else deferred.resolve(new ClipboardData({ type : 'text/plain', - data : clipboardContent.textContent + data : clipboardContent.value })); } From cc22f23c027bc4dd688eb71372c90a7b31e71e40 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 29 Aug 2017 11:39:08 -0700 Subject: [PATCH 14/94] GUACAMOLE-310: Ensure clipboard service target remains hidden (1x1 px may be below browser's minimum dimensions for a textarea). --- .../src/main/webapp/app/clipboard/styles/clipboard.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/guacamole/src/main/webapp/app/clipboard/styles/clipboard.css b/guacamole/src/main/webapp/app/clipboard/styles/clipboard.css index b4513e1b0..3d61c2be3 100644 --- a/guacamole/src/main/webapp/app/clipboard/styles/clipboard.css +++ b/guacamole/src/main/webapp/app/clipboard/styles/clipboard.css @@ -52,10 +52,10 @@ .clipboard-service-target { position: fixed; - left: -1px; - right: -1px; - width: 1px; - height: 1px; + left: -1em; + right: -1em; + width: 1em; + height: 1em; white-space: pre; overflow: hidden; } From 47acaf5b41c911d402a9f242cc58619bc74c4cb9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 29 Aug 2017 11:39:49 -0700 Subject: [PATCH 15/94] GUACAMOLE-310: Wait until clipboard target is actually focused before attempting paste. --- .../clipboard/services/clipboardService.js | 108 +++++++++++------- 1 file changed, 68 insertions(+), 40 deletions(-) diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js index ff626ea4f..311dbc0ba 100644 --- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js +++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js @@ -398,53 +398,81 @@ angular.module('clipboard').factory('clipboardService', ['$injector', var originalElement = document.activeElement; pushSelection(); + /** + * Attempts to paste the clipboard contents into the + * currently-focused element. The promise related to the current + * attempt to read the clipboard will be resolved or rejected + * depending on whether the attempt to paste succeeds. + */ + var performPaste = function performPaste() { + + // Attempt paste local clipboard into clipboard DOM element + if (document.execCommand('paste')) { + + // If the pasted data is a single image, resolve with a blob + // containing that image + var currentImage = service.getImageContent(clipboardContent); + if (currentImage) { + + // Convert the image's data URL into a blob + var blob = service.parseDataURL(currentImage); + if (blob) { + deferred.resolve(new ClipboardData({ + type : blob.type, + data : blob + })); + } + + // Reject if conversion fails + else + deferred.reject(); + + } // end if clipboard is an image + + // Otherwise, assume the clipboard contains plain text + else + deferred.resolve(new ClipboardData({ + type : 'text/plain', + data : clipboardContent.value + })); + + } + + // Otherwise, reading from the clipboard has failed + else + deferred.reject(); + + }; + + // Clean up event listener and selection once the paste attempt has + // completed + deferred.promise['finally'](function cleanupReadAttempt() { + + // Do not use future changes in focus + clipboardContent.removeEventListener('focus', performPaste); + + // Unfocus the clipboard DOM event to avoid mobile keyboard opening, + // restoring whichever element was originally focused + clipboardContent.blur(); + originalElement.focus(); + popSelection(); + + }); + + // Ensure clipboard element is blurred (and that the "focus" event + // will fire) + clipboardContent.blur(); + clipboardContent.addEventListener('focus', performPaste); + // Clear and select the clipboard DOM element clipboardContent.value = ''; clipboardContent.focus(); selectAll(clipboardContent); - // Attempt paste local clipboard into clipboard DOM element - if (document.activeElement === clipboardContent && document.execCommand('paste')) { - - // If the pasted data is a single image, resolve with a blob - // containing that image - var currentImage = service.getImageContent(clipboardContent); - if (currentImage) { - - // Convert the image's data URL into a blob - var blob = service.parseDataURL(currentImage); - if (blob) { - deferred.resolve(new ClipboardData({ - type : blob.type, - data : blob - })); - } - - // Reject if conversion fails - else - deferred.reject(); - - } // end if clipboard is an image - - // Otherwise, assume the clipboard contains plain text - else - deferred.resolve(new ClipboardData({ - type : 'text/plain', - data : clipboardContent.value - })); - - } - - // Otherwise, reading from the clipboard has failed - else + // If focus failed to be set, we cannot read the clipboard + if (document.activeElement !== clipboardContent) deferred.reject(); - // Unfocus the clipboard DOM event to avoid mobile keyboard opening, - // restoring whichever element was originally focused - clipboardContent.blur(); - originalElement.focus(); - popSelection(); - }, CLIPBOARD_READ_DELAY); return deferred.promise; From 7e0cdd2adf156b6aa15ddf96a7e78a41c8f47c9a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Sep 2017 17:07:24 -0700 Subject: [PATCH 16/94] GUACAMOLE-310: Use input element select() function when available. --- .../clipboard/services/clipboardService.js | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js index 311dbc0ba..07091f316 100644 --- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js +++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js @@ -135,14 +135,23 @@ angular.module('clipboard').factory('clipboardService', ['$injector', */ var selectAll = function selectAll(element) { - // Generate a range which selects all nodes within the given element - var range = document.createRange(); - range.selectNodeContents(element); + // Use the select() function defined for input elements, if available + if (element.select) + element.select(); - // Replace any current selection with the generated range - var selection = $window.getSelection(); - selection.removeAllRanges(); - selection.addRange(range); + // Fallback to manual manipulation of the selection + else { + + // Generate a range which selects all nodes within the given element + var range = document.createRange(); + range.selectNodeContents(element); + + // Replace any current selection with the generated range + var selection = $window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + + } }; @@ -175,6 +184,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector', } // Select all data within the clipboard target + clipboardContent.focus(); selectAll(clipboardContent); // Attempt to copy data from clipboard element into local clipboard From 75a575d050abcca8c8dec98df39ee0b3bb322dea Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Sep 2017 16:07:21 -0700 Subject: [PATCH 17/94] GUACAMOLE-128: Do not allow overlapping clipboard read attempts. --- .../clipboard/services/clipboardService.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js index 07091f316..939161eeb 100644 --- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js +++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js @@ -44,6 +44,14 @@ angular.module('clipboard').factory('clipboardService', ['$injector', */ var CLIPBOARD_READ_DELAY = 100; + /** + * The promise associated with the current pending clipboard read attempt. + * If no clipboard read is active, this will be null. + * + * @type Promise. + */ + var pendingRead = null; + /** * Reference to the window.document object. * @@ -398,8 +406,16 @@ angular.module('clipboard').factory('clipboardService', ['$injector', */ service.getLocalClipboard = function getLocalClipboard() { + // If the clipboard is already being read, do not overlap the read + // attempts; instead share the result across all requests + if (pendingRead) + return pendingRead; + var deferred = $q.defer(); + // Mark read attempt as in progress + pendingRead = deferred.promise; + // Wait for the next event queue run before attempting to read // clipboard data (in case the copy/cut has not yet completed) $window.setTimeout(function deferredClipboardRead() { @@ -467,6 +483,9 @@ angular.module('clipboard').factory('clipboardService', ['$injector', originalElement.focus(); popSelection(); + // No read is pending any longer + pendingRead = null; + }); // Ensure clipboard element is blurred (and that the "focus" event From 6ce1eb1d3a2d63597cc61b00a850619bb3546552 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Sep 2017 16:30:52 -0700 Subject: [PATCH 18/94] GUACAMOLE-128: Stop propagation of "cut" events from within clipboard service event target. --- .../src/main/webapp/app/clipboard/services/clipboardService.js | 1 + 1 file changed, 1 insertion(+) diff --git a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js index 939161eeb..06abb048a 100644 --- a/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js +++ b/guacamole/src/main/webapp/app/clipboard/services/clipboardService.js @@ -86,6 +86,7 @@ angular.module('clipboard').factory('clipboardService', ['$injector', }; // Prevent events generated due to execCommand() from disturbing external things + clipboardContent.addEventListener('cut', stopEventPropagation); clipboardContent.addEventListener('copy', stopEventPropagation); clipboardContent.addEventListener('paste', stopEventPropagation); From 1c50311178d3af5f5af07561ccc2f3f599bf62fe Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 3 Sep 2017 16:32:39 -0700 Subject: [PATCH 19/94] GUACAMOLE-128: Check clipboard for received events only during bubble phase (allow clipboard service to manage propagation from its event target). --- .../src/main/webapp/app/index/controllers/indexController.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guacamole/src/main/webapp/app/index/controllers/indexController.js b/guacamole/src/main/webapp/app/index/controllers/indexController.js index 0f4d78dc5..3a9230bf7 100644 --- a/guacamole/src/main/webapp/app/index/controllers/indexController.js +++ b/guacamole/src/main/webapp/app/index/controllers/indexController.js @@ -137,8 +137,8 @@ angular.module('index').controller('indexController', ['$scope', '$injector', // Attempt to read the clipboard if it may have changed $window.addEventListener('load', checkClipboard, true); - $window.addEventListener('copy', checkClipboard, true); - $window.addEventListener('cut', checkClipboard, true); + $window.addEventListener('copy', checkClipboard); + $window.addEventListener('cut', checkClipboard); $window.addEventListener('focus', function focusGained(e) { // Only recheck clipboard if it's the window itself that gained focus From f63c8b43a8277f9d38ada78f4acac72e02fcbed6 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Thu, 7 Sep 2017 16:58:44 -0400 Subject: [PATCH 20/94] GUACAMOLE-364: declare and implement new listener API This commit also deprecates the existing listener API and includes support for adapting existing listener implementations to the new API. --- ...camoleAuthenticationRejectedException.java | 33 --- .../GuacamoleTunnelConnectedException.java | 32 --- .../GuacamoleTunnelRejectedException.java | 32 --- .../net/event/AuthenticationSuccessEvent.java | 5 + .../guacamole/net/event/TunnelCloseEvent.java | 4 + .../net/event/TunnelConnectEvent.java | 4 + .../AuthenticationFailureListener.java | 6 +- .../AuthenticationSuccessListener.java | 6 +- .../net/event/listener/Listener.java | 29 +- .../event/listener/TunnelCloseListener.java | 6 +- .../event/listener/TunnelConnectListener.java | 6 +- .../apache/guacamole/extension/Extension.java | 10 +- .../guacamole/extension/ExtensionModule.java | 42 +-- .../guacamole/extension/ListenerFacade.java | 134 --------- .../guacamole/extension/ListenerFactory.java | 256 ++++++++++++++++++ .../rest/auth/AuthenticationService.java | 35 +-- .../guacamole/rest/event/ListenerService.java | 108 +------- .../tunnel/TunnelRequestService.java | 41 +-- 18 files changed, 378 insertions(+), 411 deletions(-) delete mode 100644 guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java delete mode 100644 guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java delete mode 100644 guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java delete mode 100644 guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java create mode 100644 guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java deleted file mode 100644 index 907e0c947..000000000 --- a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleAuthenticationRejectedException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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; - -/** - * An exception thrown when a successful authentication is rejected by a - * AuthenticationSuccessListener in an extension. - */ -public class GuacamoleAuthenticationRejectedException - extends GuacamoleSecurityException { - - public GuacamoleAuthenticationRejectedException() { - super("authentication rejected by listener extension"); - } - -} diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java deleted file mode 100644 index c7d21cf1d..000000000 --- a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelConnectedException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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; - -/** - * An exception thrown when a request to close a tunnel is vetoed by a - * TunnelCloseListener in an extension. - */ -public class GuacamoleTunnelConnectedException extends GuacamoleClientException { - - public GuacamoleTunnelConnectedException() { - super("tunnel close vetoed by listener extension"); - } - -} diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java deleted file mode 100644 index b9367c180..000000000 --- a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleTunnelRejectedException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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; - -/** - * An exception thrown when a successful tunnel connection is rejected by a - * TunnelConnectListener in an extension. - */ -public class GuacamoleTunnelRejectedException extends GuacamoleClientException { - - public GuacamoleTunnelRejectedException() { - super("tunnel connection rejected by listener extension"); - } - -} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/AuthenticationSuccessEvent.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/AuthenticationSuccessEvent.java index 2e5ae3a17..c72d669fa 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/AuthenticationSuccessEvent.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/AuthenticationSuccessEvent.java @@ -26,6 +26,11 @@ import org.apache.guacamole.net.auth.UserContext; * An event which is triggered whenever a user's credentials pass * authentication. The credentials that passed authentication are included * within this event, and can be retrieved using getCredentials(). + *

+ * If a {@link org.apache.guacamole.net.event.listener.Listener} throws + * a GuacamoleException when handling an event of this type, successful authentication + * is effectively vetoed and will be subsequently processed as though the + * authentication failed. */ public class AuthenticationSuccessEvent implements UserEvent, CredentialEvent { diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelCloseEvent.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelCloseEvent.java index ab453e87e..c0e2a622e 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelCloseEvent.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelCloseEvent.java @@ -28,6 +28,10 @@ import org.apache.guacamole.net.auth.UserContext; * being closed can be accessed through getTunnel(), and the UserContext * associated with the request which is closing the tunnel can be retrieved * with getUserContext(). + *

+ * If a {@link org.apache.guacamole.net.event.listener.Listener} throws + * a GuacamoleException when handling an event of this type, the request to close + * the tunnel is effectively vetoed and will remain connected. */ public class TunnelCloseEvent implements UserEvent, CredentialEvent, TunnelEvent { diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelConnectEvent.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelConnectEvent.java index acf5e8922..62828db8f 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelConnectEvent.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/TunnelConnectEvent.java @@ -28,6 +28,10 @@ import org.apache.guacamole.net.auth.UserContext; * being connected can be accessed through getTunnel(), and the UserContext * associated with the request which is connecting the tunnel can be retrieved * with getUserContext(). + *

+ * If a {@link org.apache.guacamole.net.event.listener.Listener} throws + * a GuacamoleException when handling an event of this type, the tunnel connection + * is effectively vetoed and will be subsequently closed. */ public class TunnelConnectEvent implements UserEvent, CredentialEvent, TunnelEvent { diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java index 86122bad2..1971af89b 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java @@ -26,8 +26,12 @@ import org.apache.guacamole.net.event.AuthenticationFailureEvent; * A listener whose authenticationFailed() hook will fire immediately * after a user's authentication attempt fails. Note that this hook cannot * be used to cancel the authentication failure. + * + * @deprecated + * Listeners should instead implement the {@link Listener} interface */ -public interface AuthenticationFailureListener extends Listener { +@Deprecated +public interface AuthenticationFailureListener { /** * Event hook which fires immediately after a user's authentication attempt diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java index cc5e01d57..77a6ed1b2 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java @@ -27,8 +27,12 @@ import org.apache.guacamole.net.event.AuthenticationSuccessEvent; * authentication attempt succeeds. If a user successfully authenticates, * the authenticationSucceeded() hook has the opportunity to cancel the * authentication and force it to fail. + * + * @deprecated + * Listeners should instead implement the {@link Listener} interface */ -public interface AuthenticationSuccessListener extends Listener { +@Deprecated +public interface AuthenticationSuccessListener { /** * Event hook which fires immediately after a user's authentication attempt diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java index 58499934e..d21f68681 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java @@ -19,10 +19,33 @@ package org.apache.guacamole.net.event.listener; +import org.apache.guacamole.GuacamoleException; + /** - * A marker interface extended by all listener types. This interface is used - * simply to validate that a listener class identified in an extension - * actually implements some listener interface. + * A listener for events that occur in handing various Guacamole requests + * such as authentication, tunnel connect/close, etc. Listeners are registered + * through the extension manifest mechanism. When an event occurs, listeners + * are notified in the order in which they are declared in the manifest and + * continues until either all listeners have been notified or with the first + * listener that throws a GuacamoleException or other runtime exception. */ public interface Listener { + + /** + * Notifies the recipient that an event has occurred. + *

+ * Throwing an exception from an event listener can act to veto an action in + * progress for some event types. See the Javadoc for specific event types for + * details. + * + * @param event + * an object that describes the subject event + * + * @throws GuacamoleException + * If the listener wishes to stop notification of the event to subsequent + * listeners. For some event types, this acts to veto an action in progress; + * e.g. treating a successful authentication as though it failed + */ + void handleEvent(Object event) throws GuacamoleException; + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java index 99f2c04de..70677b3ac 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java @@ -25,8 +25,12 @@ import org.apache.guacamole.net.event.TunnelCloseEvent; /** * A listener whose tunnelClosed() hook will fire immediately after an * existing tunnel is closed. + * + * @deprecated + * Listeners should instead implement the {@link Listener} interface */ -public interface TunnelCloseListener extends Listener { +@Deprecated +public interface TunnelCloseListener { /** * Event hook which fires immediately before an existing tunnel is closed. diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java index 7ac47e189..edc144e29 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java @@ -25,8 +25,12 @@ import org.apache.guacamole.net.event.TunnelConnectEvent; /** * A listener whose tunnelConnected() hook will fire immediately after a new * tunnel is connected. + * + * @deprecated + * Listeners should instead implement the {@link Listener} interface */ -public interface TunnelConnectListener extends Listener { +@Deprecated +public interface TunnelConnectListener { /** * Event hook which fires immediately after a new tunnel is connected. diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java b/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java index 697002d42..dc43b8f00 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/Extension.java @@ -113,7 +113,7 @@ public class Extension { /** * The collection of all Listener classes defined within the extension. */ - private final Collection> listenerClasses; + private final Collection> listenerClasses; /** * The resource for the small favicon for the extension. If provided, this @@ -328,15 +328,15 @@ public class Extension { * If any given class does not exist, or if any given class is not a * subclass of AuthenticationProvider. */ - private Collection> getListenerClasses(Collection names) + private Collection> getListenerClasses(Collection names) throws GuacamoleException { // If no classnames are provided, just return an empty list if (names == null) - return Collections.>emptyList(); + return Collections.>emptyList(); // Define all auth provider classes - Collection> classes = new ArrayList>(names.size()); + Collection> classes = new ArrayList>(names.size()); for (String name : names) classes.add(getListenerClass(name)); @@ -578,7 +578,7 @@ public class Extension { * @return * All declared listener classes with this extension. */ - public Collection> getListenerClasses() { + public Collection> getListenerClasses() { return listenerClasses; } 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 1e1a85452..f3ca70067 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java @@ -95,8 +95,8 @@ public class ExtensionModule extends ServletModule { /** * All currently-bound authentication providers, if any. */ - private final List boundListenerProviders = - new ArrayList(); + private final List boundListners = + new ArrayList(); /** * Service for adding and retrieving language resources. @@ -195,19 +195,19 @@ public class ExtensionModule extends ServletModule { } /** - * Binds the given Listener class such that any service - * requiring access to the Listener can obtain it via - * injection, along with any other bound Listener. - * - * @param listenerClass - * The Listener class to bind. + * Binds the given provider class such that a listener is bound for each + * listener interface implemented by the provider and such that all bound + * listener instances can be obtained via injection. + * * + * @param providerClass + * The listener provider class to bind */ - private void bindListenerProvider(Class listenerClass) { + private void bindListeners(Class providerClass) { + + logger.debug("[{}] Binding listeners \"{}\".", + boundListners.size(), providerClass.getName()); + boundListners.addAll(ListenerFactory.createListeners(providerClass)); - // Bind listener - logger.debug("[{}] Binding Listener \"{}\".", - boundListenerProviders.size(), listenerClass.getName()); - boundListenerProviders.add(new ListenerFacade(listenerClass)); } /** @@ -218,23 +218,23 @@ public class ExtensionModule extends ServletModule { * @param listeners * The Listener classes to bind. */ - private void bindListenerProviders(Collection> listeners) { + private void bindListeners(Collection> listeners) { // Bind each listener within extension - for (Class listener : listeners) - bindListenerProvider(listener); + for (Class listener : listeners) + bindListeners(listener); } /** - * Returns a list of all currently-bound ListenerProvider instances. + * Returns a list of all currently-bound Listener instances. * * @return - * A List of all currently-bound ListenerProvider instances. The List is + * A List of all currently-bound Listener instances. The List is * not modifiable. */ @Provides - public List getListenerProviders() { - return Collections.unmodifiableList(boundListenerProviders); + public List getListeners() { + return Collections.unmodifiableList(boundListners); } /** @@ -378,7 +378,7 @@ public class ExtensionModule extends ServletModule { bindAuthenticationProviders(extension.getAuthenticationProviderClasses()); // Attempt to load all listeners - bindListenerProviders(extension.getListenerClasses()); + bindListeners(extension.getListenerClasses()); // Add any translation resources serveLanguageResources(extension.getTranslationResources()); diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java deleted file mode 100644 index ab0b7c85d..000000000 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFacade.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * 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.extension; - -import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.net.event.AuthenticationFailureEvent; -import org.apache.guacamole.net.event.AuthenticationSuccessEvent; -import org.apache.guacamole.net.event.TunnelCloseEvent; -import org.apache.guacamole.net.event.TunnelConnectEvent; -import org.apache.guacamole.net.event.listener.*; - -/** - * Provides a wrapper around a Listener subclass, allowing listener - * extensions to be bound without regard for which specific listener interfaces - * are implemented. - */ -class ListenerFacade implements ListenerProvider { - - private final Listener delegate; - - /** - * Creates a new ListenerFacade which delegates all listener methods - * calls to an instance of the given Listener subclass. If - * an instance of the given class cannot be created, creation of this - * facade will still succeed. Errors will be logged at the time listener - * creation fails, but subsequent events directed to the listener will be - * silently dropped. - * - * @param listenerClass - * The Listener subclass to instantiate. - */ - public ListenerFacade(Class listenerClass) { - delegate = ProviderFactory.newInstance("listener", listenerClass); - } - - /** - * Notifies the delegate listener of an authentication success event, if the - * listener implements the AuthenticationSuccessListener interface. - * - * @param - * event The AuthenticationSuccessEvent describing the authentication - * success that just occurred. - * @return - * false if the delegate listener rejects the successful authentication, - * else true - * - * @throws GuacamoleException - * if the delegate listener throws this exception - */ - @Override - public boolean authenticationSucceeded(AuthenticationSuccessEvent event) - throws GuacamoleException { - return !(delegate instanceof AuthenticationSuccessListener) - || ((AuthenticationSuccessListener) delegate).authenticationSucceeded(event); - } - - /** - * Notifies the delegate listener of an authentication failure event, if the - * listener implements the AuthenticationSuccessListener interface. - * - * @param - * event The AuthenticationFailureEvent describing the authentication - * failure that just occurred. - * - * @throws GuacamoleException - * if the delegate listener throws this exception - */ - @Override - public void authenticationFailed(AuthenticationFailureEvent event) - throws GuacamoleException { - if (delegate instanceof AuthenticationFailureListener) { - ((AuthenticationFailureListener) delegate).authenticationFailed(event); - } - } - - /** - * Notifies the delegate listener of a tunnel connected event, if the - * listener implements the TunnelConnectListener interface. - * - * @param - * event The TunnelConnectEvent describing the tunnel that was just connected - - * @return - * false if the delegate listener rejects the tunnel connection, - * else true - * - * @throws GuacamoleException - * if the delegate listener throws this exception - */ - @Override - public boolean tunnelConnected(TunnelConnectEvent event) - throws GuacamoleException { - return !(delegate instanceof TunnelConnectListener) - || ((TunnelConnectListener) delegate).tunnelConnected(event); - } - - /** - * Notifies the delegate listener of a tunnel close event, if the - * listener implements the TunnelCloseListener interface. - * - * @param - * event The TunnelCloseEvent describing the tunnel that is to be close - - * @return - * false if the delegate listener rejects the tunnel close request, - * else true - * - * @throws GuacamoleException - * if the delegate listener throws this exception - */ - @Override - public boolean tunnelClosed(TunnelCloseEvent event) throws GuacamoleException { - return !(delegate instanceof TunnelCloseListener) - || ((TunnelCloseListener) delegate).tunnelClosed(event); - } - -} diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java new file mode 100644 index 000000000..c11f00f5d --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java @@ -0,0 +1,256 @@ +/* + * 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.extension; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleSecurityException; +import org.apache.guacamole.net.event.AuthenticationFailureEvent; +import org.apache.guacamole.net.event.AuthenticationSuccessEvent; +import org.apache.guacamole.net.event.TunnelCloseEvent; +import org.apache.guacamole.net.event.TunnelConnectEvent; +import org.apache.guacamole.net.event.listener.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * A factory that reflectively instantiates Listener objects for a given + * provider class. + */ +class ListenerFactory { + + /** + * Creates all listeners represented by an instance of the given provider class. + *

+ * If a provider class implements the simple Listener interface, that is the + * only listener type that will be returned. Otherwise, a list of Listener + * objects that adapt the legacy listener interfaces will be returned. + * + * @param providerClass + * a class that represents a listener provider + * + * @return + * list of listeners represented by the given provider class + */ + static List createListeners(Class providerClass) { + + Object provider = ProviderFactory.newInstance("listener", providerClass); + + if (provider instanceof Listener) { + return Collections.singletonList((Listener) provider); + } + + return createListenerAdapters(provider); + + } + + @SuppressWarnings("deprecation") + private static List createListenerAdapters(Object provider) { + + final List listeners = new ArrayList(); + + if (provider instanceof AuthenticationSuccessListener) { + listeners.add(new AuthenticationSuccessListenerAdapter( + (AuthenticationSuccessListener) provider)); + } + + if (provider instanceof AuthenticationFailureListener) { + listeners.add(new AuthenticationFailureListenerAdapter( + (AuthenticationFailureListener) provider)); + } + + if (provider instanceof TunnelConnectListener) { + listeners.add(new TunnelConnectListenerAdapter( + (TunnelConnectListener) provider)); + } + + if (provider instanceof TunnelCloseListener) { + listeners.add(new TunnelCloseListenerAdapter( + (TunnelCloseListener) provider)); + } + + return listeners; + + } + + /** + * An adapter the allows an AuthenticationSuccessListener to be used + * as an ordinary Listener. + */ + @SuppressWarnings("deprecation") + private static class AuthenticationSuccessListenerAdapter implements Listener { + + private final AuthenticationSuccessListener delegate; + + /** + * Constructs a new adapter. + * + * @param delegate + * the delegate listener + */ + AuthenticationSuccessListenerAdapter(AuthenticationSuccessListener delegate) { + this.delegate = delegate; + } + + /** + * Handles an AuthenticationSuccessEvent by passing the event to the delegate + * listener. If the delegate returns false, the adapter throws a GuacamoleException + * to veto the authentication success event. All other event types are ignored. + * + * @param event + * an object that describes the subject event + * + * @throws GuacamoleException + * if thrown by the delegate listener + */ + @Override + public void handleEvent(Object event) throws GuacamoleException { + if (event instanceof AuthenticationSuccessEvent) { + if (!delegate.authenticationSucceeded((AuthenticationSuccessEvent) event)) { + throw new GuacamoleSecurityException( + "listener vetoed successful authentication"); + } + } + } + + } + + /** + * An adapter the allows an AuthenticationFailureListener to be used + * as an ordinary Listener. + */ + @SuppressWarnings("deprecation") + private static class AuthenticationFailureListenerAdapter implements Listener { + + private final AuthenticationFailureListener delegate; + + /** + * Constructs a new adapter. + * + * @param delegate + * the delegate listener + */ + AuthenticationFailureListenerAdapter(AuthenticationFailureListener delegate) { + this.delegate = delegate; + } + + /** + * Handles an AuthenticationFailureEvent by passing the event to the delegate + * listener. All other event types are ignored. + * + * @param event + * an object that describes the subject event + * + * @throws GuacamoleException + * if thrown by the delegate listener + */ + @Override + public void handleEvent(Object event) throws GuacamoleException { + if (event instanceof AuthenticationFailureEvent) { + delegate.authenticationFailed((AuthenticationFailureEvent) event); + } + } + + } + + /** + * An adapter the allows a TunnelConnectListener to be used as an ordinary + * Listener. + */ + @SuppressWarnings("deprecation") + private static class TunnelConnectListenerAdapter implements Listener { + + private final TunnelConnectListener delegate; + + /** + * Constructs a new adapter. + * + * @param delegate + * the delegate listener + */ + TunnelConnectListenerAdapter(TunnelConnectListener delegate) { + this.delegate = delegate; + } + + /** + * Handles a TunnelConnectEvent by passing the event to the delegate listener. + * If the delegate returns false, the adapter throws a GuacamoleException + * to veto the tunnel connect event. All other event types are ignored. + * + * @param event + * an object that describes the subject event + * + * @throws GuacamoleException + * if thrown by the delegate listener + */ + @Override + public void handleEvent(Object event) throws GuacamoleException { + if (event instanceof TunnelConnectEvent) { + if (!delegate.tunnelConnected((TunnelConnectEvent) event)) { + throw new GuacamoleException("listener vetoed tunnel connection"); + } + } + } + + } + + /** + * An adapter the allows a TunnelCloseListener to be used as an ordinary + * Listener. + */ + @SuppressWarnings("deprecation") + private static class TunnelCloseListenerAdapter implements Listener { + + private final TunnelCloseListener delegate; + + /** + * Constructs a new adapter. + * + * @param delegate + * the delegate listener + */ + TunnelCloseListenerAdapter(TunnelCloseListener delegate) { + this.delegate = delegate; + } + + /** + * Handles a TunnelCloseEvent by passing the event to the delegate listener. + * If the delegate returns false, the adapter throws a GuacamoleException + * to veto the tunnel connect event. All other event types are ignored. + * + * @param event + * an object that describes the subject event + * + * @throws GuacamoleException + * if thrown by the delegate listener + */ + @Override + public void handleEvent(Object event) throws GuacamoleException { + if (event instanceof TunnelCloseEvent) { + if (!delegate.tunnelClosed((TunnelCloseEvent) event)) { + throw new GuacamoleException("listener vetoed tunnel close request"); + } + } + } + + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java index cca284524..bdefc3efb 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java @@ -24,7 +24,7 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; -import org.apache.guacamole.GuacamoleAuthenticationRejectedException; + import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleUnauthorizedException; @@ -218,19 +218,17 @@ public class AuthenticationService { } /** - * Notify all bound AuthenticationSuccessListeners that a successful authentication - * has occurred. If any of the bound listeners returns false (indicating that the - * authentication should be rejected) a GuacamoleRejectedAuthenticationException is - * thrown. + * Notify all bound listeners that a successful authentication + * has occurred. * * @param authenticatedUser * The user that was successfully authenticated * @param session * Existing session for the user (if any) * @throws GuacamoleException - * If a filter throws an exception or if any filter rejects the authentication + * If thrown by a listener */ - private void notifyAuthenticationSuccessListeners( + private void fireAuthenticationSuccessEvent( AuthenticatedUser authenticatedUser, GuacamoleSession session) throws GuacamoleException { @@ -240,26 +238,21 @@ public class AuthenticationService { authenticatedUser.getAuthenticationProvider().getIdentifier()); } - AuthenticationSuccessEvent event = new AuthenticationSuccessEvent( - userContext, authenticatedUser.getCredentials()); - - if (!listenerService.authenticationSucceeded(event)) { - throw new GuacamoleAuthenticationRejectedException(); - } + listenerService.handleEvent(new AuthenticationSuccessEvent( + userContext, authenticatedUser.getCredentials())); } /** - * Notify all bound AuthenticationFailureListeners that an authentication has failed. + * Notify all bound listeners that an authentication attempt has failed. * * @param credentials * The credentials that failed to authenticate * @throws GuacamoleException - * If a filter throws an exception + * If thrown by a listener */ - private void notifyAuthenticationFailureListeners(Credentials credentials) + private void fireAuthenticationFailedEvent(Credentials credentials) throws GuacamoleException { - - listenerService.authenticationFailed(new AuthenticationFailureEvent(credentials)); + listenerService.handleEvent(new AuthenticationFailureEvent(credentials)); } /** @@ -290,13 +283,13 @@ public class AuthenticationService { if (existingSession != null) { AuthenticatedUser updatedUser = updateAuthenticatedUser( existingSession.getAuthenticatedUser(), credentials); - notifyAuthenticationSuccessListeners(updatedUser, existingSession); + fireAuthenticationSuccessEvent(updatedUser, existingSession); return updatedUser; } // Otherwise, attempt authentication as a new user AuthenticatedUser authenticatedUser = AuthenticationService.this.authenticateUser(credentials); - notifyAuthenticationSuccessListeners(authenticatedUser, null); + fireAuthenticationSuccessEvent(authenticatedUser, null); if (logger.isInfoEnabled()) logger.info("User \"{}\" successfully authenticated from {}.", @@ -310,7 +303,7 @@ public class AuthenticationService { // Log and rethrow any authentication errors catch (GuacamoleException e) { - notifyAuthenticationFailureListeners(credentials); + fireAuthenticationFailedEvent(credentials); // Get request and username for sake of logging HttpServletRequest request = credentials.getRequest(); diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java index 30c4357df..bbff8ee4b 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java @@ -22,118 +22,32 @@ package org.apache.guacamole.rest.event; import java.util.List; import com.google.inject.Inject; import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.extension.ListenerProvider; -import org.apache.guacamole.net.event.AuthenticationFailureEvent; -import org.apache.guacamole.net.event.AuthenticationSuccessEvent; -import org.apache.guacamole.net.event.TunnelConnectEvent; -import org.apache.guacamole.net.event.TunnelCloseEvent; -import org.apache.guacamole.net.event.listener.AuthenticationFailureListener; -import org.apache.guacamole.net.event.listener.AuthenticationSuccessListener; -import org.apache.guacamole.net.event.listener.TunnelCloseListener; -import org.apache.guacamole.net.event.listener.TunnelConnectListener; +import org.apache.guacamole.net.event.listener.Listener; /** * A service used to notify listeners registered by extensions when events of * interest occur. */ -public class ListenerService implements ListenerProvider { +public class ListenerService implements Listener { @Inject - private List listeners; + private List listeners; /** - * Notifies all bound listeners of an authentication success event. Listeners - * are allowed to veto a successful authentication by returning false from the - * listener method. Regardless of whether a particular listener rejects the - * successful authentication, all listeners are notified. + * Notifies registered listeners than an event has occurred. Notification continues + * until a given listener throws a GuacamoleException or other runtime exception, or + * until all listeners have been notified. * * @param event - * The AuthenticationSuccessEvent describing the successful authentication - * that just occurred. + * an object that describes the subject event * - * @return - * false if any bound listener returns false, else true - * - * @throws GuacamoleException - * If any bound listener throws this exception. If a listener throws an exception - * some listeners may not receive the authentication success event notification. + * @throws GuacamoleException if a registered listener throws a GuacamoleException */ @Override - public boolean authenticationSucceeded(AuthenticationSuccessEvent event) - throws GuacamoleException { - boolean result = true; - for (AuthenticationSuccessListener listener : listeners) { - result = result && listener.authenticationSucceeded(event); + public void handleEvent(Object event) throws GuacamoleException { + for (final Listener listener : listeners) { + listener.handleEvent(event); } - return result; - } - - /** - * Notifies all bound listeners of an authentication failure event. - * - * @param event - * The AuthenticationSuccessEvent describing the authentication failure - * that just occurred. - * - * @throws GuacamoleException - * If any bound listener throws this exception. If a listener throws an exception - * some listeners may not receive the authentication failure event notification. - */ - @Override - public void authenticationFailed(AuthenticationFailureEvent event) - throws GuacamoleException { - for (AuthenticationFailureListener listener : listeners) { - listener.authenticationFailed(event); - } - } - - /** - * Notifies all bound listeners of an tunnel connected event. Listeners - * are allowed to veto a tunnel connection by returning false from the - * listener method. Regardless of whether a particular listener rejects the - * tunnel connection, all listeners are notified. - * @param event - * The TunnelConnectedEvent describing the tunnel that was just connected - * - * @return - * false if any bound listener returns false, else true - * - * @throws GuacamoleException - * If any bound listener throws this exception. If a listener throws an exception - * some listeners may not receive the tunnel connected event notification. - */ - @Override - public boolean tunnelConnected(TunnelConnectEvent event) - throws GuacamoleException { - boolean result = true; - for (TunnelConnectListener listener : listeners) { - result = result && listener.tunnelConnected(event); - } - return result; - } - - /** - * Notifies all bound listeners of an tunnel close event. Listeners - * are allowed to veto the request to close a tunnel by returning false from - * the listener method. Regardless of whether a particular listener rejects the - * tunnel close request, all listeners are notified. - * @param event - * The TunnelCloseEvent describing the tunnel that is to be closed - * - * @return - * false if any bound listener returns false, else true - * - * @throws GuacamoleException - * If any bound listener throws this exception. If a listener throws an exception - * some listeners may not receive the tunnel close event notification. - */ - @Override - public boolean tunnelClosed(TunnelCloseEvent event) throws GuacamoleException { - boolean result = true; - for (TunnelCloseListener listener : listeners) { - result = result && listener.tunnelClosed(event); - } - return result; } } diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java index 56cf82a59..d3543d748 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java @@ -25,8 +25,6 @@ import java.util.List; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleSession; -import org.apache.guacamole.GuacamoleTunnelConnectedException; -import org.apache.guacamole.GuacamoleTunnelRejectedException; import org.apache.guacamole.GuacamoleUnauthorizedException; import org.apache.guacamole.net.GuacamoleTunnel; import org.apache.guacamole.net.auth.Connection; @@ -70,10 +68,8 @@ public class TunnelRequestService { private ListenerService listenerService; /** - * Notifies bound TunnelConnectListeners that a new tunnel has been connected. - * Listeners are allowed to veto a connected tunnel by returning false from the - * listener method. If the ListenerService indicates that any listener rejected - * the tunnel, the tunnel is closed an GuacamoleTunnelRejectedException is thrown. + * Notifies bound listeners that a new tunnel has been connected. + * Listeners may veto a connected tunnel by throwing any GuacamoleException. * * @param userContext * The UserContext associated with the user for whom the tunnel is @@ -88,25 +84,15 @@ public class TunnelRequestService { * @throws GuacamoleException * If thrown by a listener or if any listener vetoes the connected tunnel */ - private void notifyTunnelConnectListeners(UserContext userContext, + private void fireTunnelConnectEvent(UserContext userContext, Credentials credentials, GuacamoleTunnel tunnel) throws GuacamoleException { - TunnelConnectEvent event = new TunnelConnectEvent(userContext, credentials, tunnel); - if (!listenerService.tunnelConnected(event)) { - try { - tunnel.close(); - } - catch (GuacamoleException closeEx) { - logger.warn("Error closing rejected tunnel connection: {}", closeEx.getMessage()); - } - throw new GuacamoleTunnelRejectedException(); - } + listenerService.handleEvent(new TunnelConnectEvent(userContext, credentials, tunnel)); } /** - * Notifies bound TunnelCloseListeners that a tunnel is to be closed. - * Listeners are allowed to veto a request to close a tunnel by returning false from - * the listener method. If the ListenerService indicates that any listener vetoed the - * request to the close the tunnel, a GuacamoleTunnelConnectedException is thrown. + * Notifies bound listeners that a tunnel is to be closed. + * Listeners are allowed to veto a request to close a tunnel by throwing any + * GuacamoleException. * * @param userContext * The UserContext associated with the user for whom the tunnel is @@ -119,15 +105,12 @@ public class TunnelRequestService { * The tunnel that was connected * * @throws GuacamoleException - * If thrown by a listener or if any listener vetoes the request to close the tunnel + * If thrown by a listener. */ - private void notifyTunnelCloseListeners(UserContext userContext, + private void fireTunnelClosedEvent(UserContext userContext, Credentials credentials, GuacamoleTunnel tunnel) throws GuacamoleException { - TunnelCloseEvent event = new TunnelCloseEvent(userContext, credentials, tunnel); - if (listenerService.tunnelClosed(event)) { - throw new GuacamoleTunnelConnectedException(); - } + listenerService.handleEvent(new TunnelCloseEvent(userContext, credentials, tunnel)); } /** @@ -317,7 +300,7 @@ public class TunnelRequestService { public void close() throws GuacamoleException { // notify listeners to allow close request to be vetoed - notifyTunnelCloseListeners(context, + fireTunnelClosedEvent(context, session.getAuthenticatedUser().getCredentials(), tunnel); long connectionEndTime = System.currentTimeMillis(); @@ -406,7 +389,7 @@ public class TunnelRequestService { GuacamoleTunnel tunnel = createConnectedTunnel(userContext, type, id, info); // Notify listeners to allow connection to be vetoed - notifyTunnelConnectListeners(userContext, + fireTunnelConnectEvent(userContext, session.getAuthenticatedUser().getCredentials(), tunnel); // Associate tunnel with session From 3fbf176a15b8bf850f511f9c279222e2a333250c Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Sat, 23 Sep 2017 20:55:36 +0200 Subject: [PATCH 21/94] GUACAMOLE-385: Proper MIME type for tunnel write operations --- guacamole-common-js/src/main/webapp/modules/Tunnel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guacamole-common-js/src/main/webapp/modules/Tunnel.js b/guacamole-common-js/src/main/webapp/modules/Tunnel.js index cc5fbbb1e..508aa4c28 100644 --- a/guacamole-common-js/src/main/webapp/modules/Tunnel.js +++ b/guacamole-common-js/src/main/webapp/modules/Tunnel.js @@ -306,7 +306,7 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain) { var message_xmlhttprequest = new XMLHttpRequest(); message_xmlhttprequest.open("POST", TUNNEL_WRITE + tunnel.uuid); message_xmlhttprequest.withCredentials = withCredentials; - message_xmlhttprequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8"); + message_xmlhttprequest.setRequestHeader("Content-type", "application/octet-stream"); // Once response received, send next queued event. message_xmlhttprequest.onreadystatechange = function() { From f05b108e9d507aa0936ca139b50b0b2ca1651406 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Mon, 25 Sep 2017 06:18:05 -0400 Subject: [PATCH 22/94] GUACAMOLE-364: delete unused interface --- .../guacamole/extension/ListenerProvider.java | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java deleted file mode 100644 index 1d8afc10c..000000000 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.extension; - -import org.apache.guacamole.net.event.listener.AuthenticationFailureListener; -import org.apache.guacamole.net.event.listener.AuthenticationSuccessListener; -import org.apache.guacamole.net.event.listener.TunnelCloseListener; -import org.apache.guacamole.net.event.listener.TunnelConnectListener; - -/** - * A provider of an event listener. While an implementation of this interface - * must implement all of the specified listener interfaces, an implementation - * may selectively deliver event notifications to an underlying delegate based - * on the specific listener interfaces implemented by the delegate. - */ -public interface ListenerProvider extends AuthenticationSuccessListener, - AuthenticationFailureListener, TunnelConnectListener, - TunnelCloseListener { -} From 2bdf49205cb260576959d6be0598dc58c4e6fbb8 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Mon, 25 Sep 2017 06:18:43 -0400 Subject: [PATCH 23/94] GUACAMOLE-364: fixed misspelled instance variable name --- .../org/apache/guacamole/extension/ExtensionModule.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 f3ca70067..e7cdedb80 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java @@ -95,7 +95,7 @@ public class ExtensionModule extends ServletModule { /** * All currently-bound authentication providers, if any. */ - private final List boundListners = + private final List boundListeners = new ArrayList(); /** @@ -205,8 +205,8 @@ public class ExtensionModule extends ServletModule { private void bindListeners(Class providerClass) { logger.debug("[{}] Binding listeners \"{}\".", - boundListners.size(), providerClass.getName()); - boundListners.addAll(ListenerFactory.createListeners(providerClass)); + boundListeners.size(), providerClass.getName()); + boundListeners.addAll(ListenerFactory.createListeners(providerClass)); } @@ -234,7 +234,7 @@ public class ExtensionModule extends ServletModule { */ @Provides public List getListeners() { - return Collections.unmodifiableList(boundListners); + return Collections.unmodifiableList(boundListeners); } /** From 22760b5d0b722bfcb0380c37f7414868eebf40bb Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 12 Sep 2017 13:04:48 -0700 Subject: [PATCH 24/94] GUACAMOLE-395: Populate "expired" property of Guacamole users defined via MySQL / MariaDB. --- .../resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml index 0ddb0517a..4ab11827d 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -31,6 +31,7 @@ + From c20457f89b6d0658bbb684264e06d71fb608817f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 29 May 2017 19:03:42 -0700 Subject: [PATCH 25/94] GUACAMOLE-393: Add session invalidation hooks to AuthenticatedUser. --- .../guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java | 5 +++++ .../guacamole/net/auth/AbstractAuthenticatedUser.java | 5 +++++ .../org/apache/guacamole/net/auth/AuthenticatedUser.java | 7 +++++++ .../main/java/org/apache/guacamole/GuacamoleSession.java | 3 +++ 4 files changed, 20 insertions(+) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java index a3848f427..24118af45 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/RemoteAuthenticatedUser.java @@ -136,4 +136,9 @@ public abstract class RemoteAuthenticatedUser implements AuthenticatedUser { return authenticationProvider; } + @Override + public void invalidate() { + // Nothing to invalidate + } + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java index 730eec004..08b9b4e56 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AbstractAuthenticatedUser.java @@ -29,4 +29,9 @@ public abstract class AbstractAuthenticatedUser extends AbstractIdentifiable // Prior functionality now resides within AbstractIdentifiable + @Override + public void invalidate() { + // Nothing to invalidate + } + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java index 7f363f28d..f6ceb3abe 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticatedUser.java @@ -49,4 +49,11 @@ public interface AuthenticatedUser extends Identifiable { */ Credentials getCredentials(); + /** + * Invalidates this authenticated user and their associated token such that + * they are no longer logged in. This function will be automatically + * invoked when the user logs out, or when their session expires. + */ + void invalidate(); + } diff --git a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java index de8145380..17168afa7 100644 --- a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java +++ b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java @@ -252,6 +252,9 @@ public class GuacamoleSession { } } + // Invalidate the authenticated user object + authenticatedUser.invalidate(); + } } From 45adf2fd9392338cb100379d28ad64f5e7abff6e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 29 May 2017 20:52:45 -0700 Subject: [PATCH 26/94] GUACAMOLE-393: Add session invalidation hooks to UserContext. --- .../auth/jdbc/sharing/user/SharedUserContext.java | 5 +++++ .../guacamole/auth/jdbc/user/ModeledUserContext.java | 5 +++++ .../org/apache/guacamole/auth/ldap/user/UserContext.java | 5 +++++ .../java/org/apache/guacamole/net/auth/UserContext.java | 7 +++++++ .../guacamole/net/auth/simple/SimpleUserContext.java | 5 +++++ .../main/java/org/apache/guacamole/GuacamoleSession.java | 4 ++++ 6 files changed, 31 insertions(+) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java index cad1bab7f..2092898ae 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java @@ -204,4 +204,9 @@ public class SharedUserContext implements UserContext { return Collections.

emptyList(); } + @Override + public void invalidate() { + // Nothing to invalidate + } + } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java index d43c3c1c3..9d3ba69f2 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java @@ -191,4 +191,9 @@ public class ModeledUserContext extends RestrictedObject return ModeledSharingProfile.ATTRIBUTES; } + @Override + public void invalidate() { + // Nothing to invalidate + } + } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java index 2c4703c70..39c32e421 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java @@ -229,4 +229,9 @@ public class UserContext implements org.apache.guacamole.net.auth.UserContext { return Collections.emptyList(); } + @Override + public void invalidate() { + // Nothing to invalidate + } + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java index 5c6f97428..596c5d94f 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java @@ -212,4 +212,11 @@ public interface UserContext { */ Collection getSharingProfileAttributes(); + /** + * Invalidates this user context, releasing all associated resources. This + * function will be invoked when the user logs out, or when their session + * is automatically invalidated. + */ + void invalidate(); + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java index 1e55db92f..d87cf950b 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java @@ -234,4 +234,9 @@ public class SimpleUserContext implements UserContext { return Collections.emptyList(); } + @Override + public void invalidate() { + // Nothing to invalidate + } + } diff --git a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java index 17168afa7..e723c0a9e 100644 --- a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java +++ b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java @@ -252,6 +252,10 @@ public class GuacamoleSession { } } + // Invalidate all user contextx + for (UserContext userContext : userContexts) + userContext.invalidate(); + // Invalidate the authenticated user object authenticatedUser.invalidate(); From 2c587e5f9ffe8aa84c460b8f63cd71483bd4bc7f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 29 May 2017 21:21:48 -0700 Subject: [PATCH 27/94] GUACAMOLE-393: Add AuthenticationProvider shutdown hook. --- .../auth/cas/CASAuthenticationProvider.java | 5 ++++ .../auth/duo/DuoAuthenticationProvider.java | 5 ++++ .../HTTPHeaderAuthenticationProvider.java | 5 ++++ .../jdbc/InjectedAuthenticationProvider.java | 5 ++++ .../auth/ldap/LDAPAuthenticationProvider.java | 5 ++++ .../net/auth/AuthenticationProvider.java | 7 ++++++ .../simple/SimpleAuthenticationProvider.java | 5 ++++ .../GuacamoleServletContextListener.java | 25 ++++++++++++++++++- .../AuthenticationProviderFacade.java | 6 +++++ 9 files changed, 67 insertions(+), 1 deletion(-) diff --git a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/CASAuthenticationProvider.java b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/CASAuthenticationProvider.java index 241f17aed..28122f9b8 100644 --- a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/CASAuthenticationProvider.java +++ b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/CASAuthenticationProvider.java @@ -107,4 +107,9 @@ public class CASAuthenticationProvider implements AuthenticationProvider { } + @Override + public void shutdown() { + // Do nothing + } + } diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProvider.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProvider.java index f9989965d..1c84046cc 100644 --- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProvider.java +++ b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/DuoAuthenticationProvider.java @@ -102,4 +102,9 @@ public class DuoAuthenticationProvider implements AuthenticationProvider { return context; } + @Override + public void shutdown() { + // Do nothing + } + } diff --git a/extensions/guacamole-auth-header/src/main/java/org/apache/guacamole/auth/header/HTTPHeaderAuthenticationProvider.java b/extensions/guacamole-auth-header/src/main/java/org/apache/guacamole/auth/header/HTTPHeaderAuthenticationProvider.java index 1721f16ce..b3385b1db 100644 --- a/extensions/guacamole-auth-header/src/main/java/org/apache/guacamole/auth/header/HTTPHeaderAuthenticationProvider.java +++ b/extensions/guacamole-auth-header/src/main/java/org/apache/guacamole/auth/header/HTTPHeaderAuthenticationProvider.java @@ -107,4 +107,9 @@ public class HTTPHeaderAuthenticationProvider implements AuthenticationProvider } + @Override + public void shutdown() { + // Do nothing + } + } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/InjectedAuthenticationProvider.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/InjectedAuthenticationProvider.java index d06d6edad..e73b3dfce 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/InjectedAuthenticationProvider.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/InjectedAuthenticationProvider.java @@ -104,4 +104,9 @@ public abstract class InjectedAuthenticationProvider implements AuthenticationPr authenticatedUser, credentials); } + @Override + public void shutdown() { + // Do nothing + } + } diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java index 1db4ee915..f9c4a7d2c 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPAuthenticationProvider.java @@ -103,5 +103,10 @@ public class LDAPAuthenticationProvider implements AuthenticationProvider { return context; } + @Override + public void shutdown() { + // Do nothing + } + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationProvider.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationProvider.java index 3acc5127c..448f495f1 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationProvider.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/AuthenticationProvider.java @@ -167,5 +167,12 @@ public interface AuthenticationProvider { UserContext updateUserContext(UserContext context, AuthenticatedUser authenticatedUser, Credentials credentials) throws GuacamoleException; + + /** + * Frees all resources associated with this AuthenticationProvider. This + * function will be automatically invoked when the Guacamole server is + * shutting down. + */ + void shutdown(); } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java index 96766cb31..83ac79476 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java @@ -260,4 +260,9 @@ public abstract class SimpleAuthenticationProvider } + @Override + public void shutdown() { + // Do nothing + } + } diff --git a/guacamole/src/main/java/org/apache/guacamole/GuacamoleServletContextListener.java b/guacamole/src/main/java/org/apache/guacamole/GuacamoleServletContextListener.java index 72fe27313..e8ad6a81f 100644 --- a/guacamole/src/main/java/org/apache/guacamole/GuacamoleServletContextListener.java +++ b/guacamole/src/main/java/org/apache/guacamole/GuacamoleServletContextListener.java @@ -21,14 +21,17 @@ package org.apache.guacamole; import org.apache.guacamole.tunnel.TunnelModule; import com.google.inject.Guice; +import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Stage; import com.google.inject.servlet.GuiceServletContextListener; +import java.util.List; import javax.servlet.ServletContextEvent; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; import org.apache.guacamole.extension.ExtensionModule; import org.apache.guacamole.log.LogModule; +import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.rest.RESTServiceModule; import org.apache.guacamole.rest.auth.HashTokenSessionMap; import org.apache.guacamole.rest.auth.TokenSessionMap; @@ -56,6 +59,12 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener */ private TokenSessionMap sessionMap; + /** + * List of all authentication providers from all loaded extensions. + */ + @Inject + private List authProviders; + @Override public void contextInitialized(ServletContextEvent servletContextEvent) { @@ -75,13 +84,21 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener @Override protected Injector getInjector() { - return Guice.createInjector(Stage.PRODUCTION, + + // Create injector + Injector injector = Guice.createInjector(Stage.PRODUCTION, new EnvironmentModule(environment), new LogModule(environment), new ExtensionModule(environment), new RESTServiceModule(sessionMap), new TunnelModule() ); + + // Inject any annotated members of this class + injector.injectMembers(this); + + return injector; + } @Override @@ -93,6 +110,12 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener if (sessionMap != null) sessionMap.shutdown(); + // Unload all extensions + if (authProviders != null) { + for (AuthenticationProvider authProvider : authProviders) + authProvider.shutdown(); + } + } } 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 e1ed5ff68..c1e27650c 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/AuthenticationProviderFacade.java @@ -209,4 +209,10 @@ public class AuthenticationProviderFacade implements AuthenticationProvider { } + @Override + public void shutdown() { + if (authProvider != null) + authProvider.shutdown(); + } + } From cd5d23866db316e5835cd7fcd5fcc3a9c9a3a67e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 5 Sep 2017 13:45:45 -0700 Subject: [PATCH 28/94] GUACAMOLE-394: Separate definition of records and record sets into generalized interface. --- .../guacamole/net/auth/ActivityRecord.java | 78 +++++++++++ .../guacamole/net/auth/ActivityRecordSet.java | 128 ++++++++++++++++++ .../guacamole/net/auth/ConnectionRecord.java | 48 +------ .../net/auth/ConnectionRecordSet.java | 32 +---- 4 files changed, 211 insertions(+), 75 deletions(-) create mode 100644 guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecord.java create mode 100644 guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecordSet.java diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecord.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecord.java new file mode 100644 index 000000000..2324b0ee4 --- /dev/null +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecord.java @@ -0,0 +1,78 @@ +/* + * 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.net.auth; + +import java.util.Date; + +/** + * A logging record describing when a user started and ended a particular + * activity. + */ +public interface ActivityRecord { + + /** + * Returns the date and time the activity began. + * + * @return + * The date and time the activity began. + */ + public Date getStartDate(); + + /** + * Returns the date and time the activity ended, if applicable. + * + * @return + * The date and time the activity ended, or null if the activity is + * still ongoing or if the end time is unknown. + */ + public Date getEndDate(); + + /** + * Returns the hostname or IP address of the remote host that performed the + * activity associated with this record, if known. If the hostname or IP + * address is not known, null is returned. + * + * @return + * The hostname or IP address of the remote host, or null if this + * information is not available. + */ + public String getRemoteHost(); + + /** + * Returns the name of the user who performed or is performing the activity + * at the times given by this record. + * + * @return + * The name of the user who performed or is performing the associated + * activity. + */ + public String getUsername(); + + /** + * Returns whether the activity associated with this record is still + * ongoing. + * + * @return + * true if the activity associated with this record is still ongoing, + * false otherwise. + */ + public boolean isActive(); + +} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecordSet.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecordSet.java new file mode 100644 index 000000000..4cce03e65 --- /dev/null +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ActivityRecordSet.java @@ -0,0 +1,128 @@ +/* + * 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.net.auth; + +import java.util.Collection; +import org.apache.guacamole.GuacamoleException; + +/** + * A set of all available records related to a type of activity which has a + * defined start and end time, such as a user being logged in or connected, or a + * subset of those records. + * + * @param + * The type of ActivityRecord contained within this set. + */ +public interface ActivityRecordSet { + + /** + * All properties of activity records which can be used as sorting + * criteria. + */ + enum SortableProperty { + + /** + * The date and time when the activity associated with the record + * began. + */ + START_DATE + + }; + + /** + * Returns all records within this set as a standard Collection. + * + * @return + * A collection containing all records within this set. + * + * @throws GuacamoleException + * If an error occurs while retrieving the records within this set. + */ + Collection asCollection() throws GuacamoleException; + + /** + * Returns the subset of records which contain the given value. The + * properties and semantics involved with determining whether a particular + * record "contains" the given value is implementation dependent. This + * function may affect the contents of the current ActivityRecordSet. The + * contents of the current ActivityRecordSet should NOT be relied upon + * after this function is called. + * + * @param value + * The value which all records within the resulting subset should + * contain. + * + * @return + * The subset of records which contain the specified value. + * + * @throws GuacamoleException + * If an error occurs while restricting the current subset. + */ + ActivityRecordSet contains(String value) + throws GuacamoleException; + + /** + * Returns the subset of records containing only the first + * limit records. If the subset has fewer than + * limit records, then this function has no effect. This + * function may also affect the contents of the current ActivityRecordSet. + * The contents of the current ActivityRecordSet should NOT be relied upon + * after this function is called. + * + * @param limit + * The maximum number of records that the new subset should contain. + * + * @return + * The subset of records that containing only the first + * limit records. + * + * @throws GuacamoleException + * If an error occurs while limiting the current subset. + */ + ActivityRecordSet limit(int limit) throws GuacamoleException; + + /** + * Returns a ActivityRecordSet containing identically the records within + * this set, sorted according to the specified criteria. The sort operation + * performed is guaranteed to be stable with respect to any past call to + * sort(). This function may also affect the contents of the current + * ActivityRecordSet. The contents of the current ActivityRecordSet + * should NOT be relied upon after this function is called. + * + * @param property + * The property by which the records within the resulting set should be + * sorted. + * + * @param desc + * Whether the records should be sorted according to the specified + * property in descending order. If false, records will be sorted + * according to the specified property in ascending order. + * + * @return + * The ActivityRecordSet, sorted according to the specified criteria. + * + * @throws GuacamoleException + * If an error occurs while sorting the current subset, or if the given + * property is not supported by the implementation. + */ + ActivityRecordSet sort(SortableProperty property, boolean desc) + throws GuacamoleException; + +} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecord.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecord.java index 95c5f6ca1..21e30a98e 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecord.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecord.java @@ -19,13 +19,11 @@ package org.apache.guacamole.net.auth; -import java.util.Date; - /** * A logging record describing when a user started and ended usage of a * particular connection. */ -public interface ConnectionRecord { +public interface ConnectionRecord extends ActivityRecord { /** * Returns the identifier of the connection associated with this @@ -72,48 +70,4 @@ public interface ConnectionRecord { */ public String getSharingProfileName(); - /** - * Returns the date and time the connection began. - * - * @return The date and time the connection began. - */ - public Date getStartDate(); - - /** - * Returns the date and time the connection ended, if applicable. - * - * @return The date and time the connection ended, or null if the - * connection is still running or if the end time is unknown. - */ - public Date getEndDate(); - - /** - * Returns the hostname or IP address of the remote host that used the - * connection associated with this record, if known. If the hostname or IP - * address is not known, null is returned. - * - * @return - * The hostname or IP address of the remote host, or null if this - * information is not available. - */ - public String getRemoteHost(); - - /** - * Returns the name of the user who used or is using the connection at the - * times given by this connection record. - * - * @return The name of the user who used or is using the associated - * connection. - */ - public String getUsername(); - - /** - * Returns whether the connection associated with this record is still - * active. - * - * @return true if the connection associated with this record is still - * active, false otherwise. - */ - public boolean isActive(); - } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java index 5198cfa80..87f91bb57 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java @@ -19,39 +19,12 @@ package org.apache.guacamole.net.auth; -import java.util.Collection; import org.apache.guacamole.GuacamoleException; /** * The set of all available connection records, or a subset of those records. */ -public interface ConnectionRecordSet { - - /** - * All properties of connection records which can be used as sorting - * criteria. - */ - enum SortableProperty { - - /** - * The date and time when the connection associated with the - * connection record began. - */ - START_DATE - - }; - - /** - * Returns all connection records within this set as a standard Collection. - * - * @return - * A collection containing all connection records within this set. - * - * @throws GuacamoleException - * If an error occurs while retrieving the connection records within - * this set. - */ - Collection asCollection() throws GuacamoleException; +public interface ConnectionRecordSet extends ActivityRecordSet { /** * Returns the subset of connection records to only those where the @@ -73,6 +46,7 @@ public interface ConnectionRecordSet { * @throws GuacamoleException * If an error occurs while restricting the current subset. */ + @Override ConnectionRecordSet contains(String value) throws GuacamoleException; /** @@ -93,6 +67,7 @@ public interface ConnectionRecordSet { * @throws GuacamoleException * If an error occurs while limiting the current subset. */ + @Override ConnectionRecordSet limit(int limit) throws GuacamoleException; /** @@ -119,6 +94,7 @@ public interface ConnectionRecordSet { * @throws GuacamoleException * If an error occurs while sorting the current subset. */ + @Override ConnectionRecordSet sort(SortableProperty property, boolean desc) throws GuacamoleException; From 26122ebc3eb07934264618c319f93738a230a973 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 9 Sep 2017 13:20:43 -0700 Subject: [PATCH 29/94] GUACAMOLE-394: Deprecate ConnectionRecordSet. Refactor accordingly. --- .../jdbc/connection/ConnectionRecordSet.java | 10 ++- .../ConnectionRecordSortPredicate.java | 8 +- .../jdbc/sharing/user/SharedUserContext.java | 9 +- .../connection/ConnectionRecordMapper.xml | 4 +- .../connection/ConnectionRecordMapper.xml | 4 +- .../guacamole/auth/ldap/user/UserContext.java | 9 +- .../net/auth/ConnectionRecordSet.java | 82 ++----------------- .../guacamole/net/auth/UserContext.java | 5 +- .../auth/simple/SimpleActivityRecordSet.java | 62 ++++++++++++++ .../simple/SimpleConnectionRecordSet.java | 14 ++-- .../net/auth/simple/SimpleUserContext.java | 7 +- .../APIConnectionRecordSortPredicate.java | 26 +++--- .../rest/history/HistoryResource.java | 4 +- 13 files changed, 123 insertions(+), 121 deletions(-) create mode 100644 guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleActivityRecordSet.java diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java index f89a45028..7b3d629c4 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSet.java @@ -27,15 +27,17 @@ import java.util.List; import java.util.Set; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.jdbc.base.RestrictedObject; +import org.apache.guacamole.net.auth.ActivityRecordSet; +import org.apache.guacamole.net.auth.ActivityRecordSet.SortableProperty; import org.apache.guacamole.net.auth.ConnectionRecord; /** - * A JDBC implementation of ConnectionRecordSet. Calls to asCollection() will - * query connection history records from the database. Which records are - * returned will be determined by the values passed in earlier. + * A JDBC implementation of ActivityRecordSet for ConnectionRecords. Calls to + * asCollection() will query connection history records from the database. Which + * records are returned will be determined by the values passed in earlier. */ public class ConnectionRecordSet extends RestrictedObject - implements org.apache.guacamole.net.auth.ConnectionRecordSet { + implements ActivityRecordSet { /** * Service for managing connection objects. diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSortPredicate.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSortPredicate.java index 17f43806d..69eee780b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSortPredicate.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordSortPredicate.java @@ -19,7 +19,7 @@ package org.apache.guacamole.auth.jdbc.connection; -import org.apache.guacamole.net.auth.ConnectionRecordSet; +import org.apache.guacamole.net.auth.ActivityRecordSet; /** * A sort predicate which species the property to use when sorting connection @@ -30,7 +30,7 @@ public class ConnectionRecordSortPredicate { /** * The property to use when sorting ConnectionRecords. */ - private final ConnectionRecordSet.SortableProperty property; + private final ActivityRecordSet.SortableProperty property; /** * Whether the sort order is descending (true) or ascending (false). @@ -47,7 +47,7 @@ public class ConnectionRecordSortPredicate { * @param descending * Whether the sort order is descending (true) or ascending (false). */ - public ConnectionRecordSortPredicate(ConnectionRecordSet.SortableProperty property, + public ConnectionRecordSortPredicate(ActivityRecordSet.SortableProperty property, boolean descending) { this.property = property; this.descending = descending; @@ -59,7 +59,7 @@ public class ConnectionRecordSortPredicate { * @return * The property that should be used when sorting ConnectionRecords. */ - public ConnectionRecordSet.SortableProperty getProperty() { + public ActivityRecordSet.SortableProperty getProperty() { return property; } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java index 2092898ae..cdfe0fca6 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java @@ -28,16 +28,17 @@ import org.apache.guacamole.auth.jdbc.sharing.connectiongroup.SharedRootConnecti import org.apache.guacamole.auth.jdbc.user.RemoteAuthenticatedUser; import org.apache.guacamole.form.Form; import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionGroup; -import org.apache.guacamole.net.auth.ConnectionRecordSet; +import org.apache.guacamole.net.auth.ConnectionRecord; import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.net.auth.simple.SimpleActivityRecordSet; import org.apache.guacamole.net.auth.simple.SimpleConnectionGroupDirectory; -import org.apache.guacamole.net.auth.simple.SimpleConnectionRecordSet; import org.apache.guacamole.net.auth.simple.SimpleDirectory; /** @@ -175,8 +176,8 @@ public class SharedUserContext implements UserContext { } @Override - public ConnectionRecordSet getConnectionHistory() { - return new SimpleConnectionRecordSet(); + public ActivityRecordSet getConnectionHistory() { + return new SimpleActivityRecordSet(); } @Override diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml index c2c12c138..287ca02fa 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml @@ -129,7 +129,7 @@ - + - + - + - + getConnectionHistory() throws GuacamoleException { - return new SimpleConnectionRecordSet(); + return new SimpleActivityRecordSet(); } @Override diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java index 87f91bb57..62c84ec44 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/ConnectionRecordSet.java @@ -19,83 +19,13 @@ package org.apache.guacamole.net.auth; -import org.apache.guacamole.GuacamoleException; - /** * The set of all available connection records, or a subset of those records. + * + * @deprecated + * Use {@link ActivityRecordSet}<{@link ConnectionRecord}> instead. */ -public interface ConnectionRecordSet extends ActivityRecordSet { - - /** - * Returns the subset of connection records to only those where the - * connection name, user identifier, or any associated date field contain - * the given value. This function may also affect the contents of the - * current ConnectionRecordSet. The contents of the current - * ConnectionRecordSet should NOT be relied upon after this function is - * called. - * - * @param value - * The value which all connection records within the resulting subset - * should contain within their associated connection name or user - * identifier. - * - * @return - * The subset of connection history records which contain the specified - * value within their associated connection name or user identifier. - * - * @throws GuacamoleException - * If an error occurs while restricting the current subset. - */ - @Override - ConnectionRecordSet contains(String value) throws GuacamoleException; - - /** - * Returns the subset of connection history records containing only the - * first limit records. If the subset has fewer than - * limit records, then this function has no effect. This - * function may also affect the contents of the current - * ConnectionRecordSet. The contents of the current ConnectionRecordSet - * should NOT be relied upon after this function is called. - * - * @param limit - * The maximum number of records that the new subset should contain. - * - * @return - * The subset of connection history records that containing only the - * first limit records. - * - * @throws GuacamoleException - * If an error occurs while limiting the current subset. - */ - @Override - ConnectionRecordSet limit(int limit) throws GuacamoleException; - - /** - * Returns a ConnectionRecordSet containing identically the records within - * this set, sorted according to the specified criteria. The sort operation - * performed is guaranteed to be stable with respect to any past call to - * sort(). This function may also affect the contents of the current - * ConnectionRecordSet. The contents of the current ConnectionRecordSet - * should NOT be relied upon after this function is called. - * - * @param property - * The property by which the connection records within the resulting - * set should be sorted. - * - * @param desc - * Whether the records should be sorted according to the specified - * property in descending order. If false, records will be sorted - * according to the specified property in ascending order. - * - * @return - * The ConnnectionRecordSet, sorted according to the specified - * criteria. - * - * @throws GuacamoleException - * If an error occurs while sorting the current subset. - */ - @Override - ConnectionRecordSet sort(SortableProperty property, boolean desc) - throws GuacamoleException; - +@Deprecated +public interface ConnectionRecordSet + extends ActivityRecordSet { } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java index 596c5d94f..92f360459 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java @@ -145,7 +145,7 @@ public interface UserContext { /** * Retrieves all connection records visible to current user. The resulting * set of connection records can be further filtered and ordered using the - * methods defined on ConnectionRecordSet. + * methods defined on ActivityRecordSet. * * @return * A set of all connection records visible to the current user. @@ -153,7 +153,8 @@ public interface UserContext { * @throws GuacamoleException * If an error occurs while retrieving the connection records. */ - ConnectionRecordSet getConnectionHistory() throws GuacamoleException; + ActivityRecordSet getConnectionHistory() + throws GuacamoleException; /** * Retrieves a connection group which can be used to view and manipulate diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleActivityRecordSet.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleActivityRecordSet.java new file mode 100644 index 000000000..a9a3c3eed --- /dev/null +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleActivityRecordSet.java @@ -0,0 +1,62 @@ +/* + * 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.net.auth.simple; + +import java.util.Collection; +import java.util.Collections; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.net.auth.ActivityRecord; +import org.apache.guacamole.net.auth.ActivityRecordSet; +import org.apache.guacamole.net.auth.ActivityRecordSet.SortableProperty; + +/** + * An immutable and empty ActivityRecordSet. + * + * @param + * The type of ActivityRecord contained within this set. + */ +public class SimpleActivityRecordSet + implements ActivityRecordSet { + + @Override + public Collection asCollection() + throws GuacamoleException { + return Collections.emptyList(); + } + + @Override + public ActivityRecordSet contains(String value) + throws GuacamoleException { + return this; + } + + @Override + public ActivityRecordSet limit(int limit) + throws GuacamoleException { + return this; + } + + @Override + public ActivityRecordSet sort(SortableProperty property, + boolean desc) throws GuacamoleException { + return this; + } + +} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionRecordSet.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionRecordSet.java index f18b3d6eb..41971c9ae 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionRecordSet.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionRecordSet.java @@ -23,12 +23,16 @@ import java.util.Collection; import java.util.Collections; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.auth.ConnectionRecord; -import org.apache.guacamole.net.auth.ConnectionRecordSet; /** * An immutable and empty ConnectionRecordSet. + * + * @deprecated + * Use {@link SimpleActivityRecordSet}<{@link ConnectionRecord}> + * instead. */ -public class SimpleConnectionRecordSet implements ConnectionRecordSet { +@Deprecated +public class SimpleConnectionRecordSet implements org.apache.guacamole.net.auth.ConnectionRecordSet { @Override public Collection asCollection() @@ -37,19 +41,19 @@ public class SimpleConnectionRecordSet implements ConnectionRecordSet { } @Override - public ConnectionRecordSet contains(String value) + public org.apache.guacamole.net.auth.ConnectionRecordSet contains(String value) throws GuacamoleException { return this; } @Override - public ConnectionRecordSet limit(int limit) + public org.apache.guacamole.net.auth.ConnectionRecordSet limit(int limit) throws GuacamoleException { return this; } @Override - public ConnectionRecordSet sort(SortableProperty property, boolean desc) + public org.apache.guacamole.net.auth.ConnectionRecordSet sort(SortableProperty property, boolean desc) throws GuacamoleException { return this; } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java index d87cf950b..97584ed28 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java @@ -27,10 +27,11 @@ import java.util.UUID; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.form.Form; import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionGroup; -import org.apache.guacamole.net.auth.ConnectionRecordSet; +import org.apache.guacamole.net.auth.ConnectionRecord; import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; @@ -209,9 +210,9 @@ public class SimpleUserContext implements UserContext { } @Override - public ConnectionRecordSet getConnectionHistory() + public ActivityRecordSet getConnectionHistory() throws GuacamoleException { - return new SimpleConnectionRecordSet(); + return new SimpleActivityRecordSet(); } @Override diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecordSortPredicate.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecordSortPredicate.java index 2a4c81878..d2281d037 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecordSortPredicate.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecordSortPredicate.java @@ -21,7 +21,7 @@ package org.apache.guacamole.rest.history; import javax.ws.rs.core.Response; import org.apache.guacamole.GuacamoleClientException; -import org.apache.guacamole.net.auth.ConnectionRecordSet; +import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.rest.APIException; /** @@ -38,7 +38,7 @@ public class APIConnectionRecordSortPredicate { /** * All possible property name strings and their corresponding - * ConnectionRecordSet.SortableProperty values. + * ActivityRecordSet.SortableProperty values. */ public enum SortableProperty { @@ -46,24 +46,24 @@ public class APIConnectionRecordSortPredicate { * The date that the connection associated with the connection record * began (connected). */ - startDate(ConnectionRecordSet.SortableProperty.START_DATE); + startDate(ActivityRecordSet.SortableProperty.START_DATE); /** - * The ConnectionRecordSet.SortableProperty that this property name + * The ActivityRecordSet.SortableProperty that this property name * string represents. */ - public final ConnectionRecordSet.SortableProperty recordProperty; + public final ActivityRecordSet.SortableProperty recordProperty; /** * Creates a new SortableProperty which associates the property name * string (identical to its own name) with the given - * ConnectionRecordSet.SortableProperty value. + * ActivityRecordSet.SortableProperty value. * * @param recordProperty - * The ConnectionRecordSet.SortableProperty value to associate with + * The ActivityRecordSet.SortableProperty value to associate with * the new SortableProperty. */ - SortableProperty(ConnectionRecordSet.SortableProperty recordProperty) { + SortableProperty(ActivityRecordSet.SortableProperty recordProperty) { this.recordProperty = recordProperty; } @@ -72,7 +72,7 @@ public class APIConnectionRecordSortPredicate { /** * The property to use when sorting ConnectionRecords. */ - private ConnectionRecordSet.SortableProperty property; + private ActivityRecordSet.SortableProperty property; /** * Whether the requested sort order is descending (true) or ascending @@ -102,7 +102,7 @@ public class APIConnectionRecordSortPredicate { value = value.substring(DESCENDING_PREFIX.length()); } - // Parse sorting property into ConnectionRecordSet.SortableProperty + // Parse sorting property into ActivityRecordSet.SortableProperty try { this.property = SortableProperty.valueOf(value).recordProperty; } @@ -118,15 +118,15 @@ public class APIConnectionRecordSortPredicate { } /** - * Returns the SortableProperty defined by ConnectionRecordSet which + * Returns the SortableProperty defined by ActivityRecordSet which * represents the property requested. * * @return - * The ConnectionRecordSet.SortableProperty which refers to the same + * The ActivityRecordSet.SortableProperty which refers to the same * property as the string originally provided when this * APIConnectionRecordSortPredicate was created. */ - public ConnectionRecordSet.SortableProperty getProperty() { + public ActivityRecordSet.SortableProperty getProperty() { return property; } diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java index 49695c4d3..53a8cdba8 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/HistoryResource.java @@ -28,8 +28,8 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.ConnectionRecord; -import org.apache.guacamole.net.auth.ConnectionRecordSet; import org.apache.guacamole.net.auth.UserContext; /** @@ -92,7 +92,7 @@ public class HistoryResource { throws GuacamoleException { // Retrieve overall connection history - ConnectionRecordSet history = userContext.getConnectionHistory(); + ActivityRecordSet history = userContext.getConnectionHistory(); // Restrict to records which contain the specified strings for (String required : requiredContents) { From 5340f553616108283f399a811dc1eace14aa92d2 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 9 Sep 2017 13:43:49 -0700 Subject: [PATCH 30/94] GUACAMOLE-394: Add API support for user login/logout records. --- .../jdbc/sharing/user/SharedUserContext.java | 7 ++++ .../auth/jdbc/user/ModeledUserContext.java | 9 +++++ .../guacamole/auth/ldap/user/UserContext.java | 7 ++++ .../guacamole/net/auth/UserContext.java | 13 +++++++ .../apache/guacamole/net/auth/UserRecord.java | 39 +++++++++++++++++++ .../net/auth/simple/SimpleUserContext.java | 7 ++++ 6 files changed, 82 insertions(+) create mode 100644 guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java index cdfe0fca6..67cb6e481 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java @@ -37,6 +37,7 @@ import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.net.auth.UserRecord; import org.apache.guacamole.net.auth.simple.SimpleActivityRecordSet; import org.apache.guacamole.net.auth.simple.SimpleConnectionGroupDirectory; import org.apache.guacamole.net.auth.simple.SimpleDirectory; @@ -180,6 +181,12 @@ public class SharedUserContext implements UserContext { return new SimpleActivityRecordSet(); } + @Override + public ActivityRecordSet getUserHistory() + throws GuacamoleException { + return new SimpleActivityRecordSet(); + } + @Override public ConnectionGroup getRootConnectionGroup() { return rootGroup; diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java index 9d3ba69f2..b18b9558a 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java @@ -36,12 +36,15 @@ import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile; import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileDirectory; import org.apache.guacamole.form.Form; import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionGroup; import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; +import org.apache.guacamole.net.auth.UserRecord; +import org.apache.guacamole.net.auth.simple.SimpleActivityRecordSet; /** * UserContext implementation which is driven by an arbitrary, underlying @@ -161,6 +164,12 @@ public class ModeledUserContext extends RestrictedObject return connectionRecordSet; } + @Override + public ActivityRecordSet getUserHistory() + throws GuacamoleException { + return new SimpleActivityRecordSet(); + } + @Override public ConnectionGroup getRootConnectionGroup() throws GuacamoleException { diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java index 98d65ea88..b7e9e2708 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java @@ -37,6 +37,7 @@ import org.apache.guacamole.net.auth.ConnectionRecord; import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; +import org.apache.guacamole.net.auth.UserRecord; import org.apache.guacamole.net.auth.simple.SimpleActivityRecordSet; import org.apache.guacamole.net.auth.simple.SimpleConnectionGroup; import org.apache.guacamole.net.auth.simple.SimpleConnectionGroupDirectory; @@ -210,6 +211,12 @@ public class UserContext implements org.apache.guacamole.net.auth.UserContext { return new SimpleActivityRecordSet(); } + @Override + public ActivityRecordSet getUserHistory() + throws GuacamoleException { + return new SimpleActivityRecordSet(); + } + @Override public Collection getUserAttributes() { return Collections.emptyList(); diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java index 92f360459..8c741b8d8 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java @@ -156,6 +156,19 @@ public interface UserContext { ActivityRecordSet getConnectionHistory() throws GuacamoleException; + /** + * Retrieves all user records visible to current user. The resulting + * set of user records can be further filtered and ordered using the + * methods defined on ActivityRecordSet. + * + * @return + * A set of all user records visible to the current user. + * + * @throws GuacamoleException + * If an error occurs while retrieving the user records. + */ + ActivityRecordSet getUserHistory() throws GuacamoleException; + /** * Retrieves a connection group which can be used to view and manipulate * connections, but only as allowed by the permissions given to the user of diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java new file mode 100644 index 000000000..16ca2c615 --- /dev/null +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java @@ -0,0 +1,39 @@ +/* + * 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.net.auth; + +/** + * A logging record describing when a user started and ended their Guacamole + * session. + */ +public interface UserRecord extends ActivityRecord { + + /** + * Returns the authentication token associated with the user's session, if + * known. If permission is not granted to view the authentication tokens of + * other users, this may be null. + * + * @return + * The authentication token associated with the user's session, or null + * if this information is unavailable. + */ + public String getToken(); + +} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java index 97584ed28..360d74ab7 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java @@ -36,6 +36,7 @@ import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.net.auth.UserRecord; import org.apache.guacamole.protocol.GuacamoleConfiguration; /** @@ -215,6 +216,12 @@ public class SimpleUserContext implements UserContext { return new SimpleActivityRecordSet(); } + @Override + public ActivityRecordSet getUserHistory() + throws GuacamoleException { + return new SimpleActivityRecordSet(); + } + @Override public Collection getUserAttributes() { return Collections.emptyList(); From 700005e8238ec1cba18feb00c98c3a9997380811 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 11 Sep 2017 18:20:53 -0700 Subject: [PATCH 31/94] GUACAMOLE-394: Remove UserRecord interface - recording historical auth tokens doesn't make sense, and removing that turns UserRecord into an empty interface. --- .../jdbc/sharing/user/SharedUserContext.java | 6 +-- .../auth/jdbc/user/ModeledUserContext.java | 6 +-- .../guacamole/auth/ldap/user/UserContext.java | 6 +-- .../guacamole/net/auth/UserContext.java | 18 +++++---- .../apache/guacamole/net/auth/UserRecord.java | 39 ------------------- .../net/auth/simple/SimpleUserContext.java | 6 +-- 6 files changed, 23 insertions(+), 58 deletions(-) delete mode 100644 guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java index 67cb6e481..4bc54b562 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUserContext.java @@ -28,6 +28,7 @@ import org.apache.guacamole.auth.jdbc.sharing.connectiongroup.SharedRootConnecti import org.apache.guacamole.auth.jdbc.user.RemoteAuthenticatedUser; import org.apache.guacamole.form.Form; import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Connection; @@ -37,7 +38,6 @@ import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; -import org.apache.guacamole.net.auth.UserRecord; import org.apache.guacamole.net.auth.simple.SimpleActivityRecordSet; import org.apache.guacamole.net.auth.simple.SimpleConnectionGroupDirectory; import org.apache.guacamole.net.auth.simple.SimpleDirectory; @@ -182,9 +182,9 @@ public class SharedUserContext implements UserContext { } @Override - public ActivityRecordSet getUserHistory() + public ActivityRecordSet getUserHistory() throws GuacamoleException { - return new SimpleActivityRecordSet(); + return new SimpleActivityRecordSet(); } @Override diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java index b18b9558a..1b238abf6 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUserContext.java @@ -36,6 +36,7 @@ import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile; import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileDirectory; import org.apache.guacamole.form.Form; import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Connection; @@ -43,7 +44,6 @@ import org.apache.guacamole.net.auth.ConnectionGroup; import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; -import org.apache.guacamole.net.auth.UserRecord; import org.apache.guacamole.net.auth.simple.SimpleActivityRecordSet; /** @@ -165,9 +165,9 @@ public class ModeledUserContext extends RestrictedObject } @Override - public ActivityRecordSet getUserHistory() + public ActivityRecordSet getUserHistory() throws GuacamoleException { - return new SimpleActivityRecordSet(); + return new SimpleActivityRecordSet(); } @Override diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java index b7e9e2708..5e19dcaa1 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/user/UserContext.java @@ -28,6 +28,7 @@ import org.apache.guacamole.auth.ldap.connection.ConnectionService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.form.Form; import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.AuthenticationProvider; @@ -37,7 +38,6 @@ import org.apache.guacamole.net.auth.ConnectionRecord; import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; -import org.apache.guacamole.net.auth.UserRecord; import org.apache.guacamole.net.auth.simple.SimpleActivityRecordSet; import org.apache.guacamole.net.auth.simple.SimpleConnectionGroup; import org.apache.guacamole.net.auth.simple.SimpleConnectionGroupDirectory; @@ -212,9 +212,9 @@ public class UserContext implements org.apache.guacamole.net.auth.UserContext { } @Override - public ActivityRecordSet getUserHistory() + public ActivityRecordSet getUserHistory() throws GuacamoleException { - return new SimpleActivityRecordSet(); + return new SimpleActivityRecordSet(); } @Override diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java index 8c741b8d8..1c82f9ce8 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserContext.java @@ -143,9 +143,11 @@ public interface UserContext { throws GuacamoleException; /** - * Retrieves all connection records visible to current user. The resulting - * set of connection records can be further filtered and ordered using the - * methods defined on ActivityRecordSet. + * Retrieves all connection records visible to current user. Connection + * history records describe the start and end times of connections, and + * correspond to the times that users connect or disconnect to individual + * remote desktops. The resulting set of connection records can be further + * filtered and ordered using the methods defined on ActivityRecordSet. * * @return * A set of all connection records visible to the current user. @@ -157,9 +159,11 @@ public interface UserContext { throws GuacamoleException; /** - * Retrieves all user records visible to current user. The resulting - * set of user records can be further filtered and ordered using the - * methods defined on ActivityRecordSet. + * Retrieves all user history records visible to current user. User history + * records describe the start and end times of user sessions, and correspond + * to the times that users logged in or out. The resulting set of user + * records can be further filtered and ordered using the methods defined on + * ActivityRecordSet. * * @return * A set of all user records visible to the current user. @@ -167,7 +171,7 @@ public interface UserContext { * @throws GuacamoleException * If an error occurs while retrieving the user records. */ - ActivityRecordSet getUserHistory() throws GuacamoleException; + ActivityRecordSet getUserHistory() throws GuacamoleException; /** * Retrieves a connection group which can be used to view and manipulate diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java deleted file mode 100644 index 16ca2c615..000000000 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/UserRecord.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.net.auth; - -/** - * A logging record describing when a user started and ended their Guacamole - * session. - */ -public interface UserRecord extends ActivityRecord { - - /** - * Returns the authentication token associated with the user's session, if - * known. If permission is not granted to view the authentication tokens of - * other users, this may be null. - * - * @return - * The authentication token associated with the user's session, or null - * if this information is unavailable. - */ - public String getToken(); - -} diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java index 360d74ab7..1678d8827 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUserContext.java @@ -27,6 +27,7 @@ import java.util.UUID; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.form.Form; import org.apache.guacamole.net.auth.ActiveConnection; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.ActivityRecordSet; import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Connection; @@ -36,7 +37,6 @@ import org.apache.guacamole.net.auth.Directory; import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; -import org.apache.guacamole.net.auth.UserRecord; import org.apache.guacamole.protocol.GuacamoleConfiguration; /** @@ -217,9 +217,9 @@ public class SimpleUserContext implements UserContext { } @Override - public ActivityRecordSet getUserHistory() + public ActivityRecordSet getUserHistory() throws GuacamoleException { - return new SimpleActivityRecordSet(); + return new SimpleActivityRecordSet(); } @Override From b61f14e4db06bf2d2dfc1fd7e2098e0d96618b82 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 11 Sep 2017 18:33:49 -0700 Subject: [PATCH 32/94] GUACAMOLE-394: Add history list at User object level (similar to Connection). --- .../auth/jdbc/sharing/user/SharedUser.java | 10 ++++++++++ .../guacamole/auth/jdbc/user/ModeledUser.java | 7 +++++++ .../org/apache/guacamole/net/auth/User.java | 18 ++++++++++++++++++ .../guacamole/net/auth/simple/SimpleUser.java | 7 +++++++ .../guacamole/rest/user/APIUserWrapper.java | 8 ++++++++ 5 files changed, 50 insertions(+) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java index 57120ea1c..07d762a4b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java @@ -20,9 +20,11 @@ package org.apache.guacamole.auth.jdbc.sharing.user; import java.util.Collections; +import java.util.List; import java.util.Map; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.jdbc.sharing.permission.SharedObjectPermissionSet; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionGroup; @@ -88,6 +90,14 @@ public class SharedUser implements User { // Do nothing - no attributes supported } + @Override + public List getHistory() throws GuacamoleException { + + // History is not recorded for shared users + return Collections.emptyList(); + + } + @Override public String getPassword() { return null; diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index 36a0be878..1d40c1f05 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -29,6 +29,7 @@ import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TimeZone; import org.apache.guacamole.auth.jdbc.base.ModeledDirectoryObject; @@ -49,6 +50,7 @@ import org.apache.guacamole.form.Form; import org.apache.guacamole.form.TextField; import org.apache.guacamole.form.TimeField; import org.apache.guacamole.form.TimeZoneField; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; import org.apache.guacamole.net.auth.permission.SystemPermission; @@ -792,4 +794,9 @@ public class ModeledUser extends ModeledDirectoryObject implements Us return getModel().isExpired(); } + @Override + public List getHistory() throws GuacamoleException { + return Collections.emptyList(); + } + } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java index 88756e495..43d57c0b7 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java @@ -19,6 +19,7 @@ package org.apache.guacamole.net.auth; +import java.util.List; import java.util.Map; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; @@ -100,6 +101,23 @@ public interface User extends Identifiable { */ void setAttributes(Map attributes); + /** + * Returns a list of ActivityRecords representing the login history + * of this user, including any active sessions. ActivityRecords + * in this list will be sorted in descending order of end time (active + * sessions are first), and then in descending order of start time + * (newer sessions are first). + * + * @return + * A list of ActivityRecords representing the login history of this + * User. + * + * @throws GuacamoleException + * If an error occurs while reading the history of this user, or if + * permission is denied. + */ + List getHistory() throws GuacamoleException; + /** * Returns all system-level permissions given to this user. * diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java index d6db92fa5..cd20f3961 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java @@ -22,10 +22,12 @@ package org.apache.guacamole.net.auth.simple; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.auth.AbstractUser; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.permission.ObjectPermission; import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; import org.apache.guacamole.net.auth.permission.SystemPermissionSet; @@ -163,6 +165,11 @@ public class SimpleUser extends AbstractUser { // Do nothing - there are no attributes } + @Override + public List getHistory() throws GuacamoleException { + return Collections.emptyList(); + } + @Override public SystemPermissionSet getSystemPermissions() throws GuacamoleException { diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java index 35769faa7..7f37be67c 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java @@ -19,9 +19,12 @@ package org.apache.guacamole.rest.user; +import java.util.Collections; +import java.util.List; import java.util.Map; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleUnsupportedException; +import org.apache.guacamole.net.auth.ActivityRecord; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; import org.apache.guacamole.net.auth.permission.SystemPermissionSet; @@ -112,4 +115,9 @@ public class APIUserWrapper implements User { throw new GuacamoleUnsupportedException("APIUserWrapper does not provide permission access."); } + @Override + public List getHistory() throws GuacamoleException { + return Collections.emptyList(); + } + } From 3cd7f453c0a9ba8abd69c76cce8da8a917c0021e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 11 Sep 2017 18:49:11 -0700 Subject: [PATCH 33/94] GUACAMOLE-394: Add getLastActive() function, returning the time that a user/connection was last logged-in / used. --- .../auth/jdbc/connection/ModeledConnection.java | 6 ++++++ .../jdbc/sharing/connection/SharedConnection.java | 6 ++++++ .../auth/jdbc/sharing/user/SharedUser.java | 9 +++++++++ .../guacamole/auth/jdbc/user/ModeledUser.java | 5 +++++ .../org/apache/guacamole/net/auth/Connection.java | 13 +++++++++++++ .../java/org/apache/guacamole/net/auth/User.java | 12 ++++++++++++ .../guacamole/net/auth/simple/SimpleConnection.java | 6 ++++++ .../guacamole/net/auth/simple/SimpleUser.java | 6 ++++++ .../rest/connection/APIConnectionWrapper.java | 6 ++++++ .../apache/guacamole/rest/user/APIUserWrapper.java | 6 ++++++ 10 files changed, 75 insertions(+) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java index 365c40dc5..c596b2771 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java @@ -24,6 +24,7 @@ import com.google.inject.Provider; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -232,6 +233,11 @@ public class ModeledConnection extends ModeledChildDirectoryObject getHistory() throws GuacamoleException { return connectionService.retrieveHistory(getCurrentUser(), this); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java index 1c955dbd8..5483d0267 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/connection/SharedConnection.java @@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.sharing.connection; import com.google.inject.Inject; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -146,6 +147,11 @@ public class SharedConnection implements Connection { // Do nothing - changing attributes not supported } + @Override + public Date getLastActive() { + return null; + } + @Override public List getHistory() throws GuacamoleException { diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java index 07d762a4b..8e7931d86 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/sharing/user/SharedUser.java @@ -20,6 +20,7 @@ package org.apache.guacamole.auth.jdbc.sharing.user; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import org.apache.guacamole.GuacamoleException; @@ -90,6 +91,14 @@ public class SharedUser implements User { // Do nothing - no attributes supported } + @Override + public Date getLastActive() { + + // History is not recorded for shared users + return null; + + } + @Override public List getHistory() throws GuacamoleException { diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java index 1d40c1f05..fc43e36b1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java @@ -794,6 +794,11 @@ public class ModeledUser extends ModeledDirectoryObject implements Us return getModel().isExpired(); } + @Override + public Date getLastActive() { + return null; + } + @Override public List getHistory() throws GuacamoleException { return Collections.emptyList(); diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connection.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connection.java index b0795e2a1..85fd1680d 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connection.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/Connection.java @@ -19,6 +19,7 @@ package org.apache.guacamole.net.auth; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -102,6 +103,18 @@ public interface Connection extends Identifiable, Connectable { */ void setAttributes(Map attributes); + /** + * Returns the date and time that this connection was last used. If the + * connection was never used, the time that the connection was last used is + * unknown, or this information is not visible to the current user, this + * may be null. + * + * @return + * The date and time this connection was last used, or null if this + * information is unavailable or inapplicable. + */ + Date getLastActive(); + /** * Returns a list of ConnectionRecords representing the usage history * of this Connection, including any active users. ConnectionRecords diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java index 43d57c0b7..f7bd61ca2 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/User.java @@ -19,6 +19,7 @@ package org.apache.guacamole.net.auth; +import java.util.Date; import java.util.List; import java.util.Map; import org.apache.guacamole.GuacamoleException; @@ -101,6 +102,17 @@ public interface User extends Identifiable { */ void setAttributes(Map attributes); + /** + * Returns the date and time that this user was last active. If the user + * was never active, the time that the user was last active is unknown, or + * this information is not visible to the current user, this may be null. + * + * @return + * The date and time this user was last active, or null if this + * information is unavailable or inapplicable. + */ + Date getLastActive(); + /** * Returns a list of ActivityRecords representing the login history * of this user, including any active sessions. ActivityRecords diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java index 2251a9edf..85783a0a4 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnection.java @@ -20,6 +20,7 @@ package org.apache.guacamole.net.auth.simple; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import org.apache.guacamole.GuacamoleException; @@ -136,6 +137,11 @@ public class SimpleConnection extends AbstractConnection { } + @Override + public Date getLastActive() { + return null; + } + @Override public List getHistory() throws GuacamoleException { return Collections.emptyList(); diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java index cd20f3961..19ed35731 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleUser.java @@ -21,6 +21,7 @@ package org.apache.guacamole.net.auth.simple; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -165,6 +166,11 @@ public class SimpleUser extends AbstractUser { // Do nothing - there are no attributes } + @Override + public Date getLastActive() { + return null; + } + @Override public List getHistory() throws GuacamoleException { return Collections.emptyList(); diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java index e06e338db..3a987e544 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnectionWrapper.java @@ -20,6 +20,7 @@ package org.apache.guacamole.rest.connection; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -131,6 +132,11 @@ public class APIConnectionWrapper implements Connection { throw new UnsupportedOperationException("Operation not supported."); } + @Override + public Date getLastActive() { + return null; + } + @Override public List getHistory() throws GuacamoleException { return Collections.emptyList(); diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java index 7f37be67c..c4b85f9ae 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java @@ -20,6 +20,7 @@ package org.apache.guacamole.rest.user; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import org.apache.guacamole.GuacamoleException; @@ -115,6 +116,11 @@ public class APIUserWrapper implements User { throw new GuacamoleUnsupportedException("APIUserWrapper does not provide permission access."); } + @Override + public Date getLastActive() { + return null; + } + @Override public List getHistory() throws GuacamoleException { return Collections.emptyList(); From 67c817af9ff1da7729a03205b929119f6d020027 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 1 Jan 2016 19:54:58 -0800 Subject: [PATCH 34/94] GUACAMOLE-210: Add stub OAuthAuthenticationProvider. --- extensions/guacamole-auth-openid/pom.xml | 84 +++++++++++++++++++ .../oauth/OAuthAuthenticationProvider.java | 83 ++++++++++++++++++ .../src/main/resources/guac-manifest.json | 12 +++ pom.xml | 1 + 4 files changed, 180 insertions(+) create mode 100644 extensions/guacamole-auth-openid/pom.xml create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java create mode 100644 extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml new file mode 100644 index 000000000..bc62695b8 --- /dev/null +++ b/extensions/guacamole-auth-openid/pom.xml @@ -0,0 +1,84 @@ + + + + + 4.0.0 + org.apache.guacamole + guacamole-auth-openid + jar + 0.9.9 + guacamole-auth-openid + http://guacamole.incubator.apache.org/ + + + UTF-8 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + + + + + + org.glyptodon.guacamole + guacamole-ext + 0.9.9 + provided + + + + + com.google.oauth-client + google-oauth-client + 1.21.0 + + + + + com.google.inject + guice + 3.0 + + + com.google.inject.extensions + guice-multibindings + 3.0 + + + + + diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java new file mode 100644 index 000000000..55f40b1b9 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java @@ -0,0 +1,83 @@ +/* + * 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.oauth; + +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.net.auth.AuthenticatedUser; +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.net.auth.credentials.CredentialsInfo; +import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; + +/** + * Guacamole authentication backend which authenticates users using an + * arbitrary external system implementing OAuth. No storage for connections is + * provided - only authentication. Storage must be provided by some other + * extension. + */ +public class OAuthAuthenticationProvider implements AuthenticationProvider { + + @Override + public String getIdentifier() { + return "oauth"; + } + + @Override + public AuthenticatedUser authenticateUser(Credentials credentials) + throws GuacamoleException { + + // STUB + throw new GuacamoleInvalidCredentialsException( + "Invalid login.", + CredentialsInfo.USERNAME_PASSWORD + ); + + } + + @Override + public AuthenticatedUser updateAuthenticatedUser( + AuthenticatedUser authenticatedUser, Credentials credentials) + throws GuacamoleException { + + // No update necessary + return authenticatedUser; + + } + + @Override + public UserContext getUserContext(AuthenticatedUser authenticatedUser) + throws GuacamoleException { + + // No associated data whatsoever + return null; + + } + + @Override + public UserContext updateUserContext(UserContext context, + AuthenticatedUser authenticatedUser) throws GuacamoleException { + + // No update necessary + return context; + + } + +} diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json new file mode 100644 index 000000000..77dd70922 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json @@ -0,0 +1,12 @@ +{ + + "guacamoleVersion" : "0.9.9", + + "name" : "OAuth Authentication Extension", + "namespace" : "guac-oauth", + + "authProviders" : [ + "org.apache.guacamole.auth.oauth.OAuthAuthenticationProvider" + ] + +} diff --git a/pom.xml b/pom.xml index 41317a316..55228f5aa 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ extensions/guacamole-auth-jdbc extensions/guacamole-auth-ldap extensions/guacamole-auth-noauth + extensions/guacamole-auth-openid doc/guacamole-example From c7d5bd69aa33e8d28c5391176ae7977574c660f7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 1 Jan 2016 23:54:09 -0800 Subject: [PATCH 35/94] GUACAMOLE-210: Add OAuth code field generated from configuration info in guacamole.properties. Use Guice. --- .../oauth/AuthenticationProviderService.java | 89 +++++++++++++++ .../auth/oauth/ConfigurationService.java | 107 ++++++++++++++++++ .../oauth/OAuthAuthenticationProvider.java | 35 ++++-- .../OAuthAuthenticationProviderModule.java | 78 +++++++++++++ .../guacamole/auth/oauth/OAuthCodeField.java | 97 ++++++++++++++++ .../auth/oauth/OAuthGuacamoleProperties.java | 86 ++++++++++++++ 6 files changed, 485 insertions(+), 7 deletions(-) create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/ConfigurationService.java create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthGuacamoleProperties.java diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java new file mode 100644 index 000000000..c07a78cd4 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java @@ -0,0 +1,89 @@ +/* + * 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.oauth; + +import com.google.inject.Inject; +import java.util.Arrays; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.net.auth.AuthenticatedUser; +import org.glyptodon.guacamole.net.auth.Credentials; +import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; +import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Service providing convenience functions for the OAuth AuthenticationProvider + * implementation. + */ +public class AuthenticationProviderService { + + /** + * Logger for this class. + */ + private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class); + + /** + * Service for retrieving OAuth configuration information. + */ + @Inject + private ConfigurationService confService; + + /** + * Returns an AuthenticatedUser representing the user authenticated by the + * given credentials. + * + * @param credentials + * The credentials to use for authentication. + * + * @return + * An AuthenticatedUser representing the user authenticated by the + * given credentials. + * + * @throws GuacamoleException + * If an error occurs while authenticating the user, or if access is + * denied. + */ + public AuthenticatedUser authenticateUser(Credentials credentials) + throws GuacamoleException { + + // Request auth code + throw new GuacamoleInvalidCredentialsException("Invalid login.", + new CredentialsInfo(Arrays.asList(new Field[] { + + // Normal username/password fields + CredentialsInfo.USERNAME, + CredentialsInfo.PASSWORD, + + // OAuth-specific code (will be rendered as an appropriate + // "Log in with..." button + new OAuthCodeField( + confService.getAuthorizationEndpoint(), + confService.getClientID(), + confService.getRedirectURI() + ) + + })) + ); + + } + +} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/ConfigurationService.java new file mode 100644 index 000000000..d27b0752b --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/ConfigurationService.java @@ -0,0 +1,107 @@ +/* + * 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.oauth; + +import com.google.inject.Inject; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.environment.Environment; + +/** + * Service for retrieving configuration information regarding the OAuth service. + */ +public class ConfigurationService { + + /** + * The Guacamole server environment. + */ + @Inject + private Environment environment; + + /** + * Returns the authorization endpoint (URI) of the OAuth service as + * configured with guacamole.properties. + * + * @return + * The authorization endpoint of the OAuth service, as configured with + * guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the authorization + * endpoint property is missing. + */ + public String getAuthorizationEndpoint() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_AUTHORIZATION_ENDPOINT); + } + + /** + * Returns the OAuth client ID which should be submitted to the OAuth + * service when necessary, as configured with guacamole.properties. This + * value is typically provided by the OAuth service when OAuth credentials + * are generated for your application. + * + * @return + * The client ID to use when communicating with the OAuth service, + * as configured with guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the client ID + * property is missing. + */ + public String getClientID() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_CLIENT_ID); + } + + /** + * Returns the OAuth client secret which should be submitted to the OAuth + * service when necessary, as configured with guacamole.properties. This + * value is typically provided by the OAuth service when OAuth credentials + * are generated for your application. + * + * @return + * The client secret to use when communicating with the OAuth service, + * as configured with guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the client secret + * property is missing. + */ + public String getClientSecret() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_CLIENT_SECRET); + } + + /** + * Returns the URI that the OAuth service should redirect to after + * the authentication process is complete, as configured with + * guacamole.properties. This must be the full URL that a user would enter + * into their browser to access Guacamole. + * + * @return + * The client secret to use when communicating with the OAuth service, + * as configured with guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the client secret + * property is missing. + */ + public String getRedirectURI() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_REDIRECT_URI); + } + +} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java index 55f40b1b9..06255ac80 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java @@ -19,13 +19,13 @@ package org.apache.guacamole.auth.oauth; +import com.google.inject.Guice; +import com.google.inject.Injector; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.auth.AuthenticatedUser; 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.net.auth.credentials.CredentialsInfo; -import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; /** * Guacamole authentication backend which authenticates users using an @@ -35,6 +35,29 @@ import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsE */ public class OAuthAuthenticationProvider implements AuthenticationProvider { + /** + * Injector which will manage the object graph of this authentication + * provider. + */ + private final Injector injector; + + /** + * Creates a new OAuthAuthenticationProvider that authenticates users + * against an OAuth service + * + * @throws GuacamoleException + * If a required property is missing, or an error occurs while parsing + * a property. + */ + public OAuthAuthenticationProvider() throws GuacamoleException { + + // Set up Guice injector. + injector = Guice.createInjector( + new OAuthAuthenticationProviderModule(this) + ); + + } + @Override public String getIdentifier() { return "oauth"; @@ -44,11 +67,9 @@ public class OAuthAuthenticationProvider implements AuthenticationProvider { public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException { - // STUB - throw new GuacamoleInvalidCredentialsException( - "Invalid login.", - CredentialsInfo.USERNAME_PASSWORD - ); + // Attempt to authenticate user with given credentials + AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class); + return authProviderService.authenticateUser(credentials); } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java new file mode 100644 index 000000000..66860d1ab --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java @@ -0,0 +1,78 @@ +/* + * 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.oauth; + +import com.google.inject.AbstractModule; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.environment.Environment; +import org.glyptodon.guacamole.environment.LocalEnvironment; +import org.glyptodon.guacamole.net.auth.AuthenticationProvider; + +/** + * Guice module which configures OAuth-specific injections. + */ +public class OAuthAuthenticationProviderModule extends AbstractModule { + + /** + * Guacamole server environment. + */ + private final Environment environment; + + /** + * A reference to the OAuthAuthenticationProvider on behalf of which this + * module has configured injection. + */ + private final AuthenticationProvider authProvider; + + /** + * Creates a new OAuth authentication provider module which configures + * injection for the OAuthAuthenticationProvider. + * + * @param authProvider + * The AuthenticationProvider for which injection is being configured. + * + * @throws GuacamoleException + * If an error occurs while retrieving the Guacamole server + * environment. + */ + public OAuthAuthenticationProviderModule(AuthenticationProvider authProvider) + throws GuacamoleException { + + // Get local environment + this.environment = new LocalEnvironment(); + + // Store associated auth provider + this.authProvider = authProvider; + + } + + @Override + protected void configure() { + + // Bind core implementations of guacamole-ext classes + bind(AuthenticationProvider.class).toInstance(authProvider); + bind(Environment.class).toInstance(environment); + + // Bind OAuth-specific services + bind(ConfigurationService.class); + + } + +} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java new file mode 100644 index 000000000..6f4e4689c --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java @@ -0,0 +1,97 @@ +/* + * 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.oauth; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import org.glyptodon.guacamole.form.Field; + +/** + * Field definition which represents the code returned by an OAuth service. + * Within the user interface, this will be rendered as an appropriate "Log in + * with ..." button which links to the OAuth service. + */ +public class OAuthCodeField extends Field { + + /** + * The standard HTTP parameter which will be included within the URL by all + * OAuth services upon successful authentication and redirect. + */ + private static final String OAUTH_CODE_PARAMETER_NAME = "code"; + + /** + * The full URI which the field should link to. + */ + private final String authorizationURI; + + /** + * Creates a new OAuth "code" field which links to the given OAuth service + * using the provided client ID. Successful authentication at the OAuth + * service will result in the client being redirected to the specified + * redirect URI. The OAuth code will be embedded in the query parameters of + * that URI. + * + * @param authorizationEndpoint + * The full URL of the endpoint accepting OAuth authentication + * requests. + * + * @param clientID + * The ID of the OAuth client. This is normally determined ahead of + * time by the OAuth service through some manual credential request + * procedure. + * + * @param redirectURI + * The URI that the OAuth service should redirect to upon successful + * authentication. + */ + public OAuthCodeField(String authorizationEndpoint, String clientID, + String redirectURI) { + + // Init base field properties + super(OAUTH_CODE_PARAMETER_NAME, "OAUTH_CODE"); + + // Build authorization URI from given values + try { + this.authorizationURI = authorizationEndpoint + + "?scope=openid%20email%20profile" + + "&response_type=code" + + "&client_id=" + URLEncoder.encode(clientID, "UTF-8") + + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8"); + } + + // Java is required to provide UTF-8 support + catch (UnsupportedEncodingException e) { + throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e); + } + + } + + /** + * Returns the full URI that this field should link to when a new code + * needs to be obtained from the OAuth service. + * + * @return + * The full URI that this field should link to. + */ + public String getAuthorizationURI() { + return authorizationURI; + } + +} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthGuacamoleProperties.java new file mode 100644 index 000000000..bb1e4fddc --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthGuacamoleProperties.java @@ -0,0 +1,86 @@ +/* + * 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.oauth; + +import org.glyptodon.guacamole.properties.StringGuacamoleProperty; + +/** + * Provides properties required for use of the OAuth authentication provider. + * These properties will be read from guacamole.properties when the OAuth + * authentication provider is used. + */ +public class OAuthGuacamoleProperties { + + /** + * This class should not be instantiated. + */ + private OAuthGuacamoleProperties() {} + + /** + * The authorization endpoint (URI) of the OAuth service. + */ + public static final StringGuacamoleProperty OAUTH_AUTHORIZATION_ENDPOINT = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-authorization-endpoint"; } + + }; + + /** + * OAuth client ID which should be submitted to the OAuth service when + * necessary. This value is typically provided by the OAuth service when + * OAuth credentials are generated for your application. + */ + public static final StringGuacamoleProperty OAUTH_CLIENT_ID = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-client-id"; } + + }; + + /** + * OAuth client secret which should be submitted to the OAuth service when + * necessary. This value is typically provided by the OAuth service when + * OAuth credentials are generated for your application. + */ + public static final StringGuacamoleProperty OAUTH_CLIENT_SECRET = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-client-secret"; } + + }; + + /** + * The URI that the OAuth service should redirect to after the + * authentication process is complete. This must be the full URL that a + * user would enter into their browser to access Guacamole. + */ + public static final StringGuacamoleProperty OAUTH_REDIRECT_URI = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-redirect-uri"; } + + }; + +} From 89f25a9467b62545bd1c114a35bba8680678fcc6 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 2 Jan 2016 00:22:08 -0800 Subject: [PATCH 36/94] GUACAMOLE-210: Add OAuth code/link field. --- .../guacamole/auth/oauth/OAuthCodeField.java | 2 +- .../src/main/resources/guac-manifest.json | 11 ++++++- .../src/main/resources/oauthCodeField.html | 1 + .../src/main/resources/oauthConfig.js | 31 +++++++++++++++++++ .../src/main/resources/oauthModule.js | 28 +++++++++++++++++ 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html create mode 100644 extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js create mode 100644 extensions/guacamole-auth-openid/src/main/resources/oauthModule.js diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java index 6f4e4689c..bdf16c850 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java @@ -65,7 +65,7 @@ public class OAuthCodeField extends Field { String redirectURI) { // Init base field properties - super(OAUTH_CODE_PARAMETER_NAME, "OAUTH_CODE"); + super(OAUTH_CODE_PARAMETER_NAME, "GUAC_OAUTH_CODE"); // Build authorization URI from given values try { diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json index 77dd70922..e8f2facc1 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json @@ -7,6 +7,15 @@ "authProviders" : [ "org.apache.guacamole.auth.oauth.OAuthAuthenticationProvider" - ] + ], + + "js" : [ + "oauthModule.js", + "oauthConfig.js" + ], + + "resources" : { + "oauthCodeField.html" : "text/html" + } } diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html b/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html new file mode 100644 index 000000000..e6c4fff04 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html @@ -0,0 +1 @@ +Log in using OAuth \ No newline at end of file diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js b/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js new file mode 100644 index 000000000..ba6f0cc88 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js @@ -0,0 +1,31 @@ +/* + * 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. + */ + +/** + * Config block which registers OAuth-specific field types. + */ +angular.module('guacOAuth').config(['formServiceProvider', + function guacOAuthConfig(formServiceProvider) { + + // Define field for code from OAuth service + formServiceProvider.registerFieldType("GUAC_OAUTH_CODE", { + templateUrl : 'app/ext/guac-oauth/oauthCodeField.html' + }); + +}]); diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthModule.js b/extensions/guacamole-auth-openid/src/main/resources/oauthModule.js new file mode 100644 index 000000000..545b6b79c --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/oauthModule.js @@ -0,0 +1,28 @@ +/* + * 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. + */ + +/** + * Module which provides handling for OAuth authentication. + */ +angular.module('guacOAuth', [ + 'form' +]); + +// Ensure the OAuth module is loaded along with the rest of the app +angular.module('index').requires.push('guacOAuth'); From 77e714b0e15dcbdaa5a0afc261e9a3592a8ee494 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 2 Jan 2016 00:36:12 -0800 Subject: [PATCH 37/94] GUACAMOLE-210: Stub out authentication (recognize but do not actually use code). --- extensions/guacamole-auth-openid/pom.xml | 8 +++ .../oauth/AuthenticationProviderService.java | 24 ++++++- .../guacamole/auth/oauth/OAuthCodeField.java | 4 +- .../auth/oauth/user/AuthenticatedUser.java | 71 +++++++++++++++++++ 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index bc62695b8..9ec561c81 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -79,6 +79,14 @@ 3.0 + + + javax.servlet + servlet-api + 2.5 + provided + + diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java index c07a78cd4..a183889b3 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java @@ -20,10 +20,12 @@ package org.apache.guacamole.auth.oauth; import com.google.inject.Inject; +import com.google.inject.Provider; import java.util.Arrays; +import javax.servlet.http.HttpServletRequest; +import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.form.Field; -import org.glyptodon.guacamole.net.auth.AuthenticatedUser; import org.glyptodon.guacamole.net.auth.Credentials; import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; @@ -47,6 +49,12 @@ public class AuthenticationProviderService { @Inject private ConfigurationService confService; + /** + * Provider for AuthenticatedUser objects. + */ + @Inject + private Provider authenticatedUserProvider; + /** * Returns an AuthenticatedUser representing the user authenticated by the * given credentials. @@ -65,6 +73,20 @@ public class AuthenticationProviderService { public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException { + String code = null; + + // Pull OAuth code from request if present + HttpServletRequest request = credentials.getRequest(); + if (request != null) + code = request.getParameter(OAuthCodeField.PARAMETER_NAME); + + // TODO: Actually complete authentication using received code + if (code != null) { + AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); + authenticatedUser.init("STUB", credentials); + return authenticatedUser; + } + // Request auth code throw new GuacamoleInvalidCredentialsException("Invalid login.", new CredentialsInfo(Arrays.asList(new Field[] { diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java index bdf16c850..35ae5ebef 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java @@ -34,7 +34,7 @@ public class OAuthCodeField extends Field { * The standard HTTP parameter which will be included within the URL by all * OAuth services upon successful authentication and redirect. */ - private static final String OAUTH_CODE_PARAMETER_NAME = "code"; + public static final String PARAMETER_NAME = "code"; /** * The full URI which the field should link to. @@ -65,7 +65,7 @@ public class OAuthCodeField extends Field { String redirectURI) { // Init base field properties - super(OAUTH_CODE_PARAMETER_NAME, "GUAC_OAUTH_CODE"); + super(PARAMETER_NAME, "GUAC_OAUTH_CODE"); // Build authorization URI from given values try { diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java new file mode 100644 index 000000000..935c27070 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java @@ -0,0 +1,71 @@ +/* + * 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.oauth.user; + +import com.google.inject.Inject; +import org.glyptodon.guacamole.net.auth.AbstractAuthenticatedUser; +import org.glyptodon.guacamole.net.auth.AuthenticationProvider; +import org.glyptodon.guacamole.net.auth.Credentials; + +/** + * An OAuth-specific implementation of AuthenticatedUser, associating a + * username and particular set of credentials with the OAuth authentication + * provider. + */ +public class AuthenticatedUser extends AbstractAuthenticatedUser { + + /** + * Reference to the authentication provider associated with this + * authenticated user. + */ + @Inject + private AuthenticationProvider authProvider; + + /** + * The credentials provided when this user was authenticated. + */ + private Credentials credentials; + + /** + * Initializes this AuthenticatedUser using the given username and + * credentials. + * + * @param username + * The username of the user that was authenticated. + * + * @param credentials + * The credentials provided when this user was authenticated. + */ + public void init(String username, Credentials credentials) { + this.credentials = credentials; + setIdentifier(username); + } + + @Override + public AuthenticationProvider getAuthenticationProvider() { + return authProvider; + } + + @Override + public Credentials getCredentials() { + return credentials; + } + +} From 1c6a603a08c9e291205c10e2a38a2e4e53533e24 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 2 Jan 2016 00:43:18 -0800 Subject: [PATCH 38/94] GUACAMOLE-210: Move classes to reasonable packages. --- .../guacamole/auth/oauth/AuthenticationProviderService.java | 2 ++ .../guacamole/auth/oauth/OAuthAuthenticationProviderModule.java | 1 + .../guacamole/auth/oauth/{ => conf}/ConfigurationService.java | 2 +- .../auth/oauth/{ => conf}/OAuthGuacamoleProperties.java | 2 +- .../apache/guacamole/auth/oauth/{ => form}/OAuthCodeField.java | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/{ => conf}/ConfigurationService.java (98%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/{ => conf}/OAuthGuacamoleProperties.java (98%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/{ => form}/OAuthCodeField.java (98%) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java index a183889b3..a1b9c462d 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java @@ -24,6 +24,8 @@ import com.google.inject.Provider; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; +import org.apache.guacamole.auth.oauth.conf.ConfigurationService; +import org.apache.guacamole.auth.oauth.form.OAuthCodeField; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.form.Field; import org.glyptodon.guacamole.net.auth.Credentials; diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java index 66860d1ab..e31c9457f 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java @@ -20,6 +20,7 @@ package org.apache.guacamole.auth.oauth; import com.google.inject.AbstractModule; +import org.apache.guacamole.auth.oauth.conf.ConfigurationService; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.environment.Environment; import org.glyptodon.guacamole.environment.LocalEnvironment; diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java similarity index 98% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/ConfigurationService.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java index d27b0752b..f98721833 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/ConfigurationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.oauth; +package org.apache.guacamole.auth.oauth.conf; import com.google.inject.Inject; import org.glyptodon.guacamole.GuacamoleException; diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java similarity index 98% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthGuacamoleProperties.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java index bb1e4fddc..2098d45b7 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthGuacamoleProperties.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.oauth; +package org.apache.guacamole.auth.oauth.conf; import org.glyptodon.guacamole.properties.StringGuacamoleProperty; diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java similarity index 98% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java index 35ae5ebef..9b0764a5e 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthCodeField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.oauth; +package org.apache.guacamole.auth.oauth.form; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; From 63b69ad0762676f6f3608cbd889f28b6c94c6c09 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 2 Jan 2016 21:10:30 -0800 Subject: [PATCH 39/94] GUACAMOLE-210: Use same version of Jersey as the main Guacamole webapp. --- extensions/guacamole-auth-openid/pom.xml | 39 +++++- .../guacamole/auth/oauth/TokenResponse.java | 113 ++++++++++++++++++ 2 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index 9ec561c81..d443cddee 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -41,12 +41,38 @@ org.apache.maven.plugins maven-compiler-plugin + 3.3 1.6 1.6 + + -Xlint:all + -Werror + + true + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + unpack-dependencies + prepare-package + + unpack-dependencies + + + runtime + ${project.build.directory}/classes + + + + + @@ -60,11 +86,16 @@ provided - + - com.google.oauth-client - google-oauth-client - 1.21.0 + com.sun.jersey + jersey-client + 1.17.1 + + + com.sun.jersey + jersey-json + 1.17.1 diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java new file mode 100644 index 000000000..329fb1626 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java @@ -0,0 +1,113 @@ +/* + * 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.oauth; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import java.util.Arrays; +import javax.servlet.http.HttpServletRequest; +import org.glyptodon.guacamole.GuacamoleException; +import org.apache.guacamole.auth.oauth.conf.ConfigurationService; +import org.apache.guacamole.auth.oauth.form.OAuthCodeField; +import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; +import org.glyptodon.guacamole.form.Field; +import org.glyptodon.guacamole.net.auth.Credentials; +import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; +import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Service providing convenience functions for the OAuth AuthenticationProvider + * implementation. + */ +public class AuthenticationProviderService { + + /** + * Logger for this class. + */ + private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class); + + /** + * Service for retrieving OAuth configuration information. + */ + @Inject + private ConfigurationService confService; + + /** + * Provider for AuthenticatedUser objects. + */ + @Inject + private Provider authenticatedUserProvider; + + /** + * Returns an AuthenticatedUser representing the user authenticated by the + * given credentials. + * + * @param credentials + * The credentials to use for authentication. + * + * @return + * An AuthenticatedUser representing the user authenticated by the + * given credentials. + * + * @throws GuacamoleException + * If an error occurs while authenticating the user, or if access is + * denied. + */ + public AuthenticatedUser authenticateUser(Credentials credentials) + throws GuacamoleException { + + String code = null; + + // Pull OAuth code from request if present + HttpServletRequest request = credentials.getRequest(); + if (request != null) + code = request.getParameter(OAuthCodeField.PARAMETER_NAME); + + // TODO: Actually complete authentication using received code + if (code != null) { + AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); + authenticatedUser.init("STUB", credentials); + return authenticatedUser; + } + + // Request auth code + throw new GuacamoleInvalidCredentialsException("Invalid login.", + new CredentialsInfo(Arrays.asList(new Field[] { + + // Normal username/password fields + CredentialsInfo.USERNAME, + CredentialsInfo.PASSWORD, + + // OAuth-specific code (will be rendered as an appropriate + // "Log in with..." button + new OAuthCodeField( + confService.getAuthorizationEndpoint(), + confService.getClientID(), + confService.getRedirectURI() + ) + + })) + ); + + } + +} From c20271cb9941854e46e85a5f975e4fa2aa832fea Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 2 Jan 2016 21:55:53 -0800 Subject: [PATCH 40/94] GUACAMOLE-210: Add remaining endpoint properties. --- .../auth/oauth/conf/ConfigurationService.java | 16 ++++++++++++++++ .../oauth/conf/OAuthGuacamoleProperties.java | 11 +++++++++++ 2 files changed, 27 insertions(+) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java index f98721833..e1567d239 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java @@ -50,6 +50,22 @@ public class ConfigurationService { return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_AUTHORIZATION_ENDPOINT); } + /** + * Returns the token endpoint (URI) of the OAuth service as configured with + * guacamole.properties. + * + * @return + * The token endpoint of the OAuth service, as configured with + * guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the authorization + * endpoint property is missing. + */ + public String getTokenEndpoint() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_TOKEN_ENDPOINT); + } + /** * Returns the OAuth client ID which should be submitted to the OAuth * service when necessary, as configured with guacamole.properties. This diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java index 2098d45b7..0ebb94f3a 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java @@ -44,6 +44,17 @@ public class OAuthGuacamoleProperties { }; + /** + * The token endpoint (URI) of the OAuth service. + */ + public static final StringGuacamoleProperty OAUTH_TOKEN_ENDPOINT = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-token-endpoint"; } + + }; + /** * OAuth client ID which should be submitted to the OAuth service when * necessary. This value is typically provided by the OAuth service when From c3c6e0c43b749929ae88d3c40d1da7bad2aa0309 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 2 Jan 2016 22:35:47 -0800 Subject: [PATCH 41/94] GUACAMOLE-210: POST code to OAuth service to retrieve token. --- .../oauth/AuthenticationProviderService.java | 15 ++ .../OAuthAuthenticationProviderModule.java | 25 +++ .../guacamole/auth/oauth/TokenResponse.java | 113 ------------- .../auth/oauth/token/TokenResponse.java | 153 ++++++++++++++++++ .../auth/oauth/token/TokenService.java | 101 ++++++++++++ 5 files changed, 294 insertions(+), 113 deletions(-) delete mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java index a1b9c462d..5783faa5d 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java @@ -26,6 +26,8 @@ import javax.servlet.http.HttpServletRequest; import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; import org.apache.guacamole.auth.oauth.conf.ConfigurationService; import org.apache.guacamole.auth.oauth.form.OAuthCodeField; +import org.apache.guacamole.auth.oauth.token.TokenResponse; +import org.apache.guacamole.auth.oauth.token.TokenService; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.form.Field; import org.glyptodon.guacamole.net.auth.Credentials; @@ -51,6 +53,12 @@ public class AuthenticationProviderService { @Inject private ConfigurationService confService; + /** + * Service for producing authentication tokens from OAuth codes. + */ + @Inject + private TokenService tokenService; + /** * Provider for AuthenticatedUser objects. */ @@ -84,9 +92,16 @@ public class AuthenticationProviderService { // TODO: Actually complete authentication using received code if (code != null) { + + // POST code and client information to OAuth token endpoint + TokenResponse response = tokenService.getTokenFromCode(code); + logger.debug("RESPONSE: {}", response); + + // Create corresponding authenticated user AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); authenticatedUser.init("STUB", credentials); return authenticatedUser; + } // Request auth code diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java index e31c9457f..a5cef6da5 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java @@ -20,7 +20,13 @@ package org.apache.guacamole.auth.oauth; import com.google.inject.AbstractModule; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; import org.apache.guacamole.auth.oauth.conf.ConfigurationService; +import org.apache.guacamole.auth.oauth.token.TokenService; +import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider; +import org.codehaus.jackson.map.DeserializationConfig; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.environment.Environment; import org.glyptodon.guacamole.environment.LocalEnvironment; @@ -42,6 +48,12 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { */ private final AuthenticationProvider authProvider; + /** + * A reference to the shared HTTP client to be used when making calls to + * the OAuth service. + */ + private final Client client; + /** * Creates a new OAuth authentication provider module which configures * injection for the OAuthAuthenticationProvider. @@ -62,6 +74,15 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { // Store associated auth provider this.authProvider = authProvider; + // Set up configuration for HTTP client + ClientConfig clientConfig = new DefaultClientConfig(); + clientConfig.getSingletons().add(new JacksonJaxbJsonProvider() + .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false) + ); + + // Store pre-configured HTTP client + this.client = Client.create(clientConfig); + } @Override @@ -73,6 +94,10 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { // Bind OAuth-specific services bind(ConfigurationService.class); + bind(TokenService.class); + + // Bind HTTP client + bind(Client.class).toInstance(client); } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java deleted file mode 100644 index 329fb1626..000000000 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.oauth; - -import com.google.inject.Inject; -import com.google.inject.Provider; -import java.util.Arrays; -import javax.servlet.http.HttpServletRequest; -import org.glyptodon.guacamole.GuacamoleException; -import org.apache.guacamole.auth.oauth.conf.ConfigurationService; -import org.apache.guacamole.auth.oauth.form.OAuthCodeField; -import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; -import org.glyptodon.guacamole.form.Field; -import org.glyptodon.guacamole.net.auth.Credentials; -import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; -import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Service providing convenience functions for the OAuth AuthenticationProvider - * implementation. - */ -public class AuthenticationProviderService { - - /** - * Logger for this class. - */ - private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class); - - /** - * Service for retrieving OAuth configuration information. - */ - @Inject - private ConfigurationService confService; - - /** - * Provider for AuthenticatedUser objects. - */ - @Inject - private Provider authenticatedUserProvider; - - /** - * Returns an AuthenticatedUser representing the user authenticated by the - * given credentials. - * - * @param credentials - * The credentials to use for authentication. - * - * @return - * An AuthenticatedUser representing the user authenticated by the - * given credentials. - * - * @throws GuacamoleException - * If an error occurs while authenticating the user, or if access is - * denied. - */ - public AuthenticatedUser authenticateUser(Credentials credentials) - throws GuacamoleException { - - String code = null; - - // Pull OAuth code from request if present - HttpServletRequest request = credentials.getRequest(); - if (request != null) - code = request.getParameter(OAuthCodeField.PARAMETER_NAME); - - // TODO: Actually complete authentication using received code - if (code != null) { - AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); - authenticatedUser.init("STUB", credentials); - return authenticatedUser; - } - - // Request auth code - throw new GuacamoleInvalidCredentialsException("Invalid login.", - new CredentialsInfo(Arrays.asList(new Field[] { - - // Normal username/password fields - CredentialsInfo.USERNAME, - CredentialsInfo.PASSWORD, - - // OAuth-specific code (will be rendered as an appropriate - // "Log in with..." button - new OAuthCodeField( - confService.getAuthorizationEndpoint(), - confService.getClientID(), - confService.getRedirectURI() - ) - - })) - ); - - } - -} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java new file mode 100644 index 000000000..513683041 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java @@ -0,0 +1,153 @@ +/* + * 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.oauth.token; + +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * The response produced from a successful request to the token endpoint of an + * OAuth service. + */ +public class TokenResponse { + + /** + * An arbitrary access token which can be used for future requests against + * the API associated with the OAuth service. + */ + private String accessToken; + + /** + * The type of token present. This will always be "Bearer". + */ + private String tokenType; + + /** + * The number of seconds the access token will remain valid. + */ + private int expiresIn; + + /** + * A JWT (JSON Web Token) which containing identity information which has + * been cryptographically signed. + */ + private String idToken; + + /** + * Returns an arbitrary access token which can be used for future requests + * against the API associated with the OAuth service. + * + * @return + * An arbitrary access token provided by the OAuth service. + */ + @JsonProperty("access_token") + public String getAccessToken() { + return accessToken; + } + + /** + * Sets the arbitrary access token which can be used for future requests + * against the API associated with the OAuth service. + * + * @param accessToken + * The arbitrary access token provided by the OAuth service. + */ + @JsonProperty("access_token") + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + /** + * Returns the type of token present in this response. This should always + * be "Bearer". + * + * @return + * The type of token present in this response. + */ + @JsonProperty("token_type") + public String getTokenType() { + return tokenType; + } + + /** + * Sets the type of token present in this response. This should always be + * "Bearer". + * + * @param tokenType + * The type of token present in this response, which should be + * "Bearer". + */ + @JsonProperty("token_type") + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } + + /** + * Returns the number of seconds the access token within this response will + * remain valid. + * + * @return + * The number of seconds the access token within this response will + * remain valid. + */ + @JsonProperty("expires_in") + public int getExpiresIn() { + return expiresIn; + } + + /** + * Sets the number of seconds the access token within this response will + * remain valid. + * + * @param expiresIn + * The number of seconds the access token within this response will + * remain valid. + */ + @JsonProperty("expires_in") + public void setExpiresIn(int expiresIn) { + this.expiresIn = expiresIn; + } + + /** + * Returns a JWT (JSON Web Token) containing identity information which has + * been cryptographically signed by the OAuth service. + * + * @return + * A JWT (JSON Web Token) containing identity information which has + * been cryptographically signed by the OAuth service. + */ + @JsonProperty("id_token") + public String getIdToken() { + return idToken; + } + + /** + * Sets the JWT (JSON Web Token) containing identity information which has + * been cryptographically signed by the OAuth service. + * + * @param idToken + * A JWT (JSON Web Token) containing identity information which has + * been cryptographically signed by the OAuth service. + */ + @JsonProperty("id_token") + public void setIdToken(String idToken) { + this.idToken = idToken; + } + +} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java new file mode 100644 index 000000000..a328bde4d --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java @@ -0,0 +1,101 @@ +/* + * 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.oauth.token; + +import com.google.inject.Inject; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.representation.Form; +import javax.ws.rs.core.MediaType; +import org.apache.guacamole.auth.oauth.AuthenticationProviderService; +import org.apache.guacamole.auth.oauth.conf.ConfigurationService; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.GuacamoleServerException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides relatively abstract means of producing authentication tokens from + * the codes received from OAuth services. + */ +public class TokenService { + + /** + * Logger for this class. + */ + private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class); + + /** + * Service for retrieving OAuth configuration information. + */ + @Inject + private ConfigurationService confService; + + /** + * Jersey HTTP client. + */ + @Inject + private Client client; + + /** + * Given an authorization code previously received from the OAuth service + * via the "code" parameter provided to the redirect URL, retrieves and + * returns an authentication token. + * + * @param code + * The value of the "code" parameter received from the OAuth service. + * + * @return + * The authentication roken response received from the OAuth service. + * + * @throws GuacamoleException + * If required properties within guacamole.properties cannot be read, + * or if an error occurs while contacting the OAuth service. + */ + public TokenResponse getTokenFromCode(String code) + throws GuacamoleException { + + try { + + // Generate POST data + Form form = new Form(); + form.add("code", code); + form.add("client_id", confService.getClientID()); + form.add("client_secret", confService.getClientSecret()); + form.add("redirect_uri", confService.getRedirectURI()); + form.add("grant_type", "authorization_code"); + + // POST code and client information to OAuth token endpoint + return client.resource(confService.getTokenEndpoint()) + .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) + .accept(MediaType.APPLICATION_JSON_TYPE) + .post(TokenResponse.class, form); + + } + + // Log any failure reaching the OAuth service + catch (UniformInterfaceException e) { + logger.debug("POST to token endpoint failed.", e); + throw new GuacamoleServerException("Unable to POST to token endpoint.", e); + } + + } + +} From fdc031338722242e30d1ca0b2e393a4b2ae2e8f0 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 12 Jun 2016 00:14:00 -0700 Subject: [PATCH 42/94] GUACAMOLE-210: Migrate to implicit flow (client-side, relies on "id_token"). Update to pre-release 0.9.9-incubating codebase. --- extensions/guacamole-auth-openid/pom.xml | 18 +-- .../oauth/AuthenticationProviderService.java | 46 ++---- .../oauth/OAuthAuthenticationProvider.java | 10 +- .../OAuthAuthenticationProviderModule.java | 33 +--- .../auth/oauth/conf/ConfigurationService.java | 38 +---- .../oauth/conf/OAuthGuacamoleProperties.java | 26 +-- ...uthCodeField.java => OAuthTokenField.java} | 31 ++-- .../auth/oauth/token/TokenResponse.java | 153 ------------------ .../auth/oauth/token/TokenService.java | 101 ------------ .../auth/oauth/user/AuthenticatedUser.java | 6 +- .../src/main/resources/guac-manifest.json | 9 +- .../src/main/resources/oauthCodeField.html | 1 - .../src/main/resources/oauthConfig.js | 29 +++- .../src/main/resources/oauthController.js | 30 ++++ 14 files changed, 109 insertions(+), 422 deletions(-) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/{OAuthCodeField.java => OAuthTokenField.java} (74%) delete mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java delete mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java delete mode 100644 extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html create mode 100644 extensions/guacamole-auth-openid/src/main/resources/oauthController.js diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index d443cddee..60691e2d1 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -26,7 +26,7 @@ org.apache.guacamole guacamole-auth-openid jar - 0.9.9 + 0.9.9-incubating guacamole-auth-openid http://guacamole.incubator.apache.org/ @@ -80,24 +80,12 @@ - org.glyptodon.guacamole + org.apache.guacamole guacamole-ext - 0.9.9 + 0.9.9-incubating provided - - - com.sun.jersey - jersey-client - 1.17.1 - - - com.sun.jersey - jersey-json - 1.17.1 - - com.google.inject diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java index 5783faa5d..0aac96849 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java @@ -25,14 +25,12 @@ import java.util.Arrays; import javax.servlet.http.HttpServletRequest; import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; import org.apache.guacamole.auth.oauth.conf.ConfigurationService; -import org.apache.guacamole.auth.oauth.form.OAuthCodeField; -import org.apache.guacamole.auth.oauth.token.TokenResponse; -import org.apache.guacamole.auth.oauth.token.TokenService; -import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.form.Field; -import org.glyptodon.guacamole.net.auth.Credentials; -import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; -import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; +import org.apache.guacamole.auth.oauth.form.OAuthTokenField; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.form.Field; +import org.apache.guacamole.net.auth.Credentials; +import org.apache.guacamole.net.auth.credentials.CredentialsInfo; +import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,12 +51,6 @@ public class AuthenticationProviderService { @Inject private ConfigurationService confService; - /** - * Service for producing authentication tokens from OAuth codes. - */ - @Inject - private TokenService tokenService; - /** * Provider for AuthenticatedUser objects. */ @@ -83,19 +75,15 @@ public class AuthenticationProviderService { public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException { - String code = null; + String token = null; - // Pull OAuth code from request if present + // Pull OAuth token from request if present HttpServletRequest request = credentials.getRequest(); if (request != null) - code = request.getParameter(OAuthCodeField.PARAMETER_NAME); + token = request.getParameter(OAuthTokenField.PARAMETER_NAME); - // TODO: Actually complete authentication using received code - if (code != null) { - - // POST code and client information to OAuth token endpoint - TokenResponse response = tokenService.getTokenFromCode(code); - logger.debug("RESPONSE: {}", response); + // TODO: Actually validate received token + if (token != null) { // Create corresponding authenticated user AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); @@ -104,17 +92,13 @@ public class AuthenticationProviderService { } - // Request auth code + // Request OAuth token throw new GuacamoleInvalidCredentialsException("Invalid login.", new CredentialsInfo(Arrays.asList(new Field[] { - // Normal username/password fields - CredentialsInfo.USERNAME, - CredentialsInfo.PASSWORD, - - // OAuth-specific code (will be rendered as an appropriate - // "Log in with..." button - new OAuthCodeField( + // OAuth-specific token (will automatically redirect the user + // to the authorization page via JavaScript) + new OAuthTokenField( confService.getAuthorizationEndpoint(), confService.getClientID(), confService.getRedirectURI() diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java index 06255ac80..6ede89071 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java @@ -21,11 +21,11 @@ package org.apache.guacamole.auth.oauth; import com.google.inject.Guice; import com.google.inject.Injector; -import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.net.auth.AuthenticatedUser; -import org.glyptodon.guacamole.net.auth.AuthenticationProvider; -import org.glyptodon.guacamole.net.auth.Credentials; -import org.glyptodon.guacamole.net.auth.UserContext; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.net.auth.AuthenticatedUser; +import org.apache.guacamole.net.auth.AuthenticationProvider; +import org.apache.guacamole.net.auth.Credentials; +import org.apache.guacamole.net.auth.UserContext; /** * Guacamole authentication backend which authenticates users using an diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java index a5cef6da5..202e6a267 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java @@ -20,17 +20,11 @@ package org.apache.guacamole.auth.oauth; import com.google.inject.AbstractModule; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; import org.apache.guacamole.auth.oauth.conf.ConfigurationService; -import org.apache.guacamole.auth.oauth.token.TokenService; -import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider; -import org.codehaus.jackson.map.DeserializationConfig; -import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.environment.Environment; -import org.glyptodon.guacamole.environment.LocalEnvironment; -import org.glyptodon.guacamole.net.auth.AuthenticationProvider; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.environment.Environment; +import org.apache.guacamole.environment.LocalEnvironment; +import org.apache.guacamole.net.auth.AuthenticationProvider; /** * Guice module which configures OAuth-specific injections. @@ -48,12 +42,6 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { */ private final AuthenticationProvider authProvider; - /** - * A reference to the shared HTTP client to be used when making calls to - * the OAuth service. - */ - private final Client client; - /** * Creates a new OAuth authentication provider module which configures * injection for the OAuthAuthenticationProvider. @@ -74,15 +62,6 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { // Store associated auth provider this.authProvider = authProvider; - // Set up configuration for HTTP client - ClientConfig clientConfig = new DefaultClientConfig(); - clientConfig.getSingletons().add(new JacksonJaxbJsonProvider() - .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false) - ); - - // Store pre-configured HTTP client - this.client = Client.create(clientConfig); - } @Override @@ -94,10 +73,6 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { // Bind OAuth-specific services bind(ConfigurationService.class); - bind(TokenService.class); - - // Bind HTTP client - bind(Client.class).toInstance(client); } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java index e1567d239..9debab77b 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java @@ -20,8 +20,8 @@ package org.apache.guacamole.auth.oauth.conf; import com.google.inject.Inject; -import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.environment.Environment; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.environment.Environment; /** * Service for retrieving configuration information regarding the OAuth service. @@ -50,22 +50,6 @@ public class ConfigurationService { return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_AUTHORIZATION_ENDPOINT); } - /** - * Returns the token endpoint (URI) of the OAuth service as configured with - * guacamole.properties. - * - * @return - * The token endpoint of the OAuth service, as configured with - * guacamole.properties. - * - * @throws GuacamoleException - * If guacamole.properties cannot be parsed, or if the authorization - * endpoint property is missing. - */ - public String getTokenEndpoint() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_TOKEN_ENDPOINT); - } - /** * Returns the OAuth client ID which should be submitted to the OAuth * service when necessary, as configured with guacamole.properties. This @@ -84,24 +68,6 @@ public class ConfigurationService { return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_CLIENT_ID); } - /** - * Returns the OAuth client secret which should be submitted to the OAuth - * service when necessary, as configured with guacamole.properties. This - * value is typically provided by the OAuth service when OAuth credentials - * are generated for your application. - * - * @return - * The client secret to use when communicating with the OAuth service, - * as configured with guacamole.properties. - * - * @throws GuacamoleException - * If guacamole.properties cannot be parsed, or if the client secret - * property is missing. - */ - public String getClientSecret() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_CLIENT_SECRET); - } - /** * Returns the URI that the OAuth service should redirect to after * the authentication process is complete, as configured with diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java index 0ebb94f3a..34952fe3a 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java @@ -19,7 +19,7 @@ package org.apache.guacamole.auth.oauth.conf; -import org.glyptodon.guacamole.properties.StringGuacamoleProperty; +import org.apache.guacamole.properties.StringGuacamoleProperty; /** * Provides properties required for use of the OAuth authentication provider. @@ -44,17 +44,6 @@ public class OAuthGuacamoleProperties { }; - /** - * The token endpoint (URI) of the OAuth service. - */ - public static final StringGuacamoleProperty OAUTH_TOKEN_ENDPOINT = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "oauth-token-endpoint"; } - - }; - /** * OAuth client ID which should be submitted to the OAuth service when * necessary. This value is typically provided by the OAuth service when @@ -68,19 +57,6 @@ public class OAuthGuacamoleProperties { }; - /** - * OAuth client secret which should be submitted to the OAuth service when - * necessary. This value is typically provided by the OAuth service when - * OAuth credentials are generated for your application. - */ - public static final StringGuacamoleProperty OAUTH_CLIENT_SECRET = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "oauth-client-secret"; } - - }; - /** * The URI that the OAuth service should redirect to after the * authentication process is complete. This must be the full URL that a diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java similarity index 74% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java index 9b0764a5e..84484e5e8 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java @@ -21,20 +21,21 @@ package org.apache.guacamole.auth.oauth.form; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import org.glyptodon.guacamole.form.Field; +import java.util.UUID; +import org.apache.guacamole.form.Field; /** - * Field definition which represents the code returned by an OAuth service. + * Field definition which represents the token returned by an OAuth service. * Within the user interface, this will be rendered as an appropriate "Log in * with ..." button which links to the OAuth service. */ -public class OAuthCodeField extends Field { +public class OAuthTokenField extends Field { /** * The standard HTTP parameter which will be included within the URL by all * OAuth services upon successful authentication and redirect. */ - public static final String PARAMETER_NAME = "code"; + public static final String PARAMETER_NAME = "id_token"; /** * The full URI which the field should link to. @@ -42,11 +43,12 @@ public class OAuthCodeField extends Field { private final String authorizationURI; /** - * Creates a new OAuth "code" field which links to the given OAuth service - * using the provided client ID. Successful authentication at the OAuth - * service will result in the client being redirected to the specified - * redirect URI. The OAuth code will be embedded in the query parameters of - * that URI. + * Creates a new OAuth "id_token" field which links to the given OAuth + * service using the provided client ID. Successful authentication at the + * OAuth service will result in the client being redirected to the specified + * redirect URI. The OAuth token will be embedded in the fragment (the part + * following the hash symbol) of that URI, which the JavaScript side of + * this extension will move to the query parameters. * * @param authorizationEndpoint * The full URL of the endpoint accepting OAuth authentication @@ -61,19 +63,20 @@ public class OAuthCodeField extends Field { * The URI that the OAuth service should redirect to upon successful * authentication. */ - public OAuthCodeField(String authorizationEndpoint, String clientID, + public OAuthTokenField(String authorizationEndpoint, String clientID, String redirectURI) { // Init base field properties - super(PARAMETER_NAME, "GUAC_OAUTH_CODE"); + super(PARAMETER_NAME, "GUAC_OAUTH_TOKEN"); // Build authorization URI from given values try { this.authorizationURI = authorizationEndpoint + "?scope=openid%20email%20profile" - + "&response_type=code" + + "&response_type=id_token" + "&client_id=" + URLEncoder.encode(clientID, "UTF-8") - + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8"); + + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8") + + "&nonce=" + UUID.randomUUID().toString(); } // Java is required to provide UTF-8 support @@ -84,7 +87,7 @@ public class OAuthCodeField extends Field { } /** - * Returns the full URI that this field should link to when a new code + * Returns the full URI that this field should link to when a new token * needs to be obtained from the OAuth service. * * @return diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java deleted file mode 100644 index 513683041..000000000 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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.oauth.token; - -import org.codehaus.jackson.annotate.JsonProperty; - -/** - * The response produced from a successful request to the token endpoint of an - * OAuth service. - */ -public class TokenResponse { - - /** - * An arbitrary access token which can be used for future requests against - * the API associated with the OAuth service. - */ - private String accessToken; - - /** - * The type of token present. This will always be "Bearer". - */ - private String tokenType; - - /** - * The number of seconds the access token will remain valid. - */ - private int expiresIn; - - /** - * A JWT (JSON Web Token) which containing identity information which has - * been cryptographically signed. - */ - private String idToken; - - /** - * Returns an arbitrary access token which can be used for future requests - * against the API associated with the OAuth service. - * - * @return - * An arbitrary access token provided by the OAuth service. - */ - @JsonProperty("access_token") - public String getAccessToken() { - return accessToken; - } - - /** - * Sets the arbitrary access token which can be used for future requests - * against the API associated with the OAuth service. - * - * @param accessToken - * The arbitrary access token provided by the OAuth service. - */ - @JsonProperty("access_token") - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - /** - * Returns the type of token present in this response. This should always - * be "Bearer". - * - * @return - * The type of token present in this response. - */ - @JsonProperty("token_type") - public String getTokenType() { - return tokenType; - } - - /** - * Sets the type of token present in this response. This should always be - * "Bearer". - * - * @param tokenType - * The type of token present in this response, which should be - * "Bearer". - */ - @JsonProperty("token_type") - public void setTokenType(String tokenType) { - this.tokenType = tokenType; - } - - /** - * Returns the number of seconds the access token within this response will - * remain valid. - * - * @return - * The number of seconds the access token within this response will - * remain valid. - */ - @JsonProperty("expires_in") - public int getExpiresIn() { - return expiresIn; - } - - /** - * Sets the number of seconds the access token within this response will - * remain valid. - * - * @param expiresIn - * The number of seconds the access token within this response will - * remain valid. - */ - @JsonProperty("expires_in") - public void setExpiresIn(int expiresIn) { - this.expiresIn = expiresIn; - } - - /** - * Returns a JWT (JSON Web Token) containing identity information which has - * been cryptographically signed by the OAuth service. - * - * @return - * A JWT (JSON Web Token) containing identity information which has - * been cryptographically signed by the OAuth service. - */ - @JsonProperty("id_token") - public String getIdToken() { - return idToken; - } - - /** - * Sets the JWT (JSON Web Token) containing identity information which has - * been cryptographically signed by the OAuth service. - * - * @param idToken - * A JWT (JSON Web Token) containing identity information which has - * been cryptographically signed by the OAuth service. - */ - @JsonProperty("id_token") - public void setIdToken(String idToken) { - this.idToken = idToken; - } - -} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java deleted file mode 100644 index a328bde4d..000000000 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.oauth.token; - -import com.google.inject.Inject; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.UniformInterfaceException; -import com.sun.jersey.api.representation.Form; -import javax.ws.rs.core.MediaType; -import org.apache.guacamole.auth.oauth.AuthenticationProviderService; -import org.apache.guacamole.auth.oauth.conf.ConfigurationService; -import org.glyptodon.guacamole.GuacamoleException; -import org.glyptodon.guacamole.GuacamoleServerException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Provides relatively abstract means of producing authentication tokens from - * the codes received from OAuth services. - */ -public class TokenService { - - /** - * Logger for this class. - */ - private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class); - - /** - * Service for retrieving OAuth configuration information. - */ - @Inject - private ConfigurationService confService; - - /** - * Jersey HTTP client. - */ - @Inject - private Client client; - - /** - * Given an authorization code previously received from the OAuth service - * via the "code" parameter provided to the redirect URL, retrieves and - * returns an authentication token. - * - * @param code - * The value of the "code" parameter received from the OAuth service. - * - * @return - * The authentication roken response received from the OAuth service. - * - * @throws GuacamoleException - * If required properties within guacamole.properties cannot be read, - * or if an error occurs while contacting the OAuth service. - */ - public TokenResponse getTokenFromCode(String code) - throws GuacamoleException { - - try { - - // Generate POST data - Form form = new Form(); - form.add("code", code); - form.add("client_id", confService.getClientID()); - form.add("client_secret", confService.getClientSecret()); - form.add("redirect_uri", confService.getRedirectURI()); - form.add("grant_type", "authorization_code"); - - // POST code and client information to OAuth token endpoint - return client.resource(confService.getTokenEndpoint()) - .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) - .accept(MediaType.APPLICATION_JSON_TYPE) - .post(TokenResponse.class, form); - - } - - // Log any failure reaching the OAuth service - catch (UniformInterfaceException e) { - logger.debug("POST to token endpoint failed.", e); - throw new GuacamoleServerException("Unable to POST to token endpoint.", e); - } - - } - -} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java index 935c27070..3a798eb4a 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java @@ -20,9 +20,9 @@ package org.apache.guacamole.auth.oauth.user; import com.google.inject.Inject; -import org.glyptodon.guacamole.net.auth.AbstractAuthenticatedUser; -import org.glyptodon.guacamole.net.auth.AuthenticationProvider; -import org.glyptodon.guacamole.net.auth.Credentials; +import org.apache.guacamole.net.auth.AbstractAuthenticatedUser; +import org.apache.guacamole.net.auth.AuthenticationProvider; +import org.apache.guacamole.net.auth.Credentials; /** * An OAuth-specific implementation of AuthenticatedUser, associating a diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json index e8f2facc1..cc74547df 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json @@ -1,6 +1,6 @@ { - "guacamoleVersion" : "0.9.9", + "guacamoleVersion" : "0.9.9-incubating", "name" : "OAuth Authentication Extension", "namespace" : "guac-oauth", @@ -11,11 +11,8 @@ "js" : [ "oauthModule.js", + "oauthController.js", "oauthConfig.js" - ], - - "resources" : { - "oauthCodeField.html" : "text/html" - } + ] } diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html b/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html deleted file mode 100644 index e6c4fff04..000000000 --- a/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html +++ /dev/null @@ -1 +0,0 @@ -Log in using OAuth \ No newline at end of file diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js b/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js index ba6f0cc88..431965697 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js +++ b/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js @@ -23,9 +23,32 @@ angular.module('guacOAuth').config(['formServiceProvider', function guacOAuthConfig(formServiceProvider) { - // Define field for code from OAuth service - formServiceProvider.registerFieldType("GUAC_OAUTH_CODE", { - templateUrl : 'app/ext/guac-oauth/oauthCodeField.html' + // Define field for token from OAuth service + formServiceProvider.registerFieldType("GUAC_OAUTH_TOKEN", { + template : '', + controller : 'guacOAuthController', + module : 'guacOAuth' + }); + +}]); + +/** + * Config block which augments the existing routing, providing special handling + * for the "id_token=" fragments provided by OpenID Connect. + */ +angular.module('index').config(['$routeProvider', + function indexRouteConfig($routeProvider) { + + // Transform "/#/id_token=..." to "/#/?id_token=..." + $routeProvider.when('/id_token=:response', { + + template : '', + controller : ['$location', function reroute($location) { + var params = $location.path().substring(1); + $location.url('/'); + $location.search(params); + }] + }); }]); diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthController.js b/extensions/guacamole-auth-openid/src/main/resources/oauthController.js new file mode 100644 index 000000000..ba7a1208d --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/oauthController.js @@ -0,0 +1,30 @@ +/* + * 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. + */ + +/** + * Controller for the "GUAC_OAUTH_TOKEN" field which simply redirects the user + * immediately to the authorization URI. + */ +angular.module('guacOAuth').controller('guacOAuthController', ['$scope', + function guacOAuthController($scope) { + + // Redirect to authorization URI + window.location = $scope.field.authorizationURI; + +}]); From d27ba44439e702964cb668886ccbc35f740b38e8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 12 Jun 2016 23:03:47 -0700 Subject: [PATCH 43/94] GUACAMOLE-210: Validate the JWT using jose.4.j. --- extensions/guacamole-auth-openid/pom.xml | 7 ++ .../oauth/AuthenticationProviderService.java | 13 ++- .../OAuthAuthenticationProviderModule.java | 2 + .../auth/oauth/conf/ConfigurationService.java | 52 ++++++++- .../oauth/conf/OAuthGuacamoleProperties.java | 35 ++++++ .../oauth/token/TokenValidationService.java | 102 ++++++++++++++++++ 6 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index 60691e2d1..fa819c80b 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -86,6 +86,13 @@ provided + + + org.bitbucket.b_c + jose4j + 0.5.1 + + com.google.inject diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java index 0aac96849..d89f08797 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java @@ -23,9 +23,10 @@ import com.google.inject.Inject; import com.google.inject.Provider; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; -import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; import org.apache.guacamole.auth.oauth.conf.ConfigurationService; import org.apache.guacamole.auth.oauth.form.OAuthTokenField; +import org.apache.guacamole.auth.oauth.token.TokenValidationService; +import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.form.Field; import org.apache.guacamole.net.auth.Credentials; @@ -51,6 +52,12 @@ public class AuthenticationProviderService { @Inject private ConfigurationService confService; + /** + * Service for validating received ID tokens. + */ + @Inject + private TokenValidationService tokenService; + /** * Provider for AuthenticatedUser objects. */ @@ -82,12 +89,12 @@ public class AuthenticationProviderService { if (request != null) token = request.getParameter(OAuthTokenField.PARAMETER_NAME); - // TODO: Actually validate received token + // If token provided, validate and produce authenticated user if (token != null) { // Create corresponding authenticated user AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); - authenticatedUser.init("STUB", credentials); + authenticatedUser.init(tokenService.processUsername(token), credentials); return authenticatedUser; } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java index 202e6a267..f83806319 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java @@ -21,6 +21,7 @@ package org.apache.guacamole.auth.oauth; import com.google.inject.AbstractModule; import org.apache.guacamole.auth.oauth.conf.ConfigurationService; +import org.apache.guacamole.auth.oauth.token.TokenValidationService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; @@ -73,6 +74,7 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { // Bind OAuth-specific services bind(ConfigurationService.class); + bind(TokenValidationService.class); } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java index 9debab77b..1304d5898 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java @@ -79,11 +79,61 @@ public class ConfigurationService { * as configured with guacamole.properties. * * @throws GuacamoleException - * If guacamole.properties cannot be parsed, or if the client secret + * If guacamole.properties cannot be parsed, or if the redirect URI * property is missing. */ public String getRedirectURI() throws GuacamoleException { return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_REDIRECT_URI); } + /** + * Returns the issuer to expect for all received ID tokens, as configured + * with guacamole.properties. + * + * @return + * The issuer to expect for all received ID tokens, as configured with + * guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the issuer property + * is missing. + */ + public String getIssuer() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_ISSUER); + } + + /** + * Returns the endpoint (URI) of the JWKS service which defines how + * received ID tokens (JWTs) shall be validated, as configured with + * guacamole.properties. + * + * @return + * The endpoint (URI) of the JWKS service which defines how received ID + * tokens (JWTs) shall be validated, as configured with + * guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the JWKS endpoint + * property is missing. + */ + public String getJWKSEndpoint() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_JWKS_ENDPOINT); + } + + /** + * Returns the claim type which contains the authenticated user's username + * within any valid JWT, as configured with guacamole.properties. + * + * @return + * The claim type which contains the authenticated user's username + * within any valid JWT, as configured with guacamole.properties. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed, or if the username claim + * type property is missing. + */ + public String getUsernameClaimType() throws GuacamoleException { + return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_USERNAME_CLAIM_TYPE); + } + } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java index 34952fe3a..cfb4eb37a 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java @@ -44,6 +44,41 @@ public class OAuthGuacamoleProperties { }; + /** + * The endpoint (URI) of the JWKS service which defines how received ID + * tokens (JWTs) shall be validated. + */ + public static final StringGuacamoleProperty OAUTH_JWKS_ENDPOINT = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-jwks-endpoint"; } + + }; + + /** + * The issuer to expect for all received ID tokens. + */ + public static final StringGuacamoleProperty OAUTH_ISSUER = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-issuer"; } + + }; + + /** + * The claim type which contains the authenticated user's username within + * any valid JWT. + */ + public static final StringGuacamoleProperty OAUTH_USERNAME_CLAIM_TYPE = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "oauth-username-claim-type"; } + + }; + /** * OAuth client ID which should be submitted to the OAuth service when * necessary. This value is typically provided by the OAuth service when diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java new file mode 100644 index 000000000..a61f7ceee --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java @@ -0,0 +1,102 @@ +/* + * 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.oauth.token; + +import com.google.inject.Inject; +import org.apache.guacamole.auth.oauth.conf.ConfigurationService; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleSecurityException; +import org.apache.guacamole.GuacamoleServerException; +import org.jose4j.jwk.HttpsJwks; +import org.jose4j.jwt.JwtClaims; +import org.jose4j.jwt.MalformedClaimException; +import org.jose4j.jwt.consumer.InvalidJwtException; +import org.jose4j.jwt.consumer.JwtConsumer; +import org.jose4j.jwt.consumer.JwtConsumerBuilder; +import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver; + +/** + * Service for validating ID tokens forwarded to us by the client, verifying + * that they did indeed come from the OAuth service. + */ +public class TokenValidationService { + + @Inject + private ConfigurationService confService; + + /** + * Validates and parses the given ID token, returning the username contained + * therein, as defined by the username claim type given in + * guacamole.properties. If the username claim type is missing or the ID + * token is invalid, an exception is thrown instead. + * + * @param token + * The ID token to validate and parse. + * + * @return + * The username contained within the given ID token. + * + * @throws GuacamoleException + * If the ID token is not valid, the username claim type is missing, or + * guacamole.properties could not be parsed. + */ + public String processUsername(String token) throws GuacamoleException { + + // Validating the token requires a JWKS key resolver + HttpsJwks jwks = new HttpsJwks(confService.getJWKSEndpoint()); + HttpsJwksVerificationKeyResolver resolver = new HttpsJwksVerificationKeyResolver(jwks); + + // Create JWT consumer for validating received token + JwtConsumer jwtConsumer = new JwtConsumerBuilder() + .setRequireExpirationTime() + .setMaxFutureValidityInMinutes(300) + .setAllowedClockSkewInSeconds(30) + .setRequireSubject() + .setExpectedIssuer(confService.getIssuer()) + .setExpectedAudience(confService.getClientID()) + .setVerificationKeyResolver(resolver) + .build(); + + try { + + // Validate JWT + JwtClaims claims = jwtConsumer.processToClaims(token); + + // Pull username from claims + String username = claims.getStringClaimValue(confService.getUsernameClaimType()); + if (username == null) + throw new GuacamoleSecurityException("Username missing from token"); + + // Username successfully retrieved from the JWT + return username; + + } + + // Rethrow any failures to validate/parse the JWT + catch (InvalidJwtException e) { + throw new GuacamoleSecurityException("Invalid ID token.", e); + } + catch (MalformedClaimException e) { + throw new GuacamoleServerException("Unable to parse JWT claims.", e); + } + + } + +} From 9159ca4289cc1a13d78afdea17067c64b7ea27d8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 13 Jun 2016 00:01:08 -0700 Subject: [PATCH 44/94] GUACAMOLE-210: Use cryptographically-sound nonce generator. --- .../auth/oauth/form/OAuthTokenField.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java index 84484e5e8..5d6599fc4 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java @@ -20,8 +20,9 @@ package org.apache.guacamole.auth.oauth.form; import java.io.UnsupportedEncodingException; +import java.math.BigInteger; import java.net.URLEncoder; -import java.util.UUID; +import java.security.SecureRandom; import org.apache.guacamole.form.Field; /** @@ -42,6 +43,23 @@ public class OAuthTokenField extends Field { */ private final String authorizationURI; + /** + * Cryptographically-secure random number generator for generating the + * required nonce. + */ + private static final SecureRandom random = new SecureRandom(); + + /** + * Generates a cryptographically-secure nonce value. The nonce is intended + * to be used to prevent replay attacks. + * + * @return + * A cryptographically-secure nonce value. + */ + private static String generateNonce() { + return new BigInteger(130, random).toString(32); + } + /** * Creates a new OAuth "id_token" field which links to the given OAuth * service using the provided client ID. Successful authentication at the @@ -76,7 +94,7 @@ public class OAuthTokenField extends Field { + "&response_type=id_token" + "&client_id=" + URLEncoder.encode(clientID, "UTF-8") + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8") - + "&nonce=" + UUID.randomUUID().toString(); + + "&nonce=" + generateNonce(); } // Java is required to provide UTF-8 support From faa327824beca658cbf0cb199d1bf049921b03a9 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 13 Jun 2016 02:19:05 -0700 Subject: [PATCH 45/94] GUACAMOLE-210: Add missing comment. --- .../guacamole/auth/oauth/token/TokenValidationService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java index a61f7ceee..84bfa3d19 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java @@ -38,6 +38,9 @@ import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver; */ public class TokenValidationService { + /** + * Service for retrieving OAuth configuration information. + */ @Inject private ConfigurationService confService; From c5bd3390bfd60c62ea199faa73ef6fb0bb963ffd Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 14 Aug 2016 19:25:11 -0700 Subject: [PATCH 46/94] GUACAMOLE-210: Update for recent sharing-related changes to AuthenticationProvider on 0.9.9-incubating (current upstream git). --- .../guacamole/auth/oauth/OAuthAuthenticationProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java index 6ede89071..6ecfeb574 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java @@ -94,7 +94,8 @@ public class OAuthAuthenticationProvider implements AuthenticationProvider { @Override public UserContext updateUserContext(UserContext context, - AuthenticatedUser authenticatedUser) throws GuacamoleException { + AuthenticatedUser authenticatedUser, Credentials credentials) + throws GuacamoleException { // No update necessary return context; From 254639f6e9d4a2f48b971245e69a74ae42ac9dd4 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 19 Feb 2017 11:06:49 -0800 Subject: [PATCH 47/94] GUACAMOLE-210: Update to 0.9.11-incubating API. --- extensions/guacamole-auth-openid/pom.xml | 4 ++-- .../src/main/resources/guac-manifest.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index fa819c80b..eec594109 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -26,7 +26,7 @@ org.apache.guacamole guacamole-auth-openid jar - 0.9.9-incubating + 0.9.11-incubating guacamole-auth-openid http://guacamole.incubator.apache.org/ @@ -82,7 +82,7 @@ org.apache.guacamole guacamole-ext - 0.9.9-incubating + 0.9.11-incubating provided diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json index cc74547df..add9607f1 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json @@ -1,6 +1,6 @@ { - "guacamoleVersion" : "0.9.9-incubating", + "guacamoleVersion" : "0.9.11-incubating", "name" : "OAuth Authentication Extension", "namespace" : "guac-oauth", From 6d46d5cfb8307f2f57e14261855e9a72f555c0c4 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 11:24:33 -0800 Subject: [PATCH 48/94] GUACAMOLE-210: Add Apache RAT plugin to guacamole-auth-openid build. --- extensions/guacamole-auth-openid/pom.xml | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index eec594109..698bc12cb 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -73,6 +73,32 @@ + + + org.apache.rat + apache-rat-plugin + 0.12 + + + + **/*.json + src/licenses/**/* + + + + + + + validate + validate + + check + + + + + + From 11fb9b3fa432a8e02037e403fbb6f72d6a39a78d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 11:35:47 -0800 Subject: [PATCH 49/94] GUACAMOLE-210: Update to jose4j 0.5.5. --- extensions/guacamole-auth-openid/pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index 698bc12cb..13de21497 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -116,7 +116,13 @@ org.bitbucket.b_c jose4j - 0.5.1 + 0.5.5 + + + org.slf4j + slf4j-api + + From a8f97b548ece86e866e5ea96e0e49047270e34b7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 11:42:19 -0800 Subject: [PATCH 50/94] GUACAMOLE-210: Document licenses of bundled dependencies for guacamole-auth-openid. --- .../src/licenses/DISCLAIMER | 7 + .../src/licenses/LICENSE | 248 ++++++++++++++++++ .../guacamole-auth-openid/src/licenses/NOTICE | 5 + .../src/licenses/bundled/README | 4 + .../licenses/bundled/aopalliance-1.0/LICENSE | 4 + .../src/licenses/bundled/guice-3.0/COPYING | 202 ++++++++++++++ .../bundled/javax.inject-1/LICENSE-2.0.txt | 202 ++++++++++++++ .../src/licenses/bundled/jose4j-0.5.5/LICENSE | 202 ++++++++++++++ .../licenses/bundled/jose4j-0.5.5/NOTICE.txt | 14 + 9 files changed, 888 insertions(+) create mode 100644 extensions/guacamole-auth-openid/src/licenses/DISCLAIMER create mode 100644 extensions/guacamole-auth-openid/src/licenses/LICENSE create mode 100644 extensions/guacamole-auth-openid/src/licenses/NOTICE create mode 100644 extensions/guacamole-auth-openid/src/licenses/bundled/README create mode 100644 extensions/guacamole-auth-openid/src/licenses/bundled/aopalliance-1.0/LICENSE create mode 100644 extensions/guacamole-auth-openid/src/licenses/bundled/guice-3.0/COPYING create mode 100644 extensions/guacamole-auth-openid/src/licenses/bundled/javax.inject-1/LICENSE-2.0.txt create mode 100644 extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/LICENSE create mode 100644 extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/NOTICE.txt diff --git a/extensions/guacamole-auth-openid/src/licenses/DISCLAIMER b/extensions/guacamole-auth-openid/src/licenses/DISCLAIMER new file mode 100644 index 000000000..1a9c3be8d --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/DISCLAIMER @@ -0,0 +1,7 @@ +Apache Guacamole is an effort undergoing incubation at The Apache Software +Foundation (ASF). Incubation is required of all newly accepted projects until a +further review indicates that the infrastructure, communications, and decision +making process have stabilized in a manner consistent with other successful ASF +projects. While incubation status is not necessarily a reflection of the +completeness or stability of the code, it does indicate that the project has +yet to be fully endorsed by the ASF. diff --git a/extensions/guacamole-auth-openid/src/licenses/LICENSE b/extensions/guacamole-auth-openid/src/licenses/LICENSE new file mode 100644 index 000000000..f95ed290f --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/LICENSE @@ -0,0 +1,248 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. + + +============================================================================== + +APACHE GUACAMOLE SUBCOMPONENTS + +Apache Guacamole includes a number of subcomponents with separate copyright +notices and license terms. Your use of these subcomponents is subject to the +terms and conditions of the following licenses. + + +AOP Alliance (http://aopalliance.sourceforge.net/) +-------------------------------------------------- + + Version: 1.0 + From: 'AOP Alliance' (http://aopalliance.sourceforge.net/members.html) + License(s): + Public Domain (bundled/aopalliance-1.0/LICENSE) + + +Google Guice (https://github.com/google/guice) +---------------------------------------------- + + Version: 3.0 + From: 'Google Inc.' (http://www.google.com/) + License(s): + Apache v2.0 (bundled/guice-3.0/COPYING) + + +jose.4.j (https://bitbucket.org/b_c/jose4j/) +-------------------------------------------- + + Version: 0.5.5 + From: 'Brian Campbell' (https://bitbucket.org/b_c/) + License(s): + Apache v2.0 (bundled/jose4j-0.5.5/LICENSE) + + +JSR-330 / Dependency Injection for Java (http://code.google.com/p/atinject/) +---------------------------------------------------------------------------- + + Version: 1 + From: 'JSR-330 Expert Group' (https://jcp.org/en/jsr/detail?id=330) + License(s): + Apache v2.0 (bundled/javax.inject-1/LICENSE-2.0.txt) + diff --git a/extensions/guacamole-auth-openid/src/licenses/NOTICE b/extensions/guacamole-auth-openid/src/licenses/NOTICE new file mode 100644 index 000000000..2ef7e548b --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/NOTICE @@ -0,0 +1,5 @@ +Apache Guacamole +Copyright 2016 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). diff --git a/extensions/guacamole-auth-openid/src/licenses/bundled/README b/extensions/guacamole-auth-openid/src/licenses/bundled/README new file mode 100644 index 000000000..47ba19db0 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/bundled/README @@ -0,0 +1,4 @@ +Apache Guacamole includes a number of subcomponents with separate copyright +notices and license terms. Your use of these subcomponents is subject to the +terms and conditions of their respective licenses, included within this +directory for reference. diff --git a/extensions/guacamole-auth-openid/src/licenses/bundled/aopalliance-1.0/LICENSE b/extensions/guacamole-auth-openid/src/licenses/bundled/aopalliance-1.0/LICENSE new file mode 100644 index 000000000..8e0e3786b --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/bundled/aopalliance-1.0/LICENSE @@ -0,0 +1,4 @@ +From http://aopalliance.sourceforge.net/: + + LICENCE: all the source code provided by AOP Alliance is Public Domain. + diff --git a/extensions/guacamole-auth-openid/src/licenses/bundled/guice-3.0/COPYING b/extensions/guacamole-auth-openid/src/licenses/bundled/guice-3.0/COPYING new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/bundled/guice-3.0/COPYING @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/extensions/guacamole-auth-openid/src/licenses/bundled/javax.inject-1/LICENSE-2.0.txt b/extensions/guacamole-auth-openid/src/licenses/bundled/javax.inject-1/LICENSE-2.0.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/bundled/javax.inject-1/LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/LICENSE b/extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/NOTICE.txt b/extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/NOTICE.txt new file mode 100644 index 000000000..46498244b --- /dev/null +++ b/extensions/guacamole-auth-openid/src/licenses/bundled/jose4j-0.5.5/NOTICE.txt @@ -0,0 +1,14 @@ +jose4j +Copyright 2012-2015 Brian Campbell + +EcdsaUsingShaAlgorithm contains code for converting the concatenated +R & S values of the signature to and from DER, which was originally +derived from the Apache Santuario XML Security library's SignatureECDSA +implementation. http://santuario.apache.org/ + +The Base64 implementation in this software was derived from the +Apache Commons Codec project. http://commons.apache.org/proper/commons-codec/ + +JSON processing in this software was derived from the JSON.simple toolkit. +https://code.google.com/p/json-simple/ + From 1034612a47b8fdea4b1e8ee710615d09cd85d06d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 11:43:35 -0800 Subject: [PATCH 51/94] GUACAMOLE-210: Create guacamole-auth-openid bundle .tar.gz as part of build. --- extensions/guacamole-auth-openid/pom.xml | 22 ++++++++ .../src/main/assembly/dist.xml | 53 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 extensions/guacamole-auth-openid/src/main/assembly/dist.xml diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index 13de21497..89f5b6cbd 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -73,6 +73,28 @@ + + + maven-assembly-plugin + 2.5.3 + + ${project.artifactId}-${project.version} + false + + src/main/assembly/dist.xml + + + + + make-dist-archive + package + + single + + + + + org.apache.rat diff --git a/extensions/guacamole-auth-openid/src/main/assembly/dist.xml b/extensions/guacamole-auth-openid/src/main/assembly/dist.xml new file mode 100644 index 000000000..b89fd534c --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/assembly/dist.xml @@ -0,0 +1,53 @@ + + + + + dist + ${project.artifactId}-${project.version} + + + + tar.gz + + + + + + + + + src/licenses + + + + + target + + + *.jar + + + + + + From d04d61225a9f820b99fd1815c5b24205dc1cc8e1 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 12:43:15 -0800 Subject: [PATCH 52/94] GUACAMOLE-210: Refactor source referencing OAuth to OpenID. This extension uses OpenID, not OAuth. --- .../AuthenticationProviderService.java | 24 +++++----- .../OpenIDAuthenticationProvider.java} | 16 +++---- .../OpenIDAuthenticationProviderModule.java} | 20 ++++----- .../conf/ConfigurationService.java | 31 ++++++------- .../conf/OpenIDGuacamoleProperties.java} | 44 +++++++++---------- .../form/TokenField.java} | 30 ++++++------- .../token/TokenValidationService.java | 8 ++-- .../user/AuthenticatedUser.java | 6 +-- .../src/main/resources/guac-manifest.json | 12 ++--- .../{oauthConfig.js => openidConfig.js} | 14 +++--- ...oauthController.js => openidController.js} | 6 +-- .../{oauthModule.js => openidModule.js} | 8 ++-- 12 files changed, 110 insertions(+), 109 deletions(-) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth => openid}/AuthenticationProviderService.java (82%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth/OAuthAuthenticationProvider.java => openid/OpenIDAuthenticationProvider.java} (86%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth/OAuthAuthenticationProviderModule.java => openid/OpenIDAuthenticationProviderModule.java} (76%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth => openid}/conf/ConfigurationService.java (78%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth/conf/OAuthGuacamoleProperties.java => openid/conf/OpenIDGuacamoleProperties.java} (59%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth/form/OAuthTokenField.java => openid/form/TokenField.java} (76%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth => openid}/token/TokenValidationService.java (94%) rename extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/{oauth => openid}/user/AuthenticatedUser.java (91%) rename extensions/guacamole-auth-openid/src/main/resources/{oauthConfig.js => openidConfig.js} (79%) rename extensions/guacamole-auth-openid/src/main/resources/{oauthController.js => openidController.js} (82%) rename extensions/guacamole-auth-openid/src/main/resources/{oauthModule.js => openidModule.js} (79%) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java similarity index 82% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java index d89f08797..10dea3d43 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java @@ -17,16 +17,16 @@ * under the License. */ -package org.apache.guacamole.auth.oauth; +package org.apache.guacamole.auth.openid; import com.google.inject.Inject; import com.google.inject.Provider; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; -import org.apache.guacamole.auth.oauth.conf.ConfigurationService; -import org.apache.guacamole.auth.oauth.form.OAuthTokenField; -import org.apache.guacamole.auth.oauth.token.TokenValidationService; -import org.apache.guacamole.auth.oauth.user.AuthenticatedUser; +import org.apache.guacamole.auth.openid.conf.ConfigurationService; +import org.apache.guacamole.auth.openid.form.TokenField; +import org.apache.guacamole.auth.openid.token.TokenValidationService; +import org.apache.guacamole.auth.openid.user.AuthenticatedUser; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.form.Field; import org.apache.guacamole.net.auth.Credentials; @@ -36,7 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Service providing convenience functions for the OAuth AuthenticationProvider + * Service providing convenience functions for the OpenID AuthenticationProvider * implementation. */ public class AuthenticationProviderService { @@ -47,7 +47,7 @@ public class AuthenticationProviderService { private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class); /** - * Service for retrieving OAuth configuration information. + * Service for retrieving OpenID configuration information. */ @Inject private ConfigurationService confService; @@ -84,10 +84,10 @@ public class AuthenticationProviderService { String token = null; - // Pull OAuth token from request if present + // Pull OpenID token from request if present HttpServletRequest request = credentials.getRequest(); if (request != null) - token = request.getParameter(OAuthTokenField.PARAMETER_NAME); + token = request.getParameter(TokenField.PARAMETER_NAME); // If token provided, validate and produce authenticated user if (token != null) { @@ -99,13 +99,13 @@ public class AuthenticationProviderService { } - // Request OAuth token + // Request OpenID token throw new GuacamoleInvalidCredentialsException("Invalid login.", new CredentialsInfo(Arrays.asList(new Field[] { - // OAuth-specific token (will automatically redirect the user + // OpenID-specific token (will automatically redirect the user // to the authorization page via JavaScript) - new OAuthTokenField( + new TokenField( confService.getAuthorizationEndpoint(), confService.getClientID(), confService.getRedirectURI() diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java similarity index 86% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java index 6ecfeb574..7fa854832 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.oauth; +package org.apache.guacamole.auth.openid; import com.google.inject.Guice; import com.google.inject.Injector; @@ -29,11 +29,11 @@ import org.apache.guacamole.net.auth.UserContext; /** * Guacamole authentication backend which authenticates users using an - * arbitrary external system implementing OAuth. No storage for connections is + * arbitrary external system implementing OpenID. No storage for connections is * provided - only authentication. Storage must be provided by some other * extension. */ -public class OAuthAuthenticationProvider implements AuthenticationProvider { +public class OpenIDAuthenticationProvider implements AuthenticationProvider { /** * Injector which will manage the object graph of this authentication @@ -42,25 +42,25 @@ public class OAuthAuthenticationProvider implements AuthenticationProvider { private final Injector injector; /** - * Creates a new OAuthAuthenticationProvider that authenticates users - * against an OAuth service + * Creates a new OpenIDAuthenticationProvider that authenticates users + * against an OpenID service. * * @throws GuacamoleException * If a required property is missing, or an error occurs while parsing * a property. */ - public OAuthAuthenticationProvider() throws GuacamoleException { + public OpenIDAuthenticationProvider() throws GuacamoleException { // Set up Guice injector. injector = Guice.createInjector( - new OAuthAuthenticationProviderModule(this) + new OpenIDAuthenticationProviderModule(this) ); } @Override public String getIdentifier() { - return "oauth"; + return "openid"; } @Override diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProviderModule.java similarity index 76% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProviderModule.java index f83806319..9abd6667f 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProviderModule.java @@ -17,20 +17,20 @@ * under the License. */ -package org.apache.guacamole.auth.oauth; +package org.apache.guacamole.auth.openid; import com.google.inject.AbstractModule; -import org.apache.guacamole.auth.oauth.conf.ConfigurationService; -import org.apache.guacamole.auth.oauth.token.TokenValidationService; +import org.apache.guacamole.auth.openid.conf.ConfigurationService; +import org.apache.guacamole.auth.openid.token.TokenValidationService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; import org.apache.guacamole.net.auth.AuthenticationProvider; /** - * Guice module which configures OAuth-specific injections. + * Guice module which configures openid-specific injections. */ -public class OAuthAuthenticationProviderModule extends AbstractModule { +public class OpenIDAuthenticationProviderModule extends AbstractModule { /** * Guacamole server environment. @@ -38,14 +38,14 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { private final Environment environment; /** - * A reference to the OAuthAuthenticationProvider on behalf of which this + * A reference to the OpenIDAuthenticationProvider on behalf of which this * module has configured injection. */ private final AuthenticationProvider authProvider; /** - * Creates a new OAuth authentication provider module which configures - * injection for the OAuthAuthenticationProvider. + * Creates a new OpenID authentication provider module which configures + * injection for the OpenIDAuthenticationProvider. * * @param authProvider * The AuthenticationProvider for which injection is being configured. @@ -54,7 +54,7 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { * If an error occurs while retrieving the Guacamole server * environment. */ - public OAuthAuthenticationProviderModule(AuthenticationProvider authProvider) + public OpenIDAuthenticationProviderModule(AuthenticationProvider authProvider) throws GuacamoleException { // Get local environment @@ -72,7 +72,7 @@ public class OAuthAuthenticationProviderModule extends AbstractModule { bind(AuthenticationProvider.class).toInstance(authProvider); bind(Environment.class).toInstance(environment); - // Bind OAuth-specific services + // Bind openid-specific services bind(ConfigurationService.class); bind(TokenValidationService.class); diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java similarity index 78% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java index 1304d5898..650cf47f4 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java @@ -17,14 +17,15 @@ * under the License. */ -package org.apache.guacamole.auth.oauth.conf; +package org.apache.guacamole.auth.openid.conf; import com.google.inject.Inject; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; /** - * Service for retrieving configuration information regarding the OAuth service. + * Service for retrieving configuration information regarding the OpenID + * service. */ public class ConfigurationService { @@ -35,11 +36,11 @@ public class ConfigurationService { private Environment environment; /** - * Returns the authorization endpoint (URI) of the OAuth service as + * Returns the authorization endpoint (URI) of the OpenID service as * configured with guacamole.properties. * * @return - * The authorization endpoint of the OAuth service, as configured with + * The authorization endpoint of the OpenID service, as configured with * guacamole.properties. * * @throws GuacamoleException @@ -47,17 +48,17 @@ public class ConfigurationService { * endpoint property is missing. */ public String getAuthorizationEndpoint() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_AUTHORIZATION_ENDPOINT); + return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_AUTHORIZATION_ENDPOINT); } /** - * Returns the OAuth client ID which should be submitted to the OAuth + * Returns the OpenID client ID which should be submitted to the OpenID * service when necessary, as configured with guacamole.properties. This - * value is typically provided by the OAuth service when OAuth credentials + * value is typically provided by the OpenID service when OpenID credentials * are generated for your application. * * @return - * The client ID to use when communicating with the OAuth service, + * The client ID to use when communicating with the OpenID service, * as configured with guacamole.properties. * * @throws GuacamoleException @@ -65,17 +66,17 @@ public class ConfigurationService { * property is missing. */ public String getClientID() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_CLIENT_ID); + return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_CLIENT_ID); } /** - * Returns the URI that the OAuth service should redirect to after + * Returns the URI that the OpenID service should redirect to after * the authentication process is complete, as configured with * guacamole.properties. This must be the full URL that a user would enter * into their browser to access Guacamole. * * @return - * The client secret to use when communicating with the OAuth service, + * The client secret to use when communicating with the OpenID service, * as configured with guacamole.properties. * * @throws GuacamoleException @@ -83,7 +84,7 @@ public class ConfigurationService { * property is missing. */ public String getRedirectURI() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_REDIRECT_URI); + return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_REDIRECT_URI); } /** @@ -99,7 +100,7 @@ public class ConfigurationService { * is missing. */ public String getIssuer() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_ISSUER); + return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_ISSUER); } /** @@ -117,7 +118,7 @@ public class ConfigurationService { * property is missing. */ public String getJWKSEndpoint() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_JWKS_ENDPOINT); + return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_JWKS_ENDPOINT); } /** @@ -133,7 +134,7 @@ public class ConfigurationService { * type property is missing. */ public String getUsernameClaimType() throws GuacamoleException { - return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_USERNAME_CLAIM_TYPE); + return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_USERNAME_CLAIM_TYPE); } } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/OpenIDGuacamoleProperties.java similarity index 59% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/OpenIDGuacamoleProperties.java index cfb4eb37a..2049ccaf5 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/OpenIDGuacamoleProperties.java @@ -17,30 +17,30 @@ * under the License. */ -package org.apache.guacamole.auth.oauth.conf; +package org.apache.guacamole.auth.openid.conf; import org.apache.guacamole.properties.StringGuacamoleProperty; /** - * Provides properties required for use of the OAuth authentication provider. - * These properties will be read from guacamole.properties when the OAuth + * Provides properties required for use of the OpenID authentication provider. + * These properties will be read from guacamole.properties when the OpenID * authentication provider is used. */ -public class OAuthGuacamoleProperties { +public class OpenIDGuacamoleProperties { /** * This class should not be instantiated. */ - private OAuthGuacamoleProperties() {} + private OpenIDGuacamoleProperties() {} /** - * The authorization endpoint (URI) of the OAuth service. + * The authorization endpoint (URI) of the OpenID service. */ - public static final StringGuacamoleProperty OAUTH_AUTHORIZATION_ENDPOINT = + public static final StringGuacamoleProperty OPENID_AUTHORIZATION_ENDPOINT = new StringGuacamoleProperty() { @Override - public String getName() { return "oauth-authorization-endpoint"; } + public String getName() { return "openid-authorization-endpoint"; } }; @@ -48,22 +48,22 @@ public class OAuthGuacamoleProperties { * The endpoint (URI) of the JWKS service which defines how received ID * tokens (JWTs) shall be validated. */ - public static final StringGuacamoleProperty OAUTH_JWKS_ENDPOINT = + public static final StringGuacamoleProperty OPENID_JWKS_ENDPOINT = new StringGuacamoleProperty() { @Override - public String getName() { return "oauth-jwks-endpoint"; } + public String getName() { return "openid-jwks-endpoint"; } }; /** * The issuer to expect for all received ID tokens. */ - public static final StringGuacamoleProperty OAUTH_ISSUER = + public static final StringGuacamoleProperty OPENID_ISSUER = new StringGuacamoleProperty() { @Override - public String getName() { return "oauth-issuer"; } + public String getName() { return "openid-issuer"; } }; @@ -71,37 +71,37 @@ public class OAuthGuacamoleProperties { * The claim type which contains the authenticated user's username within * any valid JWT. */ - public static final StringGuacamoleProperty OAUTH_USERNAME_CLAIM_TYPE = + public static final StringGuacamoleProperty OPENID_USERNAME_CLAIM_TYPE = new StringGuacamoleProperty() { @Override - public String getName() { return "oauth-username-claim-type"; } + public String getName() { return "openid-username-claim-type"; } }; /** - * OAuth client ID which should be submitted to the OAuth service when - * necessary. This value is typically provided by the OAuth service when - * OAuth credentials are generated for your application. + * OpenID client ID which should be submitted to the OpenID service when + * necessary. This value is typically provided by the OpenID service when + * OpenID credentials are generated for your application. */ - public static final StringGuacamoleProperty OAUTH_CLIENT_ID = + public static final StringGuacamoleProperty OPENID_CLIENT_ID = new StringGuacamoleProperty() { @Override - public String getName() { return "oauth-client-id"; } + public String getName() { return "openid-client-id"; } }; /** - * The URI that the OAuth service should redirect to after the + * The URI that the OpenID service should redirect to after the * authentication process is complete. This must be the full URL that a * user would enter into their browser to access Guacamole. */ - public static final StringGuacamoleProperty OAUTH_REDIRECT_URI = + public static final StringGuacamoleProperty OPENID_REDIRECT_URI = new StringGuacamoleProperty() { @Override - public String getName() { return "oauth-redirect-uri"; } + public String getName() { return "openid-redirect-uri"; } }; diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java similarity index 76% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java index 5d6599fc4..3ef5d9404 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.oauth.form; +package org.apache.guacamole.auth.openid.form; import java.io.UnsupportedEncodingException; import java.math.BigInteger; @@ -26,15 +26,15 @@ import java.security.SecureRandom; import org.apache.guacamole.form.Field; /** - * Field definition which represents the token returned by an OAuth service. + * Field definition which represents the token returned by an OpenID service. * Within the user interface, this will be rendered as an appropriate "Log in - * with ..." button which links to the OAuth service. + * with ..." button which links to the OpenID service. */ -public class OAuthTokenField extends Field { +public class TokenField extends Field { /** * The standard HTTP parameter which will be included within the URL by all - * OAuth services upon successful authentication and redirect. + * OpenID services upon successful authentication and redirect. */ public static final String PARAMETER_NAME = "id_token"; @@ -61,31 +61,31 @@ public class OAuthTokenField extends Field { } /** - * Creates a new OAuth "id_token" field which links to the given OAuth + * Creates a new OpenID "id_token" field which links to the given OpenID * service using the provided client ID. Successful authentication at the - * OAuth service will result in the client being redirected to the specified - * redirect URI. The OAuth token will be embedded in the fragment (the part + * OpenID service will result in the client being redirected to the specified + * redirect URI. The OpenID token will be embedded in the fragment (the part * following the hash symbol) of that URI, which the JavaScript side of * this extension will move to the query parameters. * * @param authorizationEndpoint - * The full URL of the endpoint accepting OAuth authentication + * The full URL of the endpoint accepting OpenID authentication * requests. * * @param clientID - * The ID of the OAuth client. This is normally determined ahead of - * time by the OAuth service through some manual credential request + * The ID of the OpenID client. This is normally determined ahead of + * time by the OpenID service through some manual credential request * procedure. * * @param redirectURI - * The URI that the OAuth service should redirect to upon successful + * The URI that the OpenID service should redirect to upon successful * authentication. */ - public OAuthTokenField(String authorizationEndpoint, String clientID, + public TokenField(String authorizationEndpoint, String clientID, String redirectURI) { // Init base field properties - super(PARAMETER_NAME, "GUAC_OAUTH_TOKEN"); + super(PARAMETER_NAME, "GUAC_OPENID_TOKEN"); // Build authorization URI from given values try { @@ -106,7 +106,7 @@ public class OAuthTokenField extends Field { /** * Returns the full URI that this field should link to when a new token - * needs to be obtained from the OAuth service. + * needs to be obtained from the OpenID service. * * @return * The full URI that this field should link to. diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java similarity index 94% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java index 84bfa3d19..b1a8a28f7 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenValidationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java @@ -17,10 +17,10 @@ * under the License. */ -package org.apache.guacamole.auth.oauth.token; +package org.apache.guacamole.auth.openid.token; import com.google.inject.Inject; -import org.apache.guacamole.auth.oauth.conf.ConfigurationService; +import org.apache.guacamole.auth.openid.conf.ConfigurationService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleServerException; @@ -34,12 +34,12 @@ import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver; /** * Service for validating ID tokens forwarded to us by the client, verifying - * that they did indeed come from the OAuth service. + * that they did indeed come from the OpenID service. */ public class TokenValidationService { /** - * Service for retrieving OAuth configuration information. + * Service for retrieving OpenID configuration information. */ @Inject private ConfigurationService confService; diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/user/AuthenticatedUser.java similarity index 91% rename from extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java rename to extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/user/AuthenticatedUser.java index 3a798eb4a..b7ff12549 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/user/AuthenticatedUser.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.oauth.user; +package org.apache.guacamole.auth.openid.user; import com.google.inject.Inject; import org.apache.guacamole.net.auth.AbstractAuthenticatedUser; @@ -25,8 +25,8 @@ import org.apache.guacamole.net.auth.AuthenticationProvider; import org.apache.guacamole.net.auth.Credentials; /** - * An OAuth-specific implementation of AuthenticatedUser, associating a - * username and particular set of credentials with the OAuth authentication + * An openid-specific implementation of AuthenticatedUser, associating a + * username and particular set of credentials with the OpenID authentication * provider. */ public class AuthenticatedUser extends AbstractAuthenticatedUser { diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json index add9607f1..3707a4f51 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json @@ -2,17 +2,17 @@ "guacamoleVersion" : "0.9.11-incubating", - "name" : "OAuth Authentication Extension", - "namespace" : "guac-oauth", + "name" : "OpenID Authentication Extension", + "namespace" : "guac-openid", "authProviders" : [ - "org.apache.guacamole.auth.oauth.OAuthAuthenticationProvider" + "org.apache.guacamole.auth.openid.OpenIDAuthenticationProvider" ], "js" : [ - "oauthModule.js", - "oauthController.js", - "oauthConfig.js" + "openidModule.js", + "openidController.js", + "openidConfig.js" ] } diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js b/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js similarity index 79% rename from extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js rename to extensions/guacamole-auth-openid/src/main/resources/openidConfig.js index 431965697..455c66af2 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js +++ b/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js @@ -18,16 +18,16 @@ */ /** - * Config block which registers OAuth-specific field types. + * Config block which registers openid-specific field types. */ -angular.module('guacOAuth').config(['formServiceProvider', - function guacOAuthConfig(formServiceProvider) { +angular.module('guacOpenID').config(['formServiceProvider', + function guacOpenIDConfig(formServiceProvider) { - // Define field for token from OAuth service - formServiceProvider.registerFieldType("GUAC_OAUTH_TOKEN", { + // Define field for token from OpenID service + formServiceProvider.registerFieldType("GUAC_OPENID_TOKEN", { template : '', - controller : 'guacOAuthController', - module : 'guacOAuth' + controller : 'guacOpenIDController', + module : 'guacOpenID' }); }]); diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthController.js b/extensions/guacamole-auth-openid/src/main/resources/openidController.js similarity index 82% rename from extensions/guacamole-auth-openid/src/main/resources/oauthController.js rename to extensions/guacamole-auth-openid/src/main/resources/openidController.js index ba7a1208d..a1fad885c 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/oauthController.js +++ b/extensions/guacamole-auth-openid/src/main/resources/openidController.js @@ -18,11 +18,11 @@ */ /** - * Controller for the "GUAC_OAUTH_TOKEN" field which simply redirects the user + * Controller for the "GUAC_OPENID_TOKEN" field which simply redirects the user * immediately to the authorization URI. */ -angular.module('guacOAuth').controller('guacOAuthController', ['$scope', - function guacOAuthController($scope) { +angular.module('guacOpenID').controller('guacOpenIDController', ['$scope', + function guacOpenIDController($scope) { // Redirect to authorization URI window.location = $scope.field.authorizationURI; diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthModule.js b/extensions/guacamole-auth-openid/src/main/resources/openidModule.js similarity index 79% rename from extensions/guacamole-auth-openid/src/main/resources/oauthModule.js rename to extensions/guacamole-auth-openid/src/main/resources/openidModule.js index 545b6b79c..e8fce23e2 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/oauthModule.js +++ b/extensions/guacamole-auth-openid/src/main/resources/openidModule.js @@ -18,11 +18,11 @@ */ /** - * Module which provides handling for OAuth authentication. + * Module which provides handling for OpenID authentication. */ -angular.module('guacOAuth', [ +angular.module('guacOpenID', [ 'form' ]); -// Ensure the OAuth module is loaded along with the rest of the app -angular.module('index').requires.push('guacOAuth'); +// Ensure the OpenID module is loaded along with the rest of the app +angular.module('index').requires.push('guacOpenID'); From 82c6048d504965da90b719fa948a9ee5d99edcbd Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 12:45:37 -0800 Subject: [PATCH 53/94] GUACAMOLE-210: Move OpenID configuration property definitions into ConfigurationService. --- .../openid/conf/ConfigurationService.java | 85 +++++++++++++- .../conf/OpenIDGuacamoleProperties.java | 108 ------------------ 2 files changed, 79 insertions(+), 114 deletions(-) delete mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/OpenIDGuacamoleProperties.java diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java index 650cf47f4..6f7e44be2 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java @@ -22,6 +22,7 @@ package org.apache.guacamole.auth.openid.conf; import com.google.inject.Inject; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; +import org.apache.guacamole.properties.StringGuacamoleProperty; /** * Service for retrieving configuration information regarding the OpenID @@ -29,6 +30,78 @@ import org.apache.guacamole.environment.Environment; */ public class ConfigurationService { + /** + * The authorization endpoint (URI) of the OpenID service. + */ + private static final StringGuacamoleProperty OPENID_AUTHORIZATION_ENDPOINT = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "openid-authorization-endpoint"; } + + }; + + /** + * The endpoint (URI) of the JWKS service which defines how received ID + * tokens (JWTs) shall be validated. + */ + private static final StringGuacamoleProperty OPENID_JWKS_ENDPOINT = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "openid-jwks-endpoint"; } + + }; + + /** + * The issuer to expect for all received ID tokens. + */ + private static final StringGuacamoleProperty OPENID_ISSUER = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "openid-issuer"; } + + }; + + /** + * The claim type which contains the authenticated user's username within + * any valid JWT. + */ + private static final StringGuacamoleProperty OPENID_USERNAME_CLAIM_TYPE = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "openid-username-claim-type"; } + + }; + + /** + * OpenID client ID which should be submitted to the OpenID service when + * necessary. This value is typically provided by the OpenID service when + * OpenID credentials are generated for your application. + */ + private static final StringGuacamoleProperty OPENID_CLIENT_ID = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "openid-client-id"; } + + }; + + /** + * The URI that the OpenID service should redirect to after the + * authentication process is complete. This must be the full URL that a + * user would enter into their browser to access Guacamole. + */ + private static final StringGuacamoleProperty OPENID_REDIRECT_URI = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "openid-redirect-uri"; } + + }; + /** * The Guacamole server environment. */ @@ -48,7 +121,7 @@ public class ConfigurationService { * endpoint property is missing. */ public String getAuthorizationEndpoint() throws GuacamoleException { - return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_AUTHORIZATION_ENDPOINT); + return environment.getRequiredProperty(OPENID_AUTHORIZATION_ENDPOINT); } /** @@ -66,7 +139,7 @@ public class ConfigurationService { * property is missing. */ public String getClientID() throws GuacamoleException { - return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_CLIENT_ID); + return environment.getRequiredProperty(OPENID_CLIENT_ID); } /** @@ -84,7 +157,7 @@ public class ConfigurationService { * property is missing. */ public String getRedirectURI() throws GuacamoleException { - return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_REDIRECT_URI); + return environment.getRequiredProperty(OPENID_REDIRECT_URI); } /** @@ -100,7 +173,7 @@ public class ConfigurationService { * is missing. */ public String getIssuer() throws GuacamoleException { - return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_ISSUER); + return environment.getRequiredProperty(OPENID_ISSUER); } /** @@ -118,7 +191,7 @@ public class ConfigurationService { * property is missing. */ public String getJWKSEndpoint() throws GuacamoleException { - return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_JWKS_ENDPOINT); + return environment.getRequiredProperty(OPENID_JWKS_ENDPOINT); } /** @@ -134,7 +207,7 @@ public class ConfigurationService { * type property is missing. */ public String getUsernameClaimType() throws GuacamoleException { - return environment.getRequiredProperty(OpenIDGuacamoleProperties.OPENID_USERNAME_CLAIM_TYPE); + return environment.getRequiredProperty(OPENID_USERNAME_CLAIM_TYPE); } } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/OpenIDGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/OpenIDGuacamoleProperties.java deleted file mode 100644 index 2049ccaf5..000000000 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/OpenIDGuacamoleProperties.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.openid.conf; - -import org.apache.guacamole.properties.StringGuacamoleProperty; - -/** - * Provides properties required for use of the OpenID authentication provider. - * These properties will be read from guacamole.properties when the OpenID - * authentication provider is used. - */ -public class OpenIDGuacamoleProperties { - - /** - * This class should not be instantiated. - */ - private OpenIDGuacamoleProperties() {} - - /** - * The authorization endpoint (URI) of the OpenID service. - */ - public static final StringGuacamoleProperty OPENID_AUTHORIZATION_ENDPOINT = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "openid-authorization-endpoint"; } - - }; - - /** - * The endpoint (URI) of the JWKS service which defines how received ID - * tokens (JWTs) shall be validated. - */ - public static final StringGuacamoleProperty OPENID_JWKS_ENDPOINT = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "openid-jwks-endpoint"; } - - }; - - /** - * The issuer to expect for all received ID tokens. - */ - public static final StringGuacamoleProperty OPENID_ISSUER = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "openid-issuer"; } - - }; - - /** - * The claim type which contains the authenticated user's username within - * any valid JWT. - */ - public static final StringGuacamoleProperty OPENID_USERNAME_CLAIM_TYPE = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "openid-username-claim-type"; } - - }; - - /** - * OpenID client ID which should be submitted to the OpenID service when - * necessary. This value is typically provided by the OpenID service when - * OpenID credentials are generated for your application. - */ - public static final StringGuacamoleProperty OPENID_CLIENT_ID = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "openid-client-id"; } - - }; - - /** - * The URI that the OpenID service should redirect to after the - * authentication process is complete. This must be the full URL that a - * user would enter into their browser to access Guacamole. - */ - public static final StringGuacamoleProperty OPENID_REDIRECT_URI = - new StringGuacamoleProperty() { - - @Override - public String getName() { return "openid-redirect-uri"; } - - }; - -} From b59c1e72335d8585ce32ac9351baf564c469372f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 13:28:52 -0800 Subject: [PATCH 54/94] GUACAMOLE-210: Use empty template if field otherwise has no template. --- .../src/main/webapp/app/form/services/formService.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/guacamole/src/main/webapp/app/form/services/formService.js b/guacamole/src/main/webapp/app/form/services/formService.js index c117bbf7f..64a171310 100644 --- a/guacamole/src/main/webapp/app/form/services/formService.js +++ b/guacamole/src/main/webapp/app/form/services/formService.js @@ -244,9 +244,16 @@ angular.module('form').provider('formService', function formServiceProvider() { } // If no raw HTML template is provided, retrieve template from URL - else + else if (fieldType.templateUrl) templateRequest = $templateRequest(fieldType.templateUrl); + // Otherwise, use empty template + else { + var emptyTemplate= $q.defer(); + emptyTemplate.resolve(''); + templateRequest = emptyTemplate.promise; + } + // Defer compilation of template pending successful retrieval var compiledTemplate = $q.defer(); From 28cfc39c11838d6972c21ef92d6f07daaad0214e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 21 Feb 2017 13:29:23 -0800 Subject: [PATCH 55/94] GUACAMOLE-210: Remove unnecessary empty template definitions (empty template is the default). --- .../guacamole-auth-openid/src/main/resources/openidConfig.js | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js b/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js index 455c66af2..cf4c81e5d 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js +++ b/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js @@ -25,7 +25,6 @@ angular.module('guacOpenID').config(['formServiceProvider', // Define field for token from OpenID service formServiceProvider.registerFieldType("GUAC_OPENID_TOKEN", { - template : '', controller : 'guacOpenIDController', module : 'guacOpenID' }); From 724a6a9737436b6e9a01eb209179e8ff34713758 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 26 Aug 2017 17:52:53 -0700 Subject: [PATCH 56/94] GUACAMOLE-210: Update API to 0.9.13-incubating. --- extensions/guacamole-auth-openid/pom.xml | 4 ++-- .../guacamole/auth/openid/OpenIDAuthenticationProvider.java | 5 +++++ .../src/main/resources/guac-manifest.json | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index 89f5b6cbd..14aea2b04 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -26,7 +26,7 @@ org.apache.guacamole guacamole-auth-openid jar - 0.9.11-incubating + 0.9.13-incubating guacamole-auth-openid http://guacamole.incubator.apache.org/ @@ -130,7 +130,7 @@ org.apache.guacamole guacamole-ext - 0.9.11-incubating + 0.9.13-incubating provided diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java index 7fa854832..42da6df3d 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java @@ -63,6 +63,11 @@ public class OpenIDAuthenticationProvider implements AuthenticationProvider { return "openid"; } + @Override + public Object getResource() throws GuacamoleException { + return null; + } + @Override public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException { diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json index 3707a4f51..c8d626f48 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json @@ -1,6 +1,6 @@ { - "guacamoleVersion" : "0.9.11-incubating", + "guacamoleVersion" : "0.9.13-incubating", "name" : "OpenID Authentication Extension", "namespace" : "guac-openid", From 187903563b3b9dd0a9721a5dafe5a4a58cb268c0 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 27 Aug 2017 22:36:06 -0700 Subject: [PATCH 57/94] GUACAMOLE-210: Add redirect message. Refactor to use minification and pre-cached templates. --- extensions/guacamole-auth-openid/.gitignore | 3 + extensions/guacamole-auth-openid/pom.xml | 80 +++++++++++++++++++ .../resources/{ => config}/openidConfig.js | 5 +- .../{ => controllers}/openidController.js | 0 .../src/main/resources/guac-manifest.json | 18 ++++- .../src/main/resources/license.txt | 18 +++++ .../src/main/resources/styles/openid.css | 35 ++++++++ .../resources/templates/openidTokenField.html | 5 ++ .../src/main/resources/translations/en.json | 12 +++ 9 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 extensions/guacamole-auth-openid/.gitignore rename extensions/guacamole-auth-openid/src/main/resources/{ => config}/openidConfig.js (91%) rename extensions/guacamole-auth-openid/src/main/resources/{ => controllers}/openidController.js (100%) create mode 100644 extensions/guacamole-auth-openid/src/main/resources/license.txt create mode 100644 extensions/guacamole-auth-openid/src/main/resources/styles/openid.css create mode 100644 extensions/guacamole-auth-openid/src/main/resources/templates/openidTokenField.html create mode 100644 extensions/guacamole-auth-openid/src/main/resources/translations/en.json diff --git a/extensions/guacamole-auth-openid/.gitignore b/extensions/guacamole-auth-openid/.gitignore new file mode 100644 index 000000000..30eb48707 --- /dev/null +++ b/extensions/guacamole-auth-openid/.gitignore @@ -0,0 +1,3 @@ +*~ +target/ +src/main/resources/generated/ diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index 14aea2b04..4076998f1 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -53,6 +53,85 @@ + + + com.keithbranton.mojo + angular-maven-plugin + 0.3.2 + + + generate-resources + + html2js + + + + + ${basedir}/src/main/resources + **/*.html + ${basedir}/src/main/resources/generated/templates-main/templates.js + app/ext/guac-openid + + + + + + com.samaxes.maven + minify-maven-plugin + 1.7.5 + + + default-cli + + UTF-8 + + ${basedir}/src/main/resources + ${project.build.directory}/classes + + / + / + openid.css + + + license.txt + + + + **/*.css + + + / + / + openid.js + + + license.txt + + + + **/*.js + + + + + **/*.test.js + + CLOSURE + + + + OFF + OFF + + + + + minify + + + + + org.apache.maven.plugins @@ -105,6 +184,7 @@ **/*.json src/licenses/**/* + src/main/resources/templates/*.html diff --git a/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js b/extensions/guacamole-auth-openid/src/main/resources/config/openidConfig.js similarity index 91% rename from extensions/guacamole-auth-openid/src/main/resources/openidConfig.js rename to extensions/guacamole-auth-openid/src/main/resources/config/openidConfig.js index cf4c81e5d..12bc0dabb 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/openidConfig.js +++ b/extensions/guacamole-auth-openid/src/main/resources/config/openidConfig.js @@ -25,8 +25,9 @@ angular.module('guacOpenID').config(['formServiceProvider', // Define field for token from OpenID service formServiceProvider.registerFieldType("GUAC_OPENID_TOKEN", { - controller : 'guacOpenIDController', - module : 'guacOpenID' + templateUrl : 'app/ext/guac-openid/templates/openidTokenField.html', + controller : 'guacOpenIDController', + module : 'guacOpenID' }); }]); diff --git a/extensions/guacamole-auth-openid/src/main/resources/openidController.js b/extensions/guacamole-auth-openid/src/main/resources/controllers/openidController.js similarity index 100% rename from extensions/guacamole-auth-openid/src/main/resources/openidController.js rename to extensions/guacamole-auth-openid/src/main/resources/controllers/openidController.js diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json index c8d626f48..e71c140fa 100644 --- a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json +++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json @@ -9,10 +9,20 @@ "org.apache.guacamole.auth.openid.OpenIDAuthenticationProvider" ], + "translations" : [ + "translations/en.json" + ], + "js" : [ - "openidModule.js", - "openidController.js", - "openidConfig.js" - ] + "openid.min.js" + ], + + "css" : [ + "openid.min.css" + ], + + "resources" : { + "templates/openidTokenField.html" : "text/html" + } } diff --git a/extensions/guacamole-auth-openid/src/main/resources/license.txt b/extensions/guacamole-auth-openid/src/main/resources/license.txt new file mode 100644 index 000000000..042f3ce1f --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/license.txt @@ -0,0 +1,18 @@ +/* + * 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. + */ diff --git a/extensions/guacamole-auth-openid/src/main/resources/styles/openid.css b/extensions/guacamole-auth-openid/src/main/resources/styles/openid.css new file mode 100644 index 000000000..eab7f935d --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/styles/openid.css @@ -0,0 +1,35 @@ +/* + * 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. + */ + +.openid-token-field-container { + height: 100%; + width: 100%; + position: fixed; + left: 0; + top: 0; + display: table; + background: white; +} + +.openid-token-field { + width: 100%; + display: table-cell; + vertical-align: middle; + text-align: center; +} diff --git a/extensions/guacamole-auth-openid/src/main/resources/templates/openidTokenField.html b/extensions/guacamole-auth-openid/src/main/resources/templates/openidTokenField.html new file mode 100644 index 000000000..49f6c6f0a --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/templates/openidTokenField.html @@ -0,0 +1,5 @@ +
+
+

{{ 'LOGIN.INFO_REDIRECT_PENDING' | translate }}

+
+
diff --git a/extensions/guacamole-auth-openid/src/main/resources/translations/en.json b/extensions/guacamole-auth-openid/src/main/resources/translations/en.json new file mode 100644 index 000000000..6bc52410e --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/resources/translations/en.json @@ -0,0 +1,12 @@ +{ + + "DATA_SOURCE_OPENID" : { + "NAME" : "OpenID SSO Backend" + }, + + "LOGIN" : { + "FIELD_HEADER_ID_TOKEN" : "", + "INFO_REDIRECT_PENDING" : "Please wait, redirecting to identity provider..." + } + +} From 4f8c853daa34d85b68e40c54b92a7f09e6eeac73 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 27 Aug 2017 22:58:12 -0700 Subject: [PATCH 58/94] GUACAMOLE-210: Re-request ID token if validation or username retrieval fails. --- .../openid/AuthenticationProviderService.java | 18 ++++---- .../openid/token/TokenValidationService.java | 41 +++++++++++++------ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java index 10dea3d43..1423b8dfd 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java @@ -82,19 +82,23 @@ public class AuthenticationProviderService { public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException { - String token = null; + String username = null; - // Pull OpenID token from request if present + // Validate OpenID token in request, if present, and derive username HttpServletRequest request = credentials.getRequest(); - if (request != null) - token = request.getParameter(TokenField.PARAMETER_NAME); + if (request != null) { + String token = request.getParameter(TokenField.PARAMETER_NAME); + if (token != null) + username = tokenService.processUsername(token); + } - // If token provided, validate and produce authenticated user - if (token != null) { + // If the username was successfully retrieved from the token, produce + // authenticated user + if (username != null) { // Create corresponding authenticated user AuthenticatedUser authenticatedUser = authenticatedUserProvider.get(); - authenticatedUser.init(tokenService.processUsername(token), credentials); + authenticatedUser.init(username, credentials); return authenticatedUser; } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java index b1a8a28f7..3e1a58dbb 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java @@ -31,6 +31,8 @@ import org.jose4j.jwt.consumer.InvalidJwtException; import org.jose4j.jwt.consumer.JwtConsumer; import org.jose4j.jwt.consumer.JwtConsumerBuilder; import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Service for validating ID tokens forwarded to us by the client, verifying @@ -38,6 +40,11 @@ import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver; */ public class TokenValidationService { + /** + * Logger for this class. + */ + private final Logger logger = LoggerFactory.getLogger(TokenValidationService.class); + /** * Service for retrieving OpenID configuration information. */ @@ -48,17 +55,17 @@ public class TokenValidationService { * Validates and parses the given ID token, returning the username contained * therein, as defined by the username claim type given in * guacamole.properties. If the username claim type is missing or the ID - * token is invalid, an exception is thrown instead. + * token is invalid, null is returned. * * @param token * The ID token to validate and parse. * * @return - * The username contained within the given ID token. + * The username contained within the given ID token, or null if the ID + * token is not valid or the username claim type is missing, * * @throws GuacamoleException - * If the ID token is not valid, the username claim type is missing, or - * guacamole.properties could not be parsed. + * If guacamole.properties could not be parsed. */ public String processUsername(String token) throws GuacamoleException { @@ -79,27 +86,37 @@ public class TokenValidationService { try { + String usernameClaim = confService.getUsernameClaimType(); + // Validate JWT JwtClaims claims = jwtConsumer.processToClaims(token); // Pull username from claims - String username = claims.getStringClaimValue(confService.getUsernameClaimType()); - if (username == null) - throw new GuacamoleSecurityException("Username missing from token"); + String username = claims.getStringClaimValue(usernameClaim); + if (username != null) + return username; - // Username successfully retrieved from the JWT - return username; + // Warn if username was not present in token, as it likely means + // the system is not set up correctly + logger.warn("Username claim \"{}\" missing from token. Perhaps the " + + "OpenID scope and/or username claim type are " + + "misconfigured?", usernameClaim); } - // Rethrow any failures to validate/parse the JWT + // Log any failures to validate/parse the JWT catch (InvalidJwtException e) { - throw new GuacamoleSecurityException("Invalid ID token.", e); + logger.info("Rejected invalid OpenID token: {}", e.getMessage()); + logger.debug("Invalid JWT received.", e); } catch (MalformedClaimException e) { - throw new GuacamoleServerException("Unable to parse JWT claims.", e); + logger.info("Rejected OpenID token with malformed claim: {}", e.getMessage()); + logger.debug("Malformed claim within received JWT.", e); } + // Could not retrieve username from JWT + return null; + } } From aaf1b796f3201916b9a5e8269cefd9b88df183bc Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 27 Aug 2017 23:58:15 -0700 Subject: [PATCH 59/94] GUACAMOLE-210: Properly generate and validate nonces. --- .../openid/AuthenticationProviderService.java | 10 +- .../OpenIDAuthenticationProviderModule.java | 2 + .../auth/openid/form/TokenField.java | 44 ++---- .../auth/openid/token/NonceService.java | 135 ++++++++++++++++++ .../openid/token/TokenValidationService.java | 20 +++ 5 files changed, 180 insertions(+), 31 deletions(-) create mode 100644 extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/NonceService.java diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java index 1423b8dfd..46e8b022c 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java @@ -25,6 +25,7 @@ import java.util.Arrays; import javax.servlet.http.HttpServletRequest; import org.apache.guacamole.auth.openid.conf.ConfigurationService; import org.apache.guacamole.auth.openid.form.TokenField; +import org.apache.guacamole.auth.openid.token.NonceService; import org.apache.guacamole.auth.openid.token.TokenValidationService; import org.apache.guacamole.auth.openid.user.AuthenticatedUser; import org.apache.guacamole.GuacamoleException; @@ -52,6 +53,12 @@ public class AuthenticationProviderService { @Inject private ConfigurationService confService; + /** + * Service for validating and generating unique nonce values. + */ + @Inject + private NonceService nonceService; + /** * Service for validating received ID tokens. */ @@ -112,7 +119,8 @@ public class AuthenticationProviderService { new TokenField( confService.getAuthorizationEndpoint(), confService.getClientID(), - confService.getRedirectURI() + confService.getRedirectURI(), + nonceService.generate(30000 /* FIXME: Calculate appropriate value based on configuration */) ) })) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProviderModule.java index 9abd6667f..17510cbe5 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProviderModule.java @@ -21,6 +21,7 @@ package org.apache.guacamole.auth.openid; import com.google.inject.AbstractModule; import org.apache.guacamole.auth.openid.conf.ConfigurationService; +import org.apache.guacamole.auth.openid.token.NonceService; import org.apache.guacamole.auth.openid.token.TokenValidationService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; @@ -74,6 +75,7 @@ public class OpenIDAuthenticationProviderModule extends AbstractModule { // Bind openid-specific services bind(ConfigurationService.class); + bind(NonceService.class); bind(TokenValidationService.class); } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java index 3ef5d9404..3f7c4547d 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java @@ -20,15 +20,12 @@ package org.apache.guacamole.auth.openid.form; import java.io.UnsupportedEncodingException; -import java.math.BigInteger; import java.net.URLEncoder; -import java.security.SecureRandom; import org.apache.guacamole.form.Field; /** - * Field definition which represents the token returned by an OpenID service. - * Within the user interface, this will be rendered as an appropriate "Log in - * with ..." button which links to the OpenID service. + * Field definition which represents the token returned by an OpenID Connect + * service. */ public class TokenField extends Field { @@ -44,29 +41,12 @@ public class TokenField extends Field { private final String authorizationURI; /** - * Cryptographically-secure random number generator for generating the - * required nonce. - */ - private static final SecureRandom random = new SecureRandom(); - - /** - * Generates a cryptographically-secure nonce value. The nonce is intended - * to be used to prevent replay attacks. - * - * @return - * A cryptographically-secure nonce value. - */ - private static String generateNonce() { - return new BigInteger(130, random).toString(32); - } - - /** - * Creates a new OpenID "id_token" field which links to the given OpenID - * service using the provided client ID. Successful authentication at the - * OpenID service will result in the client being redirected to the specified - * redirect URI. The OpenID token will be embedded in the fragment (the part - * following the hash symbol) of that URI, which the JavaScript side of - * this extension will move to the query parameters. + * Creates a new field which requests authentication via OpenID connect. + * Successful authentication at the OpenID Connect service will result in + * the client being redirected to the specified redirect URI. The OpenID + * token will be embedded in the fragment (the part following the hash + * symbol) of that URI, which the JavaScript side of this extension will + * move to the query parameters. * * @param authorizationEndpoint * The full URL of the endpoint accepting OpenID authentication @@ -80,9 +60,13 @@ public class TokenField extends Field { * @param redirectURI * The URI that the OpenID service should redirect to upon successful * authentication. + * + * @param nonce + * A random string unique to this request. To defend against replay + * attacks, this value must cease being valid after its first use. */ public TokenField(String authorizationEndpoint, String clientID, - String redirectURI) { + String redirectURI, String nonce) { // Init base field properties super(PARAMETER_NAME, "GUAC_OPENID_TOKEN"); @@ -94,7 +78,7 @@ public class TokenField extends Field { + "&response_type=id_token" + "&client_id=" + URLEncoder.encode(clientID, "UTF-8") + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8") - + "&nonce=" + generateNonce(); + + "&nonce=" + nonce; } // Java is required to provide UTF-8 support diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/NonceService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/NonceService.java new file mode 100644 index 000000000..778112a76 --- /dev/null +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/NonceService.java @@ -0,0 +1,135 @@ +/* + * 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.openid.token; + +import com.google.inject.Singleton; +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Service for generating and validating single-use random tokens (nonces). + */ +@Singleton +public class NonceService { + + /** + * Cryptographically-secure random number generator for generating the + * required nonce. + */ + private final SecureRandom random = new SecureRandom(); + + /** + * Map of all generated nonces to their corresponding expiration timestamps. + * This Map must be periodically swept of expired nonces to avoid growing + * without bound. + */ + private final Map nonces = new ConcurrentHashMap(); + + /** + * The timestamp of the last expired nonce sweep. + */ + private long lastSweep = System.currentTimeMillis(); + + /** + * The minimum amount of time to wait between sweeping expired nonces from + * the Map. + */ + private static final long SWEEP_INTERVAL = 60000; + + /** + * Iterates through the entire Map of generated nonces, removing any nonce + * that has exceeded its expiration timestamp. If insufficient time has + * elapsed since the last sweep, as dictated by SWEEP_INTERVAL, this + * function has no effect. + */ + private void sweepExpiredNonces() { + + // Do not sweep until enough time has elapsed since the last sweep + long currentTime = System.currentTimeMillis(); + if (currentTime - lastSweep < SWEEP_INTERVAL) + return; + + // Record time of sweep + lastSweep = currentTime; + + // For each stored nonce + Iterator> entries = nonces.entrySet().iterator(); + while (entries.hasNext()) { + + // Remove all entries which have expired + Map.Entry current = entries.next(); + if (current.getValue() <= System.currentTimeMillis()) + entries.remove(); + + } + + } + + /** + * Generates a cryptographically-secure nonce value. The nonce is intended + * to be used to prevent replay attacks. + * + * @param maxAge + * The maximum amount of time that the generated nonce should remain + * valid, in milliseconds. + * + * @return + * A cryptographically-secure nonce value. + */ + public String generate(long maxAge) { + + // Sweep expired nonces if enough time has passed + sweepExpiredNonces(); + + // Generate and store nonce, along with expiration timestamp + String nonce = new BigInteger(130, random).toString(32); + nonces.put(nonce, System.currentTimeMillis() + maxAge); + return nonce; + + } + + /** + * Returns whether the give nonce value is valid. A nonce is valid if and + * only if it was generated by this instance of the NonceService. Testing + * nonce validity through this function immediately and permanently + * invalidates that nonce. + * + * @param nonce + * The nonce value to test. + * + * @return + * true if the provided nonce is valid, false otherwise. + */ + public boolean isValid(String nonce) { + + // Remove nonce, verifying whether it was present at all + Long expires = nonces.remove(nonce); + if (expires == null) + return false; + + // Nonce is only valid if it hasn't expired + return expires > System.currentTimeMillis(); + + } + +} diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java index 3e1a58dbb..3d41ebafe 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java @@ -51,6 +51,12 @@ public class TokenValidationService { @Inject private ConfigurationService confService; + /** + * Service for validating and generating unique nonce values. + */ + @Inject + private NonceService nonceService; + /** * Validates and parses the given ID token, returning the username contained * therein, as defined by the username claim type given in @@ -91,6 +97,20 @@ public class TokenValidationService { // Validate JWT JwtClaims claims = jwtConsumer.processToClaims(token); + // Verify a nonce is present + String nonce = claims.getStringClaimValue("nonce"); + if (nonce == null) { + logger.info("Rejected OpenID token without nonce."); + return null; + } + + // Verify that we actually generated the nonce, and that it has not + // already been used + if (!nonceService.isValid(nonce)) { + logger.debug("Rejected OpenID token with invalid/old nonce."); + return null; + } + // Pull username from claims String username = claims.getStringClaimValue(usernameClaim); if (username != null) From 4dbf9a3f9ed899ca614f74871c05b4cd901b6e73 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 28 Aug 2017 02:04:21 -0700 Subject: [PATCH 60/94] GUACAMOLE-210: Add configuration options for scope, clock skew, etc., as well as sensible defaults. --- .../openid/AuthenticationProviderService.java | 3 +- .../openid/conf/ConfigurationService.java | 157 +++++++++++++++++- .../auth/openid/form/TokenField.java | 10 +- .../openid/token/TokenValidationService.java | 6 +- 4 files changed, 164 insertions(+), 12 deletions(-) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java index 46e8b022c..47d99fff6 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java @@ -118,9 +118,10 @@ public class AuthenticationProviderService { // to the authorization page via JavaScript) new TokenField( confService.getAuthorizationEndpoint(), + confService.getScope(), confService.getClientID(), confService.getRedirectURI(), - nonceService.generate(30000 /* FIXME: Calculate appropriate value based on configuration */) + nonceService.generate(confService.getMaxNonceValidity() * 60000L) ) })) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java index 6f7e44be2..c742d8991 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java @@ -22,6 +22,7 @@ package org.apache.guacamole.auth.openid.conf; import com.google.inject.Inject; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; +import org.apache.guacamole.properties.IntegerGuacamoleProperty; import org.apache.guacamole.properties.StringGuacamoleProperty; /** @@ -30,6 +31,35 @@ import org.apache.guacamole.properties.StringGuacamoleProperty; */ public class ConfigurationService { + /** + * The default claim type to use to retrieve an authenticated user's + * username. + */ + private static final String DEFAULT_USERNAME_CLAIM_TYPE = "email"; + + /** + * The default space-separated list of OpenID scopes to request. + */ + private static final String DEFAULT_SCOPE = "openid email profile"; + + /** + * The default amount of clock skew tolerated for timestamp comparisons + * between the Guacamole server and OpenID service clocks, in seconds. + */ + private static final int DEFAULT_ALLOWED_CLOCK_SKEW = 30; + + /** + * The default maximum amount of time that an OpenID token should remain + * valid, in minutes. + */ + private static final int DEFAULT_MAX_TOKEN_VALIDITY = 300; + + /** + * The default maximum amount of time that a nonce generated by the + * Guacamole server should remain valid, in minutes. + */ + private static final int DEFAULT_MAX_NONCE_VALIDITY = 10; + /** * The authorization endpoint (URI) of the OpenID service. */ @@ -76,6 +106,56 @@ public class ConfigurationService { }; + /** + * The space-separated list of OpenID scopes to request. + */ + private static final StringGuacamoleProperty OPENID_SCOPE = + new StringGuacamoleProperty() { + + @Override + public String getName() { return "openid-scope"; } + + }; + + /** + * The amount of clock skew tolerated for timestamp comparisons between the + * Guacamole server and OpenID service clocks, in seconds. + */ + private static final IntegerGuacamoleProperty OPENID_ALLOWED_CLOCK_SKEW = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "openid-allowed-clock-skew"; } + + }; + + /** + * The maximum amount of time that an OpenID token should remain valid, in + * minutes. + */ + private static final IntegerGuacamoleProperty OPENID_MAX_TOKEN_VALIDITY = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "openid-max-token-validity"; } + + }; + + /** + * The maximum amount of time that a nonce generated by the Guacamole server + * should remain valid, in minutes. As each OpenID request has a unique + * nonce value, this imposes an upper limit on the amount of time any + * particular OpenID request can result in successful authentication within + * Guacamole. + */ + private static final IntegerGuacamoleProperty OPENID_MAX_NONCE_VALIDITY = + new IntegerGuacamoleProperty() { + + @Override + public String getName() { return "openid-max-nonce-validity"; } + + }; + /** * OpenID client ID which should be submitted to the OpenID service when * necessary. This value is typically provided by the OpenID service when @@ -196,18 +276,87 @@ public class ConfigurationService { /** * Returns the claim type which contains the authenticated user's username - * within any valid JWT, as configured with guacamole.properties. + * within any valid JWT, as configured with guacamole.properties. By + * default, this will be "email". * * @return * The claim type which contains the authenticated user's username * within any valid JWT, as configured with guacamole.properties. * * @throws GuacamoleException - * If guacamole.properties cannot be parsed, or if the username claim - * type property is missing. + * If guacamole.properties cannot be parsed. */ public String getUsernameClaimType() throws GuacamoleException { - return environment.getRequiredProperty(OPENID_USERNAME_CLAIM_TYPE); + return environment.getProperty(OPENID_USERNAME_CLAIM_TYPE, DEFAULT_USERNAME_CLAIM_TYPE); + } + + /** + * Returns the space-separated list of OpenID scopes to request. By default, + * this will be "openid email profile". The OpenID scopes determine the + * information returned within the OpenID token, and thus affect what + * values can be used as an authenticated user's username. + * + * @return + * The space-separated list of OpenID scopes to request when identifying + * a user. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + public String getScope() throws GuacamoleException { + return environment.getProperty(OPENID_SCOPE, DEFAULT_SCOPE); + } + + /** + * Returns the amount of clock skew tolerated for timestamp comparisons + * between the Guacamole server and OpenID service clocks, in seconds. Too + * much clock skew will affect token expiration calculations, possibly + * allowing old tokens to be used. By default, this will be 30. + * + * @return + * The amount of clock skew tolerated for timestamp comparisons, in + * seconds. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + public int getAllowedClockSkew() throws GuacamoleException { + return environment.getProperty(OPENID_ALLOWED_CLOCK_SKEW, DEFAULT_ALLOWED_CLOCK_SKEW); + } + + /** + * Returns the maximum amount of time that an OpenID token should remain + * valid, in minutes. A token received from an OpenID service which is + * older than this amount of time will be rejected, even if it is otherwise + * valid. By default, this will be 300 (5 hours). + * + * @return + * The maximum amount of time that an OpenID token should remain valid, + * in minutes. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + public int getMaxTokenValidity() throws GuacamoleException { + return environment.getProperty(OPENID_MAX_TOKEN_VALIDITY, DEFAULT_MAX_TOKEN_VALIDITY); + } + + /** + * Returns the maximum amount of time that a nonce generated by the + * Guacamole server should remain valid, in minutes. As each OpenID request + * has a unique nonce value, this imposes an upper limit on the amount of + * time any particular OpenID request can result in successful + * authentication within Guacamole. By default, this will be 10. + * + * @return + * The maximum amount of time that a nonce generated by the Guacamole + * server should remain valid, in minutes. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + public int getMaxNonceValidity() throws GuacamoleException { + return environment.getProperty(OPENID_MAX_NONCE_VALIDITY, DEFAULT_MAX_NONCE_VALIDITY); } } diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java index 3f7c4547d..d99c3672d 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java @@ -52,6 +52,10 @@ public class TokenField extends Field { * The full URL of the endpoint accepting OpenID authentication * requests. * + * @param scope + * The space-delimited list of OpenID scopes to request from the + * identity provider, such as "openid" or "openid email profile". + * * @param clientID * The ID of the OpenID client. This is normally determined ahead of * time by the OpenID service through some manual credential request @@ -65,8 +69,8 @@ public class TokenField extends Field { * A random string unique to this request. To defend against replay * attacks, this value must cease being valid after its first use. */ - public TokenField(String authorizationEndpoint, String clientID, - String redirectURI, String nonce) { + public TokenField(String authorizationEndpoint, String scope, + String clientID, String redirectURI, String nonce) { // Init base field properties super(PARAMETER_NAME, "GUAC_OPENID_TOKEN"); @@ -74,7 +78,7 @@ public class TokenField extends Field { // Build authorization URI from given values try { this.authorizationURI = authorizationEndpoint - + "?scope=openid%20email%20profile" + + "?scope=" + URLEncoder.encode(scope, "UTF-8") + "&response_type=id_token" + "&client_id=" + URLEncoder.encode(clientID, "UTF-8") + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8") diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java index 3d41ebafe..cde4f89a6 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java @@ -22,8 +22,6 @@ package org.apache.guacamole.auth.openid.token; import com.google.inject.Inject; import org.apache.guacamole.auth.openid.conf.ConfigurationService; import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.GuacamoleSecurityException; -import org.apache.guacamole.GuacamoleServerException; import org.jose4j.jwk.HttpsJwks; import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.MalformedClaimException; @@ -82,8 +80,8 @@ public class TokenValidationService { // Create JWT consumer for validating received token JwtConsumer jwtConsumer = new JwtConsumerBuilder() .setRequireExpirationTime() - .setMaxFutureValidityInMinutes(300) - .setAllowedClockSkewInSeconds(30) + .setMaxFutureValidityInMinutes(confService.getMaxTokenValidity()) + .setAllowedClockSkewInSeconds(confService.getAllowedClockSkew()) .setRequireSubject() .setExpectedIssuer(confService.getIssuer()) .setExpectedAudience(confService.getClientID()) From 4e459b9f19752559053bac6acd0f25d202a90df8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 25 Sep 2017 13:09:11 -0700 Subject: [PATCH 61/94] GUACAMOLE-210: Implement AuthenticationProvider shutdown() function required due to GUACAMOLE-393. --- .../guacamole/auth/openid/OpenIDAuthenticationProvider.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java index 42da6df3d..57b483183 100644 --- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java +++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/OpenIDAuthenticationProvider.java @@ -107,4 +107,9 @@ public class OpenIDAuthenticationProvider implements AuthenticationProvider { } + @Override + public void shutdown() { + // Do nothing + } + } From 22bcc1b78e92d24430a7f9e1e8c1ec98159975fc Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 26 Sep 2017 12:09:29 -0700 Subject: [PATCH 62/94] GUACAMOLE-341: Automatically pull GUAC_USERNAME token from AuthenticatedUser's identifier if there is no username provided via Credentials (closes #174). --- .../AbstractGuacamoleTunnelService.java | 4 +-- .../ldap/connection/ConnectionService.java | 2 +- .../guacamole/token/StandardTokens.java | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java index 59ed13c1c..fe3a45b2f 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java @@ -235,7 +235,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS // Build token filter containing credential tokens TokenFilter tokenFilter = new TokenFilter(); - StandardTokens.addStandardTokens(tokenFilter, user.getCredentials()); + StandardTokens.addStandardTokens(tokenFilter, user); // Filter the configuration tokenFilter.filterValues(config.getParameters()); @@ -281,7 +281,7 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS // Build token filter containing credential tokens TokenFilter tokenFilter = new TokenFilter(); - StandardTokens.addStandardTokens(tokenFilter, user.getCredentials()); + StandardTokens.addStandardTokens(tokenFilter, user); // Filter the configuration tokenFilter.filterValues(config.getParameters()); diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java index d256ebb3b..eea1a95ac 100644 --- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java +++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/connection/ConnectionService.java @@ -123,7 +123,7 @@ public class ConnectionService { // Build token filter containing credential tokens TokenFilter tokenFilter = new TokenFilter(); - StandardTokens.addStandardTokens(tokenFilter, user.getCredentials()); + StandardTokens.addStandardTokens(tokenFilter, user); // Produce connections for each readable configuration Map connections = new HashMap(); diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java b/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java index c13477c4b..b1b280bee 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/token/StandardTokens.java @@ -21,6 +21,7 @@ package org.apache.guacamole.token; import java.text.SimpleDateFormat; import java.util.Date; +import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Credentials; /** @@ -138,4 +139,31 @@ public class StandardTokens { } + /** + * Adds tokens which are standardized by guacamole-ext to the given + * TokenFilter using the values from the given AuthenticatedUser object, + * including any associated credentials. These standardized tokens include + * the current username (GUAC_USERNAME), password (GUAC_PASSWORD), and the + * server date and time (GUAC_DATE and GUAC_TIME respectively). If either + * the username or password are not set within the given user or their + * provided credentials, the corresponding token(s) will remain unset. + * + * @param filter + * The TokenFilter to add standard tokens to. + * + * @param user + * The AuthenticatedUser to use when populating the GUAC_USERNAME and + * GUAC_PASSWORD tokens. + */ + public static void addStandardTokens(TokenFilter filter, AuthenticatedUser user) { + + // Default to the authenticated user's username for the GUAC_USERNAME + // token + filter.setToken(USERNAME_TOKEN, user.getIdentifier()); + + // Add tokens specific to credentials + addStandardTokens(filter, user.getCredentials()); + + } + } From b6e88d33b3967b42020aa8dbc8429f41f2a0afb8 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Mon, 14 Aug 2017 22:14:15 -0400 Subject: [PATCH 63/94] GUACAMOLE-363: Initial commit of SQLServer authentication module for JDBC. --- .../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 ++++++++++++++++++ .../SQLServerGuacamoleProperties.java | 200 ++++++++++++ .../sqlserver/SQLServerInjectorProvider.java | 49 +++ .../sqlserver/SQLServerPasswordPolicy.java | 194 +++++++++++ ...SQLServerSharedAuthenticationProvider.java | 50 +++ .../auth/sqlserver/package-info.java | 23 ++ .../src/main/resources/guac-manifest.json | 28 ++ .../auth/jdbc/connection/ConnectionMapper.xml | 235 ++++++++++++++ .../connection/ConnectionParameterMapper.xml | 68 ++++ .../connection/ConnectionRecordMapper.xml | 216 +++++++++++++ .../connectiongroup/ConnectionGroupMapper.xml | 232 +++++++++++++ .../ConnectionGroupPermissionMapper.xml | 130 ++++++++ .../permission/ConnectionPermissionMapper.xml | 130 ++++++++ .../SharingProfilePermissionMapper.xml | 130 ++++++++ .../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(+) create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/schema/002-create-admin-user.sql create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProvider.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerAuthenticationProviderModule.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerEnvironment.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerGuacamoleProperties.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerInjectorProvider.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerPasswordPolicy.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerSharedAuthenticationProvider.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/package-info.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/guac-manifest.json create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionParameterMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml 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 000000000..42f4a1a64 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/.gitignore @@ -0,0 +1,2 @@ +target/ +*~ 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 000000000..82776f7d0 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/pom.xml @@ -0,0 +1,128 @@ + + + + + 4.0.0 + org.apache.guacamole + guacamole-auth-jdbc-sqlserver + jar + guacamole-auth-jdbc-sqlserver + http://guacamole.incubator.apache.org/ + + + UTF-8 + + + + org.apache.guacamole + guacamole-auth-jdbc + 0.9.13-incubating + ../../ + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.6 + 1.6 + + -Xlint:all + -Werror + + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + unpack-dependencies + prepare-package + + unpack-dependencies + + + runtime + ${project.build.directory}/classes + + + + + + + + org.apache.rat + apache-rat-plugin + 0.12 + + + + **/*.json + + + + + + + validate + validate + + check + + + + + + + + + + + + + + org.apache.guacamole + guacamole-ext + provided + + + + + org.apache.guacamole + guacamole-auth-jdbc-base + 0.9.13-incubating + + + + + 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 0000000000000000000000000000000000000000..df95800ec6f91545eac5bdafd9d1a8d8e2bf31ed GIT binary patch literal 35118 zcmeHQYi}L55#`qw=zm!FOXb3~YsX2`6alK};TW-HSCZSNg0YbGu${`1t1HKLetg?= zICn&Hmt5}as(LIgbRWCqa5#^{87@iv_doZ{@9_GK`L!wVS(qp0t=TgN=Ge^ezK<(s z=ET0g!SBK>oA+iHCFIu@?j54UM_fC#_t$ad18VQ%${A>#;Co?~P;bkuo7?y%ljF)zl(AOT0O9Qoy|Gk zFwe}kd2Ck98txu~&Jpgr{_o?;4DGlUMG7Broir$qH?~ZHUXz=DSvtbkF8WOh+Vfpd zFYx;qEwRKqPb#iW_Vu-uAnP9EdjScbK+>NrAFt8k8Lpk6#bcB`1&8F}{k)Ic_$9ib zjH}X_;fmwA-eb}4XHfrulD>9WtFH6VLhhi>-{w52wjY46Kj8Y3ZP%CXt%`l!f<^op zCAD?R=QDmEgB$kvgSEmK{{`CoWG(f*ElIhF)ZRfZw2xg}p(Q&xhdN}>!oG;b{5Y3{ z@^S*pI|DUoVRzmNbwiCD;$7twQlnL#owx3|pjA?zXW;W2a}TeN_H`HKop0R*?NeC7 zy^5{RaOKI|em7v5wki_a0|&2c z4cgEyxMC0KZ_d9QB8WUb;=b5B?e@-je+#r(#fFq`#cZxBOL}EteJkdjf-=;&>-{Z@ zIR#|3Wp1JFclI}b(PsaS>)Ymgpur1#^7pdY#B14XSbSJRxdL}L@xFr34YO)%JhtEE z9(|4FfAm`Y0i{@$Z5&w1(1$2P+Ut8Od(nqT_AM|$q)(iQV^&obf+cEquE#S_I)Kf; zwYav2HmODG<%88AE&esM^0VdW807?OSc}+18PD)eX;Rv(OMM^V8t>8z6xn88pY!^= zdtUmU{YIW&SnDm!&YZtJ^U~gX1PSxLj7%Jz_@XXenV)R`&fqtK?J^G0Q++zS;P%AY z@k?7y%hFN>Emmz$4lJFo(b9eM5bqCwTKCN#QRh#%^AO*^F<;=lFwf0XyelvKlzyzh zKGt9Z+jcbBf~9G?}_cR)1EK&yRG=8 zEEpH?^DpN;p~r5Z$4ln7bLp<)+a3J9fF4%o(v~Z$;DLNl{&Hm*C7xOe^mJa|#GTt6 zEz6ht3@AwnGqxzNoEExrpVx_R^W_{HHz4N~iE+|J;^e$8YLAUPq9HdKW&%v56P30^;N<-Wf$P65GcwV&X3P{@L0_%I{Miaj|~8 zjj`%Er`0v|JhOGFD^EwFLwy&uvWNv5mmiwDezLhs^ob z;HxESam%Pj81_WY=UgOuG? zX?+65as+1NERyo2mf}Eay+JLG;(2*|2}!FT34+D>pfvWt32|Se;?l~R`QXX9USnAK za4zpEeMYjM(8rjq%xZR0?{RZ|jb6%mUVYkvVvLg#nIUr=JsdIIRUU8m9 zGmjGAn3;Z#v`tfiE*g zkm!)OP*^W*>#K}eS8R>j=XoUK)#u<%Foqf6n)wIlev7|nn3Y+#u?X8_wji-7XQ8&h zKSxaF5zI56f(kQIj?rP=$B2KlWC{9=nacA%g=LrR$omZ3m7px2Pw=^d^2AChyEvwQNivT6{l=<3<4GKeeE#y-PGrxGb!YQPo|Y3IG4tb9GY$*oCd6#6-v`GzT4`KY z+DyjH^^~}CIL~P~%d<#a4y|u|jP~t8W2*_TIZ|E?yjI%|XCo&RKZgJMxt8xoDVaHJ zm**&_7}wP&!pJ!mb)|EPn2)ui7n{QrG?Y1NK7nv^w@q^<)meuAkzyN34#BCq>;;cp zR*@gsRBP3mDS1waci9n7o*~QgY#DE-C^f{ls)QVxg?HkZ)-Nut`)Y`5)qGvcj}v)v zhK1`O%x zF7qHEEvKDne7Wr7i)7d`_e;B#xxQ(P3CEb2l-xKI$H6#;rXuKi3#HA(6*c0>-e#U6 zMww6Ljxg_~I2D_Fmbr!WvxI)AQ|E?peShR>mVG@ACQkd-9!hz_tL}Kk=U$w{=4>@r zw8*@0)BNwn&F`l2o(bQo_*P%p#b@=@6eAOjU){(aMusU=Yxd4|G*UWDKXXpih(}(1 zaV#dWAxKu2aTUFqrCBYVlEQ>>-7$`Sun5#@&QEUkY-Ub24xO4y#xbj3-k)n}oP3hG zF7rjkDqP9X?Du&T%^_TKuZG2E&9t3vCRDmAsKmLLY7{*o6(y3ItBT2M7<$Dc8AfXL zw!#eO>gAC+1gZD?t zyUxkQ^?Fg6XRbG?46pxeT3zndtTM-wO1N4t#p{HM-BEFI*=TMD(@l@_^70vuVJS~Z zqfWbBA@P_opBv`;yx3WfO4}K0wrLk}(+qnxxDtTt z54iGz<2<#wgFRl%Yh^Bq&jj+TnwbfO6lb_{gmn=)ivFqw&1OSNx}riT>92O{E96`O zUEN&YPZdW<@*#Wj^+W_|+h3QRdj7!^PTg^3@$=#N<2Nq?L>Fp(vDI}d+FJfRE;>dT~H=& zNBxndF5T*^Ya2OM>!kWWq0?}5;vRZAO<>q*Aw1h;6)$3toH|!O^I#Qc38dDJG@rCk z*i#AC(FXHRo}jRV7fptru6E@bSN4tPhWT=F^sbT=y6^ms$tq?iT`7+*HOXZ3EJykb&)?%I z7j5il9pzG<6knU=tcxv+$E?9(cru6Xt672vF*dB8mm_D;@tlu!{PA-GoXRtI`1r7U?N2I2nIh#q@nkz9`l{-zWs-2-0 z=A_(44~w<7RD{iOe-UWr_dON|wvk8^-gQHt%YlKilf^$%lwL27+!*WV%4$%^%)uehhU8HVt5 z>9IUDoCT(?7K7knJ8`^jw#qn0%lyrFv8h^XzP0|At7oq1Gt5PxP$+NqYAD`@6jK_! zn7&+$jW(|-Y_`_sx*-O3Mb>88YQfE=LJr0r|3h0@g!MJ|?s{RRj-1UFr=>#8cC{^~ zqE@88L#j6&`&256u``){@lOMwHWq_<^|n&T-aUW1ieqyk=OWAL~?8dR)W^ z9m~HKX|wewR`K56w`-Bo^PKr8uPc7WC@Pl5?u~`37h$(`sgGm1b-HP7URUeY5hZ7_ zS}wGku2!m4)H3yVNVWecf8DH6rTwKDNB?X+3$ z-H@`GR!WD9v`o%U@tNS*QE9HH^;Wq;z3B|bW?OEq8{%JARBfiMSle7Gfh2I{my2EZP_9F$?=VG)K!zy54SH7ERcmYjH>p*G&65`$JtzV|zrsg}fcyB%jcT zjdD*%Hd-n~-LAN=RMevNcS!ZBV0qoLF2Z(IX2av_Hv58y<8-bS|GC{{f%@NU`5zJ5 z?Fw)Iv?@=}*TpalR4bKeIKM|}*jkwOt@%Bitj)K!_A=~-a_#B*x*5;<;wU{7*Zf}9 zTkv}_Sy{@;>T>IES#?^z4z7ze<>ox|yG8oVI;pic$8G(e|0wq4=Vj}Z~y=R literal 0 HcmV?d00001 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 000000000..08cce3f07 --- /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; 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 000000000..ef5d61d90 --- /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"; + } + +} 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 000000000..ebb1a0678 --- /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); + + } + +} 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 000000000..67d882719 --- /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); + } + +} 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 000000000..e45f50268 --- /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"; } + + }; + +} 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 000000000..32d12f6e2 --- /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) + ); + + } + +} 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 000000000..f30b180bb --- /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); + } + +} 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 000000000..0a3c8d31f --- /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"; + } + +} 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 000000000..7bbe1b2e3 --- /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; 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 000000000..ee61ab578 --- /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" + ] + +} + 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 000000000..24008fcc4 --- /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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection] + WHERE connection_id = #{identifier,jdbcType=INTEGER} + + + + + + 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} + ) + + + + + + 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} + + + 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 000000000..de1ab97c1 --- /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 @@ + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_parameter] + WHERE connection_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[connection_parameter] ( + connection_id, + parameter_name, + parameter_value + ) + VALUES + + (#{parameter.connectionIdentifier,jdbcType=INTEGER}, + #{parameter.name,jdbcType=VARCHAR}, + #{parameter.value,jdbcType=VARCHAR}) + + + + + + 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 000000000..ec077db7f --- /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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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} + ) + + + + + + + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml new file mode 100644 index 000000000..47a3e63d5 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_group] + WHERE connection_group_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[connection_group] ( + connection_group_name, + parent_id, + type, + max_connections, + max_connections_per_user, + enable_session_affinity + ) + VALUES ( + #{object.name,jdbcType=VARCHAR}, + #{object.parentIdentifier,jdbcType=INTEGER}, + #{object.type,jdbcType=VARCHAR}, + #{object.maxConnections,jdbcType=INTEGER}, + #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + #{object.sessionAffinityEnabled,jdbcType=INTEGER} + ) + + + + + + UPDATE [guacamole].[connection_group] + SET connection_group_name = #{object.name,jdbcType=VARCHAR}, + parent_id = #{object.parentIdentifier,jdbcType=INTEGER}, + type = #{object.type,jdbcType=VARCHAR}, + max_connections = #{object.maxConnections,jdbcType=INTEGER}, + max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + enable_session_affinity = #{object.sessionAffinityEnabled,jdbcType=INTEGER} + WHERE connection_group_id = #{object.objectID,jdbcType=INTEGER} + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml new file mode 100644 index 000000000..2890ab31d --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_group_permission] + WHERE (user_id, permission, connection_group_id) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[connection_group_permission] ( + user_id, + permission, + connection_group_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + permissions.connection_group_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_group_id + + AS permissions + WHERE (user_id, permission, connection_group_id) NOT IN ( + SELECT + [guacamole].[connection_group_permission].user_id, + [guacamole].[connection_group_permission].permission, + [guacamole].[connection_group_permission].connection_group_id + FROM [guacamole].[connection_group_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml new file mode 100644 index 000000000..8ea85bc3c --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[connection_permission] + WHERE (user_id, permission, connection_id) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[connection_permission] ( + user_id, + permission, + connection_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + permissions.connection_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_id + + AS permissions + WHERE (user_id, permission, connection_id) NOT IN ( + SELECT + [guacamole].[connection_permission].user_id, + [guacamole].[connection_permission].permission, + [guacamole].[connection_permission].connection_id + FROM [guacamole].[connection_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml new file mode 100644 index 000000000..cb706b8d4 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[sharing_profile_permission] + WHERE (user_id, permission, sharing_profile_id) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[sharing_profile_permission] ( + user_id, + permission, + sharing_profile_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + permissions.sharing_profile_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS sharing_profile_id + + AS permissions + WHERE (user_id, permission, sharing_profile_id) NOT IN ( + SELECT + [guacamole].[sharing_profile_permission].user_id, + [guacamole].[sharing_profile_permission].permission, + [guacamole].[sharing_profile_permission].sharing_profile_id + FROM [guacamole].[sharing_profile_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml new file mode 100644 index 000000000..d9e622b69 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[system_permission] + WHERE (user_id, permission) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}) + + + + + + + + INSERT INTO [guacamole].[system_permission] ( + user_id, + permission + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission + + AS permissions + WHERE (user_id, permission) NOT IN ( + SELECT + [guacamole].[system_permission].user_id, + [guacamole].[system_permission].permission + FROM [guacamole].[system_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml new file mode 100644 index 000000000..595c3263d --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[user_permission] + USING [guacamole].[user] affected + WHERE + [guacamole].[user_permission].affected_user_id = affected.user_id + AND ([guacamole].[user_permission].user_id, permission, affected.username) IN + + (#{permission.userID,jdbcType=INTEGER}, + #{permission.type,jdbcType=VARCHAR}, + #{permission.objectIdentifier,jdbcType=INTEGER}) + + + + + + + + INSERT INTO [guacamole].[user_permission] ( + user_id, + permission, + affected_user_id + ) + SELECT DISTINCT + permissions.user_id, + permissions.permission, + [guacamole].[user].user_id + FROM + + SELECT #{permission.userID,jdbcType=INTEGER} AS user_id, + #{permission.type,jdbcType=VARCHAR} AS permission, + #{permission.objectIdentifier,jdbcType=INTEGER} AS username + + AS permissions + JOIN [guacamole].[user] ON [guacamole].[user].username = permissions.username + WHERE (permissions.user_id, permissions.permission, [guacamole].[user].user_id) NOT IN ( + SELECT + [guacamole].[user_permission].user_id, + [guacamole].[user_permission].permission, + [guacamole].[user_permission].affected_user_id + FROM [guacamole].[user_permission] + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml new file mode 100644 index 000000000..9d7d45abd --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[sharing_profile] + WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[sharing_profile] ( + sharing_profile_name, + primary_connection_id + ) + VALUES ( + #{object.name,jdbcType=VARCHAR}, + #{object.parentIdentifier,jdbcType=INTEGER} + ) + + + + + + UPDATE [guacamole].[sharing_profile] + SET sharing_profile_name = #{object.name,jdbcType=VARCHAR}, + primary_connection_id = #{object.parentIdentifier,jdbcType=INTEGER} + WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER} + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml new file mode 100644 index 000000000..8835350b7 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[sharing_profile_parameter] + WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} + + + + + + INSERT INTO [guacamole].[sharing_profile_parameter] ( + sharing_profile_id, + parameter_name, + parameter_value + ) + VALUES + + (#{parameter.sharingProfileIdentifier,jdbcType=INTEGER} + #{parameter.name,jdbcType=VARCHAR}, + #{parameter.value,jdbcType=VARCHAR}) + + + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml new file mode 100644 index 000000000..9ad67a6f3 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + INSERT INTO [guacamole].[user_password_history] ( + user_id, + password_hash, + password_salt, + password_date + ) + VALUES ( + #{record.userID,jdbcType=INTEGER}, + #{record.passwordHash,jdbcType=BINARY}, + #{record.passwordSalt,jdbcType=BINARY}, + #{record.passwordDate,jdbcType=TIMESTAMP} + ); + + DELETE FROM [guacamole].[user_password_history] + WHERE password_history_id IN ( + SELECT password_history_id + FROM [guacamole].[user_password_history] + WHERE user_id = #{record.userID,jdbcType=INTEGER} + ORDER BY password_date DESC + OFFSET #{maxHistorySize} + ); + + + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml new file mode 100644 index 000000000..a4ceea79e --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE FROM [guacamole].[user] + WHERE username = #{identifier,jdbcType=VARCHAR} + + + + + + INSERT INTO [guacamole].[user] ( + username, + password_hash, + password_salt, + password_date, + disabled, + expired, + access_window_start, + access_window_end, + valid_from, + valid_until, + timezone, + full_name, + email_address, + organization, + organizational_role + ) + VALUES ( + #{object.identifier,jdbcType=VARCHAR}, + #{object.passwordHash,jdbcType=BINARY}, + #{object.passwordSalt,jdbcType=BINARY}, + #{object.passwordDate,jdbcType=TIMESTAMP}, + #{object.disabled,jdbcType=INTEGER}, + #{object.expired,jdbcType=INTEGER}, + #{object.accessWindowStart,jdbcType=TIME}, + #{object.accessWindowEnd,jdbcType=TIME}, + #{object.validFrom,jdbcType=DATE}, + #{object.validUntil,jdbcType=DATE}, + #{object.timeZone,jdbcType=VARCHAR}, + #{object.fullName,jdbcType=VARCHAR}, + #{object.emailAddress,jdbcType=VARCHAR}, + #{object.organization,jdbcType=VARCHAR}, + #{object.organizationalRole,jdbcType=VARCHAR} + ) + + + + + + UPDATE [guacamole].[user] + SET password_hash = #{object.passwordHash,jdbcType=BINARY}, + password_salt = #{object.passwordSalt,jdbcType=BINARY}, + password_date = #{object.passwordDate,jdbcType=TIMESTAMP}, + disabled = #{object.disabled,jdbcType=INTEGER}, + expired = #{object.expired,jdbcType=INTEGER}, + access_window_start = #{object.accessWindowStart,jdbcType=TIME}, + access_window_end = #{object.accessWindowEnd,jdbcType=TIME}, + valid_from = #{object.validFrom,jdbcType=DATE}, + valid_until = #{object.validUntil,jdbcType=DATE}, + timezone = #{object.timeZone,jdbcType=VARCHAR}, + full_name = #{object.fullName,jdbcType=VARCHAR}, + email_address = #{object.emailAddress,jdbcType=VARCHAR}, + organization = #{object.organization,jdbcType=VARCHAR}, + organizational_role = #{object.organizationalRole,jdbcType=VARCHAR} + WHERE user_id = #{object.objectID,jdbcType=VARCHAR} + + + diff --git a/extensions/guacamole-auth-jdbc/pom.xml b/extensions/guacamole-auth-jdbc/pom.xml index 2a5ef5b2b..7869c8650 100644 --- a/extensions/guacamole-auth-jdbc/pom.xml +++ b/extensions/guacamole-auth-jdbc/pom.xml @@ -70,6 +70,7 @@ modules/guacamole-auth-jdbc-mysql modules/guacamole-auth-jdbc-postgresql + modules/guacamole-auth-jdbc-sqlserver From 75f51f2244ac537c70c24283586b35975abfb663 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 15 Aug 2017 14:28:20 -0400 Subject: [PATCH 64/94] GUACAMOLE-363: Fix up JDBC maps for proper SQL Server syntax. --- .../connection/ConnectionRecordMapper.xml | 8 ++------ .../ConnectionGroupPermissionMapper.xml | 10 ++++------ .../permission/ConnectionPermissionMapper.xml | 20 +++++++++---------- .../SharingProfilePermissionMapper.xml | 20 +++++++++---------- .../permission/SystemPermissionMapper.xml | 16 +++++++-------- .../jdbc/permission/UserPermissionMapper.xml | 10 ++++------ .../SharingProfileParameterMapper.xml | 2 +- 7 files changed, 36 insertions(+), 50 deletions(-) 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 index ec077db7f..2b873bb9a 100644 --- 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 @@ -90,7 +90,7 @@ diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml index 2890ab31d..a7998880a 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionGroupPermissionMapper.xml @@ -117,12 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_group_id
AS permissions - WHERE (user_id, permission, connection_group_id) NOT IN ( - SELECT - [guacamole].[connection_group_permission].user_id, - [guacamole].[connection_group_permission].permission, - [guacamole].[connection_group_permission].connection_group_id - FROM [guacamole].[connection_group_permission] + WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[connection_group_permission] + WHERE [guacamole].[connection_group_permission].user_id = permissions.user_id AND + [guacamole].[connection_group_permission].permission = permissions.permission AND + [guacamole].[connection_group_permission].connection_group_id = permissions.connection_group_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml index 8ea85bc3c..08e875ccb 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml @@ -87,12 +87,12 @@ DELETE FROM [guacamole].[connection_permission] - WHERE (user_id, permission, connection_id) IN + WHERE - (#{permission.userID,jdbcType=INTEGER}, - #{permission.type,jdbcType=VARCHAR}, - #{permission.objectIdentifier,jdbcType=INTEGER}) + open="(" separator=" OR " close=")"> + (user_id = #{permission.userID,jdbcType=INTEGER} AND + permission = #{permission.type,jdbcType=VARCHAR} AND + connection_id = #{permission.objectIdentifier,jdbcType=INTEGER}) @@ -117,12 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_id
AS permissions - WHERE (user_id, permission, connection_id) NOT IN ( - SELECT - [guacamole].[connection_permission].user_id, - [guacamole].[connection_permission].permission, - [guacamole].[connection_permission].connection_id - FROM [guacamole].[connection_permission] + WHERE NOT EXISTS ( SELECT 1 FROM [guacamole].[connection_permission] + WHERE [guacamole].[connection_permission].user_id = permissions.user_id AND + [guacamole].[connection_permission].permission = permissions.permission AND + [guacamole].[connection_permission].connection_id = permissions.connection_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml index cb706b8d4..354dfb594 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml @@ -87,12 +87,12 @@ DELETE FROM [guacamole].[sharing_profile_permission] - WHERE (user_id, permission, sharing_profile_id) IN + WHERE - (#{permission.userID,jdbcType=INTEGER}, - #{permission.type,jdbcType=VARCHAR}, - #{permission.objectIdentifier,jdbcType=INTEGER}) + open="(" separator=" OR " close=")"> + (user_id = #{permission.userID,jdbcType=INTEGER} AND + permission = #{permission.type,jdbcType=VARCHAR} AND + sharing_profile_id = #{permission.objectIdentifier,jdbcType=INTEGER}) @@ -117,12 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS sharing_profile_id
AS permissions - WHERE (user_id, permission, sharing_profile_id) NOT IN ( - SELECT - [guacamole].[sharing_profile_permission].user_id, - [guacamole].[sharing_profile_permission].permission, - [guacamole].[sharing_profile_permission].sharing_profile_id - FROM [guacamole].[sharing_profile_permission] + WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[sharing_profile_permission] + WHERE [guacamole].[sharing_profile_permission].user_id = permissions.user_id + AND [guacamole].[sharing_profile_permission].permission = permissions.permission + AND [guacamole].[sharing_profile_permission].sharing_profile_id = permissions.sharing_profile_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml index d9e622b69..048877922 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml @@ -63,11 +63,11 @@ DELETE FROM [guacamole].[system_permission] - WHERE (user_id, permission) IN + WHERE - (#{permission.userID,jdbcType=INTEGER}, - #{permission.type,jdbcType=VARCHAR}) + open="(" separator=" OR " close=")"> + (user_id = #{permission.userID,jdbcType=INTEGER} + AND permission = #{permission.type,jdbcType=VARCHAR}) @@ -89,11 +89,9 @@ #{permission.type,jdbcType=VARCHAR} AS permission
AS permissions - WHERE (user_id, permission) NOT IN ( - SELECT - [guacamole].[system_permission].user_id, - [guacamole].[system_permission].permission - FROM [guacamole].[system_permission] + WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[system_permission] + WHERE [guacamole].[system_permission].user_id = permissions.user_id + AND [guacamole].[system_permission].permission = permissions.permission ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml index 595c3263d..606719dcf 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml @@ -124,12 +124,10 @@ AS permissions JOIN [guacamole].[user] ON [guacamole].[user].username = permissions.username - WHERE (permissions.user_id, permissions.permission, [guacamole].[user].user_id) NOT IN ( - SELECT - [guacamole].[user_permission].user_id, - [guacamole].[user_permission].permission, - [guacamole].[user_permission].affected_user_id - FROM [guacamole].[user_permission] + WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[user_permission] + WHERE [guacamole].[user_permission].user_id = permissions.user_id + AND [guacamole].[user_permission].permission = permissions.permission + AND [guacamole].[user_permission].affected_user_id = [guacamole].[user].user_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml index 8835350b7..8f4a3fa10 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml @@ -57,7 +57,7 @@ ) VALUES - (#{parameter.sharingProfileIdentifier,jdbcType=INTEGER} + (#{parameter.sharingProfileIdentifier,jdbcType=INTEGER}, #{parameter.name,jdbcType=VARCHAR}, #{parameter.value,jdbcType=VARCHAR}) From 63c541b1ff8b0333340005a78703210f05767f70 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 15 Aug 2017 17:03:25 -0400 Subject: [PATCH 65/94] GUACAMOLE-363: Fix style, order, and batching in SQL Server schema scripts. --- .../schema/001-create-schema.sql | Bin 35118 -> 37808 bytes .../schema/002-create-admin-user.sql | 58 +++++++----------- 2 files changed, 21 insertions(+), 37 deletions(-) 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 index df95800ec6f91545eac5bdafd9d1a8d8e2bf31ed..166e14f3e96eb2b4456759034e531e2740543ed8 100644 GIT binary patch literal 37808 zcmeHQZEqa65$4wv=zrL6Rs%O_+$Qap0#)@Ep|<2oHj-8_4wh`kYGuigq8HQ`^RA&!4UO+G`2LrhGaIvO_UMc?^I*=KP5ShZUeC=_vpMG# zAK4_DKo_{jN7m_#C$@!M>H)_O=$GFFTmv0>&Rr2_z)Q&OHu>oHJDY^7zRt}^?;@7VI244EoVwp9>$^5l5vqL=Jx6&$Y=a961ovwo9cg&3Bj25=(JEU9M%5#!9 z%R5GWU+s7{w{A_x>#gaT`3H><_FiXAu%T_snJ4zzbMqgv<4fyZ@cx2q<{R@n()Nb< zxKGl=J1qCHm8PcmGBRK5#?tnZar*u0+Fmm1-?#dEUt6S8>rk~8wY zmvsCC*&zJnOLKhV&#$d_eNFzMv7dgTU(e~fU#wr{>tE8@jXnN~-jC_inf-P`=bcmA zjo1EFCoVvfA-{E!;33(;>_(D@bQBhg@yJDzKa;#Q`mZ{?jg3CtirD0g z?BI$x0522DEY>b0AvQC!*E$3;qhH?8A0&TDvi~%1_1Jzx4{iU&WA}B8;}&B40qHOz z2khmDJnP>gJn=0WeIUy0TC8;bWa(F1JC?^j~s8ug`d-tWcfA@I%y z>4(f25;-rWc~&b|fkbMW7f+l9A6Y^>=9f#y*V`(S4uB z`jke7ah12aOA#5;KpQin2`FrK!>dx-)@>BpH$Tv|i0ycPOz#`i54zUz+6WwDWept9 zOZ(dAw2pHQNCNR@lm4JlG5gx4^K_pRYJP6)u)yuPUa^je1;Vm4Zyw4N`nXLmyzddU zTUL+ah^mC18k=Tnrk0W~o9QJ2{g`@0X}yb$5!zXzb$)d9wcY3A8u{5H8+Cx^Uy$#4 zKo|()2HM)Nv1Esi!6N`Uwa>-T9eeJs`6s6y!>jGNcTTH_?$(z(_7;yGBX#jF8ppP}up9fZJQu-l&FVw8t zu)VQ(P>=1poLaM)D&j6j0dS+XUGS`Le&_4rL!v@-7&RZ%&Lm6IbQ&=p86Pq`Q~r3#$#F@@$@?XxU$B#>OrF zOehg~6|{`=-g0XA+P8Eq^faHBeoNW2)JC`x)XpM(nqYq?L=|ent_}i8puT-^ld)?& z_`^K=)q6>2nZSZ2JV>|FKUdYY@FR^I*#2#Wln^6NNmni?LLyt9(Wi6zemfa1_*j?K zeqphYK7O(Fv2xdN20*e_d0%C(E(;Db9pO+aKP|~$$3ga-FAGim(0nR~)OFF-V*BQe zcPU>CW#H#FF?2hOO9vXyikF3UzzZIosnQZ@IpjmBa(pg+!@-8on} z0RQ)aFvB&Sg}em#6_xXkbo`PK7$24FgY}K)C4tx$Kl_l;b~6t7#Z}FHOgLn2NLtS0 zWuWDX~4lEPPKK-lNA0V&bOsV90q4O8& z7xS=urIxvUXVSUb8(Z}|qfzAT=aKo=e3#@iuYi%uQ8fR9XSl?COLx@BW`(v}1;AD`-xoU|F@%`)^R*UrcfbYn^xPU~LzImgkBZDpfqUxzW2)V6^* z5b?NPjT#st4c1oh>eKkjrSME>395XkXQQfpMt_K@q8*L8+JUdSpev5a7XsNbHHhnI z1*>4O+6i&Fp>I5YbV^h*bt3;oubIoZbS`(XZ2ElXf5$?&x&HEzy9W6}+fa)IwvEl1 zN%hblp^htA!#G;RGE-jFlOE+*Q8L|&liezIVrA*)UDK0ZwNp|RZO6|1s-Cod_>pz^ znx1rDVZ`lMP2@tap!5sReEE)jaH*!d?Zfa+Te`*8ppw*w%q* zw$wFzd=-9``w_IO>akT?E}{HODttqvU5ZHb3O>)n@;X|~lH=}_6gEM0@y~WBHjPNI zBKz3Vy9m{-MYR~L-&%W~NDQ?AKx`MMzc&46zU1XDML*i(@vT&a;PL69`T^tMT zb}b%T@E@N3DwgP#={|)sJ?H^mZu^Q{6oCH zlfG7}q+yMv7BQv!0DY+Oq|eeRk;t%2)gBFfg!)sCr*b^&T1;MBN-Jc^qOWoyJwoXqmASd>CHiSAn|P;^(fz z(T}dV+MYRK)Ea_%%KOwS1K-&7TXB@5x4)_erFSpVxt7<2a{N->LtO5#vicdh@}6t7 zyx)Ec8b{quEjit8V}W5-?5Gc7LvB09t2(B2fQXYz?a=n#k&zQMEj-GJzpTn92X{N14&e9QmZEas#L!a8cNz0or z)X95#ZFih5%_8!%1L<1QShe~z9m|zLq{pJ?Wn1#Nr%^PyMq-puMSwkNR#=|&$de6^Yr?Q1yk7MKt={^J_rO(oF zS*WqgabHU;8v2%4j+=5^(<~;hG5s=xKD5->PHrBdPycR4VU-`$?a1AS+o80l*782N zfqO2FZl`{GnBkg+qt-W^~`zxN&85gw52iXYjTjwWlEc!iPCC@x* zKTkvCBtE`w-HztrV9W8=`|3DJ-xeCsv;+8I=-S&HAE&O(VP3z4yHc0K z`7vIsu)_Vs3TYkoeQ4XK)yJ1~Utw$+f)UdFIRCS%2h`OA(tHi&SB?$Rt@_gHSF=jD zA5wiAT9;ebn)m48-10Ot*V9_}_}VdimFZimzsS>bJ`p;IuPMcjuUH?-`&qjxkKe*6 zoq=5lT`fpkQM%~09*t(~6zy}Wix!-wYj$H=+-&ncGbo{t^CY;mXUmu-KOJN zfy_hkQ@)VJ$hE1Ke0taua69RJB6SIdR)t>2s4Rx9I*VH61NSo@DA7GXHcEW!yZdrU zf8$}alHT<7m9V$k6}e-~tZNj5miWqBtyl40-4n}Er#VI={`i)(`SX0)aNcGx)OS!@(iY=?Wxvl zl=K~rE3J_++>&}eR~umn4o_>IoE1t|{Ma-(ue2`jD{mQ>9Xw?198LSlKw;}Xs_4$w zgx5B$9F!x3zv4plN1it&&ja8cRb0-FXXEfHjg$FqD-GrK*yo?0ZpHmxP&R)$&m8b% z06et^^FFR$WP;o$)^xm~bFc?Z_~fg01yy3`;>`+$ly@U?dwoZHtnDkrioBoF0smgXa2i+Ox_^?`Kw8u9JQg5%1hLH!bhA w21DggeR;3`+(;@rbuDVS;j&?=?$ZqF@xJ3o&i90pEl2(3J@`_D#sXFS9{`FUo&W#< literal 35118 zcmeHQYi}L55#`qw=zm!FOXb3~YsX2`6alK};TW-HSCZSNg0YbGu${`1t1HKLetg?= zICn&Hmt5}as(LIgbRWCqa5#^{87@iv_doZ{@9_GK`L!wVS(qp0t=TgN=Ge^ezK<(s z=ET0g!SBK>oA+iHCFIu@?j54UM_fC#_t$ad18VQ%${A>#;Co?~P;bkuo7?y%ljF)zl(AOT0O9Qoy|Gk zFwe}kd2Ck98txu~&Jpgr{_o?;4DGlUMG7Broir$qH?~ZHUXz=DSvtbkF8WOh+Vfpd zFYx;qEwRKqPb#iW_Vu-uAnP9EdjScbK+>NrAFt8k8Lpk6#bcB`1&8F}{k)Ic_$9ib zjH}X_;fmwA-eb}4XHfrulD>9WtFH6VLhhi>-{w52wjY46Kj8Y3ZP%CXt%`l!f<^op zCAD?R=QDmEgB$kvgSEmK{{`CoWG(f*ElIhF)ZRfZw2xg}p(Q&xhdN}>!oG;b{5Y3{ z@^S*pI|DUoVRzmNbwiCD;$7twQlnL#owx3|pjA?zXW;W2a}TeN_H`HKop0R*?NeC7 zy^5{RaOKI|em7v5wki_a0|&2c z4cgEyxMC0KZ_d9QB8WUb;=b5B?e@-je+#r(#fFq`#cZxBOL}EteJkdjf-=;&>-{Z@ zIR#|3Wp1JFclI}b(PsaS>)Ymgpur1#^7pdY#B14XSbSJRxdL}L@xFr34YO)%JhtEE z9(|4FfAm`Y0i{@$Z5&w1(1$2P+Ut8Od(nqT_AM|$q)(iQV^&obf+cEquE#S_I)Kf; zwYav2HmODG<%88AE&esM^0VdW807?OSc}+18PD)eX;Rv(OMM^V8t>8z6xn88pY!^= zdtUmU{YIW&SnDm!&YZtJ^U~gX1PSxLj7%Jz_@XXenV)R`&fqtK?J^G0Q++zS;P%AY z@k?7y%hFN>Emmz$4lJFo(b9eM5bqCwTKCN#QRh#%^AO*^F<;=lFwf0XyelvKlzyzh zKGt9Z+jcbBf~9G?}_cR)1EK&yRG=8 zEEpH?^DpN;p~r5Z$4ln7bLp<)+a3J9fF4%o(v~Z$;DLNl{&Hm*C7xOe^mJa|#GTt6 zEz6ht3@AwnGqxzNoEExrpVx_R^W_{HHz4N~iE+|J;^e$8YLAUPq9HdKW&%v56P30^;N<-Wf$P65GcwV&X3P{@L0_%I{Miaj|~8 zjj`%Er`0v|JhOGFD^EwFLwy&uvWNv5mmiwDezLhs^ob z;HxESam%Pj81_WY=UgOuG? zX?+65as+1NERyo2mf}Eay+JLG;(2*|2}!FT34+D>pfvWt32|Se;?l~R`QXX9USnAK za4zpEeMYjM(8rjq%xZR0?{RZ|jb6%mUVYkvVvLg#nIUr=JsdIIRUU8m9 zGmjGAn3;Z#v`tfiE*g zkm!)OP*^W*>#K}eS8R>j=XoUK)#u<%Foqf6n)wIlev7|nn3Y+#u?X8_wji-7XQ8&h zKSxaF5zI56f(kQIj?rP=$B2KlWC{9=nacA%g=LrR$omZ3m7px2Pw=^d^2AChyEvwQNivT6{l=<3<4GKeeE#y-PGrxGb!YQPo|Y3IG4tb9GY$*oCd6#6-v`GzT4`KY z+DyjH^^~}CIL~P~%d<#a4y|u|jP~t8W2*_TIZ|E?yjI%|XCo&RKZgJMxt8xoDVaHJ zm**&_7}wP&!pJ!mb)|EPn2)ui7n{QrG?Y1NK7nv^w@q^<)meuAkzyN34#BCq>;;cp zR*@gsRBP3mDS1waci9n7o*~QgY#DE-C^f{ls)QVxg?HkZ)-Nut`)Y`5)qGvcj}v)v zhK1`O%x zF7qHEEvKDne7Wr7i)7d`_e;B#xxQ(P3CEb2l-xKI$H6#;rXuKi3#HA(6*c0>-e#U6 zMww6Ljxg_~I2D_Fmbr!WvxI)AQ|E?peShR>mVG@ACQkd-9!hz_tL}Kk=U$w{=4>@r zw8*@0)BNwn&F`l2o(bQo_*P%p#b@=@6eAOjU){(aMusU=Yxd4|G*UWDKXXpih(}(1 zaV#dWAxKu2aTUFqrCBYVlEQ>>-7$`Sun5#@&QEUkY-Ub24xO4y#xbj3-k)n}oP3hG zF7rjkDqP9X?Du&T%^_TKuZG2E&9t3vCRDmAsKmLLY7{*o6(y3ItBT2M7<$Dc8AfXL zw!#eO>gAC+1gZD?t zyUxkQ^?Fg6XRbG?46pxeT3zndtTM-wO1N4t#p{HM-BEFI*=TMD(@l@_^70vuVJS~Z zqfWbBA@P_opBv`;yx3WfO4}K0wrLk}(+qnxxDtTt z54iGz<2<#wgFRl%Yh^Bq&jj+TnwbfO6lb_{gmn=)ivFqw&1OSNx}riT>92O{E96`O zUEN&YPZdW<@*#Wj^+W_|+h3QRdj7!^PTg^3@$=#N<2Nq?L>Fp(vDI}d+FJfRE;>dT~H=& zNBxndF5T*^Ya2OM>!kWWq0?}5;vRZAO<>q*Aw1h;6)$3toH|!O^I#Qc38dDJG@rCk z*i#AC(FXHRo}jRV7fptru6E@bSN4tPhWT=F^sbT=y6^ms$tq?iT`7+*HOXZ3EJykb&)?%I z7j5il9pzG<6knU=tcxv+$E?9(cru6Xt672vF*dB8mm_D;@tlu!{PA-GoXRtI`1r7U?N2I2nIh#q@nkz9`l{-zWs-2-0 z=A_(44~w<7RD{iOe-UWr_dON|wvk8^-gQHt%YlKilf^$%lwL27+!*WV%4$%^%)uehhU8HVt5 z>9IUDoCT(?7K7knJ8`^jw#qn0%lyrFv8h^XzP0|At7oq1Gt5PxP$+NqYAD`@6jK_! zn7&+$jW(|-Y_`_sx*-O3Mb>88YQfE=LJr0r|3h0@g!MJ|?s{RRj-1UFr=>#8cC{^~ zqE@88L#j6&`&256u``){@lOMwHWq_<^|n&T-aUW1ieqyk=OWAL~?8dR)W^ z9m~HKX|wewR`K56w`-Bo^PKr8uPc7WC@Pl5?u~`37h$(`sgGm1b-HP7URUeY5hZ7_ zS}wGku2!m4)H3yVNVWecf8DH6rTwKDNB?X+3$ z-H@`GR!WD9v`o%U@tNS*QE9HH^;Wq;z3B|bW?OEq8{%JARBfiMSle7Gfh2I{my2EZP_9F$?=VG)K!zy54SH7ERcmYjH>p*G&65`$JtzV|zrsg}fcyB%jcT zjdD*%Hd-n~-LAN=RMevNcS!ZBV0qoLF2Z(IX2av_Hv58y<8-bS|GC{{f%@NU`5zJ5 z?Fw)Iv?@=}*TpalR4bKeIKM|}*jkwOt@%Bitj)K!_A=~-a_#B*x*5;<;wU{7*Zf}9 zTkv}_Sy{@;>T>IES#?^z4z7ze<>ox|yG8oVI;pic$8G(e|0wq4=Vj}Z~y=R 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 index 08cce3f07..947c5ac2f 100644 --- 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 @@ -1,43 +1,27 @@ /** - * 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. + * Create the default admin user account and set up full privileges. */ - -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] (username, password_hash, password_date) +VALUES ('guacadmin', HASHBYTES('SHA2_256', 'guacadmin'), getdate()); 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; + 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; + +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]; +GO \ No newline at end of file From 60d615274181f28de54bd7e00a3eb2d14f9a43eb Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 15 Aug 2017 19:56:00 -0400 Subject: [PATCH 66/94] GUACAMOLE-363: Fix encoding of SQL file --- .../schema/001-create-schema.sql | Bin 37808 -> 18903 bytes 1 file changed, 0 insertions(+), 0 deletions(-) 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 index 166e14f3e96eb2b4456759034e531e2740543ed8..83299a1e6ae281908943791b2e3cf5661046201b 100644 GIT binary patch literal 18903 zcmeHPZExE+68_u(`49YNr^szLz1zL}QsA_7A%JO-Ssex(=_{ZVVtHbHkgb*vU&VDNEfRhz3QI* zc*4B#jCq%%(eY93d+f~K?P{Nj+tsfB`d025S7o#NMH0v1B8MgE-=@jkmgT`UuJb%e z!;B^AZ4gJl2lzf%vmjow>tG$kizvQjTs|w;@6??!$D0m)9ORUZz2hT%^smeD%(Q+UT(d4iRGq zpgsY8`S11i7{C^YZe#Y}@FC;yT~DUGSIQ0GjKG1+W=RY8an}KJ^gb}B-)BsouYo#W znh6|$ufStCfn8~t7bBgx1DH^+=T4h^LPv4M^fL|3>^meen!N|Ie@Dc3a*sWY>%?{~ zwgvZiw>#$#-*tX*Mvm753hA)%gq2UnlXJ%#{u>tV*mFjmlY=vgC<7_7a*S^LkPjRi)utBmUY zcyc1lFv-$T2kExAxOoQ~jZsjW8Gx8to=F5IR` zo-C5}PGSSWFAx4UNr83*1IwHy-ma1?S8V#}45JZ=euZopFVcrCk3lwJzDkhTYXbgT zQ-x5b&H^IR%BqqJ?*Z*s+9BNp(K`7I+?>SgM-Z-&YF{;w7iZmuU5fC%5oTOc`hq)uzKk+VcaREbdc)s`U$#+dehpIsd6Iu0#mnU0 z&+>qC74NG1_a>nC1j=NO2Km%{wk@Zf|U|RL^ z|LddLZJI91cRIk#p!@}KHFD8S1ZAa0ajAHiL5VfUS+HIw_vnsB5S}OO8mdvyOt@rF zf{kyX*tvoHDB41EIQ~ON=EUSGJSWes0hj7of^Qma0Bz;WtWF9ftQ1Q_4ve7GL%KAC zpN%a^RQTw=q1~yJdWb*7!rhs16Rq808bq-~N1AaO#A=s>b+Lz(d0;gastBu40u!eO ztOv91^j)#8idW(sp?+mVD>4>iz}G%(9gs+IGUTvOqs>bMElbtaV-B$dNLX_HAE`WtU{umK1ZAZ>uMai&8PZ;e5{hF6i!yN4w+%p$(ZDJ>RjvQZ z5rfU#-)2xVhq|(L%@~glCEry(w?q`3suis06wTNoN!P%zJ5hcPOp#2hoYw{{I(d2E zI&>kpcFptOg4Qr(3C&Gl5(-;lYR~FFFhr~P7^4-8hG!UK0BaCaGJnT{Yqb&kb%gk=k zA(o7C^`(+#dR0B=Q@shcTS&#|iP94xme#%st$5yQhA2tdEL308fFP*8c_ZJKX;hWO zQYD#^)RWwv_GG+~FI6KDU?jDJ78eLrO@LipUs#A?A^!YnD;-KMMMI#8BH9yjpmv-}Xq*iE*y`?17)*C_l##yqlU)(R$+vOhG z;b#;>C@12$M-G&>wvASc-C6~Hapw%y5y!C|nZZ$oBVnmmCteM5CC$(kqdKaWqukR1+w1x7PD*+ob z#?b~Oq$}^cHI9VoZjvIy-Fa`>V&nK;SO81?@ByY`th5mAC}6jH?AU;|vo8%({o=M` zV`>P{o2KJgd4bw(S%IKxVz@erP||@4YD^5lNkL`_n(IALXm7UEmLF&fPfQQAJ8ARm z%MMJJP<{{h8@FV&RR^+~_b)kA4Ok(LdCI@uq677iHges=F)f5(Zbd&kG)FM&zi2)% zo83kSW~~-B;NRj%p|^UiQAHyRmhM>XGU&g;5nQ7Jru@Z}&ZHNm#xp zj83w0hUu|K^O9@e#_CJ>OHX=alf@)Usm<35KUE+%DFG)%nrY9$8Fn^C#&OV z;|f(;9`$3oA=Pu5hHE+`8#B-5S1zhL)2> z1Ro78*?p9+xNaJPCQEMWkFUz=;(`823hkgO;xEVJ%Uoge?^5t)CEBbn?utT5<;7?I z{7OrodLLLYsMbB-GL>pQX~(8oRXw3nsMo6gfhbjdW?;m9t;KE7uT>}$uJiH#041&+ Ap#T5? literal 37808 zcmeHQZEqa65$4wv=zrL6Rs%O_+$Qap0#)@Ep|<2oHj-8_4wh`kYGuigq8HQ`^RA&!4UO+G`2LrhGaIvO_UMc?^I*=KP5ShZUeC=_vpMG# zAK4_DKo_{jN7m_#C$@!M>H)_O=$GFFTmv0>&Rr2_z)Q&OHu>oHJDY^7zRt}^?;@7VI244EoVwp9>$^5l5vqL=Jx6&$Y=a961ovwo9cg&3Bj25=(JEU9M%5#!9 z%R5GWU+s7{w{A_x>#gaT`3H><_FiXAu%T_snJ4zzbMqgv<4fyZ@cx2q<{R@n()Nb< zxKGl=J1qCHm8PcmGBRK5#?tnZar*u0+Fmm1-?#dEUt6S8>rk~8wY zmvsCC*&zJnOLKhV&#$d_eNFzMv7dgTU(e~fU#wr{>tE8@jXnN~-jC_inf-P`=bcmA zjo1EFCoVvfA-{E!;33(;>_(D@bQBhg@yJDzKa;#Q`mZ{?jg3CtirD0g z?BI$x0522DEY>b0AvQC!*E$3;qhH?8A0&TDvi~%1_1Jzx4{iU&WA}B8;}&B40qHOz z2khmDJnP>gJn=0WeIUy0TC8;bWa(F1JC?^j~s8ug`d-tWcfA@I%y z>4(f25;-rWc~&b|fkbMW7f+l9A6Y^>=9f#y*V`(S4uB z`jke7ah12aOA#5;KpQin2`FrK!>dx-)@>BpH$Tv|i0ycPOz#`i54zUz+6WwDWept9 zOZ(dAw2pHQNCNR@lm4JlG5gx4^K_pRYJP6)u)yuPUa^je1;Vm4Zyw4N`nXLmyzddU zTUL+ah^mC18k=Tnrk0W~o9QJ2{g`@0X}yb$5!zXzb$)d9wcY3A8u{5H8+Cx^Uy$#4 zKo|()2HM)Nv1Esi!6N`Uwa>-T9eeJs`6s6y!>jGNcTTH_?$(z(_7;yGBX#jF8ppP}up9fZJQu-l&FVw8t zu)VQ(P>=1poLaM)D&j6j0dS+XUGS`Le&_4rL!v@-7&RZ%&Lm6IbQ&=p86Pq`Q~r3#$#F@@$@?XxU$B#>OrF zOehg~6|{`=-g0XA+P8Eq^faHBeoNW2)JC`x)XpM(nqYq?L=|ent_}i8puT-^ld)?& z_`^K=)q6>2nZSZ2JV>|FKUdYY@FR^I*#2#Wln^6NNmni?LLyt9(Wi6zemfa1_*j?K zeqphYK7O(Fv2xdN20*e_d0%C(E(;Db9pO+aKP|~$$3ga-FAGim(0nR~)OFF-V*BQe zcPU>CW#H#FF?2hOO9vXyikF3UzzZIosnQZ@IpjmBa(pg+!@-8on} z0RQ)aFvB&Sg}em#6_xXkbo`PK7$24FgY}K)C4tx$Kl_l;b~6t7#Z}FHOgLn2NLtS0 zWuWDX~4lEPPKK-lNA0V&bOsV90q4O8& z7xS=urIxvUXVSUb8(Z}|qfzAT=aKo=e3#@iuYi%uQ8fR9XSl?COLx@BW`(v}1;AD`-xoU|F@%`)^R*UrcfbYn^xPU~LzImgkBZDpfqUxzW2)V6^* z5b?NPjT#st4c1oh>eKkjrSME>395XkXQQfpMt_K@q8*L8+JUdSpev5a7XsNbHHhnI z1*>4O+6i&Fp>I5YbV^h*bt3;oubIoZbS`(XZ2ElXf5$?&x&HEzy9W6}+fa)IwvEl1 zN%hblp^htA!#G;RGE-jFlOE+*Q8L|&liezIVrA*)UDK0ZwNp|RZO6|1s-Cod_>pz^ znx1rDVZ`lMP2@tap!5sReEE)jaH*!d?Zfa+Te`*8ppw*w%q* zw$wFzd=-9``w_IO>akT?E}{HODttqvU5ZHb3O>)n@;X|~lH=}_6gEM0@y~WBHjPNI zBKz3Vy9m{-MYR~L-&%W~NDQ?AKx`MMzc&46zU1XDML*i(@vT&a;PL69`T^tMT zb}b%T@E@N3DwgP#={|)sJ?H^mZu^Q{6oCH zlfG7}q+yMv7BQv!0DY+Oq|eeRk;t%2)gBFfg!)sCr*b^&T1;MBN-Jc^qOWoyJwoXqmASd>CHiSAn|P;^(fz z(T}dV+MYRK)Ea_%%KOwS1K-&7TXB@5x4)_erFSpVxt7<2a{N->LtO5#vicdh@}6t7 zyx)Ec8b{quEjit8V}W5-?5Gc7LvB09t2(B2fQXYz?a=n#k&zQMEj-GJzpTn92X{N14&e9QmZEas#L!a8cNz0or z)X95#ZFih5%_8!%1L<1QShe~z9m|zLq{pJ?Wn1#Nr%^PyMq-puMSwkNR#=|&$de6^Yr?Q1yk7MKt={^J_rO(oF zS*WqgabHU;8v2%4j+=5^(<~;hG5s=xKD5->PHrBdPycR4VU-`$?a1AS+o80l*782N zfqO2FZl`{GnBkg+qt-W^~`zxN&85gw52iXYjTjwWlEc!iPCC@x* zKTkvCBtE`w-HztrV9W8=`|3DJ-xeCsv;+8I=-S&HAE&O(VP3z4yHc0K z`7vIsu)_Vs3TYkoeQ4XK)yJ1~Utw$+f)UdFIRCS%2h`OA(tHi&SB?$Rt@_gHSF=jD zA5wiAT9;ebn)m48-10Ot*V9_}_}VdimFZimzsS>bJ`p;IuPMcjuUH?-`&qjxkKe*6 zoq=5lT`fpkQM%~09*t(~6zy}Wix!-wYj$H=+-&ncGbo{t^CY;mXUmu-KOJN zfy_hkQ@)VJ$hE1Ke0taua69RJB6SIdR)t>2s4Rx9I*VH61NSo@DA7GXHcEW!yZdrU zf8$}alHT<7m9V$k6}e-~tZNj5miWqBtyl40-4n}Er#VI={`i)(`SX0)aNcGx)OS!@(iY=?Wxvl zl=K~rE3J_++>&}eR~umn4o_>IoE1t|{Ma-(ue2`jD{mQ>9Xw?198LSlKw;}Xs_4$w zgx5B$9F!x3zv4plN1it&&ja8cRb0-FXXEfHjg$FqD-GrK*yo?0ZpHmxP&R)$&m8b% z06et^^FFR$WP;o$)^xm~bFc?Z_~fg01yy3`;>`+$ly@U?dwoZHtnDkrioBoF0smgXa2i+Ox_^?`Kw8u9JQg5%1hLH!bhA w21DggeR;3`+(;@rbuDVS;j&?=?$ZqF@xJ3o&i90pEl2(3J@`_D#sXFS9{`FUo&W#< From 70c33efc4abbf9e9581b760eb90785b7f0271650 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Sat, 26 Aug 2017 18:00:32 -0400 Subject: [PATCH 67/94] GUACAMOLE-363: Add license to SQL schema files. --- .../schema/001-create-schema.sql | 21 ++++++++++++++++++- .../schema/002-create-admin-user.sql | 21 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) 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 index 83299a1e6..759e78d5e 100644 --- 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 @@ -1,3 +1,22 @@ +/* + * 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. + */ + /** * Create the guacamole schema. */ @@ -541,4 +560,4 @@ ALTER TABLE [guacamole].[user_password_history] ON DELETE CASCADE ALTER TABLE [guacamole].[user_password_history] CHECK CONSTRAINT [FK_user_password_history_user] -GO \ No newline at end of file +GO 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 index 947c5ac2f..f71d2837d 100644 --- 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 @@ -1,3 +1,22 @@ +/* + * 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. + */ + /** * Create the default admin user account and set up full privileges. */ @@ -24,4 +43,4 @@ FROM ( UNION SELECT 'guacadmin' AS username, 'ADMINISTER' AS permission) permissions JOIN [guacamole].[user] ON permissions.username = [guacamole].[user].[username]; -GO \ No newline at end of file +GO From c803be5c7a847bebc55790cc9d37ac0da8a24445 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Sat, 26 Aug 2017 21:07:58 -0400 Subject: [PATCH 68/94] GUACAMOLE-363: Make table names standard in schema creation scripts. --- .../schema/001-create-schema.sql | 283 +++++++++--------- .../schema/002-create-admin-user.sql | 12 +- 2 files changed, 148 insertions(+), 147 deletions(-) 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 index 759e78d5e..44e498e3f 100644 --- 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 @@ -22,10 +22,11 @@ */ CREATE SCHEMA [guacamole] GO + /** * List for permission data type. */ -CREATE RULE [guacamole].[permission_list] +CREATE RULE [guacamole].[guacamole_permission_list] AS @list IN ('READ','UPDATE','DELETE','ADMINISTER') GO @@ -33,7 +34,7 @@ GO /** * List for system permission data type. */ -CREATE RULE [guacamole].[system_permission_list] +CREATE RULE [guacamole].[guacamole_system_permission_list] AS @list IN ('CREATE_CONNECTION', 'CREATE_CONNECTION_GROUP', @@ -45,12 +46,12 @@ GO /** * The permission data type. */ -CREATE TYPE [guacamole].[permission] FROM [nvarchar](10) NOT NULL +CREATE TYPE [guacamole].[guacamole_permission] FROM [nvarchar](10) NOT NULL /** * The system permission data type. */ -CREATE TYPE [guacamole].[system_permission] FROM [nvarchar](32) NOT NULL +CREATE TYPE [guacamole].[guacamole_system_permission] FROM [nvarchar](32) NOT NULL GO /** @@ -58,7 +59,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[connection_group]( +CREATE TABLE [guacamole].[guacamole_connection_group]( [connection_group_id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NULL, [connection_group_name] [nvarchar](128) NOT NULL, @@ -67,7 +68,7 @@ CREATE TABLE [guacamole].[connection_group]( [max_connections_per_user] [int] NULL, [enable_session_affinity] [bit] NOT NULL, - CONSTRAINT [PK_connection_group] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacmaole_connection_group] PRIMARY KEY CLUSTERED ([connection_group_id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -80,24 +81,24 @@ CREATE TABLE [guacamole].[connection_group]( /** * Foreign keys for connection_group table. */ -ALTER TABLE [guacamole].[connection_group] - WITH CHECK ADD CONSTRAINT [FK_connection_group_connection_group] FOREIGN KEY([parent_id]) - REFERENCES [guacamole].[connection_group] ([connection_group_id]) -ALTER TABLE [guacamole].[connection_group] - CHECK CONSTRAINT [FK_connection_group_connection_group] -ALTER TABLE [guacamole].[connection_group] - WITH CHECK ADD CONSTRAINT [CK_connection_group_type] +ALTER TABLE [guacamole].[guacamole_connection_group] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_connection_group_id] FOREIGN KEY([parent_id]) + REFERENCES [guacamole].[guacamole_connection_group] ([connection_group_id]) +ALTER TABLE [guacamole].[guacamole_connection_group] + CHECK CONSTRAINT [FK_guacamole_connection_group_connection_group_id] +ALTER TABLE [guacamole].[guacamole_connection_group] + WITH CHECK ADD CONSTRAINT [CK_guacamole_connection_group_type] CHECK (([type]='BALANCING' OR [type]='ORGANIZATIONAL')) -ALTER TABLE [guacamole].[connection_group] - CHECK CONSTRAINT [CK_connection_group_type] +ALTER TABLE [guacamole].[guacamole_connection_group] + CHECK CONSTRAINT [CK_guacamole_connection_group_type] /** * Default values for connection_group table. */ -ALTER TABLE [guacamole].[connection_group] - ADD CONSTRAINT [DF_connection_group_type] DEFAULT (N'ORGANIZATIONAL') FOR [type] -ALTER TABLE [guacamole].[connection_group] - ADD CONSTRAINT [DF_connection_group_enable_session_affinity] DEFAULT ((0)) FOR [enable_session_affinity] +ALTER TABLE [guacamole].[guacamole_connection_group] + ADD CONSTRAINT [DF_guacamole_connection_group_type] DEFAULT (N'ORGANIZATIONAL') FOR [type] +ALTER TABLE [guacamole].[guacamole_connection_group] + ADD CONSTRAINT [DF_guacamole_connection_group_enable_session_affinity] DEFAULT ((0)) FOR [enable_session_affinity] GO /** @@ -105,7 +106,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[connection]( +CREATE TABLE [guacamole].[guacamole_connection]( [connection_id] [int] IDENTITY(1,1) NOT NULL, [connection_name] [nvarchar](128) NOT NULL, [parent_id] [int] NULL, @@ -118,7 +119,7 @@ CREATE TABLE [guacamole].[connection]( [connection_weight] [int] NULL, [failover_only] [bit] NOT NULL, - CONSTRAINT [PK_connection] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_connection] PRIMARY KEY CLUSTERED ([connection_id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -128,18 +129,18 @@ CREATE TABLE [guacamole].[connection]( ON [PRIMARY] ) ON [PRIMARY] -ALTER TABLE [guacamole].[connection] - WITH CHECK ADD CONSTRAINT [FK_connection_connection_group] FOREIGN KEY([parent_id]) -REFERENCES [guacamole].[connection_group] ([connection_group_id]) -ALTER TABLE [guacamole].[connection] - CHECK CONSTRAINT [FK_connection_connection_group] -ALTER TABLE [guacamole].[connection] +ALTER TABLE [guacamole].[guacamole_connection] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_connection_group] FOREIGN KEY([parent_id]) +REFERENCES [guacamole].[guacamole_connection_group] ([connection_group_id]) +ALTER TABLE [guacamole].[guacamole_connection] + CHECK CONSTRAINT [FK_guacamole_connection_connection_group] +ALTER TABLE [guacamole].[guacamole_connection] WITH CHECK ADD CONSTRAINT [CK_proxy_encryption_method] CHECK (([proxy_encryption_method]='SSL' OR [proxy_encryption_method]='NONE')) -ALTER TABLE [guacamole].[connection] +ALTER TABLE [guacamole].[guacamole_connection] CHECK CONSTRAINT [CK_proxy_encryption_method] -ALTER TABLE [guacamole].[connection] - ADD CONSTRAINT [DF_connection_failover_only] DEFAULT ((0)) FOR [failover_only] +ALTER TABLE [guacamole].[guacamole_connection] + ADD CONSTRAINT [DF_guacamole_connection_failover_only] DEFAULT ((0)) FOR [failover_only] GO /** @@ -147,7 +148,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[user]( +CREATE TABLE [guacamole].[guacamole_user]( [user_id] [int] IDENTITY(1,1) NOT NULL, [username] [nvarchar](128) NOT NULL, [password_hash] [binary](32) NOT NULL, @@ -165,7 +166,7 @@ CREATE TABLE [guacamole].[user]( [organization] [nvarchar](256) NULL, [organizational_role] [nvarchar](256) NULL, - CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_user] PRIMARY KEY CLUSTERED ([user_id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -178,10 +179,10 @@ CREATE TABLE [guacamole].[user]( /** * Defaults for user table */ -ALTER TABLE [guacamole].[user] - ADD CONSTRAINT [DF_user_disabled] DEFAULT ((0)) FOR [disabled] -ALTER TABLE [guacamole].[user] - ADD CONSTRAINT [DF_user_expired] DEFAULT ((0)) FOR [expired] +ALTER TABLE [guacamole].[guacamole_user] + ADD CONSTRAINT [DF_guacamole_user_disabled] DEFAULT ((0)) FOR [disabled] +ALTER TABLE [guacamole].[guacamole_user] + ADD CONSTRAINT [DF_guacamole_user_expired] DEFAULT ((0)) FOR [expired] GO /** @@ -190,12 +191,12 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[sharing_profile]( +CREATE TABLE [guacamole].[guacamole_sharing_profile]( [sharing_profile_id] [int] IDENTITY(1,1) NOT NULL, [sharing_profile_name] [nvarchar](128) NOT NULL, [primary_connection_id] [int] NOT NULL, - CONSTRAINT [PK_sharing_profile] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_sharing_profile] PRIMARY KEY CLUSTERED ([sharing_profile_id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -208,13 +209,13 @@ CREATE TABLE [guacamole].[sharing_profile]( /** * Foreign keys for sharing_profile table. */ -ALTER TABLE [guacamole].[sharing_profile] - WITH CHECK ADD CONSTRAINT [FK_sharing_profile_connection] FOREIGN KEY([primary_connection_id]) - REFERENCES [guacamole].[connection] ([connection_id]) +ALTER TABLE [guacamole].[guacamole_sharing_profile] + WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_connection] FOREIGN KEY([primary_connection_id]) + REFERENCES [guacamole].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[sharing_profile] - CHECK CONSTRAINT [FK_sharing_profile_connection] +ALTER TABLE [guacamole].[guacamole_sharing_profile] + CHECK CONSTRAINT [FK_guacamole_sharing_profile_connection] GO /** @@ -223,12 +224,12 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[connection_parameter]( +CREATE TABLE [guacamole].[guacamole_connection_parameter]( [connection_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](max) NOT NULL, - CONSTRAINT [PK_connection_parameter] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_connection_parameter] PRIMARY KEY CLUSTERED ([connection_id] ASC, [parameter_name] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -241,13 +242,13 @@ CREATE TABLE [guacamole].[connection_parameter]( /** * Foreign keys for the connection_parameter table. */ -ALTER TABLE [guacamole].[connection_parameter] - WITH CHECK ADD CONSTRAINT [FK_connection_parameter_connection] FOREIGN KEY([connection_id]) - REFERENCES [guacamole].[connection] ([connection_id]) +ALTER TABLE [guacamole].[guacamole_connection_parameter] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_parameter_connection] FOREIGN KEY([connection_id]) + REFERENCES [guacamole].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[connection_parameter] - CHECK CONSTRAINT [FK_connection_parameter_connection] +ALTER TABLE [guacamole].[guacamole_connection_parameter] + CHECK CONSTRAINT [FK_guacamole_connection_parameter_connection] GO /** @@ -256,12 +257,12 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[sharing_profile_parameter]( +CREATE TABLE [guacamole].[guacamole_sharing_profile_parameter]( [sharing_profile_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](max) NOT NULL, - CONSTRAINT [PK_sharing_profile_parameter] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_sharing_profile_parameter] PRIMARY KEY CLUSTERED ([sharing_profile_id] ASC, [parameter_name] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -275,13 +276,13 @@ CREATE TABLE [guacamole].[sharing_profile_parameter]( * Foreign keys for the sharing_profile_parameter * table. */ -ALTER TABLE [guacamole].[sharing_profile_parameter] - WITH CHECK ADD CONSTRAINT [FK_sharing_profile_parameter_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [guacamole].[sharing_profile] ([sharing_profile_id]) +ALTER TABLE [guacamole].[guacamole_sharing_profile_parameter] + WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile] FOREIGN KEY([sharing_profile_id]) + REFERENCES [guacamole].[guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[sharing_profile_parameter] - CHECK CONSTRAINT [FK_sharing_profile_parameter_sharing_profile] +ALTER TABLE [guacamole].[guacamole_sharing_profile_parameter] + CHECK CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile] GO /** @@ -290,12 +291,12 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[connection_permission]( +CREATE TABLE [guacamole].[guacamole_connection_permission]( [user_id] [int] NOT NULL, [connection_id] [int] NOT NULL, - [permission] [guacamole].[permission] NOT NULL, + [permission] [guacamole].[guacamole_permission] NOT NULL, - CONSTRAINT [PK_connection_permission] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_connection_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_id] ASC, [permission] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -308,20 +309,20 @@ CREATE TABLE [guacamole].[connection_permission]( /** * Foreign keys for the connection_permission table. */ -ALTER TABLE [guacamole].[connection_permission] - WITH CHECK ADD CONSTRAINT [FK_connection_permission_connection1] FOREIGN KEY([connection_id]) - REFERENCES [guacamole].[connection] ([connection_id]) +ALTER TABLE [guacamole].[guacamole_connection_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_connection1] FOREIGN KEY([connection_id]) + REFERENCES [guacamole].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[connection_permission] - CHECK CONSTRAINT [FK_connection_permission_connection1] -ALTER TABLE [guacamole].[connection_permission] - WITH CHECK ADD CONSTRAINT [FK_connection_permission_user1] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_connection_permission] + CHECK CONSTRAINT [FK_guacamole_connection_permission_connection1] +ALTER TABLE [guacamole].[guacamole_connection_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_user1] FOREIGN KEY([user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[connection_permission] - CHECK CONSTRAINT [FK_connection_permission_user1] +ALTER TABLE [guacamole].[guacamole_connection_permission] + CHECK CONSTRAINT [FK_guacamole_connection_permission_user1] GO /** @@ -330,12 +331,12 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[connection_group_permission]( +CREATE TABLE [guacamole].[guacamole_connection_group_permission]( [user_id] [int] NOT NULL, [connection_group_id] [int] NOT NULL, - [permission] [guacamole].[permission] NOT NULL, + [permission] [guacamole].[guacamole_permission] NOT NULL, - CONSTRAINT [PK_connection_group_permission] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_connection_group_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_group_id] ASC, [permission] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -348,20 +349,20 @@ CREATE TABLE [guacamole].[connection_group_permission]( /** * Foreign keys for the connection_group_permission table. */ -ALTER TABLE [guacamole].[connection_group_permission] - WITH CHECK ADD CONSTRAINT [FK_connection_group_permission_connection_group] FOREIGN KEY([connection_group_id]) - REFERENCES [guacamole].[connection_group] ([connection_group_id]) +ALTER TABLE [guacamole].[guacamole_connection_group_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_connection_group] FOREIGN KEY([connection_group_id]) + REFERENCES [guacamole].[guacamole_connection_group] ([connection_group_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[connection_group_permission] - CHECK CONSTRAINT [FK_connection_group_permission_connection_group] -ALTER TABLE [guacamole].[connection_group_permission] - WITH CHECK ADD CONSTRAINT [FK_connection_group_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_connection_group_permission] + CHECK CONSTRAINT [FK_guacamole_connection_group_permission_connection_group] +ALTER TABLE [guacamole].[guacamole_connection_group_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_user] FOREIGN KEY([user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[connection_group_permission] - CHECK CONSTRAINT [FK_connection_group_permission_user] +ALTER TABLE [guacamole].[guacamole_connection_group_permission] + CHECK CONSTRAINT [FK_guacamole_connection_group_permission_user] GO /** @@ -370,12 +371,12 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[sharing_profile_permission]( +CREATE TABLE [guacamole].[guacamole_sharing_profile_permission]( [user_id] [int] NOT NULL, [sharing_profile_id] [int] NOT NULL, - [permission] [guacamole].[permission] NOT NULL, + [permission] [guacamole].[guacamole_permission] NOT NULL, - CONSTRAINT [PK_sharing_profile_permission] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_sharing_profile_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [sharing_profile_id] ASC, [permission] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -388,20 +389,20 @@ CREATE TABLE [guacamole].[sharing_profile_permission]( /** * Foreign keys for the sharing_profile_permission table. */ -ALTER TABLE [guacamole].[sharing_profile_permission] - WITH CHECK ADD CONSTRAINT [FK_sharing_profile_permission_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [guacamole].[sharing_profile] ([sharing_profile_id]) +ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile] FOREIGN KEY([sharing_profile_id]) + REFERENCES [guacamole].[guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[sharing_profile_permission] - CHECK CONSTRAINT [FK_sharing_profile_permission_sharing_profile] -ALTER TABLE [guacamole].[sharing_profile_permission] - WITH CHECK ADD CONSTRAINT [FK_sharing_profile_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] + CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile] +ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_user] FOREIGN KEY([user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[sharing_profile_permission] - CHECK CONSTRAINT [FK_sharing_profile_permission_user] +ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] + CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_user] GO /** @@ -410,11 +411,11 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[system_permission]( +CREATE TABLE [guacamole].[guacamole_system_permission]( [user_id] [int] NOT NULL, - [permission] [guacamole].[system_permission] NOT NULL, + [permission] [guacamole].[guacamole_system_permission] NOT NULL, - CONSTRAINT [PK_system_permission] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_system_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [permission] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -427,13 +428,13 @@ CREATE TABLE [guacamole].[system_permission]( /** * Foreign keys for system_permission table. */ -ALTER TABLE [guacamole].[system_permission] - WITH CHECK ADD CONSTRAINT [FK_system_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_system_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_system_permission_user] FOREIGN KEY([user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[system_permission] - CHECK CONSTRAINT [FK_system_permission_user] +ALTER TABLE [guacamole].[guacamole_system_permission] + CHECK CONSTRAINT [FK_guacamole_system_permission_user] GO /** @@ -442,12 +443,12 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[user_permission]( +CREATE TABLE [guacamole].[guacamole_user_permission]( [user_id] [int] NOT NULL, [affected_user_id] [int] NOT NULL, - [permission] [guacamole].[permission] NOT NULL, + [permission] [guacamole].[guacamole_permission] NOT NULL, - CONSTRAINT [PK_user_permission] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_user_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [affected_user_id] ASC, [permission] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -460,18 +461,18 @@ CREATE TABLE [guacamole].[user_permission]( /** * Foreign keys for user_permission table. */ -ALTER TABLE [guacamole].[user_permission] - WITH CHECK ADD CONSTRAINT [FK_user_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_user_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user] FOREIGN KEY([user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[user_permission] - CHECK CONSTRAINT [FK_user_permission_user] -ALTER TABLE [guacamole].[user_permission] - WITH CHECK ADD CONSTRAINT [FK_user_permission_user1] FOREIGN KEY([affected_user_id]) - REFERENCES [guacamole].[user] ([user_id]) -ALTER TABLE [guacamole].[user_permission] - CHECK CONSTRAINT [FK_user_permission_user1] +ALTER TABLE [guacamole].[guacamole_user_permission] + CHECK CONSTRAINT [FK_guacamole_user_permission_user] +ALTER TABLE [guacamole].[guacamole_user_permission] + WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user1] FOREIGN KEY([affected_user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_user_permission] + CHECK CONSTRAINT [FK_guacamole_user_permission_user1] GO /** @@ -480,7 +481,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[connection_history]( +CREATE TABLE [guacamole].[guacamole_connection_history]( [history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NULL, [username] [nvarchar](128) NOT NULL, @@ -492,7 +493,7 @@ CREATE TABLE [guacamole].[connection_history]( [start_date] [datetime] NOT NULL, [end_date] [datetime] NULL, - CONSTRAINT [PK_connection_history] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_connection_history] PRIMARY KEY CLUSTERED ([history_id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -505,25 +506,25 @@ CREATE TABLE [guacamole].[connection_history]( /** * Foreign keys for connection_history table */ -ALTER TABLE [guacamole].[connection_history] - WITH CHECK ADD CONSTRAINT [FK_connection_history_connection] FOREIGN KEY([connection_id]) - REFERENCES [guacamole].[connection] ([connection_id]) +ALTER TABLE [guacamole].[guacamole_connection_history] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_connection] FOREIGN KEY([connection_id]) + REFERENCES [guacamole].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE SET NULL -ALTER TABLE [guacamole].[connection_history] - CHECK CONSTRAINT [FK_connection_history_connection] -ALTER TABLE [guacamole].[connection_history] - WITH CHECK ADD CONSTRAINT [FK_connection_history_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [guacamole].[sharing_profile] ([sharing_profile_id]) -ALTER TABLE [guacamole].[connection_history] - CHECK CONSTRAINT [FK_connection_history_sharing_profile] -ALTER TABLE [guacamole].[connection_history] - WITH CHECK ADD CONSTRAINT [FK_connection_history_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_connection_history] + CHECK CONSTRAINT [FK_guacamole_connection_history_connection] +ALTER TABLE [guacamole].[guacamole_connection_history] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_sharing_profile] FOREIGN KEY([sharing_profile_id]) + REFERENCES [guacamole].[guacamole_sharing_profile] ([sharing_profile_id]) +ALTER TABLE [guacamole].[guacamole_connection_history] + CHECK CONSTRAINT [FK_guacamole_connection_history_sharing_profile] +ALTER TABLE [guacamole].[guacamole_connection_history] + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_user] FOREIGN KEY([user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE SET NULL -ALTER TABLE [guacamole].[connection_history] - CHECK CONSTRAINT [FK_connection_history_user] +ALTER TABLE [guacamole].[guacamole_connection_history] + CHECK CONSTRAINT [FK_guacamole_connection_history_user] GO /** @@ -533,14 +534,14 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[user_password_history]( +CREATE TABLE [guacamole].[guacamole_user_password_history]( [password_history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NOT NULL, [password_hash] [binary](32) NOT NULL, [password_salt] [binary](32) NULL, [password_date] [datetime] NOT NULL, - CONSTRAINT [PK_user_password_history] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_guacamole_user_password_history] PRIMARY KEY CLUSTERED ([password_history_id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, @@ -553,11 +554,11 @@ CREATE TABLE [guacamole].[user_password_history]( /** * Foreign keys for user_password_history table */ -ALTER TABLE [guacamole].[user_password_history] - WITH CHECK ADD CONSTRAINT [FK_user_password_history_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[user] ([user_id]) +ALTER TABLE [guacamole].[guacamole_user_password_history] + WITH CHECK ADD CONSTRAINT [FK_guacamole_user_password_history_user] FOREIGN KEY([user_id]) + REFERENCES [guacamole].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[user_password_history] - CHECK CONSTRAINT [FK_user_password_history_user] +ALTER TABLE [guacamole].[guacamole_user_password_history] + CHECK CONSTRAINT [FK_guacamole_user_password_history_user] GO 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 index f71d2837d..fa807b26f 100644 --- 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 @@ -20,18 +20,18 @@ /** * Create the default admin user account and set up full privileges. */ -INSERT INTO [guacamole].[user] (username, password_hash, password_date) +INSERT INTO [guacamole].[guacamole_user] (username, password_hash, password_date) VALUES ('guacadmin', HASHBYTES('SHA2_256', 'guacadmin'), getdate()); -INSERT INTO [guacamole].[user_permission] -SELECT [guacamole].[user].[user_id], [affected].[user_id], permission +INSERT INTO [guacamole].[guacamole_user_permission] +SELECT [guacamole].[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; + JOIN [guacamole].[guacamole_user] ON permissions.username = [guacamole].[guacamole_user].[username] + JOIN [guacamole].[guacamole_user] affected ON permissions.affected_username = affected.username; INSERT INTO [guacamole].[system_permission] SELECT user_id, permission @@ -42,5 +42,5 @@ FROM ( 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]; + JOIN [guacamole].[guacamole_user] ON permissions.username = [guacamole].[guacamole_user].[username]; GO From 66c4b86b0aeb3550fe39489b57d8862d51486b8e Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Sun, 27 Aug 2017 16:08:33 -0400 Subject: [PATCH 69/94] GUACAMOLE-363: Standardize table names with other JDBC modules; switch back to dbo schema for now. --- .../schema/001-create-schema.sql | 172 +++++++++--------- .../schema/002-create-admin-user.sql | 14 +- .../auth/jdbc/connection/ConnectionMapper.xml | 38 ++-- .../connection/ConnectionParameterMapper.xml | 6 +- .../connection/ConnectionRecordMapper.xml | 110 +++++------ .../connectiongroup/ConnectionGroupMapper.xml | 46 ++--- .../ConnectionGroupPermissionMapper.xml | 30 +-- .../permission/ConnectionPermissionMapper.xml | 30 +-- .../SharingProfilePermissionMapper.xml | 30 +-- .../permission/SystemPermissionMapper.xml | 26 +-- .../jdbc/permission/UserPermissionMapper.xml | 52 +++--- .../sharingprofile/SharingProfileMapper.xml | 24 +-- .../SharingProfileParameterMapper.xml | 6 +- .../auth/jdbc/user/PasswordRecordMapper.xml | 22 +-- .../guacamole/auth/jdbc/user/UserMapper.xml | 26 +-- 15 files changed, 316 insertions(+), 316 deletions(-) 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 index 44e498e3f..92525dd02 100644 --- 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 @@ -20,13 +20,13 @@ /** * Create the guacamole schema. */ -CREATE SCHEMA [guacamole] +CREATE SCHEMA [dbo] GO /** * List for permission data type. */ -CREATE RULE [guacamole].[guacamole_permission_list] +CREATE RULE [dbo].[guacamole_permission_list] AS @list IN ('READ','UPDATE','DELETE','ADMINISTER') GO @@ -34,7 +34,7 @@ GO /** * List for system permission data type. */ -CREATE RULE [guacamole].[guacamole_system_permission_list] +CREATE RULE [dbo].[guacamole_system_permission_list] AS @list IN ('CREATE_CONNECTION', 'CREATE_CONNECTION_GROUP', @@ -46,12 +46,12 @@ GO /** * The permission data type. */ -CREATE TYPE [guacamole].[guacamole_permission] FROM [nvarchar](10) NOT NULL +CREATE TYPE [dbo].[guacamole_permission] FROM [nvarchar](10) NOT NULL /** * The system permission data type. */ -CREATE TYPE [guacamole].[guacamole_system_permission] FROM [nvarchar](32) NOT NULL +CREATE TYPE [dbo].[guacamole_system_permission] FROM [nvarchar](32) NOT NULL GO /** @@ -59,7 +59,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_connection_group]( +CREATE TABLE [dbo].[guacamole_connection_group]( [connection_group_id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NULL, [connection_group_name] [nvarchar](128) NOT NULL, @@ -81,23 +81,23 @@ CREATE TABLE [guacamole].[guacamole_connection_group]( /** * Foreign keys for connection_group table. */ -ALTER TABLE [guacamole].[guacamole_connection_group] +ALTER TABLE [dbo].[guacamole_connection_group] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_connection_group_id] FOREIGN KEY([parent_id]) - REFERENCES [guacamole].[guacamole_connection_group] ([connection_group_id]) -ALTER TABLE [guacamole].[guacamole_connection_group] + REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]) +ALTER TABLE [dbo].[guacamole_connection_group] CHECK CONSTRAINT [FK_guacamole_connection_group_connection_group_id] -ALTER TABLE [guacamole].[guacamole_connection_group] +ALTER TABLE [dbo].[guacamole_connection_group] WITH CHECK ADD CONSTRAINT [CK_guacamole_connection_group_type] CHECK (([type]='BALANCING' OR [type]='ORGANIZATIONAL')) -ALTER TABLE [guacamole].[guacamole_connection_group] +ALTER TABLE [dbo].[guacamole_connection_group] CHECK CONSTRAINT [CK_guacamole_connection_group_type] /** * Default values for connection_group table. */ -ALTER TABLE [guacamole].[guacamole_connection_group] +ALTER TABLE [dbo].[guacamole_connection_group] ADD CONSTRAINT [DF_guacamole_connection_group_type] DEFAULT (N'ORGANIZATIONAL') FOR [type] -ALTER TABLE [guacamole].[guacamole_connection_group] +ALTER TABLE [dbo].[guacamole_connection_group] ADD CONSTRAINT [DF_guacamole_connection_group_enable_session_affinity] DEFAULT ((0)) FOR [enable_session_affinity] GO @@ -106,7 +106,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_connection]( +CREATE TABLE [dbo].[guacamole_connection]( [connection_id] [int] IDENTITY(1,1) NOT NULL, [connection_name] [nvarchar](128) NOT NULL, [parent_id] [int] NULL, @@ -129,17 +129,17 @@ CREATE TABLE [guacamole].[guacamole_connection]( ON [PRIMARY] ) ON [PRIMARY] -ALTER TABLE [guacamole].[guacamole_connection] +ALTER TABLE [dbo].[guacamole_connection] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_connection_group] FOREIGN KEY([parent_id]) -REFERENCES [guacamole].[guacamole_connection_group] ([connection_group_id]) -ALTER TABLE [guacamole].[guacamole_connection] +REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]) +ALTER TABLE [dbo].[guacamole_connection] CHECK CONSTRAINT [FK_guacamole_connection_connection_group] -ALTER TABLE [guacamole].[guacamole_connection] +ALTER TABLE [dbo].[guacamole_connection] WITH CHECK ADD CONSTRAINT [CK_proxy_encryption_method] CHECK (([proxy_encryption_method]='SSL' OR [proxy_encryption_method]='NONE')) -ALTER TABLE [guacamole].[guacamole_connection] +ALTER TABLE [dbo].[guacamole_connection] CHECK CONSTRAINT [CK_proxy_encryption_method] -ALTER TABLE [guacamole].[guacamole_connection] +ALTER TABLE [dbo].[guacamole_connection] ADD CONSTRAINT [DF_guacamole_connection_failover_only] DEFAULT ((0)) FOR [failover_only] GO @@ -148,7 +148,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_user]( +CREATE TABLE [dbo].[guacamole_user]( [user_id] [int] IDENTITY(1,1) NOT NULL, [username] [nvarchar](128) NOT NULL, [password_hash] [binary](32) NOT NULL, @@ -179,9 +179,9 @@ CREATE TABLE [guacamole].[guacamole_user]( /** * Defaults for user table */ -ALTER TABLE [guacamole].[guacamole_user] +ALTER TABLE [dbo].[guacamole_user] ADD CONSTRAINT [DF_guacamole_user_disabled] DEFAULT ((0)) FOR [disabled] -ALTER TABLE [guacamole].[guacamole_user] +ALTER TABLE [dbo].[guacamole_user] ADD CONSTRAINT [DF_guacamole_user_expired] DEFAULT ((0)) FOR [expired] GO @@ -191,7 +191,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_sharing_profile]( +CREATE TABLE [dbo].[guacamole_sharing_profile]( [sharing_profile_id] [int] IDENTITY(1,1) NOT NULL, [sharing_profile_name] [nvarchar](128) NOT NULL, [primary_connection_id] [int] NOT NULL, @@ -209,12 +209,12 @@ CREATE TABLE [guacamole].[guacamole_sharing_profile]( /** * Foreign keys for sharing_profile table. */ -ALTER TABLE [guacamole].[guacamole_sharing_profile] +ALTER TABLE [dbo].[guacamole_sharing_profile] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_connection] FOREIGN KEY([primary_connection_id]) - REFERENCES [guacamole].[guacamole_connection] ([connection_id]) + REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_sharing_profile] +ALTER TABLE [dbo].[guacamole_sharing_profile] CHECK CONSTRAINT [FK_guacamole_sharing_profile_connection] GO @@ -224,7 +224,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_connection_parameter]( +CREATE TABLE [dbo].[guacamole_connection_parameter]( [connection_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](max) NOT NULL, @@ -242,12 +242,12 @@ CREATE TABLE [guacamole].[guacamole_connection_parameter]( /** * Foreign keys for the connection_parameter table. */ -ALTER TABLE [guacamole].[guacamole_connection_parameter] +ALTER TABLE [dbo].[guacamole_connection_parameter] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_parameter_connection] FOREIGN KEY([connection_id]) - REFERENCES [guacamole].[guacamole_connection] ([connection_id]) + REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_connection_parameter] +ALTER TABLE [dbo].[guacamole_connection_parameter] CHECK CONSTRAINT [FK_guacamole_connection_parameter_connection] GO @@ -257,7 +257,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_sharing_profile_parameter]( +CREATE TABLE [dbo].[guacamole_sharing_profile_parameter]( [sharing_profile_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](max) NOT NULL, @@ -276,12 +276,12 @@ CREATE TABLE [guacamole].[guacamole_sharing_profile_parameter]( * Foreign keys for the sharing_profile_parameter * table. */ -ALTER TABLE [guacamole].[guacamole_sharing_profile_parameter] +ALTER TABLE [dbo].[guacamole_sharing_profile_parameter] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [guacamole].[guacamole_sharing_profile] ([sharing_profile_id]) + REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_sharing_profile_parameter] +ALTER TABLE [dbo].[guacamole_sharing_profile_parameter] CHECK CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile] GO @@ -291,10 +291,10 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_connection_permission]( +CREATE TABLE [dbo].[guacamole_connection_permission]( [user_id] [int] NOT NULL, [connection_id] [int] NOT NULL, - [permission] [guacamole].[guacamole_permission] NOT NULL, + [permission] [dbo].[guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_id] ASC, [permission] ASC) @@ -309,19 +309,19 @@ CREATE TABLE [guacamole].[guacamole_connection_permission]( /** * Foreign keys for the connection_permission table. */ -ALTER TABLE [guacamole].[guacamole_connection_permission] +ALTER TABLE [dbo].[guacamole_connection_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_connection1] FOREIGN KEY([connection_id]) - REFERENCES [guacamole].[guacamole_connection] ([connection_id]) + REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_connection_permission] +ALTER TABLE [dbo].[guacamole_connection_permission] CHECK CONSTRAINT [FK_guacamole_connection_permission_connection1] -ALTER TABLE [guacamole].[guacamole_connection_permission] +ALTER TABLE [dbo].[guacamole_connection_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_user1] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_connection_permission] +ALTER TABLE [dbo].[guacamole_connection_permission] CHECK CONSTRAINT [FK_guacamole_connection_permission_user1] GO @@ -331,10 +331,10 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_connection_group_permission]( +CREATE TABLE [dbo].[guacamole_connection_group_permission]( [user_id] [int] NOT NULL, [connection_group_id] [int] NOT NULL, - [permission] [guacamole].[guacamole_permission] NOT NULL, + [permission] [dbo].[guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_group_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_group_id] ASC, [permission] ASC) @@ -349,19 +349,19 @@ CREATE TABLE [guacamole].[guacamole_connection_group_permission]( /** * Foreign keys for the connection_group_permission table. */ -ALTER TABLE [guacamole].[guacamole_connection_group_permission] +ALTER TABLE [dbo].[guacamole_connection_group_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_connection_group] FOREIGN KEY([connection_group_id]) - REFERENCES [guacamole].[guacamole_connection_group] ([connection_group_id]) + REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_connection_group_permission] +ALTER TABLE [dbo].[guacamole_connection_group_permission] CHECK CONSTRAINT [FK_guacamole_connection_group_permission_connection_group] -ALTER TABLE [guacamole].[guacamole_connection_group_permission] +ALTER TABLE [dbo].[guacamole_connection_group_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_connection_group_permission] +ALTER TABLE [dbo].[guacamole_connection_group_permission] CHECK CONSTRAINT [FK_guacamole_connection_group_permission_user] GO @@ -371,10 +371,10 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_sharing_profile_permission]( +CREATE TABLE [dbo].[guacamole_sharing_profile_permission]( [user_id] [int] NOT NULL, [sharing_profile_id] [int] NOT NULL, - [permission] [guacamole].[guacamole_permission] NOT NULL, + [permission] [dbo].[guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [sharing_profile_id] ASC, [permission] ASC) @@ -389,19 +389,19 @@ CREATE TABLE [guacamole].[guacamole_sharing_profile_permission]( /** * Foreign keys for the sharing_profile_permission table. */ -ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] +ALTER TABLE [dbo].[guacamole_sharing_profile_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [guacamole].[guacamole_sharing_profile] ([sharing_profile_id]) + REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] +ALTER TABLE [dbo].[guacamole_sharing_profile_permission] CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile] -ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] +ALTER TABLE [dbo].[guacamole_sharing_profile_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_sharing_profile_permission] +ALTER TABLE [dbo].[guacamole_sharing_profile_permission] CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_user] GO @@ -411,9 +411,9 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_system_permission]( +CREATE TABLE [dbo].[guacamole_system_permission]( [user_id] [int] NOT NULL, - [permission] [guacamole].[guacamole_system_permission] NOT NULL, + [permission] [dbo].[guacamole_system_permission] NOT NULL, CONSTRAINT [PK_guacamole_system_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [permission] ASC) @@ -428,12 +428,12 @@ CREATE TABLE [guacamole].[guacamole_system_permission]( /** * Foreign keys for system_permission table. */ -ALTER TABLE [guacamole].[guacamole_system_permission] +ALTER TABLE [dbo].[guacamole_system_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_system_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_system_permission] +ALTER TABLE [dbo].[guacamole_system_permission] CHECK CONSTRAINT [FK_guacamole_system_permission_user] GO @@ -443,10 +443,10 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_user_permission]( +CREATE TABLE [dbo].[guacamole_user_permission]( [user_id] [int] NOT NULL, [affected_user_id] [int] NOT NULL, - [permission] [guacamole].[guacamole_permission] NOT NULL, + [permission] [dbo].[guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_user_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [affected_user_id] ASC, [permission] ASC) @@ -461,17 +461,17 @@ CREATE TABLE [guacamole].[guacamole_user_permission]( /** * Foreign keys for user_permission table. */ -ALTER TABLE [guacamole].[guacamole_user_permission] +ALTER TABLE [dbo].[guacamole_user_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_user_permission] +ALTER TABLE [dbo].[guacamole_user_permission] CHECK CONSTRAINT [FK_guacamole_user_permission_user] -ALTER TABLE [guacamole].[guacamole_user_permission] +ALTER TABLE [dbo].[guacamole_user_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user1] FOREIGN KEY([affected_user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) -ALTER TABLE [guacamole].[guacamole_user_permission] + REFERENCES [dbo].[guacamole_user] ([user_id]) +ALTER TABLE [dbo].[guacamole_user_permission] CHECK CONSTRAINT [FK_guacamole_user_permission_user1] GO @@ -481,7 +481,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_connection_history]( +CREATE TABLE [dbo].[guacamole_connection_history]( [history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NULL, [username] [nvarchar](128) NOT NULL, @@ -506,24 +506,24 @@ CREATE TABLE [guacamole].[guacamole_connection_history]( /** * Foreign keys for connection_history table */ -ALTER TABLE [guacamole].[guacamole_connection_history] +ALTER TABLE [dbo].[guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_connection] FOREIGN KEY([connection_id]) - REFERENCES [guacamole].[guacamole_connection] ([connection_id]) + REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE SET NULL -ALTER TABLE [guacamole].[guacamole_connection_history] +ALTER TABLE [dbo].[guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_connection] -ALTER TABLE [guacamole].[guacamole_connection_history] +ALTER TABLE [dbo].[guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [guacamole].[guacamole_sharing_profile] ([sharing_profile_id]) -ALTER TABLE [guacamole].[guacamole_connection_history] + REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) +ALTER TABLE [dbo].[guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_sharing_profile] -ALTER TABLE [guacamole].[guacamole_connection_history] +ALTER TABLE [dbo].[guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE SET NULL -ALTER TABLE [guacamole].[guacamole_connection_history] +ALTER TABLE [dbo].[guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_user] GO @@ -534,7 +534,7 @@ GO */ SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON -CREATE TABLE [guacamole].[guacamole_user_password_history]( +CREATE TABLE [dbo].[guacamole_user_password_history]( [password_history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NOT NULL, [password_hash] [binary](32) NOT NULL, @@ -554,11 +554,11 @@ CREATE TABLE [guacamole].[guacamole_user_password_history]( /** * Foreign keys for user_password_history table */ -ALTER TABLE [guacamole].[guacamole_user_password_history] +ALTER TABLE [dbo].[guacamole_user_password_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_password_history_user] FOREIGN KEY([user_id]) - REFERENCES [guacamole].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE -ALTER TABLE [guacamole].[guacamole_user_password_history] +ALTER TABLE [dbo].[guacamole_user_password_history] CHECK CONSTRAINT [FK_guacamole_user_password_history_user] GO 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 index fa807b26f..408d7cafd 100644 --- 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 @@ -20,20 +20,20 @@ /** * Create the default admin user account and set up full privileges. */ -INSERT INTO [guacamole].[guacamole_user] (username, password_hash, password_date) +INSERT INTO [dbo].[guacamole_user] (username, password_hash, password_date) VALUES ('guacadmin', HASHBYTES('SHA2_256', 'guacadmin'), getdate()); -INSERT INTO [guacamole].[guacamole_user_permission] -SELECT [guacamole].[guacamole_user].[user_id], [affected].[user_id], permission +INSERT INTO [dbo].[guacamole_user_permission] +SELECT [dbo].[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].[guacamole_user] ON permissions.username = [guacamole].[guacamole_user].[username] - JOIN [guacamole].[guacamole_user] affected ON permissions.affected_username = affected.username; + JOIN [dbo].[guacamole_user] ON permissions.username = [dbo].[guacamole_user].[username] + JOIN [dbo].[guacamole_user] affected ON permissions.affected_username = affected.username; -INSERT INTO [guacamole].[system_permission] +INSERT INTO [dbo].[system_permission] SELECT user_id, permission FROM ( SELECT 'guacadmin' AS username, 'CREATE_CONNECTION' AS permission @@ -42,5 +42,5 @@ FROM ( UNION SELECT 'guacadmin' AS username, 'CREATE_USER' AS permission UNION SELECT 'guacadmin' AS username, 'ADMINISTER' AS permission) permissions - JOIN [guacamole].[guacamole_user] ON permissions.username = [guacamole].[guacamole_user].[username]; + JOIN [dbo].[guacamole_user] ON permissions.username = [dbo].[guacamole_user].[username]; GO 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 index 24008fcc4..c62ca6f36 100644 --- 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 @@ -51,13 +51,13 @@ SELECT connection_id - FROM [guacamole].[connection] + FROM [dbo].[guacamole_connection] WHERE parent_id = #{parentIdentifier,jdbcType=INTEGER} parent_id IS NULL @@ -74,9 +74,9 @@ - DELETE FROM [guacamole].[connection_parameter] + DELETE FROM [dbo].[guacamole_connection_parameter] WHERE connection_id = #{identifier,jdbcType=INTEGER} - INSERT INTO [guacamole].[connection_parameter] ( + INSERT INTO [dbo].[guacamole_connection_parameter] ( connection_id, parameter_name, parameter_value 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 index 2b873bb9a..648d16f60 100644 --- 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 @@ -40,28 +40,28 @@ - INSERT INTO [guacamole].[connection_history] ( + INSERT INTO [dbo].[guacamole_connection_history] ( connection_id, connection_name, remote_host, @@ -78,7 +78,7 @@ #{record.remoteHost,jdbcType=VARCHAR}, #{record.sharingProfileIdentifier,jdbcType=INTEGER}, #{record.sharingProfileName,jdbcType=VARCHAR}, - (SELECT user_id FROM [guacamole].[user] + (SELECT user_id FROM [dbo].[guacamole_user] WHERE username = #{record.username,jdbcType=VARCHAR}), #{record.username,jdbcType=VARCHAR}, #{record.startDate,jdbcType=TIMESTAMP}, @@ -91,31 +91,31 @@ SELECT TOP (#{limit,jdbcType=INTEGER}) - [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 + [dbo].[guacamole_connection_history].connection_id, + [dbo].[guacamole_connection_history].connection_name, + [dbo].[guacamole_connection_history].remote_host, + [dbo].[guacamole_connection_history].sharing_profile_id, + [dbo].[guacamole_connection_history].sharing_profile_name, + [dbo].[guacamole_connection_history].user_id, + [dbo].[guacamole_connection_history].username, + [dbo].[guacamole_connection_history].start_date, + [dbo].[guacamole_connection_history].end_date + FROM [dbo].[guacamole_connection_history] + LEFT JOIN [dbo].[guacamole_connection] ON [dbo].[guacamole_connection_history].connection_id = [dbo].[guacamole_connection].connection_id + LEFT JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_connection_history].user_id = [dbo].[guacamole_user].user_id - 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' + JOIN [dbo].[guacamole_connection_permission] ON + [dbo].[guacamole_connection_history].connection_id = [dbo].[guacamole_connection_permission].connection_id + AND [dbo].[guacamole_connection_permission].user_id = #{user.objectID,jdbcType=INTEGER} + AND [dbo].[guacamole_connection_permission].permission = 'READ' - 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' + JOIN [dbo].[guacamole_user_permission] ON + [dbo].[guacamole_connection_history].user_id = [dbo].[guacamole_user_permission].affected_user_id + AND [dbo].[guacamole_user_permission].user_id = #{user.objectID,jdbcType=INTEGER} + AND [dbo].[guacamole_user_permission].permission = 'READ' ( - [guacamole].[connection_history].user_id IN ( + [dbo].[guacamole_connection_history].user_id IN ( SELECT user_id - FROM [guacamole].[user] + FROM [dbo].[guacamole_user] WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0 ) - OR [guacamole].[connection_history].connection_id IN ( + OR [dbo].[guacamole_connection_history].connection_id IN ( SELECT connection_id - FROM [guacamole].[connection] + FROM [dbo].[guacamole_connection] WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0 ) @@ -201,7 +201,7 @@ - [guacamole].[connection_history].start_date + [dbo].[guacamole_connection_history].start_date 1 DESC diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml index 47a3e63d5..d1f97a738 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml @@ -53,13 +53,13 @@ SELECT connection_group_id - FROM [guacamole].[connection_group] + FROM [dbo].[guacamole_connection_group] WHERE parent_id = #{parentIdentifier,jdbcType=INTEGER} parent_id IS NULL @@ -76,9 +76,9 @@ SELECT - [guacamole].[connection_group_permission].user_id, + [dbo].[guacamole_connection_group_permission].user_id, username, permission, connection_group_id - FROM [guacamole].[connection_group_permission] - JOIN [guacamole].[user] ON [guacamole].[connection_group_permission].user_id = [guacamole].[user].user_id - WHERE [guacamole].[connection_group_permission].user_id = #{user.objectID,jdbcType=INTEGER} + FROM [dbo].[guacamole_connection_group_permission] + JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_connection_group_permission].user_id = [dbo].[guacamole_user].user_id + WHERE [dbo].[guacamole_connection_group_permission].user_id = #{user.objectID,jdbcType=INTEGER} @@ -50,14 +50,14 @@ SELECT DISTINCT connection_group_id - FROM [guacamole].[connection_group_permission] + FROM [dbo].[guacamole_connection_group_permission] WHERE user_id = #{user.objectID,jdbcType=INTEGER} AND connection_group_id IN @@ -86,7 +86,7 @@ - DELETE FROM [guacamole].[connection_group_permission] + DELETE FROM [dbo].[guacamole_connection_group_permission] WHERE (user_id, permission, connection_group_id) IN @@ -100,7 +100,7 @@ - INSERT INTO [guacamole].[connection_group_permission] ( + INSERT INTO [dbo].[guacamole_connection_group_permission] ( user_id, permission, connection_group_id @@ -117,10 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_group_id AS permissions - WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[connection_group_permission] - WHERE [guacamole].[connection_group_permission].user_id = permissions.user_id AND - [guacamole].[connection_group_permission].permission = permissions.permission AND - [guacamole].[connection_group_permission].connection_group_id = permissions.connection_group_id + WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_connection_group_permission] + WHERE [dbo].[guacamole_connection_group_permission].user_id = permissions.user_id AND + [dbo].[guacamole_connection_group_permission].permission = permissions.permission AND + [dbo].[guacamole_connection_group_permission].connection_group_id = permissions.connection_group_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml index 08e875ccb..fa25f637e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml @@ -36,13 +36,13 @@ @@ -50,14 +50,14 @@ SELECT DISTINCT connection_id - FROM [guacamole].[connection_permission] + FROM [dbo].[guacamole_connection_permission] WHERE user_id = #{user.objectID,jdbcType=INTEGER} AND connection_id IN @@ -86,7 +86,7 @@ - DELETE FROM [guacamole].[connection_permission] + DELETE FROM [dbo].[guacamole_connection_permission] WHERE @@ -100,7 +100,7 @@ - INSERT INTO [guacamole].[connection_permission] ( + INSERT INTO [dbo].[guacamole_connection_permission] ( user_id, permission, connection_id @@ -117,10 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_id AS permissions - WHERE NOT EXISTS ( SELECT 1 FROM [guacamole].[connection_permission] - WHERE [guacamole].[connection_permission].user_id = permissions.user_id AND - [guacamole].[connection_permission].permission = permissions.permission AND - [guacamole].[connection_permission].connection_id = permissions.connection_id + WHERE NOT EXISTS ( SELECT 1 FROM [dbo].[guacamole_connection_permission] + WHERE [dbo].[guacamole_connection_permission].user_id = permissions.user_id AND + [dbo].[guacamole_connection_permission].permission = permissions.permission AND + [dbo].[guacamole_connection_permission].connection_id = permissions.connection_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml index 354dfb594..40e9907c4 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml @@ -36,13 +36,13 @@ @@ -50,14 +50,14 @@ SELECT DISTINCT sharing_profile_id - FROM [guacamole].[sharing_profile_permission] + FROM [dbo].[guacamole_sharing_profile_permission] WHERE user_id = #{user.objectID,jdbcType=INTEGER} AND sharing_profile_id IN @@ -86,7 +86,7 @@ - DELETE FROM [guacamole].[sharing_profile_permission] + DELETE FROM [dbo].[guacamole_sharing_profile_permission] WHERE @@ -100,7 +100,7 @@ - INSERT INTO [guacamole].[sharing_profile_permission] ( + INSERT INTO [dbo].[guacamole_sharing_profile_permission] ( user_id, permission, sharing_profile_id @@ -117,10 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS sharing_profile_id AS permissions - WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[sharing_profile_permission] - WHERE [guacamole].[sharing_profile_permission].user_id = permissions.user_id - AND [guacamole].[sharing_profile_permission].permission = permissions.permission - AND [guacamole].[sharing_profile_permission].sharing_profile_id = permissions.sharing_profile_id + WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_sharing_profile_permission] + WHERE [dbo].[guacamole_sharing_profile_permission].user_id = permissions.user_id + AND [dbo].[guacamole_sharing_profile_permission].permission = permissions.permission + AND [dbo].[guacamole_sharing_profile_permission].sharing_profile_id = permissions.sharing_profile_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml index 048877922..d33dd3b65 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml @@ -35,12 +35,12 @@ @@ -48,13 +48,13 @@ @@ -62,7 +62,7 @@ - DELETE FROM [guacamole].[system_permission] + DELETE FROM [dbo].[guacamole_system_permission] WHERE @@ -75,7 +75,7 @@ - INSERT INTO [guacamole].[system_permission] ( + INSERT INTO [dbo].[guacamole_system_permission] ( user_id, permission ) @@ -89,9 +89,9 @@ #{permission.type,jdbcType=VARCHAR} AS permission AS permissions - WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[system_permission] - WHERE [guacamole].[system_permission].user_id = permissions.user_id - AND [guacamole].[system_permission].permission = permissions.permission + WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_system_permission] + WHERE [dbo].[guacamole_system_permission].user_id = permissions.user_id + AND [dbo].[guacamole_system_permission].permission = permissions.permission ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml index 606719dcf..a2d416fe6 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml @@ -36,14 +36,14 @@ @@ -51,15 +51,15 @@ SELECT DISTINCT username - FROM [guacamole].[user_permission] - JOIN [guacamole].[user] ON [guacamole].[user_permission].affected_user_id = [guacamole].[user].user_id + FROM [dbo].[guacamole_user_permission] + JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_user_permission].affected_user_id = [dbo].[guacamole_user].user_id WHERE - [guacamole].[user_permission].user_id = #{user.objectID,jdbcType=INTEGER} + [dbo].[guacamole_user_permission].user_id = #{user.objectID,jdbcType=INTEGER} AND username IN @@ -89,11 +89,11 @@ - DELETE FROM [guacamole].[user_permission] - USING [guacamole].[user] affected + DELETE FROM [dbo].[guacamole_user_permission] + USING [dbo].[guacamole_user] affected WHERE - [guacamole].[user_permission].affected_user_id = affected.user_id - AND ([guacamole].[user_permission].user_id, permission, affected.username) IN + [dbo].[guacamole_user_permission].affected_user_id = affected.user_id + AND ([dbo].[guacamole_user_permission].user_id, permission, affected.username) IN (#{permission.userID,jdbcType=INTEGER}, @@ -106,7 +106,7 @@ - INSERT INTO [guacamole].[user_permission] ( + INSERT INTO [dbo].[guacamole_user_permission] ( user_id, permission, affected_user_id @@ -114,7 +114,7 @@ SELECT DISTINCT permissions.user_id, permissions.permission, - [guacamole].[user].user_id + [dbo].[guacamole_user].user_id FROM @@ -123,11 +123,11 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS username AS permissions - JOIN [guacamole].[user] ON [guacamole].[user].username = permissions.username - WHERE NOT EXISTS (SELECT 1 FROM [guacamole].[user_permission] - WHERE [guacamole].[user_permission].user_id = permissions.user_id - AND [guacamole].[user_permission].permission = permissions.permission - AND [guacamole].[user_permission].affected_user_id = [guacamole].[user].user_id + JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_user].username = permissions.username + WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_user_permission] + WHERE [dbo].[guacamole_user_permission].user_id = permissions.user_id + AND [dbo].[guacamole_user_permission].permission = permissions.permission + AND [dbo].[guacamole_user_permission].affected_user_id = [dbo].[guacamole_user].user_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml index 9d7d45abd..d3b5c10e4 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml @@ -33,13 +33,13 @@ SELECT - [guacamole].[sharing_profile].sharing_profile_id, - [guacamole].[sharing_profile].sharing_profile_name, + [dbo].[guacamole_sharing_profile].sharing_profile_id, + [dbo].[guacamole_sharing_profile].sharing_profile_name, primary_connection_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 [guacamole].[sharing_profile].sharing_profile_id IN + FROM [dbo].[guacamole_sharing_profile] + JOIN [dbo].[guacamole_sharing_profile_permission] ON [dbo].[guacamole_sharing_profile_permission].sharing_profile_id = [dbo].[guacamole_sharing_profile].sharing_profile_id + WHERE [dbo].[guacamole_sharing_profile].sharing_profile_id IN #{identifier,jdbcType=INTEGER} @@ -87,7 +87,7 @@ sharing_profile_id, sharing_profile_name, primary_connection_id - FROM [guacamole].[sharing_profile] + FROM [dbo].[guacamole_sharing_profile] WHERE primary_connection_id = #{parentIdentifier,jdbcType=INTEGER} AND sharing_profile_name = #{name,jdbcType=VARCHAR} @@ -96,7 +96,7 @@ - DELETE FROM [guacamole].[sharing_profile] + DELETE FROM [dbo].[guacamole_sharing_profile] WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} @@ -104,7 +104,7 @@ - INSERT INTO [guacamole].[sharing_profile] ( + INSERT INTO [dbo].[guacamole_sharing_profile] ( sharing_profile_name, primary_connection_id ) @@ -117,7 +117,7 @@ - UPDATE [guacamole].[sharing_profile] + UPDATE [dbo].[guacamole_sharing_profile] SET sharing_profile_name = #{object.name,jdbcType=VARCHAR}, primary_connection_id = #{object.parentIdentifier,jdbcType=INTEGER} WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml index 8f4a3fa10..c90227678 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml @@ -36,21 +36,21 @@ sharing_profile_id, parameter_name, parameter_value - FROM [guacamole].[sharing_profile_parameter] + FROM [dbo].[guacamole_sharing_profile_parameter] WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} - DELETE FROM [guacamole].[sharing_profile_parameter] + DELETE FROM [dbo].[guacamole_sharing_profile_parameter] WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} - INSERT INTO [guacamole].[sharing_profile_parameter] ( + INSERT INTO [dbo].[guacamole_sharing_profile_parameter] ( sharing_profile_id, parameter_name, parameter_value diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml index 9ad67a6f3..a9f44e637 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml @@ -35,16 +35,16 @@ @@ -52,7 +52,7 @@ - INSERT INTO [guacamole].[user_password_history] ( + INSERT INTO [dbo].[guacamole_user_password_history] ( user_id, password_hash, password_salt, @@ -65,10 +65,10 @@ #{record.passwordDate,jdbcType=TIMESTAMP} ); - DELETE FROM [guacamole].[user_password_history] + DELETE FROM [dbo].[guacamole_user_password_history] WHERE password_history_id IN ( SELECT password_history_id - FROM [guacamole].[user_password_history] + FROM [dbo].[guacamole_user_password_history] WHERE user_id = #{record.userID,jdbcType=INTEGER} ORDER BY password_date DESC OFFSET #{maxHistorySize} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml index a4ceea79e..465ef2060 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -46,16 +46,16 @@ @@ -79,7 +79,7 @@ email_address, organization, organizational_role - FROM [guacamole].[user] + FROM [dbo].[guacamole_user] WHERE username IN @@ -92,7 +92,7 @@ @@ -140,7 +140,7 @@ email_address, organization, organizational_role - FROM [guacamole].[user] + FROM [dbo].[guacamole_user] WHERE username = #{username,jdbcType=VARCHAR} @@ -148,7 +148,7 @@ - DELETE FROM [guacamole].[user] + DELETE FROM [dbo].[guacamole_user] WHERE username = #{identifier,jdbcType=VARCHAR} @@ -156,7 +156,7 @@ - INSERT INTO [guacamole].[user] ( + INSERT INTO [dbo].[guacamole_user] ( username, password_hash, password_salt, @@ -195,7 +195,7 @@ - UPDATE [guacamole].[user] + UPDATE [dbo].[guacamole_user] SET password_hash = #{object.passwordHash,jdbcType=BINARY}, password_salt = #{object.passwordSalt,jdbcType=BINARY}, password_date = #{object.passwordDate,jdbcType=TIMESTAMP}, From 9d38306e30795bcf41e91b5c7b5a1069f6839d8d Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Sun, 27 Aug 2017 16:32:35 -0400 Subject: [PATCH 70/94] GUACAMOLE-363: Minor fixes in schema files. --- .../schema/001-create-schema.sql | 6 ------ .../schema/002-create-admin-user.sql | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) 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 index 92525dd02..95382efdc 100644 --- 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 @@ -17,12 +17,6 @@ * under the License. */ -/** - * Create the guacamole schema. - */ -CREATE SCHEMA [dbo] -GO - /** * List for permission data type. */ 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 index 408d7cafd..c6e6d9b6a 100644 --- 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 @@ -33,7 +33,7 @@ FROM ( JOIN [dbo].[guacamole_user] ON permissions.username = [dbo].[guacamole_user].[username] JOIN [dbo].[guacamole_user] affected ON permissions.affected_username = affected.username; -INSERT INTO [dbo].[system_permission] +INSERT INTO [dbo].[guacamole_system_permission] SELECT user_id, permission FROM ( SELECT 'guacadmin' AS username, 'CREATE_CONNECTION' AS permission From 2eb48895bf988a72049e581e7c3f889cc893d4b3 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 29 Aug 2017 21:15:29 -0400 Subject: [PATCH 71/94] GUACAMOLE-363: Add semicolons to SQL code to make it ANSI SQL standard. --- .../schema/001-create-schema.sql | 208 +++++++++--------- .../schema/002-create-admin-user.sql | 2 +- 2 files changed, 105 insertions(+), 105 deletions(-) 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 index 95382efdc..80e47c156 100644 --- 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 @@ -22,8 +22,8 @@ */ CREATE RULE [dbo].[guacamole_permission_list] AS - @list IN ('READ','UPDATE','DELETE','ADMINISTER') -GO + @list IN ('READ','UPDATE','DELETE','ADMINISTER'); +GO; /** * List for system permission data type. @@ -34,25 +34,25 @@ CREATE RULE [dbo].[guacamole_system_permission_list] 'CREATE_CONNECTION_GROUP', 'CREATE_SHARING_PROFILE', 'CREATE_USER', - 'ADMINISTER') -GO + 'ADMINISTER'); +GO; /** * The permission data type. */ -CREATE TYPE [dbo].[guacamole_permission] FROM [nvarchar](10) NOT NULL +CREATE TYPE [dbo].[guacamole_permission] FROM [nvarchar](10) NOT NULL; /** * The system permission data type. */ -CREATE TYPE [dbo].[guacamole_system_permission] FROM [nvarchar](32) NOT NULL -GO +CREATE TYPE [dbo].[guacamole_system_permission] FROM [nvarchar](32) NOT NULL; +GO; /** * The connection_group table stores organizational and balancing groups. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_connection_group]( [connection_group_id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NULL, @@ -70,36 +70,36 @@ CREATE TABLE [dbo].[guacamole_connection_group]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for connection_group table. */ ALTER TABLE [dbo].[guacamole_connection_group] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_connection_group_id] FOREIGN KEY([parent_id]) - REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]) + REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]); ALTER TABLE [dbo].[guacamole_connection_group] - CHECK CONSTRAINT [FK_guacamole_connection_group_connection_group_id] + CHECK CONSTRAINT [FK_guacamole_connection_group_connection_group_id]; ALTER TABLE [dbo].[guacamole_connection_group] WITH CHECK ADD CONSTRAINT [CK_guacamole_connection_group_type] - CHECK (([type]='BALANCING' OR [type]='ORGANIZATIONAL')) + CHECK (([type]='BALANCING' OR [type]='ORGANIZATIONAL')); ALTER TABLE [dbo].[guacamole_connection_group] - CHECK CONSTRAINT [CK_guacamole_connection_group_type] + CHECK CONSTRAINT [CK_guacamole_connection_group_type]; /** * Default values for connection_group table. */ ALTER TABLE [dbo].[guacamole_connection_group] - ADD CONSTRAINT [DF_guacamole_connection_group_type] DEFAULT (N'ORGANIZATIONAL') FOR [type] + ADD CONSTRAINT [DF_guacamole_connection_group_type] DEFAULT (N'ORGANIZATIONAL') FOR [type]; ALTER TABLE [dbo].[guacamole_connection_group] - ADD CONSTRAINT [DF_guacamole_connection_group_enable_session_affinity] DEFAULT ((0)) FOR [enable_session_affinity] -GO + ADD CONSTRAINT [DF_guacamole_connection_group_enable_session_affinity] DEFAULT ((0)) FOR [enable_session_affinity]; +GO; /** * The connection table, for storing connections and attributes. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_connection]( [connection_id] [int] IDENTITY(1,1) NOT NULL, [connection_name] [nvarchar](128) NOT NULL, @@ -121,27 +121,27 @@ CREATE TABLE [dbo].[guacamole_connection]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; ALTER TABLE [dbo].[guacamole_connection] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_connection_group] FOREIGN KEY([parent_id]) -REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]) + REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]); ALTER TABLE [dbo].[guacamole_connection] - CHECK CONSTRAINT [FK_guacamole_connection_connection_group] + CHECK CONSTRAINT [FK_guacamole_connection_connection_group]; ALTER TABLE [dbo].[guacamole_connection] WITH CHECK ADD CONSTRAINT [CK_proxy_encryption_method] - CHECK (([proxy_encryption_method]='SSL' OR [proxy_encryption_method]='NONE')) + CHECK (([proxy_encryption_method]='SSL' OR [proxy_encryption_method]='NONE')); ALTER TABLE [dbo].[guacamole_connection] - CHECK CONSTRAINT [CK_proxy_encryption_method] + CHECK CONSTRAINT [CK_proxy_encryption_method]; ALTER TABLE [dbo].[guacamole_connection] - ADD CONSTRAINT [DF_guacamole_connection_failover_only] DEFAULT ((0)) FOR [failover_only] -GO + ADD CONSTRAINT [DF_guacamole_connection_failover_only] DEFAULT ((0)) FOR [failover_only]; +GO; /** * The user table stores user accounts, passwords, and properties. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_user]( [user_id] [int] IDENTITY(1,1) NOT NULL, [username] [nvarchar](128) NOT NULL, @@ -168,23 +168,23 @@ CREATE TABLE [dbo].[guacamole_user]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Defaults for user table */ ALTER TABLE [dbo].[guacamole_user] - ADD CONSTRAINT [DF_guacamole_user_disabled] DEFAULT ((0)) FOR [disabled] + ADD CONSTRAINT [DF_guacamole_user_disabled] DEFAULT ((0)) FOR [disabled]; ALTER TABLE [dbo].[guacamole_user] - ADD CONSTRAINT [DF_guacamole_user_expired] DEFAULT ((0)) FOR [expired] -GO + ADD CONSTRAINT [DF_guacamole_user_expired] DEFAULT ((0)) FOR [expired]; +GO; /** * The sharing_profile table stores profiles that allow * connections to be shared amongst multiple users. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_sharing_profile]( [sharing_profile_id] [int] IDENTITY(1,1) NOT NULL, [sharing_profile_name] [nvarchar](128) NOT NULL, @@ -198,7 +198,7 @@ CREATE TABLE [dbo].[guacamole_sharing_profile]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for sharing_profile table. @@ -207,17 +207,17 @@ ALTER TABLE [dbo].[guacamole_sharing_profile] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_connection] FOREIGN KEY([primary_connection_id]) REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_sharing_profile] - CHECK CONSTRAINT [FK_guacamole_sharing_profile_connection] -GO + CHECK CONSTRAINT [FK_guacamole_sharing_profile_connection]; +GO; /** * The connection_parameter table stores parameters for * connection objects. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_connection_parameter]( [connection_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, @@ -231,7 +231,7 @@ CREATE TABLE [dbo].[guacamole_connection_parameter]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] +) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]; /** * Foreign keys for the connection_parameter table. @@ -240,17 +240,17 @@ ALTER TABLE [dbo].[guacamole_connection_parameter] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_parameter_connection] FOREIGN KEY([connection_id]) REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_connection_parameter] - CHECK CONSTRAINT [FK_guacamole_connection_parameter_connection] -GO + CHECK CONSTRAINT [FK_guacamole_connection_parameter_connection]; +GO; /** * The sharing_profile_parameter table stores parameters * for sharing_profile objects. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_sharing_profile_parameter]( [sharing_profile_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, @@ -264,7 +264,7 @@ CREATE TABLE [dbo].[guacamole_sharing_profile_parameter]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] +) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]; /** * Foreign keys for the sharing_profile_parameter @@ -274,17 +274,17 @@ ALTER TABLE [dbo].[guacamole_sharing_profile_parameter] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile] FOREIGN KEY([sharing_profile_id]) REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_sharing_profile_parameter] - CHECK CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile] -GO + CHECK CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile]; +GO; /** * The connection_permission table stores permission * mappings for connection objects. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_connection_permission]( [user_id] [int] NOT NULL, [connection_id] [int] NOT NULL, @@ -298,7 +298,7 @@ CREATE TABLE [dbo].[guacamole_connection_permission]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for the connection_permission table. @@ -307,24 +307,24 @@ ALTER TABLE [dbo].[guacamole_connection_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_connection1] FOREIGN KEY([connection_id]) REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_connection_permission] - CHECK CONSTRAINT [FK_guacamole_connection_permission_connection1] + CHECK CONSTRAINT [FK_guacamole_connection_permission_connection1]; ALTER TABLE [dbo].[guacamole_connection_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_user1] FOREIGN KEY([user_id]) REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_connection_permission] - CHECK CONSTRAINT [FK_guacamole_connection_permission_user1] -GO + CHECK CONSTRAINT [FK_guacamole_connection_permission_user1]; +GO; /** * The connection_group_permission table stores permission mappings for * connection_group objects. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_connection_group_permission]( [user_id] [int] NOT NULL, [connection_group_id] [int] NOT NULL, @@ -338,7 +338,7 @@ CREATE TABLE [dbo].[guacamole_connection_group_permission]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for the connection_group_permission table. @@ -347,24 +347,24 @@ ALTER TABLE [dbo].[guacamole_connection_group_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_connection_group] FOREIGN KEY([connection_group_id]) REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_connection_group_permission] - CHECK CONSTRAINT [FK_guacamole_connection_group_permission_connection_group] + CHECK CONSTRAINT [FK_guacamole_connection_group_permission_connection_group]; ALTER TABLE [dbo].[guacamole_connection_group_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_user] FOREIGN KEY([user_id]) REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_connection_group_permission] - CHECK CONSTRAINT [FK_guacamole_connection_group_permission_user] -GO + CHECK CONSTRAINT [FK_guacamole_connection_group_permission_user]; +GO; /** * The sharing_profile_permission table stores permission * mappings for sharing_profile objects. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_sharing_profile_permission]( [user_id] [int] NOT NULL, [sharing_profile_id] [int] NOT NULL, @@ -378,7 +378,7 @@ CREATE TABLE [dbo].[guacamole_sharing_profile_permission]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for the sharing_profile_permission table. @@ -387,24 +387,24 @@ ALTER TABLE [dbo].[guacamole_sharing_profile_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile] FOREIGN KEY([sharing_profile_id]) REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_sharing_profile_permission] - CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile] + CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile]; ALTER TABLE [dbo].[guacamole_sharing_profile_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_user] FOREIGN KEY([user_id]) REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_sharing_profile_permission] - CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_user] -GO + CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_user]; +GO; /** * The system_permission table stores permission mappings * for system-level operations. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_system_permission]( [user_id] [int] NOT NULL, [permission] [dbo].[guacamole_system_permission] NOT NULL, @@ -417,7 +417,7 @@ CREATE TABLE [dbo].[guacamole_system_permission]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for system_permission table. @@ -426,17 +426,17 @@ ALTER TABLE [dbo].[guacamole_system_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_system_permission_user] FOREIGN KEY([user_id]) REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_system_permission] - CHECK CONSTRAINT [FK_guacamole_system_permission_user] -GO + CHECK CONSTRAINT [FK_guacamole_system_permission_user]; +GO; /** * The user_permission table stores permission mappings * for users to other users. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_user_permission]( [user_id] [int] NOT NULL, [affected_user_id] [int] NOT NULL, @@ -450,7 +450,7 @@ CREATE TABLE [dbo].[guacamole_user_permission]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for user_permission table. @@ -459,22 +459,22 @@ ALTER TABLE [dbo].[guacamole_user_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user] FOREIGN KEY([user_id]) REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_user_permission] - CHECK CONSTRAINT [FK_guacamole_user_permission_user] + CHECK CONSTRAINT [FK_guacamole_user_permission_user]; ALTER TABLE [dbo].[guacamole_user_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user1] FOREIGN KEY([affected_user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [dbo].[guacamole_user] ([user_id]); ALTER TABLE [dbo].[guacamole_user_permission] - CHECK CONSTRAINT [FK_guacamole_user_permission_user1] -GO + CHECK CONSTRAINT [FK_guacamole_user_permission_user1]; +GO; /** * The connection_history table stores records for historical * connections. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_connection_history]( [history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NULL, @@ -495,7 +495,7 @@ CREATE TABLE [dbo].[guacamole_connection_history]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for connection_history table @@ -504,30 +504,30 @@ ALTER TABLE [dbo].[guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_connection] FOREIGN KEY([connection_id]) REFERENCES [dbo].[guacamole_connection] ([connection_id]) ON UPDATE CASCADE - ON DELETE SET NULL + ON DELETE SET NULL; ALTER TABLE [dbo].[guacamole_connection_history] - CHECK CONSTRAINT [FK_guacamole_connection_history_connection] + CHECK CONSTRAINT [FK_guacamole_connection_history_connection]; ALTER TABLE [dbo].[guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) + REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]); ALTER TABLE [dbo].[guacamole_connection_history] - CHECK CONSTRAINT [FK_guacamole_connection_history_sharing_profile] + CHECK CONSTRAINT [FK_guacamole_connection_history_sharing_profile]; ALTER TABLE [dbo].[guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_user] FOREIGN KEY([user_id]) REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE - ON DELETE SET NULL + ON DELETE SET NULL; ALTER TABLE [dbo].[guacamole_connection_history] - CHECK CONSTRAINT [FK_guacamole_connection_history_user] -GO + CHECK CONSTRAINT [FK_guacamole_connection_history_user]; +GO; /** * The user_password_history table stores password history * for users, allowing for enforcing rules associated with * reuse of passwords. */ -SET ANSI_NULLS ON -SET QUOTED_IDENTIFIER ON +SET ANSI_NULLS ON; +SET QUOTED_IDENTIFIER ON; CREATE TABLE [dbo].[guacamole_user_password_history]( [password_history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NOT NULL, @@ -543,7 +543,7 @@ CREATE TABLE [dbo].[guacamole_user_password_history]( ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] -) ON [PRIMARY] +) ON [PRIMARY]; /** * Foreign keys for user_password_history table @@ -552,7 +552,7 @@ ALTER TABLE [dbo].[guacamole_user_password_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_password_history_user] FOREIGN KEY([user_id]) REFERENCES [dbo].[guacamole_user] ([user_id]) ON UPDATE CASCADE - ON DELETE CASCADE + ON DELETE CASCADE; ALTER TABLE [dbo].[guacamole_user_password_history] - CHECK CONSTRAINT [FK_guacamole_user_password_history_user] -GO + CHECK CONSTRAINT [FK_guacamole_user_password_history_user]; +GO; 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 index c6e6d9b6a..f7d5b4539 100644 --- 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 @@ -43,4 +43,4 @@ FROM ( UNION SELECT 'guacadmin' AS username, 'ADMINISTER' AS permission) permissions JOIN [dbo].[guacamole_user] ON permissions.username = [dbo].[guacamole_user].[username]; -GO +GO; From d6d7c3768fb5945033627907c691c896c915bc51 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 29 Aug 2017 21:41:00 -0400 Subject: [PATCH 72/94] GUACAMOLE-363: Allow use of alternate JTDS driver. --- ...SQLServerAuthenticationProviderModule.java | 13 +++++++++++- .../auth/sqlserver/SQLServerEnvironment.java | 20 ++++++++++++++++++- .../SQLServerGuacamoleProperties.java | 11 ++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) 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 index ebb1a0678..d936f140d 100644 --- 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 @@ -40,6 +40,11 @@ public class SQLServerAuthenticationProviderModule implements Module { * SQLServer-specific driver configuration properties. */ private final Properties driverProperties = new Properties(); + + /** + * Whether or not to use JTDS Driver + */ + private Boolean useJTDSDriver = false; /** * Creates a new SQLServer authentication provider module that configures @@ -70,13 +75,19 @@ public class SQLServerAuthenticationProviderModule implements Module { // Use UTF-8 in database driverProperties.setProperty("characterEncoding", "UTF-8"); + // Capture whether or not to use the JTDS driver. + this.useJTDSDriver = environment.getSQLServerJTDSDriver(); + } @Override public void configure(Binder binder) { // Bind SQLServer-specific properties - JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); + if (this.useJTDSDriver) + JdbcHelper.SQL_Server_jTDS.configure(binder); + else + JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); // Bind MyBatis properties Names.bindProperties(binder, myBatisProperties); 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 index 67d882719..4d24dd36b 100644 --- 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 @@ -272,7 +272,7 @@ public class SQLServerEnvironment extends JDBCEnvironment { 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. @@ -302,5 +302,23 @@ public class SQLServerEnvironment extends JDBCEnvironment { public String getSQLServerPassword() throws GuacamoleException { return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_PASSWORD); } + + /** + * Returns whether or not to use the SourceForge JTDS driver for more + * generic JTDS connections instead of the Microsoft-provided JDBC driver. + * + * @return + * True if the JTDS driver should be used; false by default. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property value, or if the + * value was not set, as this property is required. + */ + public Boolean getSQLServerJTDSDriver() throws GuacamoleException { + return getProperty( + SQLServerGuacamoleProperties.SQLSERVER_JTDS_DRIVER, + false + ); + } } 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 index e45f50268..d04d9a13c 100644 --- 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 @@ -197,4 +197,15 @@ public class SQLServerGuacamoleProperties { }; + /** + * Whether or not to use the JTDS driver for SQL Server connections. + */ + public static final BooleanGuacamoleProperty + SQLSERVER_JTDS_DRIVER = new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "sqlserver-use-jtds-driver"; } + + }; + } From b72dba6b033a0da3c6bd8db248b848313dfe8fe9 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Thu, 7 Sep 2017 16:07:59 -0400 Subject: [PATCH 73/94] GUACAMOLE-363: Update so that any of the available TDS-compatible drivers can be used. --- ...SQLServerAuthenticationProviderModule.java | 15 ++++--- .../auth/sqlserver/SQLServerEnvironment.java | 39 +++++++++++++++++-- .../SQLServerGuacamoleProperties.java | 6 +-- 3 files changed, 49 insertions(+), 11 deletions(-) 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 index d936f140d..22c543403 100644 --- 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 @@ -44,8 +44,8 @@ public class SQLServerAuthenticationProviderModule implements Module { /** * Whether or not to use JTDS Driver */ - private Boolean useJTDSDriver = false; - + private String sqlServerDriver; + /** * Creates a new SQLServer authentication provider module that configures * driver and MyBatis properties using the given environment. @@ -75,8 +75,8 @@ public class SQLServerAuthenticationProviderModule implements Module { // Use UTF-8 in database driverProperties.setProperty("characterEncoding", "UTF-8"); - // Capture whether or not to use the JTDS driver. - this.useJTDSDriver = environment.getSQLServerJTDSDriver(); + // Capture which driver to use for the connection. + this.sqlServerDriver = environment.getSQLServerDriver(); } @@ -84,8 +84,13 @@ public class SQLServerAuthenticationProviderModule implements Module { public void configure(Binder binder) { // Bind SQLServer-specific properties - if (this.useJTDSDriver) + // Look at the property to choose the correct driver. + if (sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_JTDS)) JdbcHelper.SQL_Server_jTDS.configure(binder); + else if(sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_DATADIRECT)) + JdbcHelper.SQL_Server_DataDirect.configure(binder); + else if(sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_MS)) + JdbcHelper.SQL_Server_MS_Driver.configure(binder); else JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); 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 index 4d24dd36b..2110b0c7d 100644 --- 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 @@ -96,6 +96,30 @@ public class SQLServerEnvironment extends JDBCEnvironment { */ private int DEFAULT_MAX_GROUP_CONNECTIONS = 0; + /** + * The value for the sqlserver-driver property that triggers the use of + * the open source JTDS driver. + */ + public final static String SQLSERVER_DRIVER_JTDS = "jtds"; + + /** + * The value for the sqlserver-driver property that triggers the use of + * the DataDirect JDBC driver. + */ + public final static String SQLSERVER_DRIVER_DATADIRECT = "datadirect"; + + /** + * The value for the sqlserver-driver property that triggers the use of + * the older Microsoft JDBC driver. + */ + public final static String SQLSERVER_DRIVER_MS = "microsoft"; + + /** + * The value for the sqlserver-driver property that triggers the use of + * the Microsoft JDBC driver. This is the default. + */ + public final static String SQLSERVER_DRIVER_MS_2005 = "microsoft2005"; + /** * Constructs a new SQLServerEnvironment, providing access to SQLServer-specific * configuration options. @@ -169,6 +193,15 @@ public class SQLServerEnvironment extends JDBCEnvironment { } + // Check driver property is one of the acceptable values. + String driver = getProperty(SQLServerGuacamoleProperties.SQLSERVER_DRIVER); + if (!(driver.equals(SQLSERVER_DRIVER_JTDS) || + driver.equals(SQLSERVER_DRIVER_DATADIRECT) || + driver.equals(SQLSERVER_DRIVER_MS) || + driver.equals(SQLSERVER_DRIVER_MS_2005))) + logger.warn("{} property has been set to an invalid value. The default Microsoft 2005 driver will be used.", + SQLServerGuacamoleProperties.SQLSERVER_DRIVER.getName()); + } @Override @@ -314,10 +347,10 @@ public class SQLServerEnvironment extends JDBCEnvironment { * If an error occurs while retrieving the property value, or if the * value was not set, as this property is required. */ - public Boolean getSQLServerJTDSDriver() throws GuacamoleException { + public String getSQLServerDriver() throws GuacamoleException { return getProperty( - SQLServerGuacamoleProperties.SQLSERVER_JTDS_DRIVER, - false + SQLServerGuacamoleProperties.SQLSERVER_DRIVER, + SQLSERVER_DRIVER_MS_2005 ); } 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 index d04d9a13c..9d9b3864b 100644 --- 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 @@ -200,11 +200,11 @@ public class SQLServerGuacamoleProperties { /** * Whether or not to use the JTDS driver for SQL Server connections. */ - public static final BooleanGuacamoleProperty - SQLSERVER_JTDS_DRIVER = new BooleanGuacamoleProperty() { + public static final StringGuacamoleProperty + SQLSERVER_DRIVER = new StringGuacamoleProperty() { @Override - public String getName() { return "sqlserver-use-jtds-driver"; } + public String getName() { return "sqlserver-driver"; } }; From 73301901ec8b2a856f9c8066fd759db41216d66c Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Thu, 7 Sep 2017 22:30:01 -0400 Subject: [PATCH 74/94] GUACAMOLE-363: Remove explicit schema, relying on account default schema. --- .../schema/001-create-schema.sql | 170 +++++++++--------- .../schema/002-create-admin-user.sql | 14 +- .../auth/jdbc/connection/ConnectionMapper.xml | 38 ++-- .../connection/ConnectionParameterMapper.xml | 6 +- .../connection/ConnectionRecordMapper.xml | 110 ++++++------ .../connectiongroup/ConnectionGroupMapper.xml | 46 ++--- .../ConnectionGroupPermissionMapper.xml | 30 ++-- .../permission/ConnectionPermissionMapper.xml | 30 ++-- .../SharingProfilePermissionMapper.xml | 30 ++-- .../permission/SystemPermissionMapper.xml | 26 +-- .../jdbc/permission/UserPermissionMapper.xml | 52 +++--- .../sharingprofile/SharingProfileMapper.xml | 24 +-- .../SharingProfileParameterMapper.xml | 6 +- .../auth/jdbc/user/PasswordRecordMapper.xml | 22 +-- .../guacamole/auth/jdbc/user/UserMapper.xml | 26 +-- 15 files changed, 315 insertions(+), 315 deletions(-) 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 index 80e47c156..1a1e32471 100644 --- 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 @@ -20,7 +20,7 @@ /** * List for permission data type. */ -CREATE RULE [dbo].[guacamole_permission_list] +CREATE RULE [guacamole_permission_list] AS @list IN ('READ','UPDATE','DELETE','ADMINISTER'); GO; @@ -28,7 +28,7 @@ GO; /** * List for system permission data type. */ -CREATE RULE [dbo].[guacamole_system_permission_list] +CREATE RULE [guacamole_system_permission_list] AS @list IN ('CREATE_CONNECTION', 'CREATE_CONNECTION_GROUP', @@ -40,12 +40,12 @@ GO; /** * The permission data type. */ -CREATE TYPE [dbo].[guacamole_permission] FROM [nvarchar](10) NOT NULL; +CREATE TYPE [guacamole_permission] FROM [nvarchar](10) NOT NULL; /** * The system permission data type. */ -CREATE TYPE [dbo].[guacamole_system_permission] FROM [nvarchar](32) NOT NULL; +CREATE TYPE [guacamole_system_permission] FROM [nvarchar](32) NOT NULL; GO; /** @@ -53,7 +53,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_connection_group]( +CREATE TABLE [guacamole_connection_group]( [connection_group_id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NULL, [connection_group_name] [nvarchar](128) NOT NULL, @@ -75,23 +75,23 @@ CREATE TABLE [dbo].[guacamole_connection_group]( /** * Foreign keys for connection_group table. */ -ALTER TABLE [dbo].[guacamole_connection_group] +ALTER TABLE [guacamole_connection_group] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_connection_group_id] FOREIGN KEY([parent_id]) - REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]); -ALTER TABLE [dbo].[guacamole_connection_group] + REFERENCES [guacamole_connection_group] ([connection_group_id]); +ALTER TABLE [guacamole_connection_group] CHECK CONSTRAINT [FK_guacamole_connection_group_connection_group_id]; -ALTER TABLE [dbo].[guacamole_connection_group] +ALTER TABLE [guacamole_connection_group] WITH CHECK ADD CONSTRAINT [CK_guacamole_connection_group_type] CHECK (([type]='BALANCING' OR [type]='ORGANIZATIONAL')); -ALTER TABLE [dbo].[guacamole_connection_group] +ALTER TABLE [guacamole_connection_group] CHECK CONSTRAINT [CK_guacamole_connection_group_type]; /** * Default values for connection_group table. */ -ALTER TABLE [dbo].[guacamole_connection_group] +ALTER TABLE [guacamole_connection_group] ADD CONSTRAINT [DF_guacamole_connection_group_type] DEFAULT (N'ORGANIZATIONAL') FOR [type]; -ALTER TABLE [dbo].[guacamole_connection_group] +ALTER TABLE [guacamole_connection_group] ADD CONSTRAINT [DF_guacamole_connection_group_enable_session_affinity] DEFAULT ((0)) FOR [enable_session_affinity]; GO; @@ -100,7 +100,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_connection]( +CREATE TABLE [guacamole_connection]( [connection_id] [int] IDENTITY(1,1) NOT NULL, [connection_name] [nvarchar](128) NOT NULL, [parent_id] [int] NULL, @@ -123,17 +123,17 @@ CREATE TABLE [dbo].[guacamole_connection]( ON [PRIMARY] ) ON [PRIMARY]; -ALTER TABLE [dbo].[guacamole_connection] +ALTER TABLE [guacamole_connection] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_connection_group] FOREIGN KEY([parent_id]) - REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]); -ALTER TABLE [dbo].[guacamole_connection] + REFERENCES [guacamole_connection_group] ([connection_group_id]); +ALTER TABLE [guacamole_connection] CHECK CONSTRAINT [FK_guacamole_connection_connection_group]; -ALTER TABLE [dbo].[guacamole_connection] +ALTER TABLE [guacamole_connection] WITH CHECK ADD CONSTRAINT [CK_proxy_encryption_method] CHECK (([proxy_encryption_method]='SSL' OR [proxy_encryption_method]='NONE')); -ALTER TABLE [dbo].[guacamole_connection] +ALTER TABLE [guacamole_connection] CHECK CONSTRAINT [CK_proxy_encryption_method]; -ALTER TABLE [dbo].[guacamole_connection] +ALTER TABLE [guacamole_connection] ADD CONSTRAINT [DF_guacamole_connection_failover_only] DEFAULT ((0)) FOR [failover_only]; GO; @@ -142,7 +142,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_user]( +CREATE TABLE [guacamole_user]( [user_id] [int] IDENTITY(1,1) NOT NULL, [username] [nvarchar](128) NOT NULL, [password_hash] [binary](32) NOT NULL, @@ -173,9 +173,9 @@ CREATE TABLE [dbo].[guacamole_user]( /** * Defaults for user table */ -ALTER TABLE [dbo].[guacamole_user] +ALTER TABLE [guacamole_user] ADD CONSTRAINT [DF_guacamole_user_disabled] DEFAULT ((0)) FOR [disabled]; -ALTER TABLE [dbo].[guacamole_user] +ALTER TABLE [guacamole_user] ADD CONSTRAINT [DF_guacamole_user_expired] DEFAULT ((0)) FOR [expired]; GO; @@ -185,7 +185,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_sharing_profile]( +CREATE TABLE [guacamole_sharing_profile]( [sharing_profile_id] [int] IDENTITY(1,1) NOT NULL, [sharing_profile_name] [nvarchar](128) NOT NULL, [primary_connection_id] [int] NOT NULL, @@ -203,12 +203,12 @@ CREATE TABLE [dbo].[guacamole_sharing_profile]( /** * Foreign keys for sharing_profile table. */ -ALTER TABLE [dbo].[guacamole_sharing_profile] +ALTER TABLE [guacamole_sharing_profile] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_connection] FOREIGN KEY([primary_connection_id]) - REFERENCES [dbo].[guacamole_connection] ([connection_id]) + REFERENCES [guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_sharing_profile] +ALTER TABLE [guacamole_sharing_profile] CHECK CONSTRAINT [FK_guacamole_sharing_profile_connection]; GO; @@ -218,7 +218,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_connection_parameter]( +CREATE TABLE [guacamole_connection_parameter]( [connection_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](max) NOT NULL, @@ -236,12 +236,12 @@ CREATE TABLE [dbo].[guacamole_connection_parameter]( /** * Foreign keys for the connection_parameter table. */ -ALTER TABLE [dbo].[guacamole_connection_parameter] +ALTER TABLE [guacamole_connection_parameter] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_parameter_connection] FOREIGN KEY([connection_id]) - REFERENCES [dbo].[guacamole_connection] ([connection_id]) + REFERENCES [guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_connection_parameter] +ALTER TABLE [guacamole_connection_parameter] CHECK CONSTRAINT [FK_guacamole_connection_parameter_connection]; GO; @@ -251,7 +251,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_sharing_profile_parameter]( +CREATE TABLE [guacamole_sharing_profile_parameter]( [sharing_profile_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](max) NOT NULL, @@ -270,12 +270,12 @@ CREATE TABLE [dbo].[guacamole_sharing_profile_parameter]( * Foreign keys for the sharing_profile_parameter * table. */ -ALTER TABLE [dbo].[guacamole_sharing_profile_parameter] +ALTER TABLE [guacamole_sharing_profile_parameter] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) + REFERENCES [guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_sharing_profile_parameter] +ALTER TABLE [guacamole_sharing_profile_parameter] CHECK CONSTRAINT [FK_guacamole_sharing_profile_parameter_sharing_profile]; GO; @@ -285,10 +285,10 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_connection_permission]( +CREATE TABLE [guacamole_connection_permission]( [user_id] [int] NOT NULL, [connection_id] [int] NOT NULL, - [permission] [dbo].[guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_id] ASC, [permission] ASC) @@ -303,19 +303,19 @@ CREATE TABLE [dbo].[guacamole_connection_permission]( /** * Foreign keys for the connection_permission table. */ -ALTER TABLE [dbo].[guacamole_connection_permission] +ALTER TABLE [guacamole_connection_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_connection1] FOREIGN KEY([connection_id]) - REFERENCES [dbo].[guacamole_connection] ([connection_id]) + REFERENCES [guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_connection_permission] +ALTER TABLE [guacamole_connection_permission] CHECK CONSTRAINT [FK_guacamole_connection_permission_connection1]; -ALTER TABLE [dbo].[guacamole_connection_permission] +ALTER TABLE [guacamole_connection_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_permission_user1] FOREIGN KEY([user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_connection_permission] +ALTER TABLE [guacamole_connection_permission] CHECK CONSTRAINT [FK_guacamole_connection_permission_user1]; GO; @@ -325,10 +325,10 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_connection_group_permission]( +CREATE TABLE [guacamole_connection_group_permission]( [user_id] [int] NOT NULL, [connection_group_id] [int] NOT NULL, - [permission] [dbo].[guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_group_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_group_id] ASC, [permission] ASC) @@ -343,19 +343,19 @@ CREATE TABLE [dbo].[guacamole_connection_group_permission]( /** * Foreign keys for the connection_group_permission table. */ -ALTER TABLE [dbo].[guacamole_connection_group_permission] +ALTER TABLE [guacamole_connection_group_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_connection_group] FOREIGN KEY([connection_group_id]) - REFERENCES [dbo].[guacamole_connection_group] ([connection_group_id]) + REFERENCES [guacamole_connection_group] ([connection_group_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_connection_group_permission] +ALTER TABLE [guacamole_connection_group_permission] CHECK CONSTRAINT [FK_guacamole_connection_group_permission_connection_group]; -ALTER TABLE [dbo].[guacamole_connection_group_permission] +ALTER TABLE [guacamole_connection_group_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_permission_user] FOREIGN KEY([user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_connection_group_permission] +ALTER TABLE [guacamole_connection_group_permission] CHECK CONSTRAINT [FK_guacamole_connection_group_permission_user]; GO; @@ -365,10 +365,10 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_sharing_profile_permission]( +CREATE TABLE [guacamole_sharing_profile_permission]( [user_id] [int] NOT NULL, [sharing_profile_id] [int] NOT NULL, - [permission] [dbo].[guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [sharing_profile_id] ASC, [permission] ASC) @@ -383,19 +383,19 @@ CREATE TABLE [dbo].[guacamole_sharing_profile_permission]( /** * Foreign keys for the sharing_profile_permission table. */ -ALTER TABLE [dbo].[guacamole_sharing_profile_permission] +ALTER TABLE [guacamole_sharing_profile_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]) + REFERENCES [guacamole_sharing_profile] ([sharing_profile_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_sharing_profile_permission] +ALTER TABLE [guacamole_sharing_profile_permission] CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile]; -ALTER TABLE [dbo].[guacamole_sharing_profile_permission] +ALTER TABLE [guacamole_sharing_profile_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_user] FOREIGN KEY([user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_sharing_profile_permission] +ALTER TABLE [guacamole_sharing_profile_permission] CHECK CONSTRAINT [FK_guacamole_sharing_profile_permission_user]; GO; @@ -405,9 +405,9 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_system_permission]( +CREATE TABLE [guacamole_system_permission]( [user_id] [int] NOT NULL, - [permission] [dbo].[guacamole_system_permission] NOT NULL, + [permission] [guacamole_system_permission] NOT NULL, CONSTRAINT [PK_guacamole_system_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [permission] ASC) @@ -422,12 +422,12 @@ CREATE TABLE [dbo].[guacamole_system_permission]( /** * Foreign keys for system_permission table. */ -ALTER TABLE [dbo].[guacamole_system_permission] +ALTER TABLE [guacamole_system_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_system_permission_user] FOREIGN KEY([user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_system_permission] +ALTER TABLE [guacamole_system_permission] CHECK CONSTRAINT [FK_guacamole_system_permission_user]; GO; @@ -437,10 +437,10 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_user_permission]( +CREATE TABLE [guacamole_user_permission]( [user_id] [int] NOT NULL, [affected_user_id] [int] NOT NULL, - [permission] [dbo].[guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_user_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [affected_user_id] ASC, [permission] ASC) @@ -455,17 +455,17 @@ CREATE TABLE [dbo].[guacamole_user_permission]( /** * Foreign keys for user_permission table. */ -ALTER TABLE [dbo].[guacamole_user_permission] +ALTER TABLE [guacamole_user_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user] FOREIGN KEY([user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_user_permission] +ALTER TABLE [guacamole_user_permission] CHECK CONSTRAINT [FK_guacamole_user_permission_user]; -ALTER TABLE [dbo].[guacamole_user_permission] +ALTER TABLE [guacamole_user_permission] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_permission_user1] FOREIGN KEY([affected_user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]); -ALTER TABLE [dbo].[guacamole_user_permission] + REFERENCES [guacamole_user] ([user_id]); +ALTER TABLE [guacamole_user_permission] CHECK CONSTRAINT [FK_guacamole_user_permission_user1]; GO; @@ -475,7 +475,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_connection_history]( +CREATE TABLE [guacamole_connection_history]( [history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NULL, [username] [nvarchar](128) NOT NULL, @@ -500,24 +500,24 @@ CREATE TABLE [dbo].[guacamole_connection_history]( /** * Foreign keys for connection_history table */ -ALTER TABLE [dbo].[guacamole_connection_history] +ALTER TABLE [guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_connection] FOREIGN KEY([connection_id]) - REFERENCES [dbo].[guacamole_connection] ([connection_id]) + REFERENCES [guacamole_connection] ([connection_id]) ON UPDATE CASCADE ON DELETE SET NULL; -ALTER TABLE [dbo].[guacamole_connection_history] +ALTER TABLE [guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_connection]; -ALTER TABLE [dbo].[guacamole_connection_history] +ALTER TABLE [guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_sharing_profile] FOREIGN KEY([sharing_profile_id]) - REFERENCES [dbo].[guacamole_sharing_profile] ([sharing_profile_id]); -ALTER TABLE [dbo].[guacamole_connection_history] + REFERENCES [guacamole_sharing_profile] ([sharing_profile_id]); +ALTER TABLE [guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_sharing_profile]; -ALTER TABLE [dbo].[guacamole_connection_history] +ALTER TABLE [guacamole_connection_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_user] FOREIGN KEY([user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE SET NULL; -ALTER TABLE [dbo].[guacamole_connection_history] +ALTER TABLE [guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_user]; GO; @@ -528,7 +528,7 @@ GO; */ SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; -CREATE TABLE [dbo].[guacamole_user_password_history]( +CREATE TABLE [guacamole_user_password_history]( [password_history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NOT NULL, [password_hash] [binary](32) NOT NULL, @@ -548,11 +548,11 @@ CREATE TABLE [dbo].[guacamole_user_password_history]( /** * Foreign keys for user_password_history table */ -ALTER TABLE [dbo].[guacamole_user_password_history] +ALTER TABLE [guacamole_user_password_history] WITH CHECK ADD CONSTRAINT [FK_guacamole_user_password_history_user] FOREIGN KEY([user_id]) - REFERENCES [dbo].[guacamole_user] ([user_id]) + REFERENCES [guacamole_user] ([user_id]) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE [dbo].[guacamole_user_password_history] +ALTER TABLE [guacamole_user_password_history] CHECK CONSTRAINT [FK_guacamole_user_password_history_user]; GO; 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 index f7d5b4539..d348b61ae 100644 --- 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 @@ -20,20 +20,20 @@ /** * Create the default admin user account and set up full privileges. */ -INSERT INTO [dbo].[guacamole_user] (username, password_hash, password_date) +INSERT INTO [guacamole_user] (username, password_hash, password_date) VALUES ('guacadmin', HASHBYTES('SHA2_256', 'guacadmin'), getdate()); -INSERT INTO [dbo].[guacamole_user_permission] -SELECT [dbo].[guacamole_user].[user_id], [affected].[user_id], permission +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 [dbo].[guacamole_user] ON permissions.username = [dbo].[guacamole_user].[username] - JOIN [dbo].[guacamole_user] affected ON permissions.affected_username = affected.username; + JOIN [guacamole_user] ON permissions.username = [guacamole_user].[username] + JOIN [guacamole_user] affected ON permissions.affected_username = affected.username; -INSERT INTO [dbo].[guacamole_system_permission] +INSERT INTO [guacamole_system_permission] SELECT user_id, permission FROM ( SELECT 'guacadmin' AS username, 'CREATE_CONNECTION' AS permission @@ -42,5 +42,5 @@ FROM ( UNION SELECT 'guacadmin' AS username, 'CREATE_USER' AS permission UNION SELECT 'guacadmin' AS username, 'ADMINISTER' AS permission) permissions - JOIN [dbo].[guacamole_user] ON permissions.username = [dbo].[guacamole_user].[username]; + JOIN [guacamole_user] ON permissions.username = [guacamole_user].[username]; GO; 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 index c62ca6f36..3e6819f06 100644 --- 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 @@ -51,13 +51,13 @@ SELECT connection_id - FROM [dbo].[guacamole_connection] + FROM [guacamole_connection] WHERE parent_id = #{parentIdentifier,jdbcType=INTEGER} parent_id IS NULL @@ -74,9 +74,9 @@ - DELETE FROM [dbo].[guacamole_connection_parameter] + DELETE FROM [guacamole_connection_parameter] WHERE connection_id = #{identifier,jdbcType=INTEGER} - INSERT INTO [dbo].[guacamole_connection_parameter] ( + INSERT INTO [guacamole_connection_parameter] ( connection_id, parameter_name, parameter_value 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 index 648d16f60..bca8139d2 100644 --- 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 @@ -40,28 +40,28 @@ - INSERT INTO [dbo].[guacamole_connection_history] ( + INSERT INTO [guacamole_connection_history] ( connection_id, connection_name, remote_host, @@ -78,7 +78,7 @@ #{record.remoteHost,jdbcType=VARCHAR}, #{record.sharingProfileIdentifier,jdbcType=INTEGER}, #{record.sharingProfileName,jdbcType=VARCHAR}, - (SELECT user_id FROM [dbo].[guacamole_user] + (SELECT user_id FROM [guacamole_user] WHERE username = #{record.username,jdbcType=VARCHAR}), #{record.username,jdbcType=VARCHAR}, #{record.startDate,jdbcType=TIMESTAMP}, @@ -91,31 +91,31 @@ SELECT TOP (#{limit,jdbcType=INTEGER}) - [dbo].[guacamole_connection_history].connection_id, - [dbo].[guacamole_connection_history].connection_name, - [dbo].[guacamole_connection_history].remote_host, - [dbo].[guacamole_connection_history].sharing_profile_id, - [dbo].[guacamole_connection_history].sharing_profile_name, - [dbo].[guacamole_connection_history].user_id, - [dbo].[guacamole_connection_history].username, - [dbo].[guacamole_connection_history].start_date, - [dbo].[guacamole_connection_history].end_date - FROM [dbo].[guacamole_connection_history] - LEFT JOIN [dbo].[guacamole_connection] ON [dbo].[guacamole_connection_history].connection_id = [dbo].[guacamole_connection].connection_id - LEFT JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_connection_history].user_id = [dbo].[guacamole_user].user_id + [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 - JOIN [dbo].[guacamole_connection_permission] ON - [dbo].[guacamole_connection_history].connection_id = [dbo].[guacamole_connection_permission].connection_id - AND [dbo].[guacamole_connection_permission].user_id = #{user.objectID,jdbcType=INTEGER} - AND [dbo].[guacamole_connection_permission].permission = 'READ' + 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' - JOIN [dbo].[guacamole_user_permission] ON - [dbo].[guacamole_connection_history].user_id = [dbo].[guacamole_user_permission].affected_user_id - AND [dbo].[guacamole_user_permission].user_id = #{user.objectID,jdbcType=INTEGER} - AND [dbo].[guacamole_user_permission].permission = 'READ' + 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' ( - [dbo].[guacamole_connection_history].user_id IN ( + [guacamole_connection_history].user_id IN ( SELECT user_id - FROM [dbo].[guacamole_user] + FROM [guacamole_user] WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN username) > 0 ) - OR [dbo].[guacamole_connection_history].connection_id IN ( + OR [guacamole_connection_history].connection_id IN ( SELECT connection_id - FROM [dbo].[guacamole_connection] + FROM [guacamole_connection] WHERE POSITION(#{term.term,jdbcType=VARCHAR} IN connection_name) > 0 ) @@ -201,7 +201,7 @@ - [dbo].[guacamole_connection_history].start_date + [guacamole_connection_history].start_date 1 DESC diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml index d1f97a738..452c0a81e 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/connectiongroup/ConnectionGroupMapper.xml @@ -53,13 +53,13 @@ SELECT connection_group_id - FROM [dbo].[guacamole_connection_group] + FROM [guacamole_connection_group] WHERE parent_id = #{parentIdentifier,jdbcType=INTEGER} parent_id IS NULL @@ -76,9 +76,9 @@ SELECT - [dbo].[guacamole_connection_group_permission].user_id, + [guacamole_connection_group_permission].user_id, username, permission, connection_group_id - FROM [dbo].[guacamole_connection_group_permission] - JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_connection_group_permission].user_id = [dbo].[guacamole_user].user_id - WHERE [dbo].[guacamole_connection_group_permission].user_id = #{user.objectID,jdbcType=INTEGER} + FROM [guacamole_connection_group_permission] + JOIN [guacamole_user] ON [guacamole_connection_group_permission].user_id = [guacamole_user].user_id + WHERE [guacamole_connection_group_permission].user_id = #{user.objectID,jdbcType=INTEGER} @@ -50,14 +50,14 @@ SELECT DISTINCT connection_group_id - FROM [dbo].[guacamole_connection_group_permission] + FROM [guacamole_connection_group_permission] WHERE user_id = #{user.objectID,jdbcType=INTEGER} AND connection_group_id IN @@ -86,7 +86,7 @@ - DELETE FROM [dbo].[guacamole_connection_group_permission] + DELETE FROM [guacamole_connection_group_permission] WHERE (user_id, permission, connection_group_id) IN @@ -100,7 +100,7 @@ - INSERT INTO [dbo].[guacamole_connection_group_permission] ( + INSERT INTO [guacamole_connection_group_permission] ( user_id, permission, connection_group_id @@ -117,10 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_group_id AS permissions - WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_connection_group_permission] - WHERE [dbo].[guacamole_connection_group_permission].user_id = permissions.user_id AND - [dbo].[guacamole_connection_group_permission].permission = permissions.permission AND - [dbo].[guacamole_connection_group_permission].connection_group_id = permissions.connection_group_id + WHERE NOT EXISTS (SELECT 1 FROM [guacamole_connection_group_permission] + WHERE [guacamole_connection_group_permission].user_id = permissions.user_id AND + [guacamole_connection_group_permission].permission = permissions.permission AND + [guacamole_connection_group_permission].connection_group_id = permissions.connection_group_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml index fa25f637e..aaa555aee 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/ConnectionPermissionMapper.xml @@ -36,13 +36,13 @@ @@ -50,14 +50,14 @@ SELECT DISTINCT connection_id - FROM [dbo].[guacamole_connection_permission] + FROM [guacamole_connection_permission] WHERE user_id = #{user.objectID,jdbcType=INTEGER} AND connection_id IN @@ -86,7 +86,7 @@ - DELETE FROM [dbo].[guacamole_connection_permission] + DELETE FROM [guacamole_connection_permission] WHERE @@ -100,7 +100,7 @@ - INSERT INTO [dbo].[guacamole_connection_permission] ( + INSERT INTO [guacamole_connection_permission] ( user_id, permission, connection_id @@ -117,10 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS connection_id AS permissions - WHERE NOT EXISTS ( SELECT 1 FROM [dbo].[guacamole_connection_permission] - WHERE [dbo].[guacamole_connection_permission].user_id = permissions.user_id AND - [dbo].[guacamole_connection_permission].permission = permissions.permission AND - [dbo].[guacamole_connection_permission].connection_id = permissions.connection_id + WHERE NOT EXISTS ( SELECT 1 FROM [guacamole_connection_permission] + WHERE [guacamole_connection_permission].user_id = permissions.user_id AND + [guacamole_connection_permission].permission = permissions.permission AND + [guacamole_connection_permission].connection_id = permissions.connection_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml index 40e9907c4..ab40d2ade 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SharingProfilePermissionMapper.xml @@ -36,13 +36,13 @@ @@ -50,14 +50,14 @@ SELECT DISTINCT sharing_profile_id - FROM [dbo].[guacamole_sharing_profile_permission] + FROM [guacamole_sharing_profile_permission] WHERE user_id = #{user.objectID,jdbcType=INTEGER} AND sharing_profile_id IN @@ -86,7 +86,7 @@ - DELETE FROM [dbo].[guacamole_sharing_profile_permission] + DELETE FROM [guacamole_sharing_profile_permission] WHERE @@ -100,7 +100,7 @@ - INSERT INTO [dbo].[guacamole_sharing_profile_permission] ( + INSERT INTO [guacamole_sharing_profile_permission] ( user_id, permission, sharing_profile_id @@ -117,10 +117,10 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS sharing_profile_id AS permissions - WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_sharing_profile_permission] - WHERE [dbo].[guacamole_sharing_profile_permission].user_id = permissions.user_id - AND [dbo].[guacamole_sharing_profile_permission].permission = permissions.permission - AND [dbo].[guacamole_sharing_profile_permission].sharing_profile_id = permissions.sharing_profile_id + WHERE NOT EXISTS (SELECT 1 FROM [guacamole_sharing_profile_permission] + WHERE [guacamole_sharing_profile_permission].user_id = permissions.user_id + AND [guacamole_sharing_profile_permission].permission = permissions.permission + AND [guacamole_sharing_profile_permission].sharing_profile_id = permissions.sharing_profile_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml index d33dd3b65..663b94ec1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/SystemPermissionMapper.xml @@ -35,12 +35,12 @@ @@ -48,13 +48,13 @@ @@ -62,7 +62,7 @@ - DELETE FROM [dbo].[guacamole_system_permission] + DELETE FROM [guacamole_system_permission] WHERE @@ -75,7 +75,7 @@ - INSERT INTO [dbo].[guacamole_system_permission] ( + INSERT INTO [guacamole_system_permission] ( user_id, permission ) @@ -89,9 +89,9 @@ #{permission.type,jdbcType=VARCHAR} AS permission AS permissions - WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_system_permission] - WHERE [dbo].[guacamole_system_permission].user_id = permissions.user_id - AND [dbo].[guacamole_system_permission].permission = permissions.permission + WHERE NOT EXISTS (SELECT 1 FROM [guacamole_system_permission] + WHERE [guacamole_system_permission].user_id = permissions.user_id + AND [guacamole_system_permission].permission = permissions.permission ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml index a2d416fe6..453777d0c 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/permission/UserPermissionMapper.xml @@ -36,14 +36,14 @@ @@ -51,15 +51,15 @@ SELECT DISTINCT username - FROM [dbo].[guacamole_user_permission] - JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_user_permission].affected_user_id = [dbo].[guacamole_user].user_id + FROM [guacamole_user_permission] + JOIN [guacamole_user] ON [guacamole_user_permission].affected_user_id = [guacamole_user].user_id WHERE - [dbo].[guacamole_user_permission].user_id = #{user.objectID,jdbcType=INTEGER} + [guacamole_user_permission].user_id = #{user.objectID,jdbcType=INTEGER} AND username IN @@ -89,11 +89,11 @@ - DELETE FROM [dbo].[guacamole_user_permission] - USING [dbo].[guacamole_user] affected + DELETE FROM [guacamole_user_permission] + USING [guacamole_user] affected WHERE - [dbo].[guacamole_user_permission].affected_user_id = affected.user_id - AND ([dbo].[guacamole_user_permission].user_id, permission, affected.username) IN + [guacamole_user_permission].affected_user_id = affected.user_id + AND ([guacamole_user_permission].user_id, permission, affected.username) IN (#{permission.userID,jdbcType=INTEGER}, @@ -106,7 +106,7 @@ - INSERT INTO [dbo].[guacamole_user_permission] ( + INSERT INTO [guacamole_user_permission] ( user_id, permission, affected_user_id @@ -114,7 +114,7 @@ SELECT DISTINCT permissions.user_id, permissions.permission, - [dbo].[guacamole_user].user_id + [guacamole_user].user_id FROM @@ -123,11 +123,11 @@ #{permission.objectIdentifier,jdbcType=INTEGER} AS username AS permissions - JOIN [dbo].[guacamole_user] ON [dbo].[guacamole_user].username = permissions.username - WHERE NOT EXISTS (SELECT 1 FROM [dbo].[guacamole_user_permission] - WHERE [dbo].[guacamole_user_permission].user_id = permissions.user_id - AND [dbo].[guacamole_user_permission].permission = permissions.permission - AND [dbo].[guacamole_user_permission].affected_user_id = [dbo].[guacamole_user].user_id + JOIN [guacamole_user] ON [guacamole_user].username = permissions.username + WHERE NOT EXISTS (SELECT 1 FROM [guacamole_user_permission] + WHERE [guacamole_user_permission].user_id = permissions.user_id + AND [guacamole_user_permission].permission = permissions.permission + AND [guacamole_user_permission].affected_user_id = [guacamole_user].user_id ); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml index d3b5c10e4..3b4ba0980 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileMapper.xml @@ -33,13 +33,13 @@ SELECT - [dbo].[guacamole_sharing_profile].sharing_profile_id, - [dbo].[guacamole_sharing_profile].sharing_profile_name, + [guacamole_sharing_profile].sharing_profile_id, + [guacamole_sharing_profile].sharing_profile_name, primary_connection_id - FROM [dbo].[guacamole_sharing_profile] - JOIN [dbo].[guacamole_sharing_profile_permission] ON [dbo].[guacamole_sharing_profile_permission].sharing_profile_id = [dbo].[guacamole_sharing_profile].sharing_profile_id - WHERE [dbo].[guacamole_sharing_profile].sharing_profile_id IN + FROM [guacamole_sharing_profile] + JOIN [guacamole_sharing_profile_permission] ON [guacamole_sharing_profile_permission].sharing_profile_id = [guacamole_sharing_profile].sharing_profile_id + WHERE [guacamole_sharing_profile].sharing_profile_id IN #{identifier,jdbcType=INTEGER} @@ -87,7 +87,7 @@ sharing_profile_id, sharing_profile_name, primary_connection_id - FROM [dbo].[guacamole_sharing_profile] + FROM [guacamole_sharing_profile] WHERE primary_connection_id = #{parentIdentifier,jdbcType=INTEGER} AND sharing_profile_name = #{name,jdbcType=VARCHAR} @@ -96,7 +96,7 @@ - DELETE FROM [dbo].[guacamole_sharing_profile] + DELETE FROM [guacamole_sharing_profile] WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} @@ -104,7 +104,7 @@ - INSERT INTO [dbo].[guacamole_sharing_profile] ( + INSERT INTO [guacamole_sharing_profile] ( sharing_profile_name, primary_connection_id ) @@ -117,7 +117,7 @@ - UPDATE [dbo].[guacamole_sharing_profile] + UPDATE [guacamole_sharing_profile] SET sharing_profile_name = #{object.name,jdbcType=VARCHAR}, primary_connection_id = #{object.parentIdentifier,jdbcType=INTEGER} WHERE sharing_profile_id = #{object.objectID,jdbcType=INTEGER} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml index c90227678..a4327b4cd 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/sharingprofile/SharingProfileParameterMapper.xml @@ -36,21 +36,21 @@ sharing_profile_id, parameter_name, parameter_value - FROM [dbo].[guacamole_sharing_profile_parameter] + FROM [guacamole_sharing_profile_parameter] WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} - DELETE FROM [dbo].[guacamole_sharing_profile_parameter] + DELETE FROM [guacamole_sharing_profile_parameter] WHERE sharing_profile_id = #{identifier,jdbcType=INTEGER} - INSERT INTO [dbo].[guacamole_sharing_profile_parameter] ( + INSERT INTO [guacamole_sharing_profile_parameter] ( sharing_profile_id, parameter_name, parameter_value diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml index a9f44e637..562a7471f 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/PasswordRecordMapper.xml @@ -35,16 +35,16 @@ @@ -52,7 +52,7 @@ - INSERT INTO [dbo].[guacamole_user_password_history] ( + INSERT INTO [guacamole_user_password_history] ( user_id, password_hash, password_salt, @@ -65,10 +65,10 @@ #{record.passwordDate,jdbcType=TIMESTAMP} ); - DELETE FROM [dbo].[guacamole_user_password_history] + DELETE FROM [guacamole_user_password_history] WHERE password_history_id IN ( SELECT password_history_id - FROM [dbo].[guacamole_user_password_history] + FROM [guacamole_user_password_history] WHERE user_id = #{record.userID,jdbcType=INTEGER} ORDER BY password_date DESC OFFSET #{maxHistorySize} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml index 465ef2060..6df6cf26d 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml @@ -46,16 +46,16 @@ @@ -79,7 +79,7 @@ email_address, organization, organizational_role - FROM [dbo].[guacamole_user] + FROM [guacamole_user] WHERE username IN @@ -92,7 +92,7 @@ @@ -140,7 +140,7 @@ email_address, organization, organizational_role - FROM [dbo].[guacamole_user] + FROM [guacamole_user] WHERE username = #{username,jdbcType=VARCHAR} @@ -148,7 +148,7 @@ - DELETE FROM [dbo].[guacamole_user] + DELETE FROM [guacamole_user] WHERE username = #{identifier,jdbcType=VARCHAR} @@ -156,7 +156,7 @@ - INSERT INTO [dbo].[guacamole_user] ( + INSERT INTO [guacamole_user] ( username, password_hash, password_salt, @@ -195,7 +195,7 @@ - UPDATE [dbo].[guacamole_user] + UPDATE [guacamole_user] SET password_hash = #{object.passwordHash,jdbcType=BINARY}, password_salt = #{object.passwordSalt,jdbcType=BINARY}, password_date = #{object.passwordDate,jdbcType=TIMESTAMP}, From 7755241322c82f4131785af3e48235be9e890010 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Thu, 7 Sep 2017 22:31:37 -0400 Subject: [PATCH 75/94] GUACMOLE-363: Correct null pointer exception in String comparison; fix style issues. --- .../auth/sqlserver/SQLServerAuthenticationProviderModule.java | 4 ++-- .../apache/guacamole/auth/sqlserver/SQLServerEnvironment.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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 index 22c543403..f514e4198 100644 --- 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 @@ -87,9 +87,9 @@ public class SQLServerAuthenticationProviderModule implements Module { // Look at the property to choose the correct driver. if (sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_JTDS)) JdbcHelper.SQL_Server_jTDS.configure(binder); - else if(sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_DATADIRECT)) + else if (sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_DATADIRECT)) JdbcHelper.SQL_Server_DataDirect.configure(binder); - else if(sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_MS)) + else if (sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_MS)) JdbcHelper.SQL_Server_MS_Driver.configure(binder); else JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); 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 index 2110b0c7d..4d3fabab7 100644 --- 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 @@ -195,7 +195,7 @@ public class SQLServerEnvironment extends JDBCEnvironment { // Check driver property is one of the acceptable values. String driver = getProperty(SQLServerGuacamoleProperties.SQLSERVER_DRIVER); - if (!(driver.equals(SQLSERVER_DRIVER_JTDS) || + if (driver != null && !(driver.equals(SQLSERVER_DRIVER_JTDS) || driver.equals(SQLSERVER_DRIVER_DATADIRECT) || driver.equals(SQLSERVER_DRIVER_MS) || driver.equals(SQLSERVER_DRIVER_MS_2005))) From 74c055e76412797258b540a24cca8ca0bb1ee5df Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 12 Sep 2017 13:14:49 -0400 Subject: [PATCH 76/94] GUACAMOLE-363: Implement new SQLServerDriver data type and property to select the property SQL Server driver. --- ...SQLServerAuthenticationProviderModule.java | 33 +++-- .../auth/sqlserver/SQLServerDriver.java | 46 ++++++ .../sqlserver/SQLServerDriverProperty.java | 60 ++++++++ .../auth/sqlserver/SQLServerEnvironment.java | 133 ++---------------- .../SQLServerGuacamoleProperties.java | 6 +- 5 files changed, 145 insertions(+), 133 deletions(-) create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriver.java create mode 100644 extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriverProperty.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 index f514e4198..ee0584b4f 100644 --- 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 @@ -42,9 +42,9 @@ public class SQLServerAuthenticationProviderModule implements Module { private final Properties driverProperties = new Properties(); /** - * Whether or not to use JTDS Driver + * Which SQL Server driver should be used. */ - private String sqlServerDriver; + private SQLServerDriver sqlServerDriver; /** * Creates a new SQLServer authentication provider module that configures @@ -83,16 +83,25 @@ public class SQLServerAuthenticationProviderModule implements Module { @Override public void configure(Binder binder) { - // Bind SQLServer-specific properties - // Look at the property to choose the correct driver. - if (sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_JTDS)) - JdbcHelper.SQL_Server_jTDS.configure(binder); - else if (sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_DATADIRECT)) - JdbcHelper.SQL_Server_DataDirect.configure(binder); - else if (sqlServerDriver.equals(SQLServerEnvironment.SQLSERVER_DRIVER_MS)) - JdbcHelper.SQL_Server_MS_Driver.configure(binder); - else - JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); + // Bind SQLServer-specific properties with the configured driver. + switch(sqlServerDriver) { + case JTDS: + JdbcHelper.SQL_Server_jTDS.configure(binder); + break; + + case DATA_DIRECT: + JdbcHelper.SQL_Server_DataDirect.configure(binder); + break; + + case MICROSOFT_LEGACY: + JdbcHelper.SQL_Server_MS_Driver.configure(binder); + break; + + case MICROSOFT_2005: + default: + JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); + + } // Bind MyBatis properties Names.bindProperties(binder, myBatisProperties); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriver.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriver.java new file mode 100644 index 000000000..ec01d0668 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriver.java @@ -0,0 +1,46 @@ +/* + * 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; + +/** + * The possible SQL Server drivers to use when using a TDS-compatible database. + */ +public enum SQLServerDriver { + + /** + * The open source jTDS driver. + */ + JTDS, + + /** + * The Progress DataDirect driver. + */ + DATA_DIRECT, + + /** + * The Microsoft Legacy SQL Server driver. + */ + MICROSOFT_LEGACY, + + /** + * The Microsoft 2005 SQL Server driver. + */ + MICROSOFT_2005; +} diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriverProperty.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriverProperty.java new file mode 100644 index 000000000..21a62721c --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-sqlserver/src/main/java/org/apache/guacamole/auth/sqlserver/SQLServerDriverProperty.java @@ -0,0 +1,60 @@ +/* + * 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.GuacamoleServerException; +import org.apache.guacamole.properties.GuacamoleProperty; + +/** + * A property whose value is a SQLServerDriver. The incoming string values of "jtds", "datadirect", + * "microsoft", and "microsoft2005" into the corresponding SQLServerDriver enum value. Any + * values that are not valid result in a parse error. + */ +public abstract class SQLServerDriverProperty implements GuacamoleProperty { + + @Override + public SQLServerDriver parseValue(String value) throws GuacamoleException { + + // If no value provided, return null. + if (value == null) + return null; + + // jTDS Driver + if (value.equals("jtds")) + return SQLServerDriver.JTDS; + + // Progress DataDirect Driver + if (value.equals("datadirect")) + return SQLServerDriver.DATA_DIRECT; + + // Microsoft Legacy Driver + if (value.equals("microsoft")) + return SQLServerDriver.MICROSOFT_LEGACY; + + // Microsoft 2005 Driver + if (value.equals("microsoft2005")) + return SQLServerDriver.MICROSOFT_2005; + + throw new GuacamoleServerException("SQLServer driver must be one of \"jtds\", \"datadirect\", \"microsoft\", \"microsoft2005\"."); + + } + +} 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 index 4d3fabab7..efd7ae106 100644 --- 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 @@ -56,69 +56,36 @@ public class SQLServerEnvironment extends JDBCEnvironment { * 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; + private static 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. + * allowed per user to any one connection. */ - private int DEFAULT_MAX_CONNECTIONS_PER_USER = 1; + private static final 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. + * allowed per user to any one connection group. */ - private int DEFAULT_MAX_GROUP_CONNECTIONS_PER_USER = 1; + private static final 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. + * allowed to any one connection. */ - private int DEFAULT_MAX_CONNECTIONS = 0; + private static final 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. + * allowed to any one connection group. */ - private int DEFAULT_MAX_GROUP_CONNECTIONS = 0; + private static final int DEFAULT_MAX_GROUP_CONNECTIONS = 0; /** - * The value for the sqlserver-driver property that triggers the use of - * the open source JTDS driver. + * The default SQLServer driver to use. */ - public final static String SQLSERVER_DRIVER_JTDS = "jtds"; - - /** - * The value for the sqlserver-driver property that triggers the use of - * the DataDirect JDBC driver. - */ - public final static String SQLSERVER_DRIVER_DATADIRECT = "datadirect"; - - /** - * The value for the sqlserver-driver property that triggers the use of - * the older Microsoft JDBC driver. - */ - public final static String SQLSERVER_DRIVER_MS = "microsoft"; - - /** - * The value for the sqlserver-driver property that triggers the use of - * the Microsoft JDBC driver. This is the default. - */ - public final static String SQLSERVER_DRIVER_MS_2005 = "microsoft2005"; + public static final SQLServerDriver SQLSERVER_DEFAULT_DRIVER = SQLServerDriver.MICROSOFT_2005; /** * Constructs a new SQLServerEnvironment, providing access to SQLServer-specific @@ -133,75 +100,6 @@ public class SQLServerEnvironment extends JDBCEnvironment { // 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); - - } - - // Check driver property is one of the acceptable values. - String driver = getProperty(SQLServerGuacamoleProperties.SQLSERVER_DRIVER); - if (driver != null && !(driver.equals(SQLSERVER_DRIVER_JTDS) || - driver.equals(SQLSERVER_DRIVER_DATADIRECT) || - driver.equals(SQLSERVER_DRIVER_MS) || - driver.equals(SQLSERVER_DRIVER_MS_2005))) - logger.warn("{} property has been set to an invalid value. The default Microsoft 2005 driver will be used.", - SQLServerGuacamoleProperties.SQLSERVER_DRIVER.getName()); - } @Override @@ -337,20 +235,19 @@ public class SQLServerEnvironment extends JDBCEnvironment { } /** - * Returns whether or not to use the SourceForge JTDS driver for more - * generic JTDS connections instead of the Microsoft-provided JDBC driver. + * Returns which JDBC driver should be used to make the SQLServer/TDS connection. * * @return - * True if the JTDS driver should be used; false by default. + * Which TDS-compatible JDBC driver should be used. * * @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 getSQLServerDriver() throws GuacamoleException { + public SQLServerDriver getSQLServerDriver() throws GuacamoleException { return getProperty( SQLServerGuacamoleProperties.SQLSERVER_DRIVER, - SQLSERVER_DRIVER_MS_2005 + SQLSERVER_DEFAULT_DRIVER ); } 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 index 9d9b3864b..8aa02b383 100644 --- 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 @@ -198,10 +198,10 @@ public class SQLServerGuacamoleProperties { }; /** - * Whether or not to use the JTDS driver for SQL Server connections. + * Which TDS-compatible JDBC driver should be used for the connection. */ - public static final StringGuacamoleProperty - SQLSERVER_DRIVER = new StringGuacamoleProperty() { + public static final SQLServerDriverProperty + SQLSERVER_DRIVER = new SQLServerDriverProperty() { @Override public String getName() { return "sqlserver-driver"; } From 82d1b142be887372069ff69397a858183711c61e Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 27 Sep 2017 08:54:43 -0400 Subject: [PATCH 77/94] GUACAMOLE-363: Add binding for permission list rules to data types. --- .../guacamole-auth-jdbc-sqlserver/schema/001-create-schema.sql | 2 ++ 1 file changed, 2 insertions(+) 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 index 1a1e32471..6c3cd7bda 100644 --- 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 @@ -41,11 +41,13 @@ GO; * The permission data type. */ CREATE TYPE [guacamole_permission] FROM [nvarchar](10) NOT NULL; +EXEC sp_bindrule 'guacamole_permission_list','guacamole_permission'; /** * The system permission data type. */ CREATE TYPE [guacamole_system_permission] FROM [nvarchar](32) NOT NULL; +EXEC sp_bindrule 'guacamole_system_permission_list','guacamole_system_permission'; GO; /** From 7ecd3915c6a65a94c57b3d2c181501626e0595d7 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 27 Sep 2017 08:56:28 -0400 Subject: [PATCH 78/94] GUACAMOLE-363: Switch to 4000 for nvarchar size instead of max. --- .../schema/001-create-schema.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 6c3cd7bda..5bb2f8a89 100644 --- 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 @@ -223,7 +223,7 @@ SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_connection_parameter]( [connection_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, - [parameter_value] [nvarchar](max) NOT NULL, + [parameter_value] [nvarchar](4000) NOT NULL, CONSTRAINT [PK_guacamole_connection_parameter] PRIMARY KEY CLUSTERED ([connection_id] ASC, [parameter_name] ASC) @@ -256,7 +256,7 @@ SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_sharing_profile_parameter]( [sharing_profile_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, - [parameter_value] [nvarchar](max) NOT NULL, + [parameter_value] [nvarchar](4000) NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile_parameter] PRIMARY KEY CLUSTERED ([sharing_profile_id] ASC, [parameter_name] ASC) From 0459181e802dd12d868630569a2a508796181487 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 27 Sep 2017 09:05:56 -0400 Subject: [PATCH 79/94] GUACAMOLE-363: Change default driver case to throw an exception instead of default to SQL Server 2005 driver. --- .../sqlserver/SQLServerAuthenticationProviderModule.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 index ee0584b4f..22cb47461 100644 --- 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 @@ -22,6 +22,7 @@ package org.apache.guacamole.auth.sqlserver; import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.name.Names; +import java.lang.UnsupportedOperationException; import java.util.Properties; import org.apache.guacamole.GuacamoleException; import org.mybatis.guice.datasource.helper.JdbcHelper; @@ -98,9 +99,13 @@ public class SQLServerAuthenticationProviderModule implements Module { break; case MICROSOFT_2005: - default: JdbcHelper.SQL_Server_2005_MS_Driver.configure(binder); + break; + default: + throw new UnsupportedOperationException( + "A driver has been specified that is not supported by this module." + ); } // Bind MyBatis properties From 34711b7a92d439aae8af3e51dc295c7d9ae635bf Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 27 Sep 2017 09:22:30 -0400 Subject: [PATCH 80/94] GUACAMOLE-363: Make DEFAULT_USER_REQUIRED false. --- .../apache/guacamole/auth/sqlserver/SQLServerEnvironment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index efd7ae106..20361e630 100644 --- 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 @@ -50,7 +50,7 @@ public class SQLServerEnvironment extends JDBCEnvironment { * Whether a database user account is required by default for authentication * to succeed. */ - private static final boolean DEFAULT_USER_REQUIRED = true; + private static final boolean DEFAULT_USER_REQUIRED = false; /** * The default value for the maximum number of connections to be From 5ef7d116dec53f3842f51669af94f0fba6d9c6ee Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 27 Sep 2017 09:23:56 -0400 Subject: [PATCH 81/94] GUACAMOLE-363: Remove unused properties. --- .../SQLServerGuacamoleProperties.java | 26 ------------------- 1 file changed, 26 deletions(-) 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 index 8aa02b383..45635996f 100644 --- 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 @@ -105,32 +105,6 @@ public class SQLServerGuacamoleProperties { }; - /** - * 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. From b4d2f8761aa5f49c13aa857a4370cfbf8a171679 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 27 Sep 2017 09:38:43 -0400 Subject: [PATCH 82/94] GUACAMOLE-263: Change user creation to use hash values used by other modules. --- .../schema/002-create-admin-user.sql | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 index d348b61ae..15944a28a 100644 --- 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 @@ -20,8 +20,11 @@ /** * Create the default admin user account and set up full privileges. */ -INSERT INTO [guacamole_user] (username, password_hash, password_date) -VALUES ('guacadmin', HASHBYTES('SHA2_256', 'guacadmin'), getdate()); +INSERT INTO [guacamole_user] (username, password_hash, password_salt, password_date) +VALUES ('guacadmin', + 0xCA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960, + 0xFE24ADC5E11E2B25288D1704ABE67A79E342ECC26064CE69C5B3177795A82264, + getdate()); INSERT INTO [guacamole_user_permission] SELECT [guacamole_user].[user_id], [affected].[user_id], permission From 57dab6e815f61306478dbf7e404491149292224f Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Wed, 27 Sep 2017 10:17:13 -0400 Subject: [PATCH 83/94] GUACAMOLE-363: Remove unnecessary parameters that are already using default values. --- .../schema/001-create-schema.sql | 143 +++--------------- 1 file changed, 25 insertions(+), 118 deletions(-) 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 index 5bb2f8a89..a52ad7f41 100644 --- 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 @@ -17,6 +17,17 @@ * under the License. */ +/** + * Turn on ANSI_NULLS for the entire DB to make it ISO-compliant. + */ +ALTER DATABASE CURRENT SET ANSI_NULLS ON; +GO; + +/** + * Turn on QUOTED_IDENTIFIER for the entire DB. + */ +ALTER DATABASE CURRENT SET QUOTED_IDENTIFIER ON; + /** * List for permission data type. */ @@ -53,8 +64,6 @@ GO; /** * The connection_group table stores organizational and balancing groups. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_connection_group]( [connection_group_id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NULL, @@ -65,13 +74,7 @@ CREATE TABLE [guacamole_connection_group]( [enable_session_affinity] [bit] NOT NULL, CONSTRAINT [PK_guacmaole_connection_group] PRIMARY KEY CLUSTERED - ([connection_group_id] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([connection_group_id] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -100,8 +103,6 @@ GO; /** * The connection table, for storing connections and attributes. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_connection]( [connection_id] [int] IDENTITY(1,1) NOT NULL, [connection_name] [nvarchar](128) NOT NULL, @@ -116,13 +117,7 @@ CREATE TABLE [guacamole_connection]( [failover_only] [bit] NOT NULL, CONSTRAINT [PK_guacamole_connection] PRIMARY KEY CLUSTERED - ([connection_id] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([connection_id] ASC) ON [PRIMARY] ) ON [PRIMARY]; ALTER TABLE [guacamole_connection] @@ -142,8 +137,6 @@ GO; /** * The user table stores user accounts, passwords, and properties. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_user]( [user_id] [int] IDENTITY(1,1) NOT NULL, [username] [nvarchar](128) NOT NULL, @@ -163,13 +156,7 @@ CREATE TABLE [guacamole_user]( [organizational_role] [nvarchar](256) NULL, CONSTRAINT [PK_guacamole_user] PRIMARY KEY CLUSTERED - ([user_id] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([user_id] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -185,21 +172,13 @@ GO; * The sharing_profile table stores profiles that allow * connections to be shared amongst multiple users. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_sharing_profile]( [sharing_profile_id] [int] IDENTITY(1,1) NOT NULL, [sharing_profile_name] [nvarchar](128) NOT NULL, [primary_connection_id] [int] NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile] PRIMARY KEY CLUSTERED - ([sharing_profile_id] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([sharing_profile_id] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -218,21 +197,13 @@ GO; * The connection_parameter table stores parameters for * connection objects. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_connection_parameter]( [connection_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](4000) NOT NULL, CONSTRAINT [PK_guacamole_connection_parameter] PRIMARY KEY CLUSTERED - ([connection_id] ASC, [parameter_name] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([connection_id] ASC, [parameter_name] ASC) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]; /** @@ -251,21 +222,13 @@ GO; * The sharing_profile_parameter table stores parameters * for sharing_profile objects. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_sharing_profile_parameter]( [sharing_profile_id] [int] NOT NULL, [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](4000) NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile_parameter] PRIMARY KEY CLUSTERED - ([sharing_profile_id] ASC, [parameter_name] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([sharing_profile_id] ASC, [parameter_name] ASC) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]; /** @@ -285,21 +248,13 @@ GO; * The connection_permission table stores permission * mappings for connection objects. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_connection_permission]( [user_id] [int] NOT NULL, [connection_id] [int] NOT NULL, [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_permission] PRIMARY KEY CLUSTERED - ([user_id] ASC, [connection_id] ASC, [permission] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([user_id] ASC, [connection_id] ASC, [permission] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -325,21 +280,13 @@ GO; * The connection_group_permission table stores permission mappings for * connection_group objects. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_connection_group_permission]( [user_id] [int] NOT NULL, [connection_group_id] [int] NOT NULL, [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_group_permission] PRIMARY KEY CLUSTERED - ([user_id] ASC, [connection_group_id] ASC, [permission] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([user_id] ASC, [connection_group_id] ASC, [permission] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -365,21 +312,13 @@ GO; * The sharing_profile_permission table stores permission * mappings for sharing_profile objects. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_sharing_profile_permission]( [user_id] [int] NOT NULL, [sharing_profile_id] [int] NOT NULL, [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile_permission] PRIMARY KEY CLUSTERED - ([user_id] ASC, [sharing_profile_id] ASC, [permission] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([user_id] ASC, [sharing_profile_id] ASC, [permission] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -405,20 +344,12 @@ GO; * The system_permission table stores permission mappings * for system-level operations. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_system_permission]( [user_id] [int] NOT NULL, [permission] [guacamole_system_permission] NOT NULL, CONSTRAINT [PK_guacamole_system_permission] PRIMARY KEY CLUSTERED - ([user_id] ASC, [permission] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([user_id] ASC, [permission] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -437,21 +368,13 @@ GO; * The user_permission table stores permission mappings * for users to other users. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_user_permission]( [user_id] [int] NOT NULL, [affected_user_id] [int] NOT NULL, [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_user_permission] PRIMARY KEY CLUSTERED - ([user_id] ASC, [affected_user_id] ASC, [permission] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([user_id] ASC, [affected_user_id] ASC, [permission] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -475,8 +398,6 @@ GO; * The connection_history table stores records for historical * connections. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_connection_history]( [history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NULL, @@ -490,13 +411,7 @@ CREATE TABLE [guacamole_connection_history]( [end_date] [datetime] NULL, CONSTRAINT [PK_guacamole_connection_history] PRIMARY KEY CLUSTERED - ([history_id] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([history_id] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -510,7 +425,7 @@ ALTER TABLE [guacamole_connection_history] ALTER TABLE [guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_connection]; ALTER TABLE [guacamole_connection_history] - WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_sharing_profile] FOREIGN KEY([sharing_profile_id]) + WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_history_sharing_profile] FOREIGN KEY([sharing_profile_id]) REFERENCES [guacamole_sharing_profile] ([sharing_profile_id]); ALTER TABLE [guacamole_connection_history] CHECK CONSTRAINT [FK_guacamole_connection_history_sharing_profile]; @@ -528,8 +443,6 @@ GO; * for users, allowing for enforcing rules associated with * reuse of passwords. */ -SET ANSI_NULLS ON; -SET QUOTED_IDENTIFIER ON; CREATE TABLE [guacamole_user_password_history]( [password_history_id] [int] IDENTITY(1,1) NOT NULL, [user_id] [int] NOT NULL, @@ -538,13 +451,7 @@ CREATE TABLE [guacamole_user_password_history]( [password_date] [datetime] NOT NULL, CONSTRAINT [PK_guacamole_user_password_history] PRIMARY KEY CLUSTERED - ([password_history_id] ASC) - WITH (PAD_INDEX = OFF, - STATISTICS_NORECOMPUTE = OFF, - IGNORE_DUP_KEY = OFF, - ALLOW_ROW_LOCKS = ON, - ALLOW_PAGE_LOCKS = ON) - ON [PRIMARY] + ([password_history_id] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** From e084f85d1804fede4576af9a8fc124e29959896f Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Thu, 28 Sep 2017 08:41:56 -0400 Subject: [PATCH 84/94] GUACAMOLE-363: Update ConnectionRecordMapper to new ActivityRecordSet class. --- .../guacamole/auth/jdbc/connection/ConnectionRecordMapper.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index bca8139d2..d7ae41c4b 100644 --- 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 @@ -127,7 +127,7 @@ - + - + Date: Sat, 30 Sep 2017 16:45:48 -0400 Subject: [PATCH 85/94] GUACAMOLE-363: Clean up formatting on SQL schema file. --- .../schema/001-create-schema.sql | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) 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 index a52ad7f41..c64f6f971 100644 --- 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 @@ -42,10 +42,10 @@ GO; CREATE RULE [guacamole_system_permission_list] AS @list IN ('CREATE_CONNECTION', - 'CREATE_CONNECTION_GROUP', - 'CREATE_SHARING_PROFILE', - 'CREATE_USER', - 'ADMINISTER'); + 'CREATE_CONNECTION_GROUP', + 'CREATE_SHARING_PROFILE', + 'CREATE_USER', + 'ADMINISTER'); GO; /** @@ -65,16 +65,16 @@ GO; * The connection_group table stores organizational and balancing groups. */ CREATE TABLE [guacamole_connection_group]( - [connection_group_id] [int] IDENTITY(1,1) NOT NULL, - [parent_id] [int] NULL, - [connection_group_name] [nvarchar](128) NOT NULL, - [type] [nvarchar](32) NOT NULL, - [max_connections] [int] NULL, + [connection_group_id] [int] IDENTITY(1,1) NOT NULL, + [parent_id] [int] NULL, + [connection_group_name] [nvarchar](128) NOT NULL, + [type] [nvarchar](32) NOT NULL, + [max_connections] [int] NULL, [max_connections_per_user] [int] NULL, - [enable_session_affinity] [bit] NOT NULL, + [enable_session_affinity] [bit] NOT NULL, CONSTRAINT [PK_guacmaole_connection_group] PRIMARY KEY CLUSTERED - ([connection_group_id] ASC) ON [PRIMARY] + ([connection_group_id] ASC) ON [PRIMARY] ) ON [PRIMARY]; /** @@ -82,7 +82,7 @@ CREATE TABLE [guacamole_connection_group]( */ ALTER TABLE [guacamole_connection_group] WITH CHECK ADD CONSTRAINT [FK_guacamole_connection_group_connection_group_id] FOREIGN KEY([parent_id]) - REFERENCES [guacamole_connection_group] ([connection_group_id]); + REFERENCES [guacamole_connection_group] ([connection_group_id]); ALTER TABLE [guacamole_connection_group] CHECK CONSTRAINT [FK_guacamole_connection_group_connection_group_id]; ALTER TABLE [guacamole_connection_group] @@ -104,17 +104,17 @@ GO; * The connection table, for storing connections and attributes. */ CREATE TABLE [guacamole_connection]( - [connection_id] [int] IDENTITY(1,1) NOT NULL, - [connection_name] [nvarchar](128) NOT NULL, - [parent_id] [int] NULL, - [protocol] [nvarchar](32) NOT NULL, - [proxy_port] [int] NULL, - [proxy_hostname] [nvarchar](512) NULL, - [proxy_encryption_method] [nvarchar](4) NULL, - [max_connections] [int] NULL, + [connection_id] [int] IDENTITY(1,1) NOT NULL, + [connection_name] [nvarchar](128) NOT NULL, + [parent_id] [int] NULL, + [protocol] [nvarchar](32) NOT NULL, + [proxy_port] [int] NULL, + [proxy_hostname] [nvarchar](512) NULL, + [proxy_encryption_method] [nvarchar](4) NULL, + [max_connections] [int] NULL, [max_connections_per_user] [int] NULL, - [connection_weight] [int] NULL, - [failover_only] [bit] NOT NULL, + [connection_weight] [int] NULL, + [failover_only] [bit] NOT NULL, CONSTRAINT [PK_guacamole_connection] PRIMARY KEY CLUSTERED ([connection_id] ASC) ON [PRIMARY] @@ -138,22 +138,22 @@ GO; * The user table stores user accounts, passwords, and properties. */ CREATE TABLE [guacamole_user]( - [user_id] [int] IDENTITY(1,1) NOT NULL, - [username] [nvarchar](128) NOT NULL, - [password_hash] [binary](32) NOT NULL, - [password_salt] [binary](32) NULL, - [password_date] [datetime] NOT NULL, - [disabled] [bit] NOT NULL, - [expired] [bit] NOT NULL, - [access_window_start] [time](7) NULL, - [access_window_end] [time](7) NULL, - [valid_from] [date] NULL, - [valid_until] [date] NULL, - [timezone] [nvarchar](64) NULL, - [full_name] [nvarchar](256) NULL, - [email_address] [nvarchar](256) NULL, - [organization] [nvarchar](256) NULL, - [organizational_role] [nvarchar](256) NULL, + [user_id] [int] IDENTITY(1,1) NOT NULL, + [username] [nvarchar](128) NOT NULL, + [password_hash] [binary](32) NOT NULL, + [password_salt] [binary](32) NULL, + [password_date] [datetime] NOT NULL, + [disabled] [bit] NOT NULL, + [expired] [bit] NOT NULL, + [access_window_start] [time](7) NULL, + [access_window_end] [time](7) NULL, + [valid_from] [date] NULL, + [valid_until] [date] NULL, + [timezone] [nvarchar](64) NULL, + [full_name] [nvarchar](256) NULL, + [email_address] [nvarchar](256) NULL, + [organization] [nvarchar](256) NULL, + [organizational_role] [nvarchar](256) NULL, CONSTRAINT [PK_guacamole_user] PRIMARY KEY CLUSTERED ([user_id] ASC) ON [PRIMARY] @@ -173,8 +173,8 @@ GO; * connections to be shared amongst multiple users. */ CREATE TABLE [guacamole_sharing_profile]( - [sharing_profile_id] [int] IDENTITY(1,1) NOT NULL, - [sharing_profile_name] [nvarchar](128) NOT NULL, + [sharing_profile_id] [int] IDENTITY(1,1) NOT NULL, + [sharing_profile_name] [nvarchar](128) NOT NULL, [primary_connection_id] [int] NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile] PRIMARY KEY CLUSTERED @@ -198,8 +198,8 @@ GO; * connection objects. */ CREATE TABLE [guacamole_connection_parameter]( - [connection_id] [int] NOT NULL, - [parameter_name] [nvarchar](128) NOT NULL, + [connection_id] [int] NOT NULL, + [parameter_name] [nvarchar](128) NOT NULL, [parameter_value] [nvarchar](4000) NOT NULL, CONSTRAINT [PK_guacamole_connection_parameter] PRIMARY KEY CLUSTERED @@ -224,8 +224,8 @@ GO; */ CREATE TABLE [guacamole_sharing_profile_parameter]( [sharing_profile_id] [int] NOT NULL, - [parameter_name] [nvarchar](128) NOT NULL, - [parameter_value] [nvarchar](4000) NOT NULL, + [parameter_name] [nvarchar](128) NOT NULL, + [parameter_value] [nvarchar](4000) NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile_parameter] PRIMARY KEY CLUSTERED ([sharing_profile_id] ASC, [parameter_name] ASC) ON [PRIMARY] @@ -249,9 +249,9 @@ GO; * mappings for connection objects. */ CREATE TABLE [guacamole_connection_permission]( - [user_id] [int] NOT NULL, + [user_id] [int] NOT NULL, [connection_id] [int] NOT NULL, - [permission] [guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_id] ASC, [permission] ASC) ON [PRIMARY] @@ -281,9 +281,9 @@ GO; * connection_group objects. */ CREATE TABLE [guacamole_connection_group_permission]( - [user_id] [int] NOT NULL, + [user_id] [int] NOT NULL, [connection_group_id] [int] NOT NULL, - [permission] [guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_connection_group_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [connection_group_id] ASC, [permission] ASC) ON [PRIMARY] @@ -313,9 +313,9 @@ GO; * mappings for sharing_profile objects. */ CREATE TABLE [guacamole_sharing_profile_permission]( - [user_id] [int] NOT NULL, + [user_id] [int] NOT NULL, [sharing_profile_id] [int] NOT NULL, - [permission] [guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_sharing_profile_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [sharing_profile_id] ASC, [permission] ASC) ON [PRIMARY] @@ -345,7 +345,7 @@ GO; * for system-level operations. */ CREATE TABLE [guacamole_system_permission]( - [user_id] [int] NOT NULL, + [user_id] [int] NOT NULL, [permission] [guacamole_system_permission] NOT NULL, CONSTRAINT [PK_guacamole_system_permission] PRIMARY KEY CLUSTERED @@ -369,9 +369,9 @@ GO; * for users to other users. */ CREATE TABLE [guacamole_user_permission]( - [user_id] [int] NOT NULL, + [user_id] [int] NOT NULL, [affected_user_id] [int] NOT NULL, - [permission] [guacamole_permission] NOT NULL, + [permission] [guacamole_permission] NOT NULL, CONSTRAINT [PK_guacamole_user_permission] PRIMARY KEY CLUSTERED ([user_id] ASC, [affected_user_id] ASC, [permission] ASC) ON [PRIMARY] @@ -399,16 +399,16 @@ GO; * connections. */ CREATE TABLE [guacamole_connection_history]( - [history_id] [int] IDENTITY(1,1) NOT NULL, - [user_id] [int] NULL, - [username] [nvarchar](128) NOT NULL, - [remote_host] [nvarchar](256) NULL, - [connection_id] [int] NULL, - [connection_name] [nvarchar](128) NOT NULL, - [sharing_profile_id] [int] NULL, + [history_id] [int] IDENTITY(1,1) NOT NULL, + [user_id] [int] NULL, + [username] [nvarchar](128) NOT NULL, + [remote_host] [nvarchar](256) NULL, + [connection_id] [int] NULL, + [connection_name] [nvarchar](128) NOT NULL, + [sharing_profile_id] [int] NULL, [sharing_profile_name] [nvarchar](128) NULL, - [start_date] [datetime] NOT NULL, - [end_date] [datetime] NULL, + [start_date] [datetime] NOT NULL, + [end_date] [datetime] NULL, CONSTRAINT [PK_guacamole_connection_history] PRIMARY KEY CLUSTERED ([history_id] ASC) ON [PRIMARY] @@ -445,10 +445,10 @@ GO; */ CREATE TABLE [guacamole_user_password_history]( [password_history_id] [int] IDENTITY(1,1) NOT NULL, - [user_id] [int] NOT NULL, - [password_hash] [binary](32) NOT NULL, - [password_salt] [binary](32) NULL, - [password_date] [datetime] NOT NULL, + [user_id] [int] NOT NULL, + [password_hash] [binary](32) NOT NULL, + [password_salt] [binary](32) NULL, + [password_date] [datetime] NOT NULL, CONSTRAINT [PK_guacamole_user_password_history] PRIMARY KEY CLUSTERED ([password_history_id] ASC) ON [PRIMARY] From 56bce8dbe73c049c0654ad54f59a38dfdce92fa3 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Sat, 30 Sep 2017 16:49:49 -0400 Subject: [PATCH 86/94] GUACAMOLE-363: Add SQL Server components to JDBC dist. --- .../modules/guacamole-auth-jdbc-dist/pom.xml | 7 +++++++ .../guacamole-auth-jdbc-dist/project-assembly.xml | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/pom.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/pom.xml index 7b51fa2b7..05f5572d4 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/pom.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/pom.xml @@ -109,6 +109,13 @@ 0.9.13-incubating + + + org.apache.guacamole + guacamole-auth-jdbc-sqlserver + 0.9.13-incubating + + diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/project-assembly.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/project-assembly.xml index 523b3a05e..58c886ceb 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/project-assembly.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-dist/project-assembly.xml @@ -49,6 +49,14 @@ + + + sqlserver + + org.apache.guacamole:guacamole-auth-jdbc-sqlserver + + + @@ -72,6 +80,12 @@ ../guacamole-auth-jdbc-postgresql/schema + + + sqlserver/schema + ../guacamole-auth-jdbc-sqlserver/schema + + From f8484befaf44fb0e7dfad80a3a07ca96e0f2d959 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Fri, 6 Oct 2017 10:22:10 -0400 Subject: [PATCH 87/94] GUACAMOLE-364: addressed various documentation issues --- .../AuthenticationFailureListener.java | 17 +++--- .../AuthenticationSuccessListener.java | 21 ++++--- .../net/event/listener/Listener.java | 4 +- .../event/listener/TunnelCloseListener.java | 25 ++++---- .../event/listener/TunnelConnectListener.java | 37 ++++++------ .../extension/ExtensionManifest.java | 2 +- .../guacamole/extension/ExtensionModule.java | 10 ++-- .../guacamole/extension/ListenerFactory.java | 58 +++++++++++++------ .../guacamole/extension/ProviderFactory.java | 18 ++++-- .../rest/auth/AuthenticationService.java | 15 +++-- .../guacamole/rest/event/ListenerService.java | 8 ++- .../tunnel/TunnelRequestService.java | 10 ++-- 12 files changed, 136 insertions(+), 89 deletions(-) diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java index 1971af89b..6e707e6c5 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationFailureListener.java @@ -28,7 +28,7 @@ import org.apache.guacamole.net.event.AuthenticationFailureEvent; * be used to cancel the authentication failure. * * @deprecated - * Listeners should instead implement the {@link Listener} interface + * Listeners should instead implement the {@link Listener} interface. */ @Deprecated public interface AuthenticationFailureListener { @@ -37,12 +37,15 @@ public interface AuthenticationFailureListener { * Event hook which fires immediately after a user's authentication attempt * fails. * - * @param e The AuthenticationFailureEvent describing the authentication - * failure that just occurred. - * @throws GuacamoleException If an error occurs while handling the - * authentication failure event. Note that - * throwing an exception will NOT cause the - * authentication failure to be canceled. + * @param e + * The AuthenticationFailureEvent describing the authentication + * failure that just occurred. + * + * @throws GuacamoleException + * If an error occurs while handling the authentication failure event. + * Note that throwing an exception will NOT cause the authentication + * failure to be canceled (which makes no sense), but it will prevent + * subsequent listeners from receiving the notification. */ void authenticationFailed(AuthenticationFailureEvent e) throws GuacamoleException; diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java index 77a6ed1b2..29be27cf6 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java @@ -39,15 +39,18 @@ public interface AuthenticationSuccessListener { * succeeds. The return value of this hook dictates whether the * successful authentication attempt is canceled. * - * @param e The AuthenticationFailureEvent describing the authentication - * failure that just occurred. - * @return true if the successful authentication attempt should be - * allowed, or false if the attempt should be denied, causing - * the attempt to effectively fail. - * @throws GuacamoleException If an error occurs while handling the - * authentication success event. Throwing an - * exception will also cancel the authentication - * success. + * @param e + * The AuthenticationFailureEvent describing the authentication + * failure that just occurred. + * + * @return + * true if the successful authentication attempt should be + * allowed, or false if the attempt should be denied, causing + * the attempt to effectively fail. + * + * @throws GuacamoleException + * If an error occurs while handling the authentication success event. + * Throwing an exception will also cancel the authentication success. */ boolean authenticationSucceeded(AuthenticationSuccessEvent e) throws GuacamoleException; diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java index d21f68681..af480b7e0 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/Listener.java @@ -39,12 +39,12 @@ public interface Listener { * details. * * @param event - * an object that describes the subject event + * An object that describes the event that has occurred. * * @throws GuacamoleException * If the listener wishes to stop notification of the event to subsequent * listeners. For some event types, this acts to veto an action in progress; - * e.g. treating a successful authentication as though it failed + * e.g. treating a successful authentication as though it failed. */ void handleEvent(Object event) throws GuacamoleException; diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java index 70677b3ac..82da7250b 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java @@ -27,7 +27,7 @@ import org.apache.guacamole.net.event.TunnelCloseEvent; * existing tunnel is closed. * * @deprecated - * Listeners should instead implement the {@link Listener} interface + * Listeners should instead implement the {@link Listener} interface. */ @Deprecated public interface TunnelCloseListener { @@ -37,16 +37,19 @@ public interface TunnelCloseListener { * The return value of this hook dictates whether the tunnel is allowed to * be closed. * - * @param e The TunnelCloseEvent describing the tunnel being closed and - * any associated credentials. - * @return true if the tunnel should be allowed to be closed, or false - * if the attempt should be denied, causing the attempt to - * effectively fail. - * @throws GuacamoleException If an error occurs while handling the - * tunnel close event. Throwing an exception - * will also stop the tunnel from being closed. + * @param e + * The TunnelCloseEvent describing the tunnel being closed and + * any associated credentials. + * + * @return + * true if the tunnel should be allowed to be closed, or false + * if the attempt should be denied, causing the attempt to + * effectively fail. + * + * @throws GuacamoleException + * If an error occurs while handling the tunnel close event. Throwing + * an exception will also stop the tunnel from being closed. */ - boolean tunnelClosed(TunnelCloseEvent e) - throws GuacamoleException; + boolean tunnelClosed(TunnelCloseEvent e) throws GuacamoleException; } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java index edc144e29..e224f7430 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelConnectListener.java @@ -27,27 +27,30 @@ import org.apache.guacamole.net.event.TunnelConnectEvent; * tunnel is connected. * * @deprecated - * Listeners should instead implement the {@link Listener} interface + * Listeners should instead implement the {@link Listener} interface. */ @Deprecated public interface TunnelConnectListener { /** - * Event hook which fires immediately after a new tunnel is connected. - * The return value of this hook dictates whether the tunnel is made visible - * to the session. - * - * @param e The TunnelConnectEvent describing the tunnel being connected and - * any associated credentials. - * @return true if the tunnel should be allowed to be connected, or false - * if the attempt should be denied, causing the attempt to - * effectively fail. - * @throws GuacamoleException If an error occurs while handling the - * tunnel connect event. Throwing an exception - * will also stop the tunnel from being made - * visible to the session. - */ - boolean tunnelConnected(TunnelConnectEvent e) - throws GuacamoleException; + * Event hook which fires immediately after a new tunnel is connected. + * The return value of this hook dictates whether the tunnel is made visible + * to the session. + * + * @param e + * The TunnelConnectEvent describing the tunnel being connected and + * any associated credentials. + * + * @return + * true if the tunnel should be allowed to be connected, or false + * if the attempt should be denied, causing the attempt to + * effectively fail. + * + * @throws GuacamoleException + * If an error occurs while handling the tunnel connect event. Throwing + * an exception will also stop the tunnel from being made visible to the + * session. + */ + boolean tunnelConnected(TunnelConnectEvent e) throws GuacamoleException; } diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java index 1636b0350..054d9ef3d 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java @@ -380,7 +380,7 @@ public class ExtensionManifest { * class name. * * @param listeners - * a collection of classnames for all listeners within the extension + * A collection of classnames for all listeners within the extension. */ public void setListeners(Collection listeners) { this.listeners = listeners; 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 e7cdedb80..a74c4c0d6 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java @@ -198,13 +198,13 @@ public class ExtensionModule extends ServletModule { * Binds the given provider class such that a listener is bound for each * listener interface implemented by the provider and such that all bound * listener instances can be obtained via injection. - * * + * * @param providerClass - * The listener provider class to bind + * The listener class to bind. */ - private void bindListeners(Class providerClass) { + private void bindListener(Class providerClass) { - logger.debug("[{}] Binding listeners \"{}\".", + logger.debug("[{}] Binding listener \"{}\".", boundListeners.size(), providerClass.getName()); boundListeners.addAll(ListenerFactory.createListeners(providerClass)); @@ -222,7 +222,7 @@ public class ExtensionModule extends ServletModule { // Bind each listener within extension for (Class listener : listeners) - bindListeners(listener); + bindListener(listener); } /** 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 c11f00f5d..8aa6babb4 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ListenerFactory.java @@ -45,10 +45,10 @@ class ListenerFactory { * objects that adapt the legacy listener interfaces will be returned. * * @param providerClass - * a class that represents a listener provider + * A class that represents a listener. * * @return - * list of listeners represented by the given provider class + * The list of listeners represented by the given provider class. */ static List createListeners(Class providerClass) { @@ -62,6 +62,16 @@ class ListenerFactory { } + /** + * Creates a list of adapters for the given object, based on the legacy + * listener interfaces it implements. + * + * @param provider + * An object that implements zero or more legacy listener interfaces. + * + * @return + * The list of listeners represented by the given provider class. + */ @SuppressWarnings("deprecation") private static List createListenerAdapters(Object provider) { @@ -98,13 +108,16 @@ class ListenerFactory { @SuppressWarnings("deprecation") private static class AuthenticationSuccessListenerAdapter implements Listener { + /** + * The delegate listener for this adapter. + */ private final AuthenticationSuccessListener delegate; /** - * Constructs a new adapter. + * Constructs a new adapter that delivers events to the given delegate. * * @param delegate - * the delegate listener + * The delegate listener. */ AuthenticationSuccessListenerAdapter(AuthenticationSuccessListener delegate) { this.delegate = delegate; @@ -116,10 +129,10 @@ class ListenerFactory { * to veto the authentication success event. All other event types are ignored. * * @param event - * an object that describes the subject event + * An object that describes the event that occurred. * * @throws GuacamoleException - * if thrown by the delegate listener + * If thrown by the delegate listener. */ @Override public void handleEvent(Object event) throws GuacamoleException { @@ -140,13 +153,16 @@ class ListenerFactory { @SuppressWarnings("deprecation") private static class AuthenticationFailureListenerAdapter implements Listener { + /** + * The delegate listener for this adapter. + */ private final AuthenticationFailureListener delegate; /** - * Constructs a new adapter. + * Constructs a new adapter that delivers events to the given delegate. * * @param delegate - * the delegate listener + * The delegate listener. */ AuthenticationFailureListenerAdapter(AuthenticationFailureListener delegate) { this.delegate = delegate; @@ -157,10 +173,10 @@ class ListenerFactory { * listener. All other event types are ignored. * * @param event - * an object that describes the subject event + * An object that describes the event that occurred. * * @throws GuacamoleException - * if thrown by the delegate listener + * If thrown by the delegate listener. */ @Override public void handleEvent(Object event) throws GuacamoleException { @@ -178,13 +194,16 @@ class ListenerFactory { @SuppressWarnings("deprecation") private static class TunnelConnectListenerAdapter implements Listener { + /** + * The delegate listener for this adapter. + */ private final TunnelConnectListener delegate; /** - * Constructs a new adapter. + * Constructs a new adapter that delivers events to the given delegate. * * @param delegate - * the delegate listener + * The delegate listener. */ TunnelConnectListenerAdapter(TunnelConnectListener delegate) { this.delegate = delegate; @@ -196,10 +215,10 @@ class ListenerFactory { * to veto the tunnel connect event. All other event types are ignored. * * @param event - * an object that describes the subject event + * An object that describes the event that occurred. * * @throws GuacamoleException - * if thrown by the delegate listener + * If thrown by the delegate listener. */ @Override public void handleEvent(Object event) throws GuacamoleException { @@ -219,13 +238,16 @@ class ListenerFactory { @SuppressWarnings("deprecation") private static class TunnelCloseListenerAdapter implements Listener { + /** + * The delegate listener for this adapter. + */ private final TunnelCloseListener delegate; /** - * Constructs a new adapter. + * Constructs a new adapter that delivers events to the given delegate. * * @param delegate - * the delegate listener + * The delegate listener. */ TunnelCloseListenerAdapter(TunnelCloseListener delegate) { this.delegate = delegate; @@ -237,10 +259,10 @@ class ListenerFactory { * to veto the tunnel connect event. All other event types are ignored. * * @param event - * an object that describes the subject event + * An object that describes the event that occurred. * * @throws GuacamoleException - * if thrown by the delegate listener + * If thrown by the delegate listener. */ @Override public void handleEvent(Object event) throws GuacamoleException { 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 376b213d6..01fda5719 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ProviderFactory.java @@ -26,24 +26,30 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationTargetException; /** - * Static factory method for creating provider instances and logging unexpected outcomes - * with sufficient detail to allow user/developer debugging. + * A utility for creating provider instances and logging unexpected outcomes + * with sufficient detail to allow debugging. */ class ProviderFactory { + /** + * Logger used to log unexpected outcomes. + */ private static final Logger logger = LoggerFactory.getLogger(ProviderFactory.class); /** * Creates an instance of the specified provider class using the no-arg constructor. * * @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 + * The provider class to instantiate. + * * @param - * The provider type + * The provider type. + * * @return - * A provider instance or null if no instance was created due to error + * A provider instance or null if no instance was created due to error. */ static T newInstance(String typeName, Class providerClass) { T instance = null; diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java index bdefc3efb..b18f00f4a 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java @@ -79,7 +79,7 @@ public class AuthenticationService { private AuthTokenGenerator authTokenGenerator; /** - * The service to use to notify registered authentication listeners + * The service to use to notify registered authentication listeners. */ @Inject private ListenerService listenerService; @@ -222,11 +222,13 @@ public class AuthenticationService { * has occurred. * * @param authenticatedUser - * The user that was successfully authenticated + * The user that was successfully authenticated. + * * @param session - * Existing session for the user (if any) + * The existing session for the user (if any). + * * @throws GuacamoleException - * If thrown by a listener + * If thrown by a listener. */ private void fireAuthenticationSuccessEvent( AuthenticatedUser authenticatedUser, GuacamoleSession session) @@ -246,9 +248,10 @@ public class AuthenticationService { * Notify all bound listeners that an authentication attempt has failed. * * @param credentials - * The credentials that failed to authenticate + * The credentials that failed to authenticate. + * * @throws GuacamoleException - * If thrown by a listener + * If thrown by a listener. */ private void fireAuthenticationFailedEvent(Credentials credentials) throws GuacamoleException { diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java index bbff8ee4b..e92cc8a66 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/event/ListenerService.java @@ -30,6 +30,9 @@ import org.apache.guacamole.net.event.listener.Listener; */ public class ListenerService implements Listener { + /** + * The collection of registered listeners. + */ @Inject private List listeners; @@ -39,9 +42,10 @@ public class ListenerService implements Listener { * until all listeners have been notified. * * @param event - * an object that describes the subject event + * An object that describes the event that has occurred. * - * @throws GuacamoleException if a registered listener throws a GuacamoleException + * @throws GuacamoleException + * If a registered listener throws a GuacamoleException. */ @Override public void handleEvent(Object event) throws GuacamoleException { diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java index d3543d748..b029a3050 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequestService.java @@ -76,13 +76,13 @@ public class TunnelRequestService { * being created. * * @param credentials - * Credentials that authenticate the user + * Credentials that authenticate the user. * * @param tunnel - * The tunnel that was connected + * The tunnel that was connected. * * @throws GuacamoleException - * If thrown by a listener or if any listener vetoes the connected tunnel + * If thrown by a listener or if any listener vetoes the connected tunnel. */ private void fireTunnelConnectEvent(UserContext userContext, Credentials credentials, GuacamoleTunnel tunnel) throws GuacamoleException { @@ -99,10 +99,10 @@ public class TunnelRequestService { * being created. * * @param credentials - * Credentials that authenticate the user + * Credentials that authenticate the user. * * @param tunnel - * The tunnel that was connected + * The tunnel that was connected. * * @throws GuacamoleException * If thrown by a listener. From 25705a86e85f392deba3bcf43a8d669f70b8fce4 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Fri, 6 Oct 2017 10:26:26 -0400 Subject: [PATCH 88/94] GUACAMOLE-364: addressed some documentation stragglers --- .../net/event/listener/AuthenticationSuccessListener.java | 2 +- .../guacamole/net/event/listener/TunnelCloseListener.java | 2 +- .../java/org/apache/guacamole/extension/ExtensionManifest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java index 29be27cf6..6ba05a3f1 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/AuthenticationSuccessListener.java @@ -29,7 +29,7 @@ import org.apache.guacamole.net.event.AuthenticationSuccessEvent; * authentication and force it to fail. * * @deprecated - * Listeners should instead implement the {@link Listener} interface + * Listeners should instead implement the {@link Listener} interface. */ @Deprecated public interface AuthenticationSuccessListener { diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java index 82da7250b..84d765815 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/event/listener/TunnelCloseListener.java @@ -23,7 +23,7 @@ import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.event.TunnelCloseEvent; /** - * A listener whose tunnelClosed() hook will fire immediately after an + * A listener whose tunnelClosed() hook will fire immediately before an * existing tunnel is closed. * * @deprecated diff --git a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java index 054d9ef3d..2ed6c7579 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionManifest.java @@ -367,7 +367,7 @@ public class ExtensionManifest { * class name. * * @return - * a collection of classnames for all listeners within the extension + * A collection of classnames for all listeners within the extension. */ public Collection getListeners() { return listeners; From 5c07e4a4eeabf68c5fa1ea24ced373ac8d697bbf Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Sat, 7 Oct 2017 10:07:20 -0400 Subject: [PATCH 89/94] GUACAMOLE-408: revise Dockerfile to use multi-stage image build --- Dockerfile | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index bd8131f28..ebc3cb0c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,29 +21,36 @@ # Dockerfile for guacamole-client # -# Start from Tomcat image -FROM tomcat:8.0.20-jre8 +# Use args for Tomcat image label to allow image builder to choose alternatives +# such as `--build-arg TOMCAT_JRE=jre8-alpine` +# +ARG TOMCAT_VERSION=8.0.20 +ARG TOMCAT_JRE=jre8 -# Environment variables +# Use official maven image for the build +FROM maven:3-jdk-8 AS builder + +# Build environment variables ENV \ - BUILD_DIR=/tmp/guacamole-docker-BUILD \ - BUILD_DEPENDENCIES=" \ - maven \ - openjdk-8-jdk-headless" + BUILD_DIR=/tmp/guacamole-docker-BUILD # Add configuration scripts -COPY guacamole-docker/bin /opt/guacamole/bin/ +COPY guacamole-docker/bin/ /opt/guacamole/bin/ # Copy source to container for sake of build COPY . "$BUILD_DIR" -# Build latest guacamole-client and authentication -RUN apt-get update && \ - apt-get install -y --no-install-recommends $BUILD_DEPENDENCIES && \ - /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole && \ - rm -Rf "$BUILD_DIR" && \ - rm -Rf /var/lib/apt/lists/* && \ - apt-get purge -y --auto-remove $BUILD_DEPENDENCIES +# Run the build itself +RUN /opt/guacamole/bin/build-guacamole.sh "$BUILD_DIR" /opt/guacamole + +# For the runtime image, we start with the official Tomcat distribution +FROM tomcat:${TOMCAT_VERSION}-${TOMCAT_JRE} + +# This is where the build artifacts go in the runtime image +WORKDIR /opt/guacamole + +# Copy artifacts from builder image into this image +COPY --from=builder /opt/guacamole/ . # Start Guacamole under Tomcat, listening on 0.0.0.0:8080 EXPOSE 8080 From ac50375ad526ba6f1453ca10e32b6f393e6e486d Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Sat, 7 Oct 2017 10:09:18 -0400 Subject: [PATCH 90/94] GUACAMOLE-408: don't try to clean up the local Maven repository There's no need to clean up the local Maven repository after the build, since only the artifacts we want are copied to the runtime image. For reasons not investigated, attempting to remove the local repository directory fails because the directory is in use after the build. --- guacamole-docker/bin/build-guacamole.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/guacamole-docker/bin/build-guacamole.sh b/guacamole-docker/bin/build-guacamole.sh index 4df6289f0..41e01b500 100755 --- a/guacamole-docker/bin/build-guacamole.sh +++ b/guacamole-docker/bin/build-guacamole.sh @@ -54,7 +54,6 @@ mkdir -p "$DESTINATION" cd "$BUILD_DIR" mvn package -rm -Rf ~/.m2 # # Copy guacamole.war to destination From 70db9a4c42418fdc520e4f3d6414a0e753a79266 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Sat, 7 Oct 2017 10:12:49 -0400 Subject: [PATCH 91/94] GUACAMOLE-408: exclude generated HTML files from rat validation When building inside of the Docker container, some files with generated HTML are being validated by RAT and failing due to the lack of a license header. When building outside of Docker, this problem does not occur. Not sure why these paths don't fail when building outside of the container, and I don't know enough about the plugin that generates these files to understand why it behaves differently inside of the container. Nonetheless, I think these excludes seem reasonable. --- extensions/guacamole-auth-cas/pom.xml | 1 + extensions/guacamole-auth-duo/pom.xml | 1 + extensions/guacamole-auth-openid/pom.xml | 1 + guacamole/pom.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/extensions/guacamole-auth-cas/pom.xml b/extensions/guacamole-auth-cas/pom.xml index e76c50b88..b517e6cd1 100644 --- a/extensions/guacamole-auth-cas/pom.xml +++ b/extensions/guacamole-auth-cas/pom.xml @@ -185,6 +185,7 @@ **/*.json src/licenses/**/* src/main/resources/templates/*.html + src/main/resources/generated/** diff --git a/extensions/guacamole-auth-duo/pom.xml b/extensions/guacamole-auth-duo/pom.xml index 104b5942b..6f7037cc8 100644 --- a/extensions/guacamole-auth-duo/pom.xml +++ b/extensions/guacamole-auth-duo/pom.xml @@ -186,6 +186,7 @@ **/*.json src/licenses/**/* src/main/resources/templates/*.html + src/main/resources/generated/** src/main/resources/lib/DuoWeb/**/* src/main/java/com/duosecurity/duoweb/**/* diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index 4076998f1..e5cb9b63d 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -185,6 +185,7 @@ **/*.json src/licenses/**/* src/main/resources/templates/*.html + src/main/resources/generated/** diff --git a/guacamole/pom.xml b/guacamole/pom.xml index 4784cdabd..2afb743d8 100644 --- a/guacamole/pom.xml +++ b/guacamole/pom.xml @@ -223,6 +223,7 @@ src/main/webapp/app/*/templates/*.html + src/main/webapp/generated/** **/*.json src/licenses/**/* From 65c16ce90e0dd8500911435c5f0a6610370d1684 Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Sat, 7 Oct 2017 20:31:24 -0400 Subject: [PATCH 92/94] GUACAMOLE-408: revert changes to rat excludes The excludes for rat should include everything in .gitignore, so these explicit excludes are not needed. --- extensions/guacamole-auth-cas/pom.xml | 1 - extensions/guacamole-auth-duo/pom.xml | 1 - extensions/guacamole-auth-openid/pom.xml | 1 - guacamole/pom.xml | 1 - 4 files changed, 4 deletions(-) diff --git a/extensions/guacamole-auth-cas/pom.xml b/extensions/guacamole-auth-cas/pom.xml index b517e6cd1..e76c50b88 100644 --- a/extensions/guacamole-auth-cas/pom.xml +++ b/extensions/guacamole-auth-cas/pom.xml @@ -185,7 +185,6 @@ **/*.json src/licenses/**/* src/main/resources/templates/*.html - src/main/resources/generated/** diff --git a/extensions/guacamole-auth-duo/pom.xml b/extensions/guacamole-auth-duo/pom.xml index 6f7037cc8..104b5942b 100644 --- a/extensions/guacamole-auth-duo/pom.xml +++ b/extensions/guacamole-auth-duo/pom.xml @@ -186,7 +186,6 @@ **/*.json src/licenses/**/* src/main/resources/templates/*.html - src/main/resources/generated/** src/main/resources/lib/DuoWeb/**/* src/main/java/com/duosecurity/duoweb/**/* diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml index e5cb9b63d..4076998f1 100644 --- a/extensions/guacamole-auth-openid/pom.xml +++ b/extensions/guacamole-auth-openid/pom.xml @@ -185,7 +185,6 @@ **/*.json src/licenses/**/* src/main/resources/templates/*.html - src/main/resources/generated/** diff --git a/guacamole/pom.xml b/guacamole/pom.xml index 2afb743d8..4784cdabd 100644 --- a/guacamole/pom.xml +++ b/guacamole/pom.xml @@ -223,7 +223,6 @@ src/main/webapp/app/*/templates/*.html - src/main/webapp/generated/** **/*.json src/licenses/**/* From e42a875f08096f8f130828ce133053457b5d8d4b Mon Sep 17 00:00:00 2001 From: Carl Harris Date: Sat, 7 Oct 2017 20:35:20 -0400 Subject: [PATCH 93/94] GUACAMOLE-408: don't exclude .gitignore in .dockerignore Because the .gitignore files are needed for configuring implicit excludes for rat, .dockerignore must not exclude these files when copying files into the image build context. --- .dockerignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index cea180242..629ad03ea 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,5 @@ .git -**/.gitignore **/*~ **/target/ From cc8ea75426b0fbdbc36a929e17ec20334506c085 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Fri, 13 Oct 2017 13:13:12 -0400 Subject: [PATCH 94/94] GUACAMOLE-416: Add translation entries for SQL Server module. --- .../src/main/resources/translations/en.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json index c781c158c..6e03340b3 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json @@ -63,6 +63,14 @@ "NAME" : "Shared Connections (PostgreSQL)" }, + "DATA_SOURCE_SQLSERVER" : { + "NAME" : "SQL Server" + }, + + "DATA_SOURCe_SQLSERVER_SHARED" : { + "NAME" : "Shared Connections (SQL Server)" + }, + "HOME" : { "INFO_SHARED_BY" : "Shared by {USERNAME}" },