package org.pac4j.vertx.handler.impl; import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; import io.vertx.ext.web.RoutingContext; import org.pac4j.core.config.Config; import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.engine.CallbackLogic; import org.pac4j.core.engine.DefaultCallbackLogic; import org.pac4j.core.exception.TechnicalException; import org.pac4j.core.http.HttpActionAdapter; import org.pac4j.vertx.VertxProfileManager; import org.pac4j.vertx.VertxWebContext; import org.pac4j.vertx.http.DefaultHttpActionAdapter; /** * Callback handler for Vert.x pac4j binding. This handler finishes the stateful authentication process. * * @author Michael Remond * @since 1.0.0 * */ public class CallbackHandler implements Handler<RoutingContext> { protected static final Logger LOG = LoggerFactory.getLogger(CallbackHandler.class); private final HttpActionAdapter httpActionHandler = new DefaultHttpActionAdapter(); private final Vertx vertx; private final SessionStore<VertxWebContext> sessionStore; private final Config config; // Config elements which are all optional private final Boolean multiProfile; private final Boolean renewSession; private final String defaultUrl; private final CallbackLogic<Void, VertxWebContext> callbackLogic = new DefaultCallbackLogic(); { ((DefaultCallbackLogic<Void, VertxWebContext>) callbackLogic) .setProfileManagerFactory(VertxProfileManager::new); } public CallbackHandler(final Vertx vertx, final SessionStore<VertxWebContext> sessionStore, final Config config, final CallbackHandlerOptions options) { this.vertx = vertx; this.sessionStore = sessionStore; this.config = config; this.multiProfile = options.getMultiProfile(); this.renewSession = options.getRenewSession(); this.defaultUrl = options.getDefaultUrl(); } @Override public void handle(RoutingContext event) { // Can we complete the authentication process here? final VertxWebContext webContext = new VertxWebContext(event, sessionStore); vertx.executeBlocking(future -> { callbackLogic.perform(webContext, config, httpActionHandler, defaultUrl, multiProfile, renewSession); future.complete(null); }, false, asyncResult -> { // If we succeeded we're all good here, the job is done either through approving, or redirect, or // forbidding // However, if an error occurred we need to handle this here if (asyncResult.failed()) { event.fail(new TechnicalException(asyncResult.cause())); } }); } }