/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.sling.auth.form.impl;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Dictionary;
import java.util.HashMap;

import javax.jcr.Credentials;
import javax.jcr.SimpleCredentials;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyOption;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.auth.Authenticator;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.auth.core.spi.AbstractAuthenticationHandler;
import org.apache.sling.auth.core.spi.AuthenticationHandler;
import org.apache.sling.auth.core.spi.AuthenticationInfo;
import org.apache.sling.auth.core.spi.DefaultAuthenticationFeedbackHandler;
import org.apache.sling.auth.form.FormReason;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The <code>FormAuthenticationHandler</code> class implements the authorization
 * steps based on a cookie.
 */
@Component(label = "%auth.form.name", description = "%auth.form.description", metatype = true, name = "org.apache.sling.auth.form.FormAuthenticationHandler")
@Properties( {
    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Apache Sling Form Based Authentication Handler"),
    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
    @Property(name = AuthenticationHandler.PATH_PROPERTY, value = "/", cardinality = 100),
    @Property(name = AuthenticationHandler.TYPE_PROPERTY, value = HttpServletRequest.FORM_AUTH, propertyPrivate = true),
    @Property(name = Constants.SERVICE_RANKING, intValue = 0, propertyPrivate = false) })
@Service
public class FormAuthenticationHandler extends AbstractAuthenticationHandler {

    /**
     * The name of the parameter providing the login form URL.
     */
    @Property(value=AuthenticationFormServlet.SERVLET_PATH)
    private static final String PAR_LOGIN_FORM = "form.login.form";

    /**
     * The value of the {@link #PAR_AUTH_STORAGE} parameter indicating the use
     * of a Cookie to store the authentication data.
     */
    private static final String AUTH_STORAGE_COOKIE = "cookie";

    /**
     * The value of the {@link #PAR_AUTH_STORAGE} parameter indicating the use
     * of a session attribute to store the authentication data.
     */
    private static final String AUTH_STORAGE_SESSION_ATTRIBUTE = "session";

    /**
     * To be used to determine if the auth has value comes from a cookie or from
     * a session attribute.
     */
    private static final String DEFAULT_AUTH_STORAGE = AUTH_STORAGE_COOKIE;

    @Property(value = DEFAULT_AUTH_STORAGE, options = {
        @PropertyOption(name = AUTH_STORAGE_COOKIE, value = "Cookie"),
        @PropertyOption(name = AUTH_STORAGE_SESSION_ATTRIBUTE, value = "Session Attribute") })
    private static final String PAR_AUTH_STORAGE = "form.auth.storage";

    /**
     * The default Cookie or session attribute name
     *
     * @see #PAR_AUTH_NAME
     */
    private static final String DEFAULT_AUTH_NAME = "sling.formauth";

    /**
     * The name of the configuration parameter providing the Cookie or session
     * attribute name.
     */
    @Property(value = DEFAULT_AUTH_NAME)
    private static final String PAR_AUTH_NAME = "form.auth.name";

    /**
     * Default value for the {@link #PAR_CREDENTIALS_ATTRIBUTE_NAME} property
     */
    private static final String DEFAULT_CREDENTIALS_ATTRIBUTE_NAME = DEFAULT_AUTH_NAME;

    /**
     * This is the name of the SimpleCredentials attribute that holds the auth
     * info extracted from the cookie value.
     */
    @Property(value = DEFAULT_CREDENTIALS_ATTRIBUTE_NAME)
    private static final String PAR_CREDENTIALS_ATTRIBUTE_NAME = "form.credentials.name";

    /**
     * The default authentication data time out value.
     *
     * @see #PAR_AUTH_TIMEOUT
     */
    private static final int DEFAULT_AUTH_TIMEOUT = 30;

    /**
     * The number of minutes after which a login session times out. This value
     * is used as the expiry time set in the authentication data.
     */
    @Property(intValue = DEFAULT_AUTH_TIMEOUT)
    public static final String PAR_AUTH_TIMEOUT = "form.auth.timeout";

