Search in sources :

Example 1 with RestException

use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.

the class RemoteExceptionClientResponseFilter method filter.

@Override
public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) throws IOException {
    final int code = responseContext.getStatus();
    String operationId;
    if (Tracing.isVerbose()) {
        operationId = requestContext.getHeaderString(TracingConstants.HTTP_HEADER_CORRELATION_ID);
        if (operationId != null)
            Tracing.logOngoing(operationId, "HTTP:resp", () -> "" + code);
        else
            // can't find outgoing trace id
            operationId = Tracing.log("HTTP:resp:unexpected", () -> "" + code);
    } else {
        operationId = null;
    }
    if (code >= 200 && code <= 299)
        // Do not run if the return code is 2xx
        return;
    if (responseContext.getHeaders().containsKey(RestThrowableConstants.HEADER_RICH_EXCEPTION)) {
        try {
            final InputStream is = responseContext.getEntityStream();
            RestFailure failure;
            if (tryParseLegacyExceptionNamespace) {
                // If parsing the legacy namespace fails, throw the original parse error back to the client
                try {
                    // Mark the start of the stream so we can reset back to it if we need to process this as a legacy exception
                    is.mark(Integer.MAX_VALUE);
                    failure = parseResponse(is);
                } catch (JAXBUnmarshalException e) {
                    log.trace("Error parsing rich exception response, will fall back on parsing it as a legacy exception XML", e);
                    try {
                        failure = parseLegacyResponse(is);
                    } catch (Throwable legacyFailure) {
                        log.trace("Error parsing rich exception response as legacy rich exception XML!", legacyFailure);
                        // throw the original exception
                        throw e;
                    }
                }
            } else {
                failure = parseResponse(is);
            }
            if (Tracing.isVerbose() && failure != null && failure.exception != null) {
                final ExceptionInfo ei = failure.exception;
                Tracing.logOngoing(operationId, "HTTP:error", () -> ei.shortName + " " + ei.detail);
            }
            RestException exception = exceptionFactory.build(failure, responseContext);
            // Try to shorten the stack trace
            exception.fillInStackTrace();
            throw exception;
        } catch (ResponseProcessingException e) {
            throw e;
        } catch (Throwable e) {
            throw new ResponseProcessingException(null, "Error mapping exception from thrown from " + requestContext.getUri() + " to exception!", e);
        }
    }
}
Also used : JAXBUnmarshalException(org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException) RestFailure(com.peterphi.std.guice.restclient.jaxb.RestFailure) InputStream(java.io.InputStream) RestException(com.peterphi.std.guice.restclient.exception.RestException) ResponseProcessingException(javax.ws.rs.client.ResponseProcessingException) ExceptionInfo(com.peterphi.std.guice.restclient.jaxb.ExceptionInfo)

Example 2 with RestException

use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.

the class RedirectToOAuthAccessRefuser method refuse.

@Override
public Throwable refuse(final AuthScope scope, final AuthConstraint constraint, final CurrentUser login) {
    final RestException accessDeniedException = new RestException(403, "You do not have sufficient privileges to access this resource" + (constraint != null ? ": " + constraint.comment() : "") + ". Required role: " + scope.getRole(constraint) + ". You are: anonymous=" + login.isAnonymous() + ", browser=" + isBrowserConsumer());
    // If the user is logged in, deny access with a 403
    if (!login.isAnonymous()) {
        throw accessDeniedException;
    } else if (!isBrowserConsumer()) {
        // Non-browser consumer, send back an HTTP 401 immediately
        // TODO allow configuration of Basic with a realm?
        Response tryBasicAuth = Response.status(401).header("WWW-Authenticate", "Bearer").build();
        throw new LiteralRestResponseException(tryBasicAuth, accessDeniedException);
    } else if (!isGETRequest()) {
        // Don't redirect requests other than GET (the browser will retry the POST/PUT/DELETE/etc. against the redirect endpoint!
        throw new RestException(401, "You must log in to access this resource! Could not redirect you to the login provider because you were submitting a form, not requesting a page. Please return to the main page of the application and proceed to log in", accessDeniedException);
    } else {
        // Start an authorisation flow with the OAuth2 provider
        final OAuth2SessionRef sessionRef = sessionRefProvider.get();
        final URI redirectTo = sessionRef.getAuthFlowStartEndpoint(getRequestURI(), null);
        throw new LiteralRestResponseException(Response.seeOther(redirectTo).build(), accessDeniedException);
    }
}
Also used : Response(javax.ws.rs.core.Response) RestException(com.peterphi.std.guice.restclient.exception.RestException) URI(java.net.URI) LiteralRestResponseException(com.peterphi.std.guice.web.rest.jaxrs.exception.LiteralRestResponseException)

