mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUAC-587: Remove ancient eventing system - it's been partially broken since 0.9.4, and really should be replaced with a true eventing subsystem.
This commit is contained in:
@@ -60,11 +60,6 @@ public class GuacamoleSession {
|
|||||||
*/
|
*/
|
||||||
private UserContext userContext;
|
private UserContext userContext;
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection of all event listeners configured in guacamole.properties.
|
|
||||||
*/
|
|
||||||
private final Collection<Object> listeners = new ArrayList<Object>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current clipboard state.
|
* The current clipboard state.
|
||||||
*/
|
*/
|
||||||
@@ -98,52 +93,9 @@ public class GuacamoleSession {
|
|||||||
*/
|
*/
|
||||||
public GuacamoleSession(Environment environment, Credentials credentials,
|
public GuacamoleSession(Environment environment, Credentials credentials,
|
||||||
UserContext userContext) throws GuacamoleException {
|
UserContext userContext) throws GuacamoleException {
|
||||||
|
|
||||||
this.lastAccessedTime = System.currentTimeMillis();
|
this.lastAccessedTime = System.currentTimeMillis();
|
||||||
this.credentials = credentials;
|
this.credentials = credentials;
|
||||||
this.userContext = userContext;
|
this.userContext = userContext;
|
||||||
|
|
||||||
// Load listeners from guacamole.properties
|
|
||||||
try {
|
|
||||||
|
|
||||||
// Get all listener classes from properties
|
|
||||||
Collection<Class> listenerClasses =
|
|
||||||
environment.getProperty(BasicGuacamoleProperties.EVENT_LISTENERS);
|
|
||||||
|
|
||||||
// Add an instance of each class to the list
|
|
||||||
if (listenerClasses != null) {
|
|
||||||
for (Class<?> listenerClass : listenerClasses) {
|
|
||||||
|
|
||||||
// Instantiate listener
|
|
||||||
Object listener = listenerClass.getConstructor().newInstance();
|
|
||||||
|
|
||||||
// Add listener to collection of listeners
|
|
||||||
listeners.add(listener);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (InstantiationException e) {
|
|
||||||
throw new GuacamoleException("Listener class is abstract.", e);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException e) {
|
|
||||||
throw new GuacamoleException("No access to listener constructor.", e);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e) {
|
|
||||||
// This should not happen, given there ARE no arguments
|
|
||||||
throw new GuacamoleException("Illegal arguments to listener constructor.", e);
|
|
||||||
}
|
|
||||||
catch (InvocationTargetException e) {
|
|
||||||
throw new GuacamoleException("Error while instantiating listener.", e);
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodException e) {
|
|
||||||
throw new GuacamoleException("Listener has no default constructor.", e);
|
|
||||||
}
|
|
||||||
catch (SecurityException e) {
|
|
||||||
throw new GuacamoleException("Security restrictions prevent instantiation of listener.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -198,19 +150,6 @@ public class GuacamoleSession {
|
|||||||
return clipboardState;
|
return clipboardState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a collection which iterates over instances of all listeners
|
|
||||||
* defined in guacamole.properties. For each listener defined in
|
|
||||||
* guacamole.properties, a new instance is created and stored in this
|
|
||||||
* collection.
|
|
||||||
*
|
|
||||||
* @return A collection which iterates over instances of all listeners
|
|
||||||
* defined in guacamole.properties.
|
|
||||||
*/
|
|
||||||
public Collection<Object> getListeners() {
|
|
||||||
return Collections.unmodifiableCollection(listeners);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this session has any associated active tunnels.
|
* Returns whether this session has any associated active tunnels.
|
||||||
*
|
*
|
||||||
|
@@ -38,10 +38,6 @@ import org.glyptodon.guacamole.net.auth.ConnectionGroup;
|
|||||||
import org.glyptodon.guacamole.net.auth.Directory;
|
import org.glyptodon.guacamole.net.auth.Directory;
|
||||||
import org.glyptodon.guacamole.net.auth.UserContext;
|
import org.glyptodon.guacamole.net.auth.UserContext;
|
||||||
import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService;
|
import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService;
|
||||||
import org.glyptodon.guacamole.net.event.TunnelCloseEvent;
|
|
||||||
import org.glyptodon.guacamole.net.event.TunnelConnectEvent;
|
|
||||||
import org.glyptodon.guacamole.net.event.listener.TunnelCloseListener;
|
|
||||||
import org.glyptodon.guacamole.net.event.listener.TunnelConnectListener;
|
|
||||||
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -76,84 +72,6 @@ public class TunnelRequestService {
|
|||||||
@Inject
|
@Inject
|
||||||
private AuthenticationService authenticationService;
|
private AuthenticationService authenticationService;
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies all listeners in the given session that a tunnel has been
|
|
||||||
* connected.
|
|
||||||
*
|
|
||||||
* @param session The session associated with the listeners to be notified.
|
|
||||||
* @param tunnel The tunnel being connected.
|
|
||||||
* @return true if all listeners are allowing the tunnel to connect,
|
|
||||||
* or if there are no listeners, and false if any listener is
|
|
||||||
* canceling the connection. Note that once one listener cancels,
|
|
||||||
* no other listeners will run.
|
|
||||||
* @throws GuacamoleException If any listener throws an error while being
|
|
||||||
* notified. Note that if any listener throws an
|
|
||||||
* error, the connect is canceled, and no other
|
|
||||||
* listeners will run.
|
|
||||||
*/
|
|
||||||
private boolean notifyConnect(GuacamoleSession session, GuacamoleTunnel tunnel)
|
|
||||||
throws GuacamoleException {
|
|
||||||
|
|
||||||
// Build event for auth success
|
|
||||||
TunnelConnectEvent event = new TunnelConnectEvent(
|
|
||||||
session.getUserContext(),
|
|
||||||
session.getCredentials(),
|
|
||||||
tunnel);
|
|
||||||
|
|
||||||
// Notify all listeners
|
|
||||||
for (Object listener : session.getListeners()) {
|
|
||||||
if (listener instanceof TunnelConnectListener) {
|
|
||||||
|
|
||||||
// Cancel immediately if hook returns false
|
|
||||||
if (!((TunnelConnectListener) listener).tunnelConnected(event))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies all listeners in the given session that a tunnel has been
|
|
||||||
* closed.
|
|
||||||
*
|
|
||||||
* @param session The session associated with the listeners to be notified.
|
|
||||||
* @param tunnel The tunnel being closed.
|
|
||||||
* @return true if all listeners are allowing the tunnel to close,
|
|
||||||
* or if there are no listeners, and false if any listener is
|
|
||||||
* canceling the close. Note that once one listener cancels,
|
|
||||||
* no other listeners will run.
|
|
||||||
* @throws GuacamoleException If any listener throws an error while being
|
|
||||||
* notified. Note that if any listener throws an
|
|
||||||
* error, the close is canceled, and no other
|
|
||||||
* listeners will run.
|
|
||||||
*/
|
|
||||||
private boolean notifyClose(GuacamoleSession session, GuacamoleTunnel tunnel)
|
|
||||||
throws GuacamoleException {
|
|
||||||
|
|
||||||
// Build event for auth success
|
|
||||||
TunnelCloseEvent event = new TunnelCloseEvent(
|
|
||||||
session.getUserContext(),
|
|
||||||
session.getCredentials(),
|
|
||||||
tunnel);
|
|
||||||
|
|
||||||
// Notify all listeners
|
|
||||||
for (Object listener : session.getListeners()) {
|
|
||||||
if (listener instanceof TunnelCloseListener) {
|
|
||||||
|
|
||||||
// Cancel immediately if hook returns false
|
|
||||||
if (!((TunnelCloseListener) listener).tunnelClosed(event))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads and returns the client information provided within the given
|
* Reads and returns the client information provided within the given
|
||||||
* request.
|
* request.
|
||||||
@@ -335,10 +253,6 @@ public class TunnelRequestService {
|
|||||||
@Override
|
@Override
|
||||||
public void close() throws GuacamoleException {
|
public void close() throws GuacamoleException {
|
||||||
|
|
||||||
// Signal listeners
|
|
||||||
if (!notifyClose(session, this))
|
|
||||||
throw new GuacamoleException("Tunnel close canceled by listener.");
|
|
||||||
|
|
||||||
session.removeTunnel(getUUID().toString());
|
session.removeTunnel(getUUID().toString());
|
||||||
|
|
||||||
// Close if no exception due to listener
|
// Close if no exception due to listener
|
||||||
@@ -348,12 +262,6 @@ public class TunnelRequestService {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Notify listeners about connection
|
|
||||||
if (!notifyConnect(session, monitoredTunnel)) {
|
|
||||||
logger.info("Successful connection canceled by hook.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Associate tunnel with session
|
// Associate tunnel with session
|
||||||
session.addTunnel(monitoredTunnel);
|
session.addTunnel(monitoredTunnel);
|
||||||
return monitoredTunnel;
|
return monitoredTunnel;
|
||||||
|
@@ -63,18 +63,6 @@ public class BasicGuacamoleProperties {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The comma-separated list of all classes to use as event listeners. This
|
|
||||||
* property is currently supported, but deprecated in favor of declared
|
|
||||||
* event listeners within extension manifests.
|
|
||||||
*/
|
|
||||||
public static final EventListenersProperty EVENT_LISTENERS = new EventListenersProperty() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() { return "event-listeners"; }
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The session timeout for the API, in minutes.
|
* The session timeout for the API, in minutes.
|
||||||
*/
|
*/
|
||||||
|
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 Glyptodon LLC
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.glyptodon.guacamole.net.basic.properties;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import org.glyptodon.guacamole.GuacamoleException;
|
|
||||||
import org.glyptodon.guacamole.net.basic.GuacamoleClassLoader;
|
|
||||||
import org.glyptodon.guacamole.properties.GuacamoleProperty;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A GuacamoleProperty whose value is a comma-separated list of class names,
|
|
||||||
* where each class will be used as a listener for events. This type of
|
|
||||||
* property is deprecated in favor of declaring event listeners within
|
|
||||||
* extension manifests.
|
|
||||||
*
|
|
||||||
* @author Michael Jumper
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public abstract class EventListenersProperty implements GuacamoleProperty<Collection<Class>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Class> parseValue(String classNameList) throws GuacamoleException {
|
|
||||||
|
|
||||||
// If no property provided, return null.
|
|
||||||
if (classNameList == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Parse list
|
|
||||||
String[] classNames = classNameList.split(",[\\s]*");
|
|
||||||
|
|
||||||
// Fill list of classes
|
|
||||||
Collection<Class> listeners = new ArrayList<Class>();
|
|
||||||
try {
|
|
||||||
|
|
||||||
// Load all classes in list
|
|
||||||
for (String className : classNames) {
|
|
||||||
Class clazz = GuacamoleClassLoader.getInstance().loadClass(className);
|
|
||||||
listeners.add(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e) {
|
|
||||||
throw new GuacamoleException("Listener class not found.", e);
|
|
||||||
}
|
|
||||||
catch (SecurityException e) {
|
|
||||||
throw new GuacamoleException("Security settings prevent loading of listener class.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return listeners;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Reference in New Issue
Block a user