    private static final String DEFAULT_TOKEN_FILE = "cookie-tokens.bin";

    /**
     * The name of the file used to persist the security tokens
     */
    @Property(value = DEFAULT_TOKEN_FILE)
    private static final String PAR_TOKEN_FILE = "form.token.file";

    private static final boolean DEFAULT_TOKEN_FAST_SEED = false;

    /**
     * Whether to use a less secure but faster seeding mechanism to seed the
     * random number generator in the {@link TokenStore}. By default the faster
     * mechanism is disabled and the platform provided seeding is used. This may
     * however block the startup considerably, particularly on Linux and Solaris
     * platforms which use the (blocking but secure) <code>/dev/random</code>
     * device for seeding.
     */
    @Property(boolValue = DEFAULT_TOKEN_FAST_SEED)
    private static final String PAR_TOKEN_FAST_SEED = "form.token.fastseed";

    /**
     * The default include value.
     *
     * @see #PAR_INCLUDE_FORM
     */
    private static final boolean DEFAULT_INCLUDE_FORM = false;

    /**
     * Whether to redirect to the login form or simple do an include.
     */
    @Property(boolValue = DEFAULT_INCLUDE_FORM)
    public static final String PAR_INCLUDE_FORM = "form.use.include";

    /**
     * The default login after expire of a cookie.
     *
     * @see #PAR_LOGIN_AFTER_EXPIRE
     */
    private static final boolean DEFAULT_LOGIN_AFTER_EXPIRE = false;

    /**
     * Whether to present a login form when a users cookie expires, the default
     * is not to present the form.
     */
    @Property(boolValue = DEFAULT_LOGIN_AFTER_EXPIRE)
    private static final String PAR_LOGIN_AFTER_EXPIRE = "form.onexpire.login";

    /**
     * The default domain on which to see the auth cookie (if cookie storage is used)
     */
    @Property
    private static final String PAR_DEFAULT_COOKIE_DOMAIN = "form.default.cookie.domain";

    /**
     * The request method required for user name and password submission by the
     * form (value is "POST").
     */
    private static final String REQUEST_METHOD = "POST";

    /**
     * The last segment of the request URL for the user name and password
     * submission by the form (value is "/j_security_check").
     * <p>
     * This name is derived from the prescription in the Servlet API 2.4
     * Specification, Section SRV.12.5.3.1 Login Form Notes: <i>In order for the
     * authentication to proceed appropriately, the action of the login form
     * must always be set to <code>j_security_check</code>.</i>
     */
    private static final String REQUEST_URL_SUFFIX = "/j_security_check";

    /**
     * The name of the form submission parameter providing the name of the user
     * to authenticate (value is "j_username").
     * <p>
     * This name is prescribed by the Servlet API 2.4 Specification, Section
     * SRV.12.5.3 Form Based Authentication.
     */
    private static final String PAR_J_USERNAME = "j_username";

    /**
     * The name of the form submission parameter providing the password of the
     * user to authenticate (value is "j_password").
     * <p>
     * This name is prescribed by the Servlet API 2.4 Specification, Section
     * SRV.12.5.3 Form Based Authentication.
     */
    private static final String PAR_J_PASSWORD = "j_password";

    /**
     * Key in the AuthenticationInfo map which contains the domain on which the
     * auth cookie should be set.
     */
    private static final String COOKIE_DOMAIN = "cookie.domain";

    /**
     * The factor to convert minute numbers into milliseconds used internally
     */
    private static final long MINUTES = 60L * 1000L;

    /** default log */
    private final Logger log = LoggerFactory.getLogger(getClass());

    private AuthenticationStorage authStorage;

    private String loginForm;

    /**
     * The timeout of a login session in milliseconds, converted from the
     * configuration property {@link #PAR_AUTH_TIMEOUT} by multiplying with
     * {@link #MINUTES}.
     */
    private long sessionTimeout;

