From 508a476e2effc0aaa4f76be2d0bd547f12501170 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 5 Jan 2015 12:03:53 -0800 Subject: [PATCH] GUAC-971: Allow existing sessions/tokens to be updated through the login process. --- .../guacamole/net/basic/GuacamoleSession.java | 26 +++++++- .../net/basic/rest/auth/TokenRESTService.java | 61 +++++++++++++++---- 2 files changed, 74 insertions(+), 13 deletions(-) diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/GuacamoleSession.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/GuacamoleSession.java index dcf3bd705..0455b8436 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/GuacamoleSession.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/GuacamoleSession.java @@ -53,12 +53,12 @@ public class GuacamoleSession { /** * The credentials provided when the user logged in. */ - private final Credentials credentials; + private Credentials credentials; /** * The user context associated with this session. */ - private final UserContext userContext; + private UserContext userContext; /** * Collection of all event listeners configured in guacamole.properties. @@ -148,6 +148,17 @@ public class GuacamoleSession { return credentials; } + /** + * Replaces the credentials associated with this session with the given + * credentials. + * + * @param credentials + * The credentials to associate with this session. + */ + public void setCredentials(Credentials credentials) { + this.credentials = credentials; + } + /** * Returns the UserContext associated with this session. * @@ -157,6 +168,17 @@ public class GuacamoleSession { return userContext; } + /** + * Replaces the user context associated with this session with the given + * user context. + * + * @param userContext + * The user context to associate with this session. + */ + public void setUserContext(UserContext userContext) { + this.userContext = userContext; + } + /** * Returns the ClipboardState associated with this session. * 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 6db943908..740f74b38 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 @@ -77,20 +77,41 @@ public class TokenRESTService { /** * Authenticates a user, generates an auth token, associates that auth token - * with the user's UserContext for use by further requests. + * with the user's UserContext for use by further requests. If an existing + * token is provided, the authentication procedure will attempt to update + * or reuse the provided token. * - * @param username The username of the user who is to be authenticated. - * @param password The password of the user who is to be authenticated. - * @param request The HttpServletRequest associated with the login attempt. + * @param username + * The username of the user who is to be authenticated. + * + * @param password + * The password of the user who is to be authenticated. + * + * @param token + * An optional existing auth token for the user who is to be + * authenticated. + * + * @param request + * The HttpServletRequest associated with the login attempt. + * * @return The auth token for the newly logged-in user. * @throws GuacamoleException If an error prevents successful login. */ @POST @AuthProviderRESTExposure public APIAuthToken createToken(@FormParam("username") String username, - @FormParam("password") String password, + @FormParam("password") String password, + @FormParam("token") String token, @Context HttpServletRequest request) throws GuacamoleException { - + + // Pull existing session if token provided + GuacamoleSession existingSession; + if (token != null) + existingSession = tokenSessionMap.get(token); + else + existingSession = null; + + // Build credentials Credentials credentials = new Credentials(); credentials.setUsername(username); credentials.setPassword(password); @@ -99,7 +120,15 @@ public class TokenRESTService { UserContext userContext; try { - userContext = authProvider.getUserContext(credentials); + + // Update existing user context if session already exists + if (existingSession != null) + userContext = authProvider.updateUserContext(existingSession.getUserContext(), credentials); + + /// Otherwise, generate a new user context + else + userContext = authProvider.getUserContext(credentials); + } catch(GuacamoleException e) { logger.error("Exception caught while authenticating user.", e); @@ -110,10 +139,20 @@ public class TokenRESTService { // Authentication failed. if (userContext == null) throw new HTTPException(Status.UNAUTHORIZED, "Permission Denied."); - - String authToken = authTokenGenerator.getToken(); - - tokenSessionMap.put(authToken, new GuacamoleSession(credentials, userContext)); + + // Update existing session, if it exists + String authToken; + if (existingSession != null) { + authToken = token; + existingSession.setCredentials(credentials); + existingSession.setUserContext(userContext); + } + + // If no existing session, generate a new token/session pair + else { + authToken = authTokenGenerator.getToken(); + tokenSessionMap.put(authToken, new GuacamoleSession(credentials, userContext)); + } logger.debug("Login was successful for user \"{}\".", userContext.self().getUsername()); return new APIAuthToken(authToken, username);