Package com.psddev.cms.tool

Source Code of com.psddev.cms.tool.AuthenticationFilter$Static

package com.psddev.cms.tool;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.psddev.cms.db.Preview;
import com.psddev.cms.db.ToolUser;
import com.psddev.dari.db.Database;
import com.psddev.dari.db.ForwardingDatabase;
import com.psddev.dari.db.Query;
import com.psddev.dari.util.AbstractFilter;
import com.psddev.dari.util.DebugFilter;
import com.psddev.dari.util.JspUtils;
import com.psddev.dari.util.ObjectUtils;
import com.psddev.dari.util.PageContextFilter;
import com.psddev.dari.util.Settings;
import com.psddev.dari.util.StringUtils;
import com.psddev.dari.util.UrlBuilder;

public class AuthenticationFilter extends AbstractFilter {

    /**
     * Settings key for tool user session timeout (in milliseconds).
     */
    public static final String TOOL_USER_SESSION_TIMEOUT_SETTING = "brightspot/toolUserSessionTimeout";

    private static final String ATTRIBUTE_PREFIX = AuthenticationFilter.class.getName() + ".";

    public static final String AUTHENTICATED_ATTRIBUTE = ATTRIBUTE_PREFIX + "authenticated";
    public static final String DATABASE_OVERRIDDEN_ATTRIBUTE = ATTRIBUTE_PREFIX + "databaseOverridden";

    /**
     * @deprecated Don't use this directly.
     */
    @Deprecated
    public static final String USER_ATTRIBUTE = ATTRIBUTE_PREFIX + "user";

    /**
     * @deprecated Don't use this directly.
     */
    @Deprecated
    public static final String USER_CHECKED_ATTRIBUTE = ATTRIBUTE_PREFIX + "userChecked";

    public static final String USER_SETTINGS_CHANGED_ATTRIBUTE = ATTRIBUTE_PREFIX + "userSettingsChanged";

    private static final String INSECURE_TOOL_USER_ATTRIBUTE = ATTRIBUTE_PREFIX + "insecureToolUser";
    private static final String INSECURE_TOOL_USER_CHECKED_ATTRIBUTE = ATTRIBUTE_PREFIX + "insecureToolUserChecked";
    private static final String PREVIEW_ATTRIBUTE = ATTRIBUTE_PREFIX + "preview";
    private static final String PREVIEW_CHECKED_ATTRIBUTE = ATTRIBUTE_PREFIX + "previewChecked";
    private static final String TOOL_USER_ATTRIBUTE = ATTRIBUTE_PREFIX + "toolUser";
    private static final String TOOL_USER_CHECKED_ATTRIBUTE = ATTRIBUTE_PREFIX + "toolUserChecked";

    public static final String LOG_IN_PATH = "/logIn.jsp";
    public static final String RETURN_PATH_PARAMETER = "returnPath";

    /**
     * @deprecated Don't use this directly.
     */
    @Deprecated
    public static final String USER_COOKIE = "cmsToolUser";

    private static final String INSECURE_TOOL_USER_COOKIE = "bsp.itu";
    private static final String PREVIEW_COOKIE = "bsp.p";
    private static final String TOOL_USER_COOKIE = "bsp.tu";

    // --- AbstractFilter support ---

    @Override
    protected void doRequest(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain chain)
            throws Exception {

        if (ObjectUtils.to(boolean.class, request.getParameter("_clearPreview"))) {
            Static.removeCurrentPreview(request, response);
            response.sendRedirect(new UrlBuilder(request).
                    currentPath().
                    currentParameters().
                    parameter("_clearPreview", null).
                    toString());
            return;
        }

        try {
            chain.doFilter(request, response);

        } catch (Exception error) {
            if (Static.isAuthenticated(request)) {
                DebugFilter.Static.writeError(request, response, error);

            } else {
                throw error;
            }

        } finally {
            if (Boolean.TRUE.equals(request.getAttribute(DATABASE_OVERRIDDEN_ATTRIBUTE))) {
                Database.Static.setIgnoreReadConnection(false);
                Database.Static.restoreDefault();
            }

            ToolUser user = Static.getUser(request);

            if (user != null && Boolean.TRUE.equals(request.getAttribute(USER_SETTINGS_CHANGED_ATTRIBUTE))) {
                user.save();
            }
        }
    }

    /**
     * {@link AuthenticationFilter} utility methods.
     */
    public static final class Static {

