001/*
002 * (C) Copyright 2006-2007 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 *     Nuxeo - initial API and implementation
018 *
019 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
020 */
021
022package org.nuxeo.ecm.platform.ui.web.auth.plugins;
023
024import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.ERROR_CONNECTION_FAILED;
025import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.ERROR_USERNAME_MISSING;
026import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.FORM_SUBMITTED_MARKER;
027import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.LOGIN_CONNECTION_FAILED;
028import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.LOGIN_ERROR;
029import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.LOGIN_FAILED;
030import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.LOGIN_MISSING;
031import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.PASSWORD_KEY;
032import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.REQUESTED_URL;
033import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.SESSION_TIMEOUT;
034import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.START_PAGE_SAVE_KEY;
035import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.USERNAME_KEY;
036
037import java.io.IOException;
038import java.util.ArrayList;
039import java.util.Enumeration;
040import java.util.HashMap;
041import java.util.List;
042import java.util.Map;
043
044import javax.servlet.http.HttpServletRequest;
045import javax.servlet.http.HttpServletResponse;
046import javax.servlet.http.HttpSession;
047
048import org.apache.commons.logging.Log;
049import org.apache.commons.logging.LogFactory;
050import org.nuxeo.common.utils.URIUtils;
051import org.nuxeo.ecm.platform.api.login.UserIdentificationInfo;
052import org.nuxeo.ecm.platform.ui.web.auth.interfaces.NuxeoAuthenticationPlugin;
053
054public class FormAuthenticator implements NuxeoAuthenticationPlugin {
055
056    private static final Log log = LogFactory.getLog(FormAuthenticator.class);
057
058    protected String loginPage = "login.jsp";
059
060    protected String usernameKey = USERNAME_KEY;
061
062    protected String passwordKey = PASSWORD_KEY;
063
064    protected String getLoginPage() {
065        return loginPage;
066    }
067
068    @Override
069    public Boolean handleLoginPrompt(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String baseURL) {
070        try {
071            log.debug("Forward to Login Screen");
072            Map<String, String> parameters = new HashMap<String, String>();
073            String redirectUrl = baseURL + getLoginPage();
074            @SuppressWarnings("unchecked")
075            Enumeration<String> paramNames = httpRequest.getParameterNames();
076            while (paramNames.hasMoreElements()) {
077                String name = paramNames.nextElement();
078                String value = httpRequest.getParameter(name);
079                parameters.put(name, value);
080            }
081            HttpSession session = httpRequest.getSession(false);
082            String requestedUrl = null;
083            boolean isTimeout = false;
084            if (session != null) {
085                requestedUrl = (String) session.getAttribute(START_PAGE_SAVE_KEY);
086                Object obj = session.getAttribute(SESSION_TIMEOUT);
087                if (obj != null) {
088                    isTimeout = (Boolean) obj;
089                }
090            }
091            if (requestedUrl != null && !requestedUrl.equals("")) {
092                parameters.put(REQUESTED_URL, requestedUrl);
093            }
094            String loginError = (String) httpRequest.getAttribute(LOGIN_ERROR);
095            if (loginError != null) {
096                if (ERROR_USERNAME_MISSING.equals(loginError)) {
097                    parameters.put(LOGIN_MISSING, "true");
098                } else if (ERROR_CONNECTION_FAILED.equals(loginError)) {
099                    parameters.put(LOGIN_CONNECTION_FAILED, "true");
100                    parameters.put(LOGIN_FAILED, "true"); // compat
101                } else {
102                    parameters.put(LOGIN_FAILED, "true");
103                }
104            }
105            if (isTimeout) {
106                parameters.put(SESSION_TIMEOUT, "true");
107            }
108
109            // avoid resending the password in clear !!!
110            parameters.remove(passwordKey);
111            redirectUrl = URIUtils.addParametersToURIQuery(redirectUrl, parameters);
112            httpResponse.sendRedirect(redirectUrl);
113        } catch (IOException e) {
114            log.error(e, e);
115            return Boolean.FALSE;
116        }
117        return Boolean.TRUE;
118    }
119
120    @Override
121    public UserIdentificationInfo handleRetrieveIdentity(HttpServletRequest httpRequest,
122            HttpServletResponse httpResponse) {
123        // Only accept POST requests
124        String method = httpRequest.getMethod();
125        if (!"POST".equals(method)) {
126            log.debug("Request method is " + method + ", only accepting POST");
127            return null;
128        }
129        log.debug("Looking for user/password in the request");
130        String userName = httpRequest.getParameter(usernameKey);
131        String password = httpRequest.getParameter(passwordKey);
132        // NXP-2650: ugly hack to check if form was submitted
133        if (httpRequest.getParameter(FORM_SUBMITTED_MARKER) != null && (userName == null || userName.length() == 0)) {
134            httpRequest.setAttribute(LOGIN_ERROR, ERROR_USERNAME_MISSING);
135        }
136        if (userName == null || userName.length() == 0) {
137            return null;
138        }
139        return new UserIdentificationInfo(userName, password);
140    }
141
142    @Override
143    public Boolean needLoginPrompt(HttpServletRequest httpRequest) {
144        return Boolean.TRUE;
145    }
146
147    @Override
148    public void initPlugin(Map<String, String> parameters) {
149        if (parameters.get("LoginPage") != null) {
150            loginPage = parameters.get("LoginPage");
151        }
152        if (parameters.get("UsernameKey") != null) {
153            usernameKey = parameters.get("UsernameKey");
154        }
155        if (parameters.get("PasswordKey") != null) {
156            passwordKey = parameters.get("PasswordKey");
157        }
158    }
159
160    @Override
161    public List<String> getUnAuthenticatedURLPrefix() {
162        // Login Page is unauthenticated !
163        List<String> prefix = new ArrayList<String>();
164        prefix.add(getLoginPage());
165        return prefix;
166    }
167
168}