    /**
     * The name of the credentials attribute which is set to the cookie data
     * to validate.
     */
    private String attrCookieAuthData;

    /**
     * The {@link TokenStore} used to persist and check authentication data
     */
    private TokenStore tokenStore;

    /**
     * The {@link FormLoginModulePlugin} service registration created when
     * this authentication handler is registered. If the login module plugin
     * cannot be created this field is set to <code>null</code>.
     */
    private ServiceRegistration loginModule;

    /**
     * If true, the handler will attempt to include the login form instead of
     * doing a redirect.
     */
    private boolean includeLoginForm;

    /**
     * The resource resolver factory used to resolve the login form as a resource
     */
    @Reference(policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.OPTIONAL_UNARY)
    private ResourceResolverFactory resourceResolverFactory;

    /**
     * If true the login form will be presented when the token expires.
     */
    private boolean loginAfterExpire;

    /**
     * Extracts cookie/session based credentials from the request. Returns
     * <code>null</code> if the handler assumes HTTP Basic authentication would
     * be more appropriate, if no form fields are present in the request and if
     * the secure user data is not present either in the cookie or an HTTP
     * Session.
     */
    public AuthenticationInfo extractCredentials(HttpServletRequest request,
            HttpServletResponse response) {

        AuthenticationInfo info = null;

        // 1. try credentials from POST'ed request parameters
        info = this.extractRequestParameterAuthentication(request);

        // 2. try credentials from the cookie or session
        if (info == null) {
            String authData = authStorage.extractAuthenticationInfo(request);
            if (authData != null) {
                if (tokenStore.isValid(authData)) {
                    info = createAuthInfo(authData);
                } else {
                    // clear the cookie, its invalid and we should get rid of it
                    // so that the invalid cookie isn't present on the authN
                    // operation.
                    authStorage.clear(request, response);
                    if (this.loginAfterExpire || isValidateRequest(request)) {
                        // signal the requestCredentials method a previous login
                        // failure
                        request.setAttribute(FAILURE_REASON, FormReason.TIMEOUT);
                        info = AuthenticationInfo.FAIL_AUTH;
                    }
                }
            }
        }

        return info;
    }

    /**
     * Unless the <code>sling:authRequestLogin</code> to anything other than
     * <code>Form</code> this method either sends back a 403/FORBIDDEN response
     * if the <code>j_verify</code> parameter is set to <code>true</code> or
     * redirects to the login form to ask for credentials.
     * <p>
     * This method assumes the <code>j_verify</code> request parameter to only
     * be set in the initial username/password submission through the login
     * form. No further checks are applied, though, before sending back the
     * 403/FORBIDDEN response.
     */
    public boolean requestCredentials(HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        // 0. ignore this handler if an authentication handler is requested
        if (ignoreRequestCredentials(request)) {
            // consider this handler is not used
            return false;
        }

        //check the referer to see if the request is for this handler
        if (!checkReferer(request, loginForm)) {
        	//not for this handler, so return
        	return false;
        }
        
        final String resource = setLoginResourceAttribute(request,
            request.getRequestURI());

        if (includeLoginForm && (resourceResolverFactory != null)) {
            ResourceResolver resourceResolver = null;
            try {
                resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
                Resource loginFormResource = resourceResolver.resolve(loginForm);
                Servlet loginFormServlet = loginFormResource.adaptTo(Servlet.class);
                if (loginFormServlet != null) {
                    try {
                        loginFormServlet.service(request, response);
                        return true;
                    } catch (ServletException e) {
                        log.error("Failed to include the form: " + loginForm, e);
                    }
                }
            } catch (LoginException e) {
                log.error("Unable to get a resource resolver to include for the login resource. Will redirect instead.");
            } finally {
                if (resourceResolver != null) {
                    resourceResolver.close();
                }
            }
        }

        HashMap<String, String> params = new HashMap<String, String>();
        params.put(Authenticator.LOGIN_RESOURCE, resource);

        // append indication of previous login failure
        if (request.getAttribute(FAILURE_REASON) != null) {
            final Object jReason = request.getAttribute(FAILURE_REASON);
            @SuppressWarnings("rawtypes")
            final String reason = (jReason instanceof Enum)
                    ? ((Enum) jReason).name()
                    : jReason.toString();
            params.put(FAILURE_REASON, reason);
        }

        try {
            sendRedirect(request, response, loginForm, params);
        } catch (IOException e) {
            log.error("Failed to redirect to the login form " + loginForm, e);
        }

        return true;
    }