        private static void setSignedCookie(
                HttpServletRequest request,
                HttpServletResponse response,
                String name,
                String value,
                int maxAge,
                boolean secure) {

            Cookie c = new Cookie(name, name + value);

            c.setMaxAge(maxAge);
            c.setSecure(secure && JspUtils.isSecure(request));

            String siteUrl = Query.from(CmsTool.class).first().getDefaultSiteUrl();

            if (!ObjectUtils.isBlank(siteUrl)) {
                siteUrl = siteUrl.replaceFirst("^(?i)(?:https?://)?(?:www\\.)?", "");
                int slashAt = siteUrl.indexOf('/');

                if (slashAt > -1) {
                    siteUrl = siteUrl.substring(0, slashAt);
                }

                int colonAt = siteUrl.indexOf(':');

                if (colonAt > -1) {
                    siteUrl = siteUrl.substring(0, colonAt);
                }

                c.setDomain(siteUrl);
            }

            c.setPath("/");
            JspUtils.setSignedCookie(response, c);

            Cookie dc = new Cookie(name, name + value);

            dc.setMaxAge(maxAge);
            dc.setSecure(secure && JspUtils.isSecure(request));
            dc.setPath("/");
            JspUtils.setSignedCookie(response, dc);
        }

        /**
         * Logs in the given tool {@code user}.
         *
         * @param request Can't be {@code null}.
         * @param response Can't be {@code null}.
         * @param user Can't be {@code null}.
         */
        public static void logIn(HttpServletRequest request, HttpServletResponse response, ToolUser user) {
            String userId = user.getId().toString();

            setSignedCookie(request, response, TOOL_USER_COOKIE, userId, -1, true);
            setSignedCookie(request, response, INSECURE_TOOL_USER_COOKIE, userId, -1, false);
            request.setAttribute(USER_ATTRIBUTE, user);
            request.setAttribute(USER_CHECKED_ATTRIBUTE, Boolean.TRUE);
        }

        /**
         * Logs out the current tool user.
         *
         * @param request Can't be {@code null}.
         * @param response Can't be {@code null}.
         */
        public static void logOut(HttpServletRequest request, HttpServletResponse response) {
            setSignedCookie(request, response, TOOL_USER_COOKIE, "", 0, true);
            setSignedCookie(request, response, INSECURE_TOOL_USER_COOKIE, "", 0, false);
        }

        /**
         * Logs out the current tool user.
         *
         * @param request Can't be {@code null}.
         * @param response Can't be {@code null}.
         * @deprecated Use {@link #logOut(HttpServletRequest, HttpServletResponse)} instead.
         */
        @Deprecated
        public static void logOut(HttpServletResponse response) {
            logOut(PageContextFilter.Static.getRequest(), response);
        }

        /**
         * Returns {@code true} if a tool user is authenticated in the given
         * {@code request}.
         *
         * @param request Can't be {@code null}.
         */
        public static boolean isAuthenticated(HttpServletRequest request) {
            return Boolean.TRUE.equals(request.getAttribute(AUTHENTICATED_ATTRIBUTE));
        }

        public static boolean requireUser(ServletContext context, HttpServletRequest request, HttpServletResponse response) throws IOException {
            String toolUrlPrefix = Settings.get(String.class, ToolPageContext.TOOL_URL_PREFIX_SETTING);

            if (!ObjectUtils.isBlank(toolUrlPrefix) &&
                    !new UrlBuilder(request).
                            currentScheme().
                            currentHost().
                            currentPath().
                            toString().startsWith(toolUrlPrefix)) {

                response.sendRedirect(
                        StringUtils.removeEnd(toolUrlPrefix, "/") +
                        new UrlBuilder(request).
                                currentPath().
                                currentParameters().
                                toString());

                return true;
            }

            ToolUser user = getUser(request);

            if (user != null) {
                request.setAttribute(AUTHENTICATED_ATTRIBUTE, Boolean.TRUE);

                logIn(request, response, user);

                ForwardingDatabase db = new ForwardingDatabase() {
                    @Override
                    protected <T> Query<T> filterQuery(Query<T> query) {
                        return query.clone().master().resolveInvisible();
                    }
                };

                db.setDelegate(Database.Static.getDefault());
                Database.Static.setIgnoreReadConnection(true);
                Database.Static.overrideDefault(db);
                request.setAttribute(DATABASE_OVERRIDDEN_ATTRIBUTE, Boolean.TRUE);

            } else if (!JspUtils.getEmbeddedServletPath(context, request.getServletPath()).equals(LOG_IN_PATH)) {
                @SuppressWarnings("resource")
                ToolPageContext page = new ToolPageContext(context, request, response);
                String loginUrl = page.cmsUrl(LOG_IN_PATH, RETURN_PATH_PARAMETER, JspUtils.getAbsolutePath(request, ""));

                response.sendRedirect(loginUrl);

                return true;
            }

            return false;
        }

