diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java index c1e6bf856..94deb77e4 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/RESTModule.java @@ -23,6 +23,7 @@ import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.net.auth.AuthenticationProvider; import org.glyptodon.guacamole.net.basic.properties.BasicGuacamoleProperties; import org.glyptodon.guacamole.net.basic.rest.auth.AuthTokenGenerator; +import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; import org.glyptodon.guacamole.net.basic.rest.auth.BasicTokenUserContextMap; import org.glyptodon.guacamole.net.basic.rest.auth.SecureRandomAuthTokenGenerator; import org.glyptodon.guacamole.net.basic.rest.auth.TokenUserContextMap; @@ -64,6 +65,7 @@ public class RESTModule extends AbstractModule { bind(AuthenticationProvider.class).toInstance(authProvider); bind(TokenUserContextMap.class).toInstance(new BasicTokenUserContextMap()); bind(ConnectionService.class); + bind(AuthenticationService.class); bind(AuthTokenGenerator.class).to(SecureRandomAuthTokenGenerator.class); } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/auth/AuthenticationService.java new file mode 100644 index 000000000..ccf2a518f --- /dev/null +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/rest/auth/AuthenticationService.java @@ -0,0 +1,64 @@ +package org.glyptodon.guacamole.net.basic.rest.auth; + +/* + * Guacamole - Clientless Remote Desktop + * Copyright (C) 2010 Michael Jumper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import com.google.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import org.glyptodon.guacamole.net.auth.UserContext; +import org.glyptodon.guacamole.net.basic.rest.APIError; + +/** + * A service for performing authentication checks in REST endpoints. + * + * @author James Muehlner + */ +public class AuthenticationService { + + /** + * The map of auth tokens to users for the REST endpoints. + */ + @Inject + private TokenUserContextMap tokenUserMap; + + /** + * Finds the UserContext for a given auth token, if the auth token represents + * a currently logged in user. Throws an unauthorized error otherwise. + * + * @param authToken The auth token to check against the map of logged in users. + * @return The userContext that corresponds to the provided auth token. + * @throws WebApplicationException If the auth token does not correspond to + * any logged in user. + */ + public UserContext getUserContextFromAuthToken(String authToken) + throws WebApplicationException { + + // Try to get the userContext from the map of logged in users. + UserContext userContext = tokenUserMap.get(authToken); + + // Authentication failed. + if(userContext == null) + throw new WebApplicationException( + Response.status(Response.Status.UNAUTHORIZED) + .entity(new APIError("Permission Denied.")).build()); + + return userContext; + } + +} 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 1bc98328e..92a46e2b0 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 @@ -19,7 +19,6 @@ package org.glyptodon.guacamole.net.basic.rest.connection; */ import com.google.inject.Inject; -import com.google.inject.servlet.RequestScoped; import java.util.ArrayList; import java.util.List; import javax.ws.rs.GET; @@ -35,7 +34,7 @@ import org.glyptodon.guacamole.net.auth.ConnectionGroup; import org.glyptodon.guacamole.net.auth.Directory; import org.glyptodon.guacamole.net.auth.UserContext; import org.glyptodon.guacamole.net.basic.rest.APIError; -import org.glyptodon.guacamole.net.basic.rest.auth.TokenUserContextMap; +import org.glyptodon.guacamole.net.basic.rest.auth.AuthenticationService; /** * A REST Service for handling connection CRUD operations. @@ -47,10 +46,10 @@ import org.glyptodon.guacamole.net.basic.rest.auth.TokenUserContextMap; public class ConnectionRESTService { /** - * The map of auth tokens to users for the REST endpoints. + * A service for authenticating users from auth tokens. */ @Inject - private TokenUserContextMap tokenUserMap; + private AuthenticationService authenticationService; /** * A service for managing the REST endpoint Connection objects. @@ -60,13 +59,7 @@ public class ConnectionRESTService { @GET public List getConnections(@QueryParam("token") String authToken, @QueryParam("parentID") String parentID) { - UserContext userContext = tokenUserMap.get(authToken); - - // authentication failed. - if(userContext == null) - throw new WebApplicationException( - Response.status(Response.Status.UNAUTHORIZED) - .entity(new APIError("Permission Denied.")).build()); + UserContext userContext = authenticationService.getUserContextFromAuthToken(authToken); try { // If the parent connection group is passed in, try to find it. @@ -107,6 +100,6 @@ public class ConnectionRESTService { Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity(e).build()); } - } - + } + }