001/*
002 * (C) Copyright 2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 */
017
018package org.nuxeo.ecm.platform.shibboleth.service;
019
020import static org.apache.commons.lang.StringUtils.isNotEmpty;
021
022import java.io.UnsupportedEncodingException;
023import java.util.HashMap;
024import java.util.Map;
025
026import javax.servlet.http.HttpServletRequest;
027
028import org.nuxeo.common.utils.URIUtils;
029import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants;
030import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper;
031import org.nuxeo.runtime.model.ComponentInstance;
032import org.nuxeo.runtime.model.DefaultComponent;
033
034public class ShibbolethAuthenticationServiceImpl extends DefaultComponent implements ShibbolethAuthenticationService {
035
036    public static final String CONFIG_EP = "config";
037
038    protected ShibbolethAuthenticationConfig config;
039
040    @Override
041    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
042        if (CONFIG_EP.equals(extensionPoint)) {
043            config = (ShibbolethAuthenticationConfig) contribution;
044        }
045    }
046
047    public ShibbolethAuthenticationConfig getConfig() {
048        return config;
049    }
050
051    @Override
052    public String getLoginURL(String redirectURL) {
053        if (config == null || config.getLoginURL() == null) {
054            return null;
055        }
056
057        Map<String, String> urlParameters = new HashMap<String, String>(1);
058        urlParameters.put(config.getLoginRedirectURLParameter(), redirectURL);
059        return URIUtils.addParametersToURIQuery(config.getLoginURL(), urlParameters);
060    }
061
062    @Override
063    public String getLogoutURL(String redirectURL) {
064        if (config == null || config.getLogoutURL() == null) {
065            return null;
066        }
067
068        Map<String, String> urlParameters = new HashMap<String, String>(1);
069        urlParameters.put(config.getLogoutRedirectURLParameter(), redirectURL);
070        return URIUtils.addParametersToURIQuery(config.getLogoutURL(), urlParameters);
071    }
072
073    protected static String getRedirectUrl(HttpServletRequest request) {
074        String redirectURL = VirtualHostHelper.getBaseURL(request);
075        if (request.getAttribute(NXAuthConstants.REQUESTED_URL) != null) {
076            redirectURL += request.getAttribute(NXAuthConstants.REQUESTED_URL);
077        } else if (request.getParameter(NXAuthConstants.REQUESTED_URL) != null) {
078            redirectURL += request.getParameter(NXAuthConstants.REQUESTED_URL);
079        } else {
080            redirectURL = request.getRequestURL().toString();
081            String queryString = request.getQueryString();
082            if (queryString != null) {
083                redirectURL += '?' + queryString;
084            }
085        }
086        return redirectURL;
087    }
088
089    @Override
090    public String getLoginURL(HttpServletRequest request) {
091        return getLoginURL(getRedirectUrl(request));
092    }
093
094    @Override
095    public String getLogoutURL(HttpServletRequest request) {
096        return getLogoutURL(getRedirectUrl(request));
097    }
098
099    @Override
100    public String getUserID(HttpServletRequest httpRequest) {
101        String idpUrl = httpRequest.getHeader(config.getIdpHeader());
102        String uidHeader = config.getUidHeaders().get(idpUrl);
103        if (uidHeader == null || readHeader(httpRequest, uidHeader) == null
104                || readHeader(httpRequest, uidHeader).isEmpty()) {
105            uidHeader = config.getDefaultUidHeader();
106        }
107        return readHeader(httpRequest, uidHeader);
108    }
109
110    @Override
111    public Map<String, Object> getUserMetadata(String userIdField, HttpServletRequest httpRequest) {
112        Map<String, Object> fieldMap = new HashMap<String, Object>(config.fieldMapping.size());
113        for (String key : config.getFieldMapping().keySet()) {
114            fieldMap.put(config.getFieldMapping().get(key), readHeader(httpRequest, key));
115        }
116        // Force userIdField to shibb userId value in case of the IdP do
117        // not use the same mapping as the default's one.
118        fieldMap.put(userIdField, getUserID(httpRequest));
119        return fieldMap;
120    }
121
122    protected String readHeader(HttpServletRequest request, String key) {
123        String value = request.getHeader(key);
124        if (isNotEmpty(value) && isNotEmpty(config.getHeaderEncoding())) {
125            try {
126                value = new String(value.getBytes("ISO-8859-1"), config.getHeaderEncoding());
127            } catch (UnsupportedEncodingException ignored) {
128                // Nothing
129            }
130        }
131        return value;
132    }
133}