GUAC-1161: Include credential information in REST responses.

This commit is contained in:
Michael Jumper
2015-04-20 13:33:20 -07:00
parent 2537b3d8ee
commit c80a203e97
2 changed files with 169 additions and 7 deletions

View File

@@ -0,0 +1,102 @@
/*
* 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 org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo;
/**
* Represents an error related to either invalid or insufficient credentials
* submitted to a REST endpoint.
*
* @author Michael Jumper
*/
public class APICredentialError extends APIError {
/**
* The required credentials.
*/
private final CredentialsInfo info;
/**
* The type of error that occurred.
*/
private final Type type;
/**
* All possible types of credential errors.
*/
public enum Type {
/**
* The credentials provided were invalid.
*/
INVALID,
/**
* The credentials provided were not necessarily invalid, but were not
* sufficient to determine validity.
*/
INSUFFICIENT
}
/**
* Create a new APICredentialError with the specified error message and
* credentials information.
*
* @param type
* The type of error that occurred.
*
* @param message
* The error message.
*
* @param info
* An object which describes the required credentials.
*/
public APICredentialError(Type type, String message, CredentialsInfo info) {
super(message);
this.type = type;
this.info = info;
}
/**
* Returns the type of error that occurred.
*
* @return
* The type of error that occurred.
*/
public Type getType() {
return type;
}
/**
* Returns an object which describes the required credentials.
*
* @return
* An object which describes the required credentials.
*/
public CredentialsInfo getInfo() {
return info;
}
}

View File

@@ -28,6 +28,9 @@ import org.aopalliance.intercept.MethodInvocation;
import org.glyptodon.guacamole.GuacamoleClientException;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.GuacamoleSecurityException;
import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo;
import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,15 +52,72 @@ public class AuthProviderRESTExceptionWrapper implements MethodInterceptor {
try {
return invocation.proceed();
}
catch(GuacamoleSecurityException e) {
throw new HTTPException(Response.Status.FORBIDDEN, e.getMessage() != null ? e.getMessage() : "Permission denied.");
// Additional credentials are needed
catch (GuacamoleInsufficientCredentialsException e) {
// Generate default message
String message = e.getMessage();
if (message == null)
message = "Permission denied.";
throw new HTTPException(Response.Status.FORBIDDEN, new APICredentialError(
APICredentialError.Type.INSUFFICIENT,
message,
e.getCredentialsInfo()
));
}
catch(GuacamoleClientException e) {
throw new HTTPException(Response.Status.BAD_REQUEST, e.getMessage() != null ? e.getMessage() : "Invalid Request.");
// The provided credentials are wrong
catch (GuacamoleInvalidCredentialsException e) {
// Generate default message
String message = e.getMessage();
if (message == null)
message = "Permission denied.";
throw new HTTPException(Response.Status.FORBIDDEN, new APICredentialError(
APICredentialError.Type.INVALID,
message,
e.getCredentialsInfo()
));
}
catch(GuacamoleException e) {
logger.error("Unexpected GuacamoleException caught while executing " + invocation.getMethod().getName() + ".", e);
throw new HTTPException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage() != null ? e.getMessage() : "Unexpected server error.");
// Generic permission denied
catch (GuacamoleSecurityException e) {
// Generate default message
String message = e.getMessage();
if (message == null)
message = "Permission denied.";
throw new HTTPException(Response.Status.FORBIDDEN, message);
}
// Arbitrary bad requests
catch (GuacamoleClientException e) {
// Generate default message
String message = e.getMessage();
if (message == null)
message = "Invalid request.";
throw new HTTPException(Response.Status.BAD_REQUEST, message);
}
// All other errors
catch (GuacamoleException e) {
// Generate default message
String message = e.getMessage();
if (message == null)
message = "Unexpected server error.";
logger.debug("Unexpected exception in REST endpoint.", e);
throw new HTTPException(Response.Status.INTERNAL_SERVER_ERROR, message);
}
}