    /**
     * Clears all authentication state which might have been prepared by this
     * authentication handler.
     */
    public void dropCredentials(HttpServletRequest request,
            HttpServletResponse response) {
        authStorage.clear(request, response);
    }

    // ---------- AuthenticationFeedbackHandler

    /**
     * Called after an unsuccessful login attempt. This implementation makes
     * sure the authentication data is removed either by removing the cookie or
     * by remove the HTTP Session attribute.
     */
    @Override
    public void authenticationFailed(HttpServletRequest request,
            HttpServletResponse response, AuthenticationInfo authInfo) {

        /*
         * Note: This method is called if this handler provided credentials
         * which cause a login failure
         */

        // clear authentication data from Cookie or Http Session
        authStorage.clear(request, response);

        // signal the reason for login failure
        request.setAttribute(FAILURE_REASON, FormReason.INVALID_CREDENTIALS);
    }

    /**
     * Called after successful login with the given authentication info. This
     * implementation ensures the authentication data is set in either the
     * cookie or the HTTP session with the correct security tokens.
     * <p>
     * If no authentication data already exists, it is created. Otherwise if the
     * data has expired the data is updated with a new security token and a new
     * expiry time.
     * <p>
     * If creating or updating the authentication data fails, it is actually
     * removed from the cookie or the HTTP session and future requests will not
     * be authenticated any longer.
     */
    @Override
    public boolean authenticationSucceeded(HttpServletRequest request,
            HttpServletResponse response, AuthenticationInfo authInfo) {

        /*
         * Note: This method is called if this handler provided credentials
         * which succeeded login into the repository
         */

        // ensure fresh authentication data
        refreshAuthData(request, response, authInfo);

        final boolean result;
        // SLING-1847: only consider a resource redirect if this is a POST request
        // to the j_security_check URL
        if (REQUEST_METHOD.equals(request.getMethod())
        		&& request.getRequestURI().endsWith(REQUEST_URL_SUFFIX)) {

            if (DefaultAuthenticationFeedbackHandler.handleRedirect(request, response)) {
            	// terminate request, all done in the default handler
            	result = false;
            } else {
            	// check whether redirect is requested by the resource parameter
            	final String resource = getLoginResource(request, null);
            	if (resource != null) {
            		try {
            			response.sendRedirect(resource);
            		} catch (IOException ioe) {
            			log.error("Failed to send redirect to: " + resource, ioe);
            		}

            		// terminate request, all done
            		result = true;
            	} else {
            		// no redirect, hence continue processing
            		result = false;
            	}
            }
        } else {
            // no redirect, hence continue processing
            result = false;
        }

        // no redirect
        return result;
    }

    @Override
    public String toString() {
        return "Form Based Authentication Handler";
    }

    // --------- Force HTTP Basic Auth ---------

    /**
     * Returns <code>true</code> if this authentication handler should ignore
     * the call to
     * {@link #requestCredentials(HttpServletRequest, HttpServletResponse)}.
     * <p>
     * This method returns <code>true</code> if the
     * {@link #REQUEST_LOGIN_PARAMETER} is set to any value other than "Form"
     * (HttpServletRequest.FORM_AUTH).
     */
    private boolean ignoreRequestCredentials(final HttpServletRequest request) {
        final String requestLogin = request.getParameter(REQUEST_LOGIN_PARAMETER);
        return requestLogin != null
            && !HttpServletRequest.FORM_AUTH.equals(requestLogin);
    }

