org.jboss.dashboard.ui.controller.requestChain.FriendlyUrlProcessor.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.dashboard.ui.controller.requestChain.FriendlyUrlProcessor.java

Source

/**
 * Copyright (C) 2012 JBoss Inc
 *
 * Licensed 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.jboss.dashboard.ui.controller.requestChain;

import org.apache.commons.lang3.StringUtils;
import org.jboss.dashboard.LocaleManager;
import org.jboss.dashboard.annotation.config.Config;
import org.jboss.dashboard.ui.NavigationManager;
import org.jboss.dashboard.ui.UIServices;
import org.jboss.dashboard.ui.components.URLMarkupGenerator;
import org.jboss.dashboard.ui.controller.RequestContext;
import org.jboss.dashboard.workspace.Workspace;
import org.jboss.dashboard.workspace.WorkspaceImpl;
import org.jboss.dashboard.workspace.Section;
import org.jboss.dashboard.security.WorkspacePermission;
import org.jboss.dashboard.security.SectionPermission;
import org.jboss.dashboard.users.UserStatus;
import org.slf4j.Logger;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

@ApplicationScoped
public class FriendlyUrlProcessor extends AbstractChainProcessor {

    @Inject
    private transient Logger log;

    @Inject
    @Config("true")
    private boolean showLoginBackDoorOnPermissionDenied;

    public static final String FRIENDLY_MAPPING = "/" + URLMarkupGenerator.FRIENDLY_PREFIX;
    public static final String LOCALE_PARAMETER = "locale";

    public boolean isShowLoginBackDoorOnPermissionDenied() {
        return showLoginBackDoorOnPermissionDenied;
    }

    /**
     * Make required processing of request.
     *
     * @return true if processing must continue, false otherwise.
     */
    public boolean processRequest() throws Exception {
        HttpServletRequest request = getHttpRequest();
        String servletPath = request.getServletPath();
        NavigationManager navigationManager = NavigationManager.lookup();
        UserStatus userStatus = UserStatus.lookup();
        RequestContext requestContext = RequestContext.lookup();

        // ---- Apply locale information, --------------
        LocaleManager localeManager = LocaleManager.lookup();
        // First check if a locale parameter is present in the URI query string.
        Locale localeToSet = null;
        String localeParam = request.getParameter(LOCALE_PARAMETER);
        if (localeParam != null && localeParam.trim().length() > 0) {
            localeToSet = localeManager.getLocaleById(localeParam);
            if (localeToSet != null) {
                localeManager.setCurrentLocale(localeToSet);
            }
        }

        // No friendly -> nothing to do.
        if (!servletPath.startsWith(FRIENDLY_MAPPING))
            return true;

        String contextPath = request.getContextPath();
        requestContext.consumeURIPart(FRIENDLY_MAPPING);
        navigationManager.setShowingConfig(false);
        String requestUri = request.getRequestURI();
        String relativeUri = requestUri.substring(contextPath == null ? 0 : (contextPath.length()));
        relativeUri = relativeUri.substring(servletPath == null ? 0 : (servletPath.length()));

        // Empty URI -> nothing to do.
        if (StringUtils.isBlank(relativeUri))
            return true;

        /*
        * Check if the locale information is in the URI value in order to consume it.
        * Locale information is expected in the URI after "/workspace".
        * Examples:
        * - /workspace/en/....
        * - /workspace/es/....
        * - /workspace/en_ES/....
        * NOTES:
        * - Available locales matched in the URI parameter are obtained from JVM available locales.
        * - If the locale is found as platform available, the locale is set.
        * - Otherwise, do nothing, the locale used will be the last one set or default.
        * - In both cases URI locale parameter will be consumed.
        */
        int startLocaleUri = relativeUri.indexOf("/");
        int endLocaleUri = relativeUri.indexOf("/", startLocaleUri + 1);
        endLocaleUri = endLocaleUri > 0 ? endLocaleUri : relativeUri.length();
        String localeUri = relativeUri.substring(startLocaleUri + 1, endLocaleUri);
        Locale uriLocale = localeManager.getLocaleById(localeUri);
        if (uriLocale != null) {
            requestContext.consumeURIPart("/" + localeUri);
            relativeUri = relativeUri.substring(localeUri.length() + 1);
            // Use the locale specified in the URI value only if no locale specified in the qeury string.
            if (localeToSet == null)
                localeManager.setCurrentLocale(uriLocale);
        }

        // Tokenize the friendly URI.
        StringTokenizer tokenizer = new StringTokenizer(relativeUri, "/", false);
        List tokens = new ArrayList();
        int i = 0;
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (i < 2) {
                tokens.add(token);
                i++;
            } else if (tokens.size() == 2) {
                tokens.add("/" + token);
            } else {
                tokens.set(2, tokens.get(2) + "/" + token);
            }
        }
        try {
            // Get the target workspace/section spcified.
            log.debug("Tokens=" + tokens);
            String workspaceCandidate = null;
            String sectionCandidate = null;
            if (tokens.size() > 0)
                workspaceCandidate = (String) tokens.get(0);
            if (tokens.size() > 1)
                sectionCandidate = (String) tokens.get(1);
            if (log.isDebugEnabled()) {
                log.debug("workspaceCandidate=" + workspaceCandidate);
                log.debug("sectionCandidate=" + sectionCandidate);
            }
            WorkspaceImpl workspace = null;
            Section section = null;
            if (workspaceCandidate != null) {
                workspace = (WorkspaceImpl) UIServices.lookup().getWorkspacesManager()
                        .getWorkspace(workspaceCandidate);
                if (workspace == null)
                    workspace = (WorkspaceImpl) UIServices.lookup().getWorkspacesManager()
                            .getWorkspaceByUrl(workspaceCandidate);
            }
            if (workspace != null && sectionCandidate != null) {
                try {
                    section = workspace.getSection(Long.decode(sectionCandidate));
                } catch (NumberFormatException nfe) {
                    section = workspace.getSectionByUrl(sectionCandidate);
                }
            }
            // Check the user has access permissions to the target workspace.
            if (workspace != null && section == null) {
                try {
                    Workspace currentWorkspace = navigationManager.getCurrentWorkspace();
                    log.debug("currentWorkspace = " + (currentWorkspace == null ? "null" : currentWorkspace.getId())
                            + " workspaceCandidate = " + workspaceCandidate);
                    if (!workspace.equals(currentWorkspace)) {

                        WorkspacePermission workspacePerm = WorkspacePermission.newInstance(workspace,
                                WorkspacePermission.ACTION_LOGIN);
                        if (userStatus.hasPermission(workspacePerm)) {
                            navigationManager.setCurrentWorkspace(workspace);
                            log.debug("SessionManager.setWorkspace(" + workspace.getId() + ")");
                        } else {
                            if (log.isDebugEnabled())
                                log.debug("User has no " + WorkspacePermission.ACTION_LOGIN
                                        + " permission in workspace " + workspaceCandidate);
                            if (isShowLoginBackDoorOnPermissionDenied()) {
                                navigationManager.setUserRequiresLoginBackdoor(true);
                                navigationManager.setCurrentWorkspace(workspace);
                            }
                        }
                    }
                    requestContext.consumeURIPart("/" + workspaceCandidate);
                } catch (Exception e) {
                    log.error("Cannot set current workspace.", e);
                }
            }
            // Check the user has access permissions to the target section.
            else if (section != null) {
                try {
                    if (!section.equals(navigationManager.getCurrentSection())) {

                        WorkspacePermission workspacePerm = WorkspacePermission.newInstance(section.getWorkspace(),
                                WorkspacePermission.ACTION_LOGIN);
                        SectionPermission sectionPerm = SectionPermission.newInstance(section,
                                SectionPermission.ACTION_VIEW);
                        if (userStatus.hasPermission(workspacePerm) && userStatus.hasPermission(sectionPerm)) {
                            if (log.isDebugEnabled())
                                log.debug("SessionManager.setSection(" + section.getId() + ")");
                            navigationManager.setCurrentSection(section);
                        } else {
                            if (log.isDebugEnabled())
                                log.debug("User has no " + WorkspacePermission.ACTION_LOGIN
                                        + " permission in workspace " + workspaceCandidate);
                            if (isShowLoginBackDoorOnPermissionDenied()) {
                                navigationManager.setUserRequiresLoginBackdoor(true);
                                navigationManager.setCurrentSection(section);
                            }
                        }
                    }
                    requestContext.consumeURIPart("/" + workspaceCandidate);
                    requestContext.consumeURIPart("/" + sectionCandidate);
                } catch (Exception e) {
                    log.error("Cannot set current section.", e);
                }
            }
        } catch (Exception e) {
            log.error("Exception processing friendly URI", e);
        }
        return true;
    }
}