mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUACAMOLE-1298: Migrate to latest version of Guice and Jersey 2.x
This commit is contained in:
@@ -254,6 +254,11 @@
|
|||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>1.7.7</version>
|
<version>1.7.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>jul-to-slf4j</artifactId>
|
||||||
|
<version>1.7.7</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ch.qos.logback</groupId>
|
<groupId>ch.qos.logback</groupId>
|
||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
@@ -435,33 +440,38 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.inject</groupId>
|
<groupId>com.google.inject</groupId>
|
||||||
<artifactId>guice</artifactId>
|
<artifactId>guice</artifactId>
|
||||||
<version>3.0</version>
|
<version>4.2.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.inject.extensions</groupId>
|
<groupId>com.google.inject.extensions</groupId>
|
||||||
<artifactId>guice-assistedinject</artifactId>
|
<artifactId>guice-assistedinject</artifactId>
|
||||||
<version>3.0</version>
|
<version>4.2.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Guice Servlet -->
|
<!-- Guice Servlet -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.inject.extensions</groupId>
|
<groupId>com.google.inject.extensions</groupId>
|
||||||
<artifactId>guice-servlet</artifactId>
|
<artifactId>guice-servlet</artifactId>
|
||||||
<version>3.0</version>
|
<version>4.2.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Jersey - JAX-RS Implementation -->
|
<!-- Jersey - JAX-RS Implementation -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.jersey</groupId>
|
<groupId>org.glassfish.jersey.containers</groupId>
|
||||||
<artifactId>jersey-server</artifactId>
|
<artifactId>jersey-container-servlet-core</artifactId>
|
||||||
<version>1.17.1</version>
|
<version>2.31</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.inject</groupId>
|
||||||
|
<artifactId>jersey-hk2</artifactId>
|
||||||
|
<version>2.31</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Jersey - Guice extension -->
|
<!-- Guice bridge for HK2 - the dependency injection framework integrated with Jersey 2.x -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.jersey.contribs</groupId>
|
<groupId>org.glassfish.hk2</groupId>
|
||||||
<artifactId>jersey-guice</artifactId>
|
<artifactId>guice-bridge</artifactId>
|
||||||
<version>1.17.1</version>
|
<version>2.6.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- JSR-250 annotations -->
|
<!-- JSR-250 annotations -->
|
||||||
@@ -473,9 +483,9 @@
|
|||||||
|
|
||||||
<!-- Jackson for JSON support -->
|
<!-- Jackson for JSON support -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.jersey</groupId>
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
<artifactId>jersey-json</artifactId>
|
<artifactId>jersey-media-json-jackson</artifactId>
|
||||||
<version>1.17.1</version>
|
<version>2.31</version>
|
||||||
|
|
||||||
<!-- Exclude StAX API, which is part of Java 6 -->
|
<!-- Exclude StAX API, which is part of Java 6 -->
|
||||||
<exclusions>
|
<exclusions>
|
||||||
|
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
import org.glassfish.hk2.api.ServiceLocator;
|
||||||
|
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
import org.jvnet.hk2.guice.bridge.api.GuiceBridge;
|
||||||
|
import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge;
|
||||||
|
import org.slf4j.bridge.SLF4JBridgeHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JAX-RS Application which serves as the root definition of the Guacamole
|
||||||
|
* REST API. The HK2 dependency injection used by Jersey is automatically
|
||||||
|
* bridged to Guice, allowing injections managed by Guice to be injected within
|
||||||
|
* classes served by Jersey.
|
||||||
|
*/
|
||||||
|
@ApplicationPath("/*")
|
||||||
|
public class GuacamoleApplication extends ResourceConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new GuacamoleApplication which defines the Guacamole REST API,
|
||||||
|
* automatically configuring Jersey's HK2 dependency injection to
|
||||||
|
* additionally pull services from a Guice injector.
|
||||||
|
*
|
||||||
|
* @param servletContext
|
||||||
|
* The ServletContext which has already associated with a Guice
|
||||||
|
* injector via a GuacamoleServletContextListener.
|
||||||
|
*
|
||||||
|
* @param serviceLocator
|
||||||
|
* The HK2 service locator (injector).
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
public GuacamoleApplication(ServletContext servletContext,
|
||||||
|
ServiceLocator serviceLocator) {
|
||||||
|
|
||||||
|
// Bridge Jersey logging (java.util.logging) to SLF4J
|
||||||
|
SLF4JBridgeHandler.removeHandlersForRootLogger();
|
||||||
|
SLF4JBridgeHandler.install();
|
||||||
|
|
||||||
|
// Bridge HK2 service locator with Guice injector
|
||||||
|
Injector guiceInjector = (Injector) servletContext.getAttribute(GuacamoleServletContextListener.GUICE_INJECTOR);
|
||||||
|
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
|
||||||
|
GuiceIntoHK2Bridge bridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
|
||||||
|
bridge.bridgeGuiceInjector(guiceInjector);
|
||||||
|
|
||||||
|
// Automatically scan for REST resources
|
||||||
|
packages("org.apache.guacamole.rest");
|
||||||
|
|
||||||
|
// Use Jackson for JSON
|
||||||
|
register(JacksonFeature.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -25,6 +25,7 @@ import com.google.inject.Injector;
|
|||||||
import com.google.inject.Stage;
|
import com.google.inject.Stage;
|
||||||
import com.google.inject.servlet.GuiceServletContextListener;
|
import com.google.inject.servlet.GuiceServletContextListener;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import org.apache.guacamole.environment.Environment;
|
import org.apache.guacamole.environment.Environment;
|
||||||
@@ -41,9 +42,45 @@ import org.slf4j.LoggerFactory;
|
|||||||
/**
|
/**
|
||||||
* A ServletContextListener to listen for initialization of the servlet context
|
* A ServletContextListener to listen for initialization of the servlet context
|
||||||
* in order to set up dependency injection.
|
* in order to set up dependency injection.
|
||||||
|
*
|
||||||
|
* NOTE: Guacamole's REST API uses Jersey 2.x which does not natively support
|
||||||
|
* dependency injection using Guice. It DOES support dependency injection using
|
||||||
|
* HK2, which supports bi-directional bridging with Guice.
|
||||||
|
*
|
||||||
|
* The overall process is thus:
|
||||||
|
*
|
||||||
|
* 1. Application initialization proceeds using GuacamoleServletContextListener,
|
||||||
|
* a subclass of GuiceServletContextListener, with all HTTP requests being
|
||||||
|
* routed through GuiceFilter which serves as the absolute root.
|
||||||
|
*
|
||||||
|
* 2. GuacamoleServletContextListener prepares the Guice injector, storing the
|
||||||
|
* injector within the ServletContext such that it can later be bridged with
|
||||||
|
* HK2.
|
||||||
|
*
|
||||||
|
* 3. Several of the modules used to prepare the Guice injector are
|
||||||
|
* ServletModule subclasses, which define HTTP request paths that GuiceFilter
|
||||||
|
* should route to specific servlets. One of these paths is "/api/*" (the
|
||||||
|
* root of the REST API) which is routed to Jersey's ServletContainer servlet
|
||||||
|
* (the root of Jersey's JAX-RS implementation).
|
||||||
|
*
|
||||||
|
* 4. Configuration information passed to Jersey's ServletContainer tells Jersey
|
||||||
|
* to use the GuacamoleApplication class (a subclass of ResourceConfig) to
|
||||||
|
* define the rest of the resources and any other configuration.
|
||||||
|
*
|
||||||
|
* 5. When Jersey creates its instance of GuacamoleApplication, the
|
||||||
|
* initialization process of GuacamoleApplication pulls the Guice injector
|
||||||
|
* from the ServletContext, completes the HK2 bridging, and configures Jersey
|
||||||
|
* to automatically locate and inject all REST services.
|
||||||
*/
|
*/
|
||||||
public class GuacamoleServletContextListener extends GuiceServletContextListener {
|
public class GuacamoleServletContextListener extends GuiceServletContextListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the ServletContext attribute which will contain a reference
|
||||||
|
* to the Guice injector once the contextInitialized() event has been
|
||||||
|
* handled.
|
||||||
|
*/
|
||||||
|
public static final String GUICE_INJECTOR = "GUAC_GUICE_INJECTOR";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger for this class.
|
* Logger for this class.
|
||||||
*/
|
*/
|
||||||
@@ -65,6 +102,12 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
|||||||
@Inject
|
@Inject
|
||||||
private List<AuthenticationProvider> authProviders;
|
private List<AuthenticationProvider> authProviders;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal reference to the Guice injector that was lazily created when
|
||||||
|
* getInjector() was first invoked.
|
||||||
|
*/
|
||||||
|
private final AtomicReference<Injector> guiceInjector = new AtomicReference<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||||
|
|
||||||
@@ -78,14 +121,29 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: The superclass implementation of contextInitialized() is
|
||||||
|
// expected to invoke getInjector(), hence the need to call AFTER
|
||||||
|
// setting up the environment and session map
|
||||||
super.contextInitialized(servletContextEvent);
|
super.contextInitialized(servletContextEvent);
|
||||||
|
|
||||||
|
// Inject any annotated members of this class
|
||||||
|
Injector injector = getInjector();
|
||||||
|
injector.injectMembers(this);
|
||||||
|
|
||||||
|
// Store reference to injector for use by Jersey and HK2 bridge
|
||||||
|
servletContextEvent.getServletContext().setAttribute(GUICE_INJECTOR, injector);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Injector getInjector() {
|
protected Injector getInjector() {
|
||||||
|
return guiceInjector.updateAndGet((current) -> {
|
||||||
|
|
||||||
// Create injector
|
// Use existing injector if already created
|
||||||
|
if (current != null)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
// Create new injector if necessary
|
||||||
Injector injector = Guice.createInjector(Stage.PRODUCTION,
|
Injector injector = Guice.createInjector(Stage.PRODUCTION,
|
||||||
new EnvironmentModule(environment),
|
new EnvironmentModule(environment),
|
||||||
new LogModule(environment),
|
new LogModule(environment),
|
||||||
@@ -94,17 +152,16 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
|||||||
new TunnelModule()
|
new TunnelModule()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Inject any annotated members of this class
|
|
||||||
injector.injectMembers(this);
|
|
||||||
|
|
||||||
return injector;
|
return injector;
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||||
|
|
||||||
super.contextDestroyed(servletContextEvent);
|
// Clean up reference to Guice injector
|
||||||
|
servletContextEvent.getServletContext().removeAttribute(GUICE_INJECTOR);
|
||||||
|
|
||||||
// Shutdown TokenSessionMap
|
// Shutdown TokenSessionMap
|
||||||
if (sessionMap != null)
|
if (sessionMap != null)
|
||||||
@@ -116,6 +173,9 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
|
|||||||
authProvider.shutdown();
|
authProvider.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Continue any Guice-specific cleanup
|
||||||
|
super.contextDestroyed(servletContextEvent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,35 +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.rest;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import javax.ws.rs.HttpMethod;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An annotation for using the HTTP PATCH method in the REST endpoints.
|
|
||||||
*/
|
|
||||||
@Target({ElementType.METHOD})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@HttpMethod("PATCH")
|
|
||||||
public @interface PATCH {}
|
|
@@ -1,128 +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.rest;
|
|
||||||
|
|
||||||
import com.google.inject.matcher.AbstractMatcher;
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import javax.ws.rs.HttpMethod;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import org.apache.guacamole.GuacamoleException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Guice Matcher which matches only methods which throw GuacamoleException
|
|
||||||
* (or a subclass thereof) and are explicitly annotated as with an HTTP method
|
|
||||||
* annotation like <code>@GET</code> or <code>@POST</code>. Any method which
|
|
||||||
* throws GuacamoleException and is annotated with an annotation that is
|
|
||||||
* annotated with <code>@HttpMethod</code> will match.
|
|
||||||
*/
|
|
||||||
public class RESTMethodMatcher extends AbstractMatcher<Method> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the given method throws the specified exception type,
|
|
||||||
* including any subclasses of that type.
|
|
||||||
*
|
|
||||||
* @param method
|
|
||||||
* The method to test.
|
|
||||||
*
|
|
||||||
* @param exceptionType
|
|
||||||
* The exception type to test for.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* true if the given method throws an exception of the specified type,
|
|
||||||
* false otherwise.
|
|
||||||
*/
|
|
||||||
private boolean methodThrowsException(Method method,
|
|
||||||
Class<? extends Exception> exceptionType) {
|
|
||||||
|
|
||||||
// Check whether the method throws an exception of the specified type
|
|
||||||
for (Class<?> thrownType : method.getExceptionTypes()) {
|
|
||||||
if (exceptionType.isAssignableFrom(thrownType))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No such exception is declared to be thrown
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the given method is annotated as a REST method. A REST
|
|
||||||
* method is annotated with an annotation which is annotated with
|
|
||||||
* <code>@HttpMethod</code> or <code>@Path</code>.
|
|
||||||
*
|
|
||||||
* @param method
|
|
||||||
* The method to test.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* true if the given method is annotated as a REST method, false
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
private boolean isRESTMethod(Method method) {
|
|
||||||
|
|
||||||
// Check whether the required REST annotations are present
|
|
||||||
for (Annotation annotation : method.getAnnotations()) {
|
|
||||||
|
|
||||||
// A method is a REST method if it is annotated with @HttpMethod
|
|
||||||
Class<? extends Annotation> annotationType = annotation.annotationType();
|
|
||||||
if (annotationType.isAnnotationPresent(HttpMethod.class))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// A method is a REST method if it is annotated with @Path
|
|
||||||
if (Path.class.isAssignableFrom(annotationType))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// A method is also REST method if it overrides a REST method within
|
|
||||||
// the superclass
|
|
||||||
Class<?> superclass = method.getDeclaringClass().getSuperclass();
|
|
||||||
if (superclass != null) {
|
|
||||||
|
|
||||||
// Recheck against identical method within superclass
|
|
||||||
try {
|
|
||||||
return isRESTMethod(superclass.getMethod(method.getName(),
|
|
||||||
method.getParameterTypes()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is no such method, then this method cannot possibly be
|
|
||||||
// a REST method
|
|
||||||
catch (NoSuchMethodException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lacking a superclass, the search stops here - it's not a REST method
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Method method) {
|
|
||||||
|
|
||||||
// Guacamole REST methods are REST methods which throw
|
|
||||||
// GuacamoleExceptions
|
|
||||||
return isRESTMethod(method)
|
|
||||||
&& methodThrowsException(method, GuacamoleException.class);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -19,19 +19,14 @@
|
|||||||
|
|
||||||
package org.apache.guacamole.rest;
|
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;
|
import com.google.inject.Scopes;
|
||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
import com.sun.jersey.api.core.ResourceConfig;
|
import java.util.Collections;
|
||||||
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
|
import org.apache.guacamole.rest.event.ListenerService;
|
||||||
import java.util.HashMap;
|
import org.apache.guacamole.rest.session.UserContextResourceFactory;
|
||||||
import java.util.Map;
|
import org.apache.guacamole.GuacamoleApplication;
|
||||||
import org.apache.guacamole.rest.activeconnection.ActiveConnectionModule;
|
import org.apache.guacamole.rest.activeconnection.ActiveConnectionModule;
|
||||||
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
|
|
||||||
import org.apache.guacamole.rest.auth.TokenRESTService;
|
|
||||||
import org.apache.guacamole.rest.auth.AuthTokenGenerator;
|
import org.apache.guacamole.rest.auth.AuthTokenGenerator;
|
||||||
import org.apache.guacamole.rest.auth.AuthenticationService;
|
import org.apache.guacamole.rest.auth.AuthenticationService;
|
||||||
import org.apache.guacamole.rest.auth.DecorationService;
|
import org.apache.guacamole.rest.auth.DecorationService;
|
||||||
@@ -39,15 +34,14 @@ import org.apache.guacamole.rest.auth.SecureRandomAuthTokenGenerator;
|
|||||||
import org.apache.guacamole.rest.auth.TokenSessionMap;
|
import org.apache.guacamole.rest.auth.TokenSessionMap;
|
||||||
import org.apache.guacamole.rest.connection.ConnectionModule;
|
import org.apache.guacamole.rest.connection.ConnectionModule;
|
||||||
import org.apache.guacamole.rest.connectiongroup.ConnectionGroupModule;
|
import org.apache.guacamole.rest.connectiongroup.ConnectionGroupModule;
|
||||||
import org.apache.guacamole.rest.extension.ExtensionRESTService;
|
|
||||||
import org.apache.guacamole.rest.language.LanguageRESTService;
|
|
||||||
import org.apache.guacamole.rest.patch.PatchRESTService;
|
|
||||||
import org.apache.guacamole.rest.session.SessionResourceFactory;
|
import org.apache.guacamole.rest.session.SessionResourceFactory;
|
||||||
import org.apache.guacamole.rest.sharingprofile.SharingProfileModule;
|
import org.apache.guacamole.rest.sharingprofile.SharingProfileModule;
|
||||||
import org.apache.guacamole.rest.tunnel.TunnelCollectionResourceFactory;
|
import org.apache.guacamole.rest.tunnel.TunnelCollectionResourceFactory;
|
||||||
import org.apache.guacamole.rest.tunnel.TunnelResourceFactory;
|
import org.apache.guacamole.rest.tunnel.TunnelResourceFactory;
|
||||||
import org.apache.guacamole.rest.user.UserModule;
|
import org.apache.guacamole.rest.user.UserModule;
|
||||||
import org.apache.guacamole.rest.usergroup.UserGroupModule;
|
import org.apache.guacamole.rest.usergroup.UserGroupModule;
|
||||||
|
import org.glassfish.jersey.servlet.ServletContainer;
|
||||||
|
import org.glassfish.jersey.servlet.ServletProperties;
|
||||||
import org.webjars.servlet.WebjarsServlet;
|
import org.webjars.servlet.WebjarsServlet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,8 +70,6 @@ public class RESTServiceModule extends ServletModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
|
|
||||||
Map<String, String> containerParams = new HashMap<>();
|
|
||||||
|
|
||||||
// Bind session map
|
// Bind session map
|
||||||
bind(TokenSessionMap.class).toInstance(tokenSessionMap);
|
bind(TokenSessionMap.class).toInstance(tokenSessionMap);
|
||||||
|
|
||||||
@@ -87,21 +79,7 @@ public class RESTServiceModule extends ServletModule {
|
|||||||
bind(AuthTokenGenerator.class).to(SecureRandomAuthTokenGenerator.class);
|
bind(AuthTokenGenerator.class).to(SecureRandomAuthTokenGenerator.class);
|
||||||
bind(DecorationService.class);
|
bind(DecorationService.class);
|
||||||
|
|
||||||
// Automatically translate GuacamoleExceptions for REST methods
|
|
||||||
bind(RESTExceptionMapper.class);
|
|
||||||
|
|
||||||
// Restrict API requests by entity size
|
|
||||||
containerParams.put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, RequestSizeFilter.class.getName());
|
|
||||||
bind(RequestSizeFilter.class).in(Scopes.SINGLETON);
|
|
||||||
|
|
||||||
// Set up the API endpoints
|
|
||||||
bind(ExtensionRESTService.class);
|
|
||||||
bind(LanguageRESTService.class);
|
|
||||||
bind(PatchRESTService.class);
|
|
||||||
bind(TokenRESTService.class);
|
|
||||||
|
|
||||||
// Root-level resources
|
// Root-level resources
|
||||||
bind(SessionRESTService.class);
|
|
||||||
install(new FactoryModuleBuilder().build(SessionResourceFactory.class));
|
install(new FactoryModuleBuilder().build(SessionResourceFactory.class));
|
||||||
install(new FactoryModuleBuilder().build(TunnelCollectionResourceFactory.class));
|
install(new FactoryModuleBuilder().build(TunnelCollectionResourceFactory.class));
|
||||||
install(new FactoryModuleBuilder().build(TunnelResourceFactory.class));
|
install(new FactoryModuleBuilder().build(TunnelResourceFactory.class));
|
||||||
@@ -115,10 +93,12 @@ public class RESTServiceModule extends ServletModule {
|
|||||||
install(new UserModule());
|
install(new UserModule());
|
||||||
install(new UserGroupModule());
|
install(new UserGroupModule());
|
||||||
|
|
||||||
// Set up the servlet and JSON mappings
|
// Serve REST services using Jersey 2.x
|
||||||
bind(GuiceContainer.class);
|
bind(ServletContainer.class).in(Scopes.SINGLETON);
|
||||||
bind(JacksonJsonProvider.class).in(Scopes.SINGLETON);
|
serve("/api/*").with(ServletContainer.class, Collections.singletonMap(
|
||||||
serve("/api/*").with(GuiceContainer.class, containerParams);
|
ServletProperties.JAXRS_APPLICATION_CLASS,
|
||||||
|
GuacamoleApplication.class.getName()
|
||||||
|
));
|
||||||
|
|
||||||
// Serve Webjar JavaScript dependencies
|
// Serve Webjar JavaScript dependencies
|
||||||
bind(WebjarsServlet.class).in(Scopes.SINGLETON);
|
bind(WebjarsServlet.class).in(Scopes.SINGLETON);
|
||||||
|
@@ -19,11 +19,12 @@
|
|||||||
|
|
||||||
package org.apache.guacamole.rest;
|
package org.apache.guacamole.rest;
|
||||||
|
|
||||||
import com.sun.jersey.spi.container.ContainerRequest;
|
import java.io.IOException;
|
||||||
import com.sun.jersey.spi.container.ContainerRequestFilter;
|
|
||||||
import com.sun.jersey.spi.resource.Singleton;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.ws.rs.container.ContainerRequestContext;
|
||||||
|
import javax.ws.rs.container.ContainerRequestFilter;
|
||||||
import javax.ws.rs.ext.Provider;
|
import javax.ws.rs.ext.Provider;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.environment.Environment;
|
import org.apache.guacamole.environment.Environment;
|
||||||
@@ -61,7 +62,7 @@ public class RequestSizeFilter implements ContainerRequestFilter {
|
|||||||
private Environment environment;
|
private Environment environment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContainerRequest filter(ContainerRequest request) {
|
public void filter(ContainerRequestContext context) throws IOException {
|
||||||
|
|
||||||
// Retrieve configured request size limits
|
// Retrieve configured request size limits
|
||||||
final long maxRequestSize;
|
final long maxRequestSize;
|
||||||
@@ -74,15 +75,13 @@ public class RequestSizeFilter implements ContainerRequestFilter {
|
|||||||
|
|
||||||
// Ignore request size if limit is disabled
|
// Ignore request size if limit is disabled
|
||||||
if (maxRequestSize == 0)
|
if (maxRequestSize == 0)
|
||||||
return request;
|
return;
|
||||||
|
|
||||||
// Restrict maximum size of requests which have an input stream
|
// Restrict maximum size of requests which have an input stream
|
||||||
// available to be limited
|
// available to be limited
|
||||||
InputStream stream = request.getEntityInputStream();
|
InputStream stream = context.getEntityStream();
|
||||||
if (stream != null)
|
if (stream != null)
|
||||||
request.setEntityInputStream(new LimitedRequestInputStream(stream, maxRequestSize));
|
context.setEntityStream(new LimitedRequestInputStream(stream, maxRequestSize));
|
||||||
|
|
||||||
return request;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PATCH;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
@@ -44,7 +45,6 @@ import org.apache.guacamole.net.auth.permission.ObjectPermissionSet;
|
|||||||
import org.apache.guacamole.net.auth.permission.SystemPermission;
|
import org.apache.guacamole.net.auth.permission.SystemPermission;
|
||||||
import org.apache.guacamole.net.auth.permission.SystemPermissionSet;
|
import org.apache.guacamole.net.auth.permission.SystemPermissionSet;
|
||||||
import org.apache.guacamole.rest.APIPatch;
|
import org.apache.guacamole.rest.APIPatch;
|
||||||
import org.apache.guacamole.rest.PATCH;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A REST resource which abstracts the operations available on all Guacamole
|
* A REST resource which abstracts the operations available on all Guacamole
|
||||||
|
@@ -23,13 +23,13 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PATCH;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import org.apache.guacamole.GuacamoleClientException;
|
import org.apache.guacamole.GuacamoleClientException;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.net.auth.RelatedObjectSet;
|
import org.apache.guacamole.net.auth.RelatedObjectSet;
|
||||||
import org.apache.guacamole.rest.APIPatch;
|
import org.apache.guacamole.rest.APIPatch;
|
||||||
import org.apache.guacamole.rest.PATCH;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A REST resource which abstracts the operations available on arbitrary sets
|
* A REST resource which abstracts the operations available on arbitrary sets
|
||||||
|
@@ -22,6 +22,7 @@ package org.apache.guacamole.rest.permission;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PATCH;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import org.apache.guacamole.GuacamoleClientException;
|
import org.apache.guacamole.GuacamoleClientException;
|
||||||
@@ -31,7 +32,6 @@ import org.apache.guacamole.net.auth.permission.ObjectPermission;
|
|||||||
import org.apache.guacamole.net.auth.permission.Permission;
|
import org.apache.guacamole.net.auth.permission.Permission;
|
||||||
import org.apache.guacamole.net.auth.permission.SystemPermission;
|
import org.apache.guacamole.net.auth.permission.SystemPermission;
|
||||||
import org.apache.guacamole.rest.APIPatch;
|
import org.apache.guacamole.rest.APIPatch;
|
||||||
import org.apache.guacamole.rest.PATCH;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A REST resource which abstracts the operations available on the permissions
|
* A REST resource which abstracts the operations available on the permissions
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
<welcome-file>index.html</welcome-file>
|
<welcome-file>index.html</welcome-file>
|
||||||
</welcome-file-list>
|
</welcome-file-list>
|
||||||
|
|
||||||
<!-- Guice -->
|
<!-- Route all requests through Guice -->
|
||||||
<filter>
|
<filter>
|
||||||
<filter-name>guiceFilter</filter-name>
|
<filter-name>guiceFilter</filter-name>
|
||||||
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
|
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
|
||||||
@@ -37,7 +37,6 @@
|
|||||||
<filter-name>guiceFilter</filter-name>
|
<filter-name>guiceFilter</filter-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</filter-mapping>
|
</filter-mapping>
|
||||||
|
|
||||||
<listener>
|
<listener>
|
||||||
<listener-class>org.apache.guacamole.GuacamoleServletContextListener</listener-class>
|
<listener-class>org.apache.guacamole.GuacamoleServletContextListener</listener-class>
|
||||||
</listener>
|
</listener>
|
||||||
|
Reference in New Issue
Block a user