Example 3 with RestException

use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.

the class ServiceManagerResourceUIServiceImpl method getResource.

/**
 * N.B. transaction may be read-write because this read operation may result in reading a new template (or discovering an
 * update was made to the template)
 *
 * @param id
 *
 * @return
 */
@Override
@Transactional
public String getResource(String id) {
    final TemplateCall call = templater.template("resource_template");
    final ResourceTemplateEntity entity = resourceProvisionService.getOrCreateTemplate(id);
    if (entity == null)
        throw new RestException(404, "No such resource with id: " + id);
    call.set("entity", entity);
    call.set("nonce", nonceStore.getValue());
    return call.process();
}
Also used : RestException(com.peterphi.std.guice.restclient.exception.RestException) ResourceTemplateEntity(com.peterphi.servicemanager.service.db.entity.ResourceTemplateEntity) TemplateCall(com.peterphi.std.guice.web.rest.templating.TemplateCall) Transactional(com.peterphi.std.guice.database.annotation.Transactional)

Example 4 with RestException

use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.

the class RestFailureMarshaller method renderFailure.

/**
 * Render a Throwable as a RestFailure
 *
 * @param e
 *
 * @return
 */
public RestFailure renderFailure(Throwable e) {
    // Strip away ApplicationException wrappers
    if (e.getCause() != null && (e instanceof ApplicationException)) {
        return renderFailure(e.getCause());
    }
    RestFailure failure = new RestFailure();
    failure.id = getOrGenerateFailureId();
    failure.date = new Date();
    if (e instanceof RestException) {
        RestException re = (RestException) e;
        failure.httpCode = re.getHttpCode();
        failure.exception = renderThrowable(e);
    } else {
        // by default
        failure.httpCode = 500;
        failure.exception = renderThrowable(e);
    }
    return failure;
}
Also used : ApplicationException(org.jboss.resteasy.spi.ApplicationException) RestFailure(com.peterphi.std.guice.restclient.jaxb.RestFailure) RestException(com.peterphi.std.guice.restclient.exception.RestException) Date(java.util.Date)

Example 5 with RestException

use of com.peterphi.std.guice.restclient.exception.RestException in project stdlib by petergeneric.

the class ServiceManagerResourceUIServiceImpl method doProvision.

@Override
public Response doProvision(final String id, final String nonce) {
    nonceStore.validate(nonce);
    final ResourceTemplateEntity entity = resourceProvisionService.getOrCreateTemplate(id);
    if (entity == null)
        throw new RestException(404, "No such resource with id: " + id);
    resourceProvisionService.newInstance(id, Collections.emptyMap());
    // Redirect to template page
    return Response.seeOther(URI.create("/resources/template/" + id)).build();
}
Also used : RestException(com.peterphi.std.guice.restclient.exception.RestException) ResourceTemplateEntity(com.peterphi.servicemanager.service.db.entity.ResourceTemplateEntity)

Aggregations

RestException (com.peterphi.std.guice.restclient.exception.RestException)5 ResourceTemplateEntity (com.peterphi.servicemanager.service.db.entity.ResourceTemplateEntity)2 RestFailure (com.peterphi.std.guice.restclient.jaxb.RestFailure)2 Transactional (com.peterphi.std.guice.database.annotation.Transactional)1 ExceptionInfo (com.peterphi.std.guice.restclient.jaxb.ExceptionInfo)1 LiteralRestResponseException (com.peterphi.std.guice.web.rest.jaxrs.exception.LiteralRestResponseException)1 TemplateCall (com.peterphi.std.guice.web.rest.templating.TemplateCall)1 InputStream (java.io.InputStream)1 URI (java.net.URI)1 Date (java.util.Date)1 ResponseProcessingException (javax.ws.rs.client.ResponseProcessingException)1 Response (javax.ws.rs.core.Response)1 JAXBUnmarshalException (org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException)1 ApplicationException (org.jboss.resteasy.spi.ApplicationException)1