Search in sources :

Example 1 with HttpException

use of io.vertx.ext.web.handler.HttpException in project hono by eclipse.

the class DefaultFailureHandler method handle.

/**
 * Handles routing failures.
 * <p>
 * This method simply delegates to the next handler if the response is already
 * ended or the context is not failed.
 *
 * @param ctx The failing routing context.
 */
@Override
public void handle(final RoutingContext ctx) {
    if (ctx.failed()) {
        if (ctx.response().ended()) {
            LOG.debug("skipping processing of failed route, response already ended");
        } else {
            LOG.debug("handling failed route for request [method: {}, URI: {}, status: {}] - {}", ctx.request().method(), HttpUtils.getAbsoluteURI(ctx.request()), ctx.statusCode(), ctx.getBody(), ctx.failure());
            if (ctx.failure() != null) {
                if (ctx.failure() instanceof ServiceInvocationException) {
                    final ServiceInvocationException e = (ServiceInvocationException) ctx.failure();
                    sendError(ctx.response(), e.getErrorCode(), e.getMessage());
                } else if (ctx.failure() instanceof HttpException) {
                    final HttpException e = (HttpException) ctx.failure();
                    sendError(ctx.response(), e.getStatusCode(), e.getMessage());
                } else {
                    LOG.debug("unexpected internal failure", ctx.failure());
                    sendError(ctx.response(), HttpURLConnection.HTTP_INTERNAL_ERROR, ctx.failure().getMessage());
                }
            } else if (ctx.statusCode() != -1) {
                sendError(ctx.response(), ctx.statusCode(), null);
            } else {
                sendError(ctx.response(), HttpURLConnection.HTTP_INTERNAL_ERROR, "Internal Server Error");
            }
        }
    } else {
        LOG.debug("skipping processing of non-failed route");
        ctx.next();
    }
}
Also used : HttpException(io.vertx.ext.web.handler.HttpException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException)

Example 2 with HttpException

use of io.vertx.ext.web.handler.HttpException in project hono by eclipse.

the class AuthHandlerTools method processException.

/**
 * Processes an exception that occurred while trying to authenticate
 * a device.
 * <p>
 * This method checks if the given exception is an {@code HttpException}
 * and if so, tries to extract the root cause of the problem from its
 * <em>cause</em> field. If the root cause is a {@link ServiceInvocationException}
 * the routing context is failed with that exception (provided the status code
 * isn't 302, in which case the context is ended with a <em>Location</em> header).
 * <p>
 * In all other cases, the routing context is failed with the given exception.
 * <p>
 * Note that the routing context is failed with just the exception, no status
 * code. Setting the status code on the response corresponding to the exception
 * is to be done in the failure handler, e.g. as implemented in the
 * {@link org.eclipse.hono.service.http.DefaultFailureHandler}.
 *
 * @param ctx The routing context.
 * @param exception The cause of failure to process the request.
 * @param authenticateHeader The value to return in the HTTP Authenticate header.
 * @see io.vertx.ext.web.handler.impl.AuthenticationHandlerImpl
 */
public static void processException(final RoutingContext ctx, final Throwable exception, final String authenticateHeader) {
    if (exception instanceof HttpException) {
        final Throwable failure = Optional.ofNullable(exception.getCause()).map(c -> {
            if (c instanceof ServiceInvocationException) {
                // extract and use root cause
                return c;
            } else {
                return exception;
            }
        }).orElse(exception);
        final int statusCode;
        final String payload;
        if (failure instanceof ServiceInvocationException) {
            final ServiceInvocationException sie = (ServiceInvocationException) exception.getCause();
            statusCode = sie.getErrorCode();
            payload = null;
        } else {
            statusCode = ((HttpException) exception).getStatusCode();
            payload = ((HttpException) exception).getPayload();
        }
        switch(statusCode) {
            case 302:
                ctx.response().putHeader(HttpHeaders.LOCATION, payload).setStatusCode(302).end("Redirecting to " + payload + ".");
                return;
            case 401:
                if (authenticateHeader != null) {
                    ctx.response().putHeader("WWW-Authenticate", authenticateHeader);
                }
            // fall through
            default:
                // rely on DefaultFailureHandler to extract/apply the status code
                ctx.fail(failure);
        }
    } else {
        ctx.fail(exception);
    }
}
Also used : Optional(java.util.Optional) HttpHeaders(io.vertx.core.http.HttpHeaders) RoutingContext(io.vertx.ext.web.RoutingContext) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) HttpException(io.vertx.ext.web.handler.HttpException) HttpException(io.vertx.ext.web.handler.HttpException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException)

Example 3 with HttpException

use of io.vertx.ext.web.handler.HttpException in project hono by eclipse.

the class HonoBasicAuthHandler method authenticate.