    /**
     * Ensures the authentication data is set (if not set yet) and the expiry
     * time is prolonged (if auth data already existed).
     * <p>
     * This method is intended to be called in case authentication succeeded.
     *
     * @param request The current request
     * @param response The current response
     * @param authInfo The authentication info used to successful log in
     */
    private void refreshAuthData(final HttpServletRequest request,
            final HttpServletResponse response,
            final AuthenticationInfo authInfo) {

        // get current authentication data, may be missing after first login
        String authData = getCookieAuthData(authInfo);

        // check whether we have to "store" or create the data
        final boolean refreshCookie = needsRefresh(authData,
            this.sessionTimeout);

        // add or refresh the stored auth hash
        if (refreshCookie) {
            long expires = System.currentTimeMillis() + this.sessionTimeout;
            try {
                authData = null;
                authData = tokenStore.encode(expires, authInfo.getUser());
            } catch (InvalidKeyException e) {
                log.error(e.getMessage(), e);
            } catch (IllegalStateException e) {
                log.error(e.getMessage(), e);
            } catch (UnsupportedEncodingException e) {
                log.error(e.getMessage(), e);
            } catch (NoSuchAlgorithmException e) {
                log.error(e.getMessage(), e);
            }

            if (authData != null) {
                authStorage.set(request, response, authData, authInfo);
            } else {
                authStorage.clear(request, response);
            }
        }
    }

    // --------- Request Parameter Auth ---------

    private AuthenticationInfo extractRequestParameterAuthentication(
            HttpServletRequest request) {
        AuthenticationInfo info = null;

        // only consider login form parameters if this is a POST request
        // to the j_security_check URL
        if (REQUEST_METHOD.equals(request.getMethod())
            && request.getRequestURI().endsWith(REQUEST_URL_SUFFIX)) {

            String user = request.getParameter(PAR_J_USERNAME);
            String pwd = request.getParameter(PAR_J_PASSWORD);

            if (user != null && pwd != null) {
                info = new AuthenticationInfo(HttpServletRequest.FORM_AUTH,
                    user, pwd.toCharArray());

                // if this request is providing form credentials, we have to
                // make sure, that the request is redirected after successful
                // authentication, otherwise the request may be processed
                // as a POST request to the j_security_check page (unless
                // the j_validate parameter is set); but only if this is not
                // a validation request
                if (!isValidateRequest(request)) {
                    setLoginResourceAttribute(request, request.getContextPath());
                }
            }
        }

        return info;
    }

    private AuthenticationInfo createAuthInfo(final String authData) {
        final String userId = getUserId(authData);
        if (userId == null) {
            return null;
        }

        final AuthenticationInfo info = new AuthenticationInfo(
            HttpServletRequest.FORM_AUTH, userId);
        info.put(attrCookieAuthData, authData);

        return info;
    }

    private String getCookieAuthData(final AuthenticationInfo info) {
        Object data = info.get(attrCookieAuthData);
        if (data instanceof String) {
            return (String) data;
        }
        return null;
    }

    // ---------- LoginModulePlugin support

    private String getCookieAuthData(final Credentials credentials) {
        if (credentials instanceof SimpleCredentials) {
            Object data = ((SimpleCredentials) credentials).getAttribute(attrCookieAuthData);
            if (data instanceof String) {
                return (String) data;
            }
        }

        // no SimpleCredentials or no valid attribute
        return null;
    }

    boolean hasAuthData(final Credentials credentials) {
        return getCookieAuthData(credentials) != null;
    }

    boolean isValid(final Credentials credentials) {
        String authData = getCookieAuthData(credentials);
        if (authData != null) {
            return tokenStore.isValid(authData);
        }

        // no authdata, not valid
        return false;
    }

