From 4b26750a3ab890bdf4b8238bd86f297b37fde3a5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 14 Oct 2015 17:18:08 -0700 Subject: [PATCH] GUAC-1364: Finally remove the @AuthProviderRESTExposure annotation. --- .../basic/rest/AuthProviderRESTExposure.java | 38 ------ ...Wrapper.java => RESTExceptionWrapper.java} | 15 ++- .../net/basic/rest/RESTMethodMatcher.java | 109 ++++++++++++++++++ .../net/basic/rest/RESTServletModule.java | 6 +- .../ActiveConnectionRESTService.java | 3 - .../net/basic/rest/auth/TokenRESTService.java | 17 +-- .../connection/ConnectionRESTService.java | 7 -- .../ConnectionGroupRESTService.java | 6 - .../basic/rest/schema/SchemaRESTService.java | 5 - .../net/basic/rest/user/UserRESTService.java | 43 +++---- 10 files changed, 145 insertions(+), 104 deletions(-) delete mode 100644 guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/AuthProviderRESTExposure.java rename guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/{AuthProviderRESTExceptionWrapper.java => RESTExceptionWrapper.java} (90%) create mode 100644 guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTMethodMatcher.java diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/AuthProviderRESTExposure.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/AuthProviderRESTExposure.java deleted file mode 100644 index 2a450c2c3..000000000 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/AuthProviderRESTExposure.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2014 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.rest; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marks that a method exposes functionality from the Guacamole AuthenticationProvider - * using a REST interface. - * - * @author James Muehlner - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) -public @interface AuthProviderRESTExposure {} diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/AuthProviderRESTExceptionWrapper.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTExceptionWrapper.java similarity index 90% rename from guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/AuthProviderRESTExceptionWrapper.java rename to guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTExceptionWrapper.java index d73903ef5..9cb0bc807 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/AuthProviderRESTExceptionWrapper.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTExceptionWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Glyptodon LLC + * Copyright (C) 2015 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 @@ -34,13 +34,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * A method interceptor to wrap some custom exception handling around methods - * that expose AuthenticationProvider functionality through the REST interface. - * Translates various types of GuacamoleExceptions into appropriate HTTP responses. - * + * A method interceptor which wraps custom exception handling around methods + * which can throw GuacamoleExceptions and which are exposed through the REST + * interface. The various types of GuacamoleExceptions are automatically + * translated into appropriate HTTP responses, including JSON describing the + * error that occurred. + * * @author James Muehlner + * @author Michael Jumper */ -public class AuthProviderRESTExceptionWrapper implements MethodInterceptor { +public class RESTExceptionWrapper implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTMethodMatcher.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTMethodMatcher.java new file mode 100644 index 000000000..643addcd9 --- /dev/null +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTMethodMatcher.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 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.rest; + +import com.google.inject.matcher.AbstractMatcher; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import javax.ws.rs.HttpMethod; +import org.glyptodon.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 @GET or @POST. Any method which + * throws GuacamoleException and is annotated with an annotation that is + * annotated with @HttpMethod will match. + * + * @author Michael Jumper + */ +public class RESTMethodMatcher extends AbstractMatcher { + + /** + * 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 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 + * @HttpMethod. + * + * @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 annotationType = annotation.annotationType(); + if (annotationType.isAnnotationPresent(HttpMethod.class)) + return true; + + } + + // The method is not an HTTP 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); + + } + +} diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java index 478c2182e..48db9857b 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTServletModule.java @@ -45,11 +45,11 @@ public class RESTServletModule extends ServletModule { @Override protected void configureServlets() { - // Bind @AuthProviderRESTExposure annotation + // Automatically translate GuacamoleExceptions for REST methods bindInterceptor( Matchers.any(), - Matchers.annotatedWith(AuthProviderRESTExposure.class), - new AuthProviderRESTExceptionWrapper() + new RESTMethodMatcher(), + new RESTExceptionWrapper() ); // Bind convenience services used by the REST API diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/activeconnection/ActiveConnectionRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/activeconnection/ActiveConnectionRESTService.java index 42ae1c15f..2f2b69994 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/activeconnection/ActiveConnectionRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/activeconnection/ActiveConnectionRESTService.java @@ -47,7 +47,6 @@ import org.glyptodon.guacamole.net.auth.permission.SystemPermission; import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; import org.glyptodon.guacamole.net.basic.GuacamoleSession; import org.glyptodon.guacamole.net.basic.rest.APIPatch; -import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; import org.glyptodon.guacamole.net.basic.rest.ObjectRetrievalService; import org.glyptodon.guacamole.net.basic.rest.PATCH; import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; @@ -107,7 +106,6 @@ public class ActiveConnectionRESTService { * If an error is encountered while retrieving active connections. */ @GET - @AuthProviderRESTExposure public Map getActiveConnections(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @QueryParam("permission") List permissions) @@ -166,7 +164,6 @@ public class ActiveConnectionRESTService { * If an error occurs while deleting the active connections. */ @PATCH - @AuthProviderRESTExposure public void patchTunnels(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, List> patches) throws GuacamoleException { diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/auth/TokenRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/auth/TokenRESTService.java index 998cd5e44..4351b890e 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/auth/TokenRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/auth/TokenRESTService.java @@ -39,6 +39,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.xml.bind.DatatypeConverter; import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.GuacamoleResourceNotFoundException; import org.glyptodon.guacamole.GuacamoleSecurityException; import org.glyptodon.guacamole.environment.Environment; import org.glyptodon.guacamole.net.auth.AuthenticatedUser; @@ -49,10 +50,7 @@ import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo; import org.glyptodon.guacamole.net.auth.credentials.GuacamoleCredentialsException; import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException; import org.glyptodon.guacamole.net.basic.GuacamoleSession; -import org.glyptodon.guacamole.net.basic.rest.APIError; import org.glyptodon.guacamole.net.basic.rest.APIRequest; -import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; -import org.glyptodon.guacamole.net.basic.rest.APIException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -464,7 +462,6 @@ public class TokenRESTService { * If an error prevents successful authentication. */ @POST - @AuthProviderRESTExposure public APIAuthenticationResult createToken(@FormParam("username") String username, @FormParam("password") String password, @FormParam("token") String token, @@ -523,16 +520,20 @@ public class TokenRESTService { * Invalidates a specific auth token, effectively logging out the associated * user. * - * @param authToken The token being invalidated. + * @param authToken + * The token being invalidated. + * + * @throws GuacamoleException + * If the specified token does not exist. */ @DELETE @Path("/{token}") - @AuthProviderRESTExposure - public void invalidateToken(@PathParam("token") String authToken) { + public void invalidateToken(@PathParam("token") String authToken) + throws GuacamoleException { GuacamoleSession session = tokenSessionMap.remove(authToken); if (session == null) - throw new APIException(APIError.Type.NOT_FOUND, "No such token."); + throw new GuacamoleResourceNotFoundException("No such token."); session.invalidate(); diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java index 270e3c302..caa4aa99a 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connection/ConnectionRESTService.java @@ -49,7 +49,6 @@ import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet; import org.glyptodon.guacamole.net.auth.permission.SystemPermission; import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; import org.glyptodon.guacamole.net.basic.GuacamoleSession; -import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; import org.glyptodon.guacamole.net.basic.rest.ObjectRetrievalService; import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; @@ -105,7 +104,6 @@ public class ConnectionRESTService { */ @GET @Path("/{connectionID}") - @AuthProviderRESTExposure public APIConnection getConnection(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionID") String connectionID) @@ -141,7 +139,6 @@ public class ConnectionRESTService { */ @GET @Path("/{connectionID}/parameters") - @AuthProviderRESTExposure public Map getConnectionParameters(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionID") String connectionID) @@ -195,7 +192,6 @@ public class ConnectionRESTService { */ @GET @Path("/{connectionID}/history") - @AuthProviderRESTExposure public List getConnectionHistory(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionID") String connectionID) @@ -235,7 +231,6 @@ public class ConnectionRESTService { */ @DELETE @Path("/{connectionID}") - @AuthProviderRESTExposure public void deleteConnection(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionID") String connectionID) @@ -275,7 +270,6 @@ public class ConnectionRESTService { */ @POST @Produces(MediaType.TEXT_PLAIN) - @AuthProviderRESTExposure public String createConnection(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, APIConnection connection) throws GuacamoleException { @@ -320,7 +314,6 @@ public class ConnectionRESTService { */ @PUT @Path("/{connectionID}") - @AuthProviderRESTExposure public void updateConnection(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionID") String connectionID, diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java index 5899d32d7..77bcbdfae 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/connectiongroup/ConnectionGroupRESTService.java @@ -41,7 +41,6 @@ import org.glyptodon.guacamole.net.auth.Directory; import org.glyptodon.guacamole.net.auth.UserContext; import org.glyptodon.guacamole.net.auth.permission.ObjectPermission; import org.glyptodon.guacamole.net.basic.GuacamoleSession; -import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; import org.glyptodon.guacamole.net.basic.rest.ObjectRetrievalService; import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; import org.slf4j.Logger; @@ -96,7 +95,6 @@ public class ConnectionGroupRESTService { */ @GET @Path("/{connectionGroupID}") - @AuthProviderRESTExposure public APIConnectionGroup getConnectionGroup(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionGroupID") String connectionGroupID) @@ -138,7 +136,6 @@ public class ConnectionGroupRESTService { */ @GET @Path("/{connectionGroupID}/tree") - @AuthProviderRESTExposure public APIConnectionGroup getConnectionGroupTree(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionGroupID") String connectionGroupID, @@ -176,7 +173,6 @@ public class ConnectionGroupRESTService { */ @DELETE @Path("/{connectionGroupID}") - @AuthProviderRESTExposure public void deleteConnectionGroup(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionGroupID") String connectionGroupID) @@ -218,7 +214,6 @@ public class ConnectionGroupRESTService { */ @POST @Produces(MediaType.TEXT_PLAIN) - @AuthProviderRESTExposure public String createConnectionGroup(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, APIConnectionGroup connectionGroup) throws GuacamoleException { @@ -263,7 +258,6 @@ public class ConnectionGroupRESTService { */ @PUT @Path("/{connectionGroupID}") - @AuthProviderRESTExposure public void updateConnectionGroup(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("connectionGroupID") String connectionGroupID, diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java index 6a09cba32..66a2aa78f 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/schema/SchemaRESTService.java @@ -38,7 +38,6 @@ import org.glyptodon.guacamole.environment.LocalEnvironment; import org.glyptodon.guacamole.form.Form; import org.glyptodon.guacamole.net.auth.UserContext; import org.glyptodon.guacamole.net.basic.GuacamoleSession; -import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; import org.glyptodon.guacamole.net.basic.rest.ObjectRetrievalService; import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; import org.glyptodon.guacamole.protocols.ProtocolInfo; @@ -86,7 +85,6 @@ public class SchemaRESTService { */ @GET @Path("/users/attributes") - @AuthProviderRESTExposure public Collection
getUserAttributes(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier) throws GuacamoleException { @@ -118,7 +116,6 @@ public class SchemaRESTService { */ @GET @Path("/connections/attributes") - @AuthProviderRESTExposure public Collection getConnectionAttributes(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier) throws GuacamoleException { @@ -151,7 +148,6 @@ public class SchemaRESTService { */ @GET @Path("/connectionGroups/attributes") - @AuthProviderRESTExposure public Collection getConnectionGroupAttributes(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier) throws GuacamoleException { @@ -186,7 +182,6 @@ public class SchemaRESTService { */ @GET @Path("/protocols") - @AuthProviderRESTExposure public Map getProtocols(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier) throws GuacamoleException { diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java index 687d4ff85..404757b86 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/user/UserRESTService.java @@ -39,8 +39,10 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import org.glyptodon.guacamole.GuacamoleClientException; import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.GuacamoleResourceNotFoundException; +import org.glyptodon.guacamole.GuacamoleSecurityException; import org.glyptodon.guacamole.net.auth.AuthenticationProvider; import org.glyptodon.guacamole.net.auth.Credentials; import org.glyptodon.guacamole.net.auth.Directory; @@ -53,12 +55,9 @@ import org.glyptodon.guacamole.net.auth.permission.Permission; import org.glyptodon.guacamole.net.auth.permission.SystemPermission; import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet; import org.glyptodon.guacamole.net.basic.GuacamoleSession; -import org.glyptodon.guacamole.net.basic.rest.APIError; import org.glyptodon.guacamole.net.basic.rest.APIPatch; import static org.glyptodon.guacamole.net.basic.rest.APIPatch.Operation.add; import static org.glyptodon.guacamole.net.basic.rest.APIPatch.Operation.remove; -import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; -import org.glyptodon.guacamole.net.basic.rest.APIException; import org.glyptodon.guacamole.net.basic.rest.ObjectRetrievalService; import org.glyptodon.guacamole.net.basic.rest.PATCH; import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; @@ -150,7 +149,6 @@ public class UserRESTService { * If an error is encountered while retrieving users. */ @GET - @AuthProviderRESTExposure public List getUsers(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @QueryParam("permission") List permissions) @@ -205,7 +203,6 @@ public class UserRESTService { */ @GET @Path("/{username}") - @AuthProviderRESTExposure public APIUser getUser(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("username") String username) @@ -241,7 +238,6 @@ public class UserRESTService { */ @POST @Produces(MediaType.TEXT_PLAIN) - @AuthProviderRESTExposure public String createUser(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, APIUser user) throws GuacamoleException { @@ -285,7 +281,6 @@ public class UserRESTService { */ @PUT @Path("/{username}") - @AuthProviderRESTExposure public void updateUser(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("username") String username, APIUser user) @@ -299,14 +294,11 @@ public class UserRESTService { // Validate data and path are sane if (!user.getUsername().equals(username)) - throw new APIException(APIError.Type.BAD_REQUEST, - "Username in path does not match username provided JSON data."); + throw new GuacamoleClientException("Username in path does not match username provided JSON data."); // A user may not use this endpoint to modify himself - if (userContext.self().getIdentifier().equals(user.getUsername())) { - throw new APIException(APIError.Type.PERMISSION_DENIED, - "Permission denied."); - } + if (userContext.self().getIdentifier().equals(user.getUsername())) + throw new GuacamoleSecurityException("Permission denied."); // Get the user User existingUser = retrievalService.retrieveUser(userContext, username); @@ -349,7 +341,6 @@ public class UserRESTService { */ @PUT @Path("/{username}/password") - @AuthProviderRESTExposure public void updatePassword(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("username") String username, @@ -369,18 +360,15 @@ public class UserRESTService { // Verify that the old password was correct try { AuthenticationProvider authProvider = userContext.getAuthenticationProvider(); - if (authProvider.authenticateUser(credentials) == null) { - throw new APIException(APIError.Type.PERMISSION_DENIED, - "Permission denied."); - } + if (authProvider.authenticateUser(credentials) == null) + throw new GuacamoleSecurityException("Permission denied."); } // Pass through any credentials exceptions as simple permission denied catch (GuacamoleCredentialsException e) { - throw new APIException(APIError.Type.PERMISSION_DENIED, - "Permission denied."); + throw new GuacamoleSecurityException("Permission denied."); } - + // Get the user directory Directory userDirectory = userContext.getUserDirectory(); @@ -414,7 +402,6 @@ public class UserRESTService { */ @DELETE @Path("/{username}") - @AuthProviderRESTExposure public void deleteUser(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("username") String username) @@ -458,7 +445,6 @@ public class UserRESTService { */ @GET @Path("/{username}/permissions") - @AuthProviderRESTExposure public APIPermissionSet getPermissions(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("username") String username) @@ -499,11 +485,14 @@ public class UserRESTService { * * @param permission * The permission being added or removed from the set. + * + * @throws GuacamoleException + * If the requested patch operation is not supported. */ private void updatePermissionSet( APIPatch.Operation operation, PermissionSetPatch permissionSetPatch, - PermissionType permission) { + PermissionType permission) throws GuacamoleException { // Add or remove permission based on operation switch (operation) { @@ -520,8 +509,7 @@ public class UserRESTService { // Unsupported patch operation default: - throw new APIException(APIError.Type.BAD_REQUEST, - "Unsupported patch operation: \"" + operation + "\""); + throw new GuacamoleClientException("Unsupported patch operation: \"" + operation + "\""); } @@ -553,7 +541,6 @@ public class UserRESTService { */ @PATCH @Path("/{username}/permissions") - @AuthProviderRESTExposure public void patchPermissions(@QueryParam("token") String authToken, @PathParam("dataSource") String authProviderIdentifier, @PathParam("username") String username, @@ -645,7 +632,7 @@ public class UserRESTService { // Otherwise, the path is not supported else - throw new APIException(APIError.Type.BAD_REQUEST, "Unsupported patch path: \"" + path + "\""); + throw new GuacamoleClientException("Unsupported patch path: \"" + path + "\""); } // end for each patch operation