@Override
public void authenticate(final RoutingContext context, final Handler<AsyncResult<User>> handler) {
    parseAuthorization(context, parseAuthorization -> {
        if (parseAuthorization.failed()) {
            handler.handle(Future.failedFuture(parseAuthorization.cause()));
            return;
        }
        final String suser;
        final String spass;
        try {
            // decode the payload
            final String decoded = new String(Base64.getDecoder().decode(parseAuthorization.result()));
            final int colonIdx = decoded.indexOf(":");
            if (colonIdx != -1) {
                suser = decoded.substring(0, colonIdx);
                spass = decoded.substring(colonIdx + 1);
            } else {
                suser = decoded;
                spass = null;
            }
        } catch (RuntimeException e) {
            handler.handle(Future.failedFuture(new HttpException(400, e)));
            return;
        }
        final var credentials = new JsonObject().put("username", suser).put("password", spass);
        final ExecutionContextAuthHandler<HttpContext> authHandler = new ExecutionContextAuthHandler<>((DeviceCredentialsAuthProvider<?>) authProvider, preCredentialsValidationHandler) {

            @Override
            public Future<JsonObject> parseCredentials(final HttpContext context) {
                return Future.succeededFuture(credentials);
            }
        };
        authHandler.authenticateDevice(HttpContext.from(context)).map(deviceUser -> (User) deviceUser).onComplete(handler);
    });
}
Also used : HttpContext(org.eclipse.hono.service.http.HttpContext) AuthenticationProvider(io.vertx.ext.auth.authentication.AuthenticationProvider) RoutingContext(io.vertx.ext.web.RoutingContext) Future(io.vertx.core.Future) BasicAuthHandler(io.vertx.ext.web.handler.BasicAuthHandler) Objects(java.util.Objects) Base64(java.util.Base64) User(io.vertx.ext.auth.User) DeviceCredentialsAuthProvider(org.eclipse.hono.adapter.auth.device.DeviceCredentialsAuthProvider) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) PreCredentialsValidationHandler(org.eclipse.hono.adapter.auth.device.PreCredentialsValidationHandler) Handler(io.vertx.core.Handler) HttpException(io.vertx.ext.web.handler.HttpException) HTTPAuthorizationHandler(io.vertx.ext.web.handler.impl.HTTPAuthorizationHandler) ExecutionContextAuthHandler(org.eclipse.hono.adapter.auth.device.ExecutionContextAuthHandler) User(io.vertx.ext.auth.User) ExecutionContextAuthHandler(org.eclipse.hono.adapter.auth.device.ExecutionContextAuthHandler) HttpContext(org.eclipse.hono.service.http.HttpContext) JsonObject(io.vertx.core.json.JsonObject) HttpException(io.vertx.ext.web.handler.HttpException)

Example 4 with HttpException

use of io.vertx.ext.web.handler.HttpException in project hono by eclipse.

the class HonoBasicAuthHandlerTest method testHandleFailsForMalformedAuthorizationHeader.

/**
 * Verifies that the handler returns the status code {@link HttpURLConnection#HTTP_BAD_REQUEST} in case of malformed
 * authorization header.
 */
@Test
public void testHandleFailsForMalformedAuthorizationHeader() {
    final DeviceCredentialsAuthProvider<?> authProvider = mock(DeviceCredentialsAuthProvider.class);
    final HonoBasicAuthHandler authHandler = new HonoBasicAuthHandler(authProvider, "test");
    // WHEN trying to authenticate a request using the HTTP BASIC scheme
    final String authorization = "BASIC test test";
    final MultiMap headers = mock(MultiMap.class);
    when(headers.get(eq(HttpHeaders.AUTHORIZATION))).thenReturn(authorization);
    final HttpServerRequest req = mock(HttpServerRequest.class);
    when(req.headers()).thenReturn(headers);
    final HttpServerResponse resp = mock(HttpServerResponse.class);
    final RoutingContext ctx = mock(RoutingContext.class);
    when(ctx.request()).thenReturn(req);
    when(ctx.response()).thenReturn(resp);
    when(ctx.currentRoute()).thenReturn(mock(Route.class));
    authHandler.handle(ctx);
    // THEN the routing context is failed with a 400 error
    final ArgumentCaptor<Throwable> error = ArgumentCaptor.forClass(Throwable.class);
    verify(ctx).fail(error.capture());
    assertThat(error.getValue()).isInstanceOf(HttpException.class);
    assertThat(((HttpException) error.getValue()).getStatusCode()).isEqualTo(HttpURLConnection.HTTP_BAD_REQUEST);
}
Also used : MultiMap(io.vertx.core.MultiMap) RoutingContext(io.vertx.ext.web.RoutingContext) HttpServerRequest(io.vertx.core.http.HttpServerRequest) HttpServerResponse(io.vertx.core.http.HttpServerResponse) HttpException(io.vertx.ext.web.handler.HttpException) Route(io.vertx.ext.web.Route) Test(org.junit.jupiter.api.Test)

Aggregations

HttpException (io.vertx.ext.web.handler.HttpException)4 RoutingContext (io.vertx.ext.web.RoutingContext)3 ServiceInvocationException (org.eclipse.hono.client.ServiceInvocationException)2 AsyncResult (io.vertx.core.AsyncResult)1 Future (io.vertx.core.Future)1 Handler (io.vertx.core.Handler)1 MultiMap (io.vertx.core.MultiMap)1 HttpHeaders (io.vertx.core.http.HttpHeaders)1 HttpServerRequest (io.vertx.core.http.HttpServerRequest)1 HttpServerResponse (io.vertx.core.http.HttpServerResponse)1 JsonObject (io.vertx.core.json.JsonObject)1 User (io.vertx.ext.auth.User)1 AuthenticationProvider (io.vertx.ext.auth.authentication.AuthenticationProvider)1 Route (io.vertx.ext.web.Route)1 BasicAuthHandler (io.vertx.ext.web.handler.BasicAuthHandler)1 HTTPAuthorizationHandler (io.vertx.ext.web.handler.impl.HTTPAuthorizationHandler)1 Base64 (java.util.Base64)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 DeviceCredentialsAuthProvider (org.eclipse.hono.adapter.auth.device.DeviceCredentialsAuthProvider)1