    // ---------- SCR Integration ----------------------------------------------

    /**
     * Called by SCR to activate the authentication handler.
     *
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws IllegalStateException
     * @throws UnsupportedEncodingException
     */
    protected void activate(ComponentContext componentContext)
            throws InvalidKeyException, NoSuchAlgorithmException,
            IllegalStateException, UnsupportedEncodingException {

        Dictionary<?, ?> properties = componentContext.getProperties();

        this.loginForm = OsgiUtil.toString(properties.get(PAR_LOGIN_FORM),
            AuthenticationFormServlet.SERVLET_PATH);
        log.info("Login Form URL {}", loginForm);

        final String authName = OsgiUtil.toString(
            properties.get(PAR_AUTH_NAME), DEFAULT_AUTH_NAME);

        String defaultCookieDomain = OsgiUtil.toString(
            properties.get(PAR_DEFAULT_COOKIE_DOMAIN), "");
        if (defaultCookieDomain.length() == 0) {
            defaultCookieDomain = null;
        }

        final String authStorage = OsgiUtil.toString(
            properties.get(PAR_AUTH_STORAGE), DEFAULT_AUTH_STORAGE);
        if (AUTH_STORAGE_SESSION_ATTRIBUTE.equals(authStorage)) {

            this.authStorage = new SessionStorage(authName);
            log.info("Using HTTP Session store with attribute name {}",
                authName);

        } else {

            this.authStorage = new CookieStorage(authName, defaultCookieDomain);
            log.info("Using Cookie store with name {}", authName);

        }

        this.attrCookieAuthData = OsgiUtil.toString(
            properties.get(PAR_CREDENTIALS_ATTRIBUTE_NAME),
            DEFAULT_CREDENTIALS_ATTRIBUTE_NAME);
        log.info("Setting Auth Data attribute name {}", attrCookieAuthData);

        int timeoutMinutes = OsgiUtil.toInteger(
            properties.get(PAR_AUTH_TIMEOUT), DEFAULT_AUTH_TIMEOUT);
        if (timeoutMinutes < 1) {
            timeoutMinutes = DEFAULT_AUTH_TIMEOUT;
        }
        log.info("Setting session timeout {} minutes", timeoutMinutes);
        this.sessionTimeout = MINUTES * timeoutMinutes;

        final String tokenFileName = OsgiUtil.toString(
            properties.get(PAR_TOKEN_FILE), DEFAULT_TOKEN_FILE);
        final File tokenFile = getTokenFile(tokenFileName,
            componentContext.getBundleContext());
        final boolean fastSeed = OsgiUtil.toBoolean(
            properties.get(PAR_TOKEN_FAST_SEED), DEFAULT_TOKEN_FAST_SEED);
        log.info("Storing tokens in {}", tokenFile.getAbsolutePath());
        this.tokenStore = new TokenStore(tokenFile, sessionTimeout, fastSeed);

        this.loginModule = null;
        try {
            this.loginModule = FormLoginModulePlugin.register(this,
                componentContext.getBundleContext());
        } catch (Throwable t) {
            log.info("Cannot register FormLoginModulePlugin. This is expected if Sling LoginModulePlugin services are not supported");
            log.debug("dump", t);
        }

        this.includeLoginForm = OsgiUtil.toBoolean(properties.get(PAR_INCLUDE_FORM), DEFAULT_INCLUDE_FORM);

        this.loginAfterExpire = OsgiUtil.toBoolean(properties.get(PAR_LOGIN_AFTER_EXPIRE), DEFAULT_LOGIN_AFTER_EXPIRE);
    }

    protected void deactivate(
            @SuppressWarnings("unused") ComponentContext componentContext) {
        if (loginModule != null) {
            loginModule.unregister();
            loginModule = null;
        }
    }

