001/*
002 * (C) Copyright 2012 Nuxeo SA (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 *     bjalon
016 */
017package org.nuxeo.ecm.mobile.filter;
018
019import java.io.UnsupportedEncodingException;
020import java.net.URLEncoder;
021import java.util.Enumeration;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import javax.servlet.http.HttpServletRequest;
027import javax.servlet.http.HttpSession;
028
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031import org.nuxeo.common.utils.URIUtils;
032import org.nuxeo.ecm.core.api.NuxeoException;
033import org.nuxeo.ecm.mobile.ApplicationDefinitionService;
034import org.nuxeo.ecm.platform.ui.web.auth.service.OpenUrlDescriptor;
035import org.nuxeo.ecm.platform.ui.web.auth.service.PluggableAuthenticationService;
036import org.nuxeo.runtime.api.Framework;
037
038import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.START_PAGE_SAVE_KEY;
039
040/**
041 * Request Wrapper with some needed method.
042 *
043 * @author <a href="mailto:bjalon@nuxeo.com">Benjamin JALON</a>
044 * @since 5.5
045 */
046public class RequestAdapter {
047
048    public static final String TARGET_URL_PARAMETER_NAME = "targetURL";
049
050    private static final Log log = LogFactory.getLog(RequestAdapter.class);
051
052    private HttpServletRequest request;
053
054    private PluggableAuthenticationService authenticationService;
055
056    private ApplicationDefinitionService service;
057
058    public RequestAdapter(HttpServletRequest request) {
059        this.request = request;
060    }
061
062    /**
063     * return true if the PluggableAuthenticationService is configured to let this following request URI open.
064     */
065    public boolean isOpenURL() {
066        if (getAuthenticationService() != null) {
067            List<OpenUrlDescriptor> openUrls = getAuthenticationService().getOpenUrls();
068            for (OpenUrlDescriptor openUrl : openUrls) {
069                if (openUrl.allowByPassAuth(request)) {
070                    log.debug("Open URL (defined into the PluggableAuthenticationService) detected: "
071                            + "no redirect: final URL: " + request.getRequestURI());
072                    return true;
073                }
074            }
075
076            if (service == null) {
077                service = Framework.getLocalService(ApplicationDefinitionService.class);
078            }
079
080            String requestPage = getRequestedPage(request);
081
082            for (String prefix : service.getUnAuthenticatedURLPrefix(request)) {
083                if (requestPage.startsWith(prefix)) {
084                    return true;
085                }
086            }
087        }
088        return false;
089    }
090
091    protected static String getRequestedPage(HttpServletRequest httpRequest) {
092        String requestURI = httpRequest.getRequestURI();
093        String context = httpRequest.getContextPath() + '/';
094
095        return requestURI.substring(context.length());
096    }
097
098    private String getRequestURIWithParameters() throws UnsupportedEncodingException {
099        String queryString = request.getQueryString() != null ? "?" + URIUtils.getURIQuery(getParameters()) : "";
100        return request.getRequestURI() + queryString;
101    }
102
103    private PluggableAuthenticationService getAuthenticationService() {
104        if (authenticationService == null) {
105            authenticationService = (PluggableAuthenticationService) Framework.getRuntime().getComponent(
106                    PluggableAuthenticationService.NAME);
107            if (authenticationService == null) {
108                throw new RuntimeException("Unable to get Service " + PluggableAuthenticationService.NAME);
109            }
110        }
111        return authenticationService;
112    }
113
114    /**
115     * Create the parameter map with parameter given into the request and add the initial request into the map into the
116     * {@code NXAuthConstants#REQUESTED_URL} key.
117     */
118    public Map<String, String> getParametersAndAddTargetURLIfNotSet() throws UnsupportedEncodingException {
119
120        Map<String, String> result = new HashMap<String, String>();
121
122        Enumeration<?> paramNames = request.getParameterNames();
123        while (paramNames.hasMoreElements()) {
124            String name = (String) paramNames.nextElement();
125            String value = request.getParameter(name);
126            result.put(name, value);
127        }
128
129        HttpSession session = request.getSession(false);
130        String targetUrl = null;
131        if (session != null && !result.containsKey(TARGET_URL_PARAMETER_NAME)) {
132            targetUrl = (String) session.getAttribute(START_PAGE_SAVE_KEY);
133            if (targetUrl != null && !"".equals(targetUrl.trim())) {
134                log.debug("Put the target URL into the URL parameter: " + request.getRequestURI());
135                result.put(TARGET_URL_PARAMETER_NAME, URLEncoder.encode(targetUrl, "UTF-8"));
136            } else {
137                result.put(TARGET_URL_PARAMETER_NAME, getRequestURIWithParameters());
138            }
139        }
140        return result;
141    }
142
143    public String getTargetURLFromParameter() {
144        try {
145            return getParameters().get(TARGET_URL_PARAMETER_NAME);
146        } catch (UnsupportedEncodingException e) {
147            throw new NuxeoException(e.getMessage(), e);
148        }
149    }
150
151    /**
152     * Return map containing parameters given into the request
153     */
154    public Map<String, String> getParameters() throws UnsupportedEncodingException {
155
156        Map<String, String> result = new HashMap<String, String>();
157
158        Enumeration<?> paramNames = request.getParameterNames();
159        while (paramNames.hasMoreElements()) {
160            String name = (String) paramNames.nextElement();
161            String value = request.getParameter(name);
162            result.put(name, value);
163        }
164
165        return result;
166    }
167
168}