        private static ToolUser getToolUserByCookieName(
                HttpServletRequest request,
                String cookieName,
                String toolUserAttribute,
                String toolUserCheckedAttribute) {

            ToolUser toolUser;

            if (Boolean.TRUE.equals(request.getAttribute(toolUserCheckedAttribute))) {
                toolUser = (ToolUser) request.getAttribute(toolUserAttribute);

            } else {
                long sessionTimeout = ObjectUtils.firstNonNull(
                        Settings.get(Long.class, TOOL_USER_SESSION_TIMEOUT_SETTING),
                        Settings.getOrDefault(long.class, "cms/tool/sessionTimeout", 0L));

                String cookieValue = JspUtils.getSignedCookieWithExpiry(request, cookieName, sessionTimeout);

                if (cookieValue == null || cookieValue.length() < cookieName.length()) {
                    toolUser = null;

                } else {
                    toolUser = Query.
                            from(ToolUser.class).
                            where("_id = ?", ObjectUtils.to(UUID.class, cookieValue.substring(cookieName.length()))).
                            first();

                    request.setAttribute(toolUserAttribute, toolUser);
                }

                request.setAttribute(toolUserCheckedAttribute, Boolean.TRUE);
            }

            return toolUser;
        }

        /**
         * Returns the tool user associated with the given {@code request}.
         *
         * @param request Can't be {@code null}.
         */
        public static ToolUser getUser(HttpServletRequest request) {
            return getToolUserByCookieName(
                    request,
                    TOOL_USER_COOKIE,
                    TOOL_USER_ATTRIBUTE,
                    TOOL_USER_CHECKED_ATTRIBUTE);
        }

        /**
         * Returns the possible and probably insecure tool user associated
         * with the given {@code request}.
         *
         * @param request Can't be {@code null}.
         */
        public static ToolUser getInsecureToolUser(HttpServletRequest request) {
            return getToolUserByCookieName(
                    request,
                    INSECURE_TOOL_USER_COOKIE,
                    INSECURE_TOOL_USER_ATTRIBUTE,
                    INSECURE_TOOL_USER_CHECKED_ATTRIBUTE);
        }

        public static Preview getCurrentPreview(HttpServletRequest request) {
            Preview preview;

            if (Boolean.TRUE.equals(request.getAttribute(PREVIEW_CHECKED_ATTRIBUTE))) {
                preview = (Preview) request.getAttribute(PREVIEW_ATTRIBUTE);

            } else {
                String cookieValue = JspUtils.getSignedCookie(request, PREVIEW_COOKIE);

                if (cookieValue == null || cookieValue.length() < PREVIEW_COOKIE.length()) {
                    preview = null;

                } else {
                    preview = Query.
                            from(Preview.class).
                            where("_id = ?", ObjectUtils.to(UUID.class, cookieValue.substring(PREVIEW_COOKIE.length()))).
                            first();

                    request.setAttribute(PREVIEW_ATTRIBUTE, preview);
                }

                request.setAttribute(PREVIEW_CHECKED_ATTRIBUTE, Boolean.TRUE);
            }

            return preview;
        }

        public static void setCurrentPreview(HttpServletRequest request, HttpServletResponse response, Preview preview) {
            setSignedCookie(request, response, PREVIEW_COOKIE, preview.getId().toString(), -1, true);
            request.setAttribute(PREVIEW_ATTRIBUTE, preview);
            request.setAttribute(PREVIEW_CHECKED_ATTRIBUTE, Boolean.TRUE);
        }

        public static void removeCurrentPreview(HttpServletRequest request, HttpServletResponse response) {
            setSignedCookie(request, response, PREVIEW_COOKIE, "", 0, true);
            request.removeAttribute(PREVIEW_ATTRIBUTE);
            request.removeAttribute(PREVIEW_CHECKED_ATTRIBUTE);
        }

        /**
         * Returns the user setting value associated with the given
         * {@code key}.
         */
        public static Object getUserSetting(HttpServletRequest request, String key) {
            ToolUser user = getUser(request);

            return user != null ? user.getSettings().get(key) : null;
        }

        /**
         * Puts the given user setting {@code value} at the given {@code key}.
         * The user, along with the setting values, are saved once at the end
         * of the given {@code request}.
         */
        public static void putUserSetting(HttpServletRequest request, String key, Object value) {
            ToolUser user = getUser(request);

            if (user != null) {
                user.getSettings().put(key, value);
                request.setAttribute(USER_SETTINGS_CHANGED_ATTRIBUTE, Boolean.TRUE);
            }
        }

        // Returns the page setting key for use with the given {@code request}
        // and {@code key}.
        private static String getPageSettingKey(HttpServletRequest request, String key) {
            return "page" + request.getServletPath() + "/" + key;
        }

        /**
         * Returns the page setting value associated with the given
         * {@code request} and {@code key}.
         */
        public static Object getPageSetting(HttpServletRequest request, String key) {
            return getUserSetting(request, getPageSettingKey(request, key));
        }

        /**
         * Puts the given page setting {@code value} at the given
         * {@code request} and {@code key}. The user, along with the setting
         * values, are saved once at the end of the given {@code request}.
         */
        public static void putPageSetting(HttpServletRequest request, String key, Object value) {
            putUserSetting(request, getPageSettingKey(request, key), value);
        }
    }
}
TOP

Related Classes of com.psddev.cms.tool.AuthenticationFilter$Static

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.