001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Fran├žois Maturel
018 */
019
020package org.nuxeo.ecm.platform.ui.web.keycloak;
021
022import javax.servlet.http.HttpServletRequest;
023import javax.servlet.http.HttpServletResponse;
024
025import org.apache.catalina.connector.Request;
026import org.keycloak.adapters.AdapterDeploymentContext;
027import org.keycloak.adapters.KeycloakDeployment;
028import org.keycloak.adapters.NodesRegistrationManagement;
029import org.keycloak.adapters.tomcat.CatalinaHttpFacade;
030import org.nuxeo.ecm.platform.ui.web.auth.LoginScreenHelper;
031
032/**
033 * @since 7.4
034 */
035
036public class KeycloakAuthenticatorProvider {
037
038    private final NodesRegistrationManagement nodesRegistrationManagement = new NodesRegistrationManagement();
039
040    private final AdapterDeploymentContext deploymentContext;
041
042    private KeycloakDeployment resolvedDeployment;
043
044    public KeycloakAuthenticatorProvider(AdapterDeploymentContext deploymentContext) {
045        this.deploymentContext = deploymentContext;
046    }
047
048    public KeycloakRequestAuthenticator provide(HttpServletRequest httpServletRequest,
049            HttpServletResponse httpServletResponse) {
050        DeploymentResult deploymentResult = new DeploymentResult(httpServletRequest, httpServletResponse).invokeOn(
051                deploymentContext);
052
053        if (!deploymentResult.isOk()) {
054            return null;
055        }
056
057        resolvedDeployment = DeploymentResult.getKeycloakDeployment();
058        Request request = deploymentResult.getRequest();
059        CatalinaHttpFacade facade = deploymentResult.getFacade();
060
061        // Register the deployment to refresh it
062        nodesRegistrationManagement.tryRegister(resolvedDeployment);
063
064        // And return authenticator
065        return new KeycloakRequestAuthenticator(request, httpServletResponse, facade, resolvedDeployment);
066    }
067
068    public String logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
069        DeploymentResult deploymentResult = new DeploymentResult(httpServletRequest, httpServletResponse).invokeOn(
070                deploymentContext);
071
072        if (!deploymentResult.isOk()) {
073            return null;
074        }
075
076        resolvedDeployment = DeploymentResult.getKeycloakDeployment();
077        Request request = deploymentResult.getRequest();
078        String redirecResource = getRedirectResource(request);
079
080        return resolvedDeployment.getLogoutUrl().build().toString() + "?redirect_uri=" + redirecResource;
081    }
082
083    public KeycloakDeployment getResolvedDeployment() {
084        return resolvedDeployment;
085    }
086
087    private String getRedirectResource(Request request) {
088        String scheme = request.getScheme();
089        String serverName = request.getServerName();
090        int serverPort = request.getServerPort();
091        String contextPath = request.getContextPath();
092        return scheme + "://" + serverName + ":" + serverPort + contextPath + "/"
093                + LoginScreenHelper.getStartupPagePath();
094    }
095}