GUAC-1102: Reconstitute consumed HTTP requests with an external collection of parameter name/value pairs.

This commit is contained in:
Michael Jumper
2015-04-13 12:38:03 -07:00
parent c10c0985e8
commit 89b4ff642f
2 changed files with 125 additions and 3 deletions

View File

@@ -0,0 +1,107 @@
/*
* 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 java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.ws.rs.core.MultivaluedMap;
/**
* Wrapper for HttpServletRequest which uses a given MultivaluedMap to provide
* the values of all request parameters.
*
* @author Michael Jumper
*/
public class APIRequest extends HttpServletRequestWrapper {
/**
* Map of all request parameter names to their corresponding values.
*/
private final Map<String, String[]> parameters;
/**
* Wraps the given HttpServletRequest, using the given MultivaluedMap to
* provide all request parameters. All HttpServletRequest functions which
* do not deal with parameter names and values are delegated to the wrapped
* request.
*
* @param request
* The HttpServletRequest to wrap.
*
* @param parameters
* All request parameters.
*/
public APIRequest(HttpServletRequest request,
MultivaluedMap<String, String> parameters) {
super(request);
// Copy parameters from given MultivaluedMap
this.parameters = new HashMap<String, String[]>(parameters.size());
for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
// Get parameter name and all corresponding values
String name = entry.getKey();
List<String> values = entry.getValue();
// Add parameters to map
this.parameters.put(name, values.toArray(new String[values.size()]));
}
}
@Override
public String[] getParameterValues(String name) {
return parameters.get(name);
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(parameters.keySet());
}
@Override
public Map<String, String[]> getParameterMap() {
return Collections.unmodifiableMap(parameters);
}
@Override
public String getParameter(String name) {
// If no such parameter exists, just return null
String[] values = getParameterValues(name);
if (values == null)
return null;
// Otherwise, return first value
return values[0];
}
}

View File

@@ -34,6 +34,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.Response.Status;
import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverter;
import org.glyptodon.guacamole.GuacamoleException; import org.glyptodon.guacamole.GuacamoleException;
@@ -41,6 +42,7 @@ import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
import org.glyptodon.guacamole.net.auth.Credentials; import org.glyptodon.guacamole.net.auth.Credentials;
import org.glyptodon.guacamole.net.auth.UserContext; import org.glyptodon.guacamole.net.auth.UserContext;
import org.glyptodon.guacamole.net.basic.GuacamoleSession; import org.glyptodon.guacamole.net.basic.GuacamoleSession;
import org.glyptodon.guacamole.net.basic.rest.APIRequest;
import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure; import org.glyptodon.guacamole.net.basic.rest.AuthProviderRESTExposure;
import org.glyptodon.guacamole.net.basic.rest.HTTPException; import org.glyptodon.guacamole.net.basic.rest.HTTPException;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -140,8 +142,16 @@ public class TokenRESTService {
* An optional existing auth token for the user who is to be * An optional existing auth token for the user who is to be
* authenticated. * authenticated.
* *
* @param request * @param consumedRequest
* The HttpServletRequest associated with the login attempt. * The HttpServletRequest associated with the login attempt. The
* parameters of this request may not be accessible, as the request may
* have been fully consumed by JAX-RS.
*
* @param parameters
* A MultivaluedMap containing all parameters from the given HTTP
* request. All request parameters must be made available through this
* map, even if those parameters are no longer accessible within the
* now-fully-consumed HTTP request.
* *
* @return The auth token for the newly logged-in user. * @return The auth token for the newly logged-in user.
* @throws GuacamoleException If an error prevents successful login. * @throws GuacamoleException If an error prevents successful login.
@@ -151,8 +161,13 @@ public class TokenRESTService {
public APIAuthToken createToken(@FormParam("username") String username, public APIAuthToken createToken(@FormParam("username") String username,
@FormParam("password") String password, @FormParam("password") String password,
@FormParam("token") String token, @FormParam("token") String token,
@Context HttpServletRequest request) throws GuacamoleException { @Context HttpServletRequest consumedRequest,
MultivaluedMap<String, String> parameters)
throws GuacamoleException {
// Reconstitute the HTTP request with the map of parameters
HttpServletRequest request = new APIRequest(consumedRequest, parameters);
// Pull existing session if token provided // Pull existing session if token provided
GuacamoleSession existingSession; GuacamoleSession existingSession;
if (token != null) if (token != null)