From a60377486552176a745e5000c70658a4c96f678b Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Mon, 28 May 2018 21:05:11 -0400 Subject: [PATCH] GUACAMOLE-566: Implement GuacamoleExceptionMapper to deal with exceptions thrown in REST APIs in extensions. --- .../guacamole/extension/ExtensionModule.java | 4 ++ .../rest/GuacamoleExceptionMapper.java | 54 +++++++++++++++++++ .../guacamole/rest/RESTExceptionWrapper.java | 3 -- .../guacamole/rest/RESTServiceModule.java | 3 ++ 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 guacamole/src/main/java/org/apache/guacamole/rest/GuacamoleExceptionMapper.java 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 524ff5789..665c02881 100644 --- a/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/extension/ExtensionModule.java @@ -39,6 +39,7 @@ import org.apache.guacamole.resource.Resource; import org.apache.guacamole.resource.ResourceServlet; import org.apache.guacamole.resource.SequenceResource; import org.apache.guacamole.resource.WebApplicationResource; +import org.apache.guacamole.rest.GuacamoleExceptionMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -418,6 +419,9 @@ public class ExtensionModule extends ServletModule { bind(LanguageResourceService.class).toInstance(languageResourceService); bind(PatchResourceService.class).toInstance(patchResourceService); + // Get ExceptionMapper to rewrite exceptions in JSON. + bind(GuacamoleExceptionMapper.class); + // Load initial language resources from servlet context languageResourceService.addLanguageResources(getServletContext()); diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/GuacamoleExceptionMapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/GuacamoleExceptionMapper.java new file mode 100644 index 000000000..4af39b8fa --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/GuacamoleExceptionMapper.java @@ -0,0 +1,54 @@ +/* + * 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.Singleton; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; +import org.apache.guacamole.GuacamoleException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A class that maps GuacamoleExceptions in a way that returns a + * custom response to the user via JSON rather than allowing the default + * web application error handling to take place. + */ +@Provider +@Singleton +public class GuacamoleExceptionMapper + implements ExceptionMapper { + + private final Logger logger = LoggerFactory.getLogger(GuacamoleExceptionMapper.class); + + @Override + public Response toResponse(GuacamoleException e) { + logger.debug(">>>EXMAPPER<<< Mapping exception {}", e.getMessage()); + return Response + .status(e.getHttpStatusCode()) + .entity(new APIError(e)) + .type(MediaType.APPLICATION_JSON) + .build(); + + } + +} \ No newline at end of file diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java index a0c756ebe..fb854b041 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java @@ -28,10 +28,7 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; -import org.apache.guacamole.GuacamoleClientException; import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.GuacamoleResourceNotFoundException; -import org.apache.guacamole.GuacamoleSecurityException; import org.apache.guacamole.GuacamoleUnauthorizedException; import org.apache.guacamole.rest.auth.AuthenticationService; import org.slf4j.Logger; 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 b326fa534..cfa8b063a 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java @@ -88,6 +88,9 @@ public class RESTServiceModule extends ServletModule { MethodInterceptor interceptor = new RESTExceptionWrapper(); requestInjection(interceptor); bindInterceptor(Matchers.any(), new RESTMethodMatcher(), interceptor); + + // Get the ExceptionMapper that will rewrite exceptions into JSON. + bind(GuacamoleExceptionMapper.class); // Set up the API endpoints bind(ExtensionRESTService.class);