    /**
     * Returns an absolute file indicating the file to use to persist the
     * security tokens.
     * <p>
     * This method is not part of the API of this class and is package private
     * to enable unit tests.
     *
     * @param tokenFileName The configured file name, must not be null
     * @param bundleContext The BundleContext to use to make an relative file
     *            absolute
     * @return The absolute file
     */
    File getTokenFile(final String tokenFileName,
            final BundleContext bundleContext) {
        File tokenFile = new File(tokenFileName);
        if (tokenFile.isAbsolute()) {
            return tokenFile;
        }

        tokenFile = bundleContext.getDataFile(tokenFileName);
        if (tokenFile == null) {
            final String slingHome = bundleContext.getProperty("sling.home");
            if (slingHome != null) {
                tokenFile = new File(slingHome, tokenFileName);
            } else {
                tokenFile = new File(tokenFileName);
            }
        }

        return tokenFile.getAbsoluteFile();
    }

    /**
     * Returns the user id from the authentication data. If the authentication
     * data is a non-<code>null</code> value with 3 fields separated by an @
     * sign, the value of the third field is returned. Otherwise
     * <code>null</code> is returned.
     * <p>
     * This method is not part of the API of this class and is package private
     * to enable unit tests.
     *
     * @param authData
     * @return
     */
    String getUserId(final String authData) {
        if (authData != null) {
            String[] parts = TokenStore.split(authData);
            if (parts != null) {
                return parts[2];
            }
        }
        return null;
    }

    /**
     * Refresh the cookie periodically.
     *
     * @param sessionTimeout time to live for the session
     * @return true or false
     */
    private boolean needsRefresh(final String authData,
            final long sessionTimeout) {
        boolean updateCookie = false;
        if (authData == null) {
            updateCookie = true;
        } else {
            String[] parts = TokenStore.split(authData);
            if (parts != null && parts.length == 3) {
                long cookieTime = Long.parseLong(parts[1].substring(1));
                if (System.currentTimeMillis() + (sessionTimeout / 2) > cookieTime) {
                    updateCookie = true;
                }
            }
        }
        return updateCookie;
    }

    /**
     * The <code>AuthenticationStorage</code> interface abstracts the API
     * required to store the authentication data in an HTTP cookie or in an
     * HTTP Session. The concrete class -- {@link CookieStorage} or
     * {@link SessionStorage} -- is selected using the
     * {@link FormAuthenticationHandler#PAR_AUTH_STORAGE} configuration
     * parameter, {@link CookieStorage} by default.
     */
    private static interface AuthenticationStorage {
        String extractAuthenticationInfo(HttpServletRequest request);

        void set(HttpServletRequest request, HttpServletResponse response,
                String authData, AuthenticationInfo info);

        void clear(HttpServletRequest request, HttpServletResponse response);
    }

    /**
     * The <code>CookieStorage</code> class supports storing the
     * authentication data in an HTTP Cookie.
     */
    private static class CookieStorage implements AuthenticationStorage {

        /**
         * The Set-Cookie header used to manage the login cookie.
         *
         * @see CookieStorage#setCookie(HttpServletRequest, HttpServletResponse,
         *      String, String, int, String)
         */
        private static final String HEADER_SET_COOKIE = "Set-Cookie";

        private final String cookieName;
        private final String domainCookieName;
        private final String defaultCookieDomain;

        public CookieStorage(final String cookieName, final String defaultCookieDomain) {
            this.cookieName = cookieName;
            this.domainCookieName = cookieName + "." + COOKIE_DOMAIN;
            this.defaultCookieDomain = defaultCookieDomain;
        }

