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