        public String extractAuthenticationInfo(HttpServletRequest request) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (this.cookieName.equals(cookie.getName())) {
                        // found the cookie, so try to extract the credentials
                        // from it and reverse the base64 encoding
                        String value = cookie.getValue();
                        if (value.length() > 0) {
                            try {
                                return new String(Base64.decodeBase64(value),
                                    "UTF-8");
                            } catch (UnsupportedEncodingException e1) {
                                throw new RuntimeException(e1);
                            }
                        }
                    }
                }
            }

            return null;
        }

        public void set(HttpServletRequest request,
                HttpServletResponse response, String authData, AuthenticationInfo info) {
            // base64 encode to handle any special characters
            String cookieValue;
            try {
                cookieValue = Base64.encodeBase64URLSafeString(authData.getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e1) {
                throw new RuntimeException(e1);
            }

            // send the cookie to the response
            String cookieDomain = (String) info.get(COOKIE_DOMAIN);
            if (cookieDomain == null || cookieDomain.length() == 0) {
                cookieDomain = defaultCookieDomain;
            }
            setCookie(request, response, this.cookieName, cookieValue, -1,
                cookieDomain);

            // send the cookie domain cookie if domain is not null
            if (cookieDomain != null) {
                setCookie(request, response, this.domainCookieName,
                    cookieDomain, -1, cookieDomain);
            }
        }

        public void clear(HttpServletRequest request,
                HttpServletResponse response) {
            Cookie oldCookie = null;
            String oldCookieDomain = null;
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (this.cookieName.equals(cookie.getName())) {
                        // found the cookie
                        oldCookie = cookie;
                    } else if (this.domainCookieName.equals(cookie.getName())) {
                        oldCookieDomain = cookie.getValue();
                    }
                }
            }

            // remove the old cookie from the client
            if (oldCookie != null) {
                setCookie(request, response, this.cookieName, "", 0, oldCookieDomain);
                if (oldCookieDomain != null && oldCookieDomain.length() > 0) {
                    setCookie(request, response, this.domainCookieName, "", 0, oldCookieDomain);
                }
            }
        }

        private void setCookie(final HttpServletRequest request,
                final HttpServletResponse response, final String name,
                final String value, final int age, final String domain) {

            final String ctxPath = request.getContextPath();
            final String cookiePath = (ctxPath == null || ctxPath.length() == 0)
                    ? "/"
                    : ctxPath;

            /*
             * The Servlet Spec 2.5 does not allow us to set the commonly used
             * HttpOnly attribute on cookies (Servlet API 3.0 does) so we create
             * the Set-Cookie header manually. See
             * http://www.owasp.org/index.php/HttpOnly for information on what
             * the HttpOnly attribute is used for.
             */

            final StringBuilder header = new StringBuilder();

            // default setup with name, value, cookie path and HttpOnly
            header.append(name).append("=").append(value);
            header.append("; Path=").append(cookiePath);
            header.append("; HttpOnly"); // don't allow JS access

            // set the cookie domain if so configured
            if (domain != null) {
                header.append("; Domain=").append(domain);
            }

            // Only set the Max-Age attribute to remove the cookie
            if (age >= 0) {
                header.append("; Max-Age=").append(age);
            }

            // ensure the cookie is secured if this is an https request
            if (request.isSecure()) {
                header.append("; Secure");
            }

            response.addHeader(HEADER_SET_COOKIE, header.toString());
        }
    }

    /**
     * The <code>SessionStorage</code> class provides support to store the
     * authentication data in an HTTP Session.
     */
    private static class SessionStorage implements AuthenticationStorage {
        private final String sessionAttributeName;

        SessionStorage(final String sessionAttributeName) {
            this.sessionAttributeName = sessionAttributeName;
        }

        public String extractAuthenticationInfo(HttpServletRequest request) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                Object attribute = session.getAttribute(sessionAttributeName);
                if (attribute instanceof String) {
                    return (String) attribute;
                }
            }
            return null;
        }

        public void set(HttpServletRequest request,
                HttpServletResponse response, String authData, AuthenticationInfo info) {
            // store the auth hash as a session attribute
            HttpSession session = request.getSession();
            session.setAttribute(sessionAttributeName, authData);
        }

        public void clear(HttpServletRequest request,
                HttpServletResponse response) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                session.removeAttribute(sessionAttributeName);
            }
        }

    }
}