001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.struts;
016    
017    import com.liferay.portal.LayoutPermissionException;
018    import com.liferay.portal.PortletActiveException;
019    import com.liferay.portal.UserActiveException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
024    import com.liferay.portal.kernel.servlet.HttpMethods;
025    import com.liferay.portal.kernel.servlet.SessionErrors;
026    import com.liferay.portal.kernel.struts.LastPath;
027    import com.liferay.portal.kernel.util.CharPool;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.HttpUtil;
030    import com.liferay.portal.kernel.util.JavaConstants;
031    import com.liferay.portal.kernel.util.ParamUtil;
032    import com.liferay.portal.kernel.util.PropsKeys;
033    import com.liferay.portal.kernel.util.StringBundler;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.Validator;
036    import com.liferay.portal.liveusers.LiveUsers;
037    import com.liferay.portal.model.Company;
038    import com.liferay.portal.model.Layout;
039    import com.liferay.portal.model.LayoutConstants;
040    import com.liferay.portal.model.Portlet;
041    import com.liferay.portal.model.PortletPreferencesIds;
042    import com.liferay.portal.model.User;
043    import com.liferay.portal.model.UserTracker;
044    import com.liferay.portal.model.UserTrackerPath;
045    import com.liferay.portal.security.auth.PrincipalException;
046    import com.liferay.portal.security.permission.ActionKeys;
047    import com.liferay.portal.security.permission.PermissionChecker;
048    import com.liferay.portal.service.LayoutLocalServiceUtil;
049    import com.liferay.portal.service.PortletLocalServiceUtil;
050    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
051    import com.liferay.portal.service.permission.PortletPermissionUtil;
052    import com.liferay.portal.service.persistence.UserTrackerPathUtil;
053    import com.liferay.portal.setup.SetupWizardUtil;
054    import com.liferay.portal.theme.ThemeDisplay;
055    import com.liferay.portal.util.PortalUtil;
056    import com.liferay.portal.util.PrefsPropsUtil;
057    import com.liferay.portal.util.PropsUtil;
058    import com.liferay.portal.util.PropsValues;
059    import com.liferay.portal.util.WebKeys;
060    import com.liferay.portlet.InvokerPortlet;
061    import com.liferay.portlet.PortletConfigFactoryUtil;
062    import com.liferay.portlet.PortletInstanceFactoryUtil;
063    import com.liferay.portlet.PortletPreferencesFactoryUtil;
064    import com.liferay.portlet.PortletURLImpl;
065    import com.liferay.portlet.RenderRequestFactory;
066    import com.liferay.portlet.RenderRequestImpl;
067    import com.liferay.portlet.RenderResponseFactory;
068    import com.liferay.portlet.RenderResponseImpl;
069    
070    import java.io.IOException;
071    
072    import java.util.Date;
073    import java.util.HashSet;
074    import java.util.Map;
075    import java.util.Set;
076    
077    import javax.portlet.PortletConfig;
078    import javax.portlet.PortletContext;
079    import javax.portlet.PortletMode;
080    import javax.portlet.PortletPreferences;
081    import javax.portlet.PortletRequest;
082    import javax.portlet.WindowState;
083    
084    import javax.servlet.ServletContext;
085    import javax.servlet.ServletException;
086    import javax.servlet.http.HttpServletRequest;
087    import javax.servlet.http.HttpServletResponse;
088    import javax.servlet.http.HttpSession;
089    import javax.servlet.jsp.PageContext;
090    
091    import org.apache.struts.Globals;
092    import org.apache.struts.action.Action;
093    import org.apache.struts.action.ActionMapping;
094    import org.apache.struts.config.ActionConfig;
095    import org.apache.struts.config.ForwardConfig;
096    import org.apache.struts.tiles.TilesRequestProcessor;
097    import org.apache.struts.util.MessageResources;
098    
099    /**
100     * @author Brian Wing Shun Chan
101     * @author Jorge Ferrer
102     * @author Wesley Gong
103     * @author Mika Koivisto
104     */
105    public class PortalRequestProcessor extends TilesRequestProcessor {
106    
107            public PortalRequestProcessor() {
108    
109                    // auth.forward.last.path.
110    
111                    _lastPaths = new HashSet<String>();
112    
113                    _lastPaths.add(_PATH_PORTAL_LAYOUT);
114    
115                    addPaths(_lastPaths, PropsKeys.AUTH_FORWARD_LAST_PATHS);
116    
117                    // auth.public.path.
118    
119                    _publicPaths = new HashSet<String>();
120    
121                    _publicPaths.add(_PATH_C);
122                    _publicPaths.add(_PATH_PORTAL_API_JSONWS);
123                    _publicPaths.add(_PATH_PORTAL_FLASH);
124                    _publicPaths.add(_PATH_PORTAL_J_LOGIN);
125                    _publicPaths.add(_PATH_PORTAL_LAYOUT);
126                    _publicPaths.add(_PATH_PORTAL_LICENSE);
127                    _publicPaths.add(_PATH_PORTAL_LOGIN);
128                    _publicPaths.add(_PATH_PORTAL_RENDER_PORTLET);
129                    _publicPaths.add(_PATH_PORTAL_RESILIENCY);
130                    _publicPaths.add(_PATH_PORTAL_TCK);
131                    _publicPaths.add(_PATH_PORTAL_UPDATE_PASSWORD);
132                    _publicPaths.add(_PATH_PORTAL_VERIFY_EMAIL_ADDRESS);
133                    _publicPaths.add(PropsValues.AUTH_LOGIN_DISABLED_PATH);
134    
135                    _trackerIgnorePaths = new HashSet<String>();
136    
137                    addPaths(_trackerIgnorePaths, PropsKeys.SESSION_TRACKER_IGNORE_PATHS);
138            }
139    
140            @Override
141            public void process(
142                            HttpServletRequest request, HttpServletResponse response)
143                    throws IOException, ServletException {
144    
145                    HttpSession session = request.getSession();
146    
147                    Boolean basicAuthEnabled = (Boolean)session.getAttribute(
148                            WebKeys.BASIC_AUTH_ENABLED);
149    
150                    if (basicAuthEnabled != null) {
151                            session.removeAttribute(WebKeys.BASIC_AUTH_ENABLED);
152                    }
153    
154                    String path = super.processPath(request, response);
155    
156                    ActionMapping actionMapping =
157                            (ActionMapping)moduleConfig.findActionConfig(path);
158    
159                    Action action = StrutsActionRegistryUtil.getAction(path);
160    
161                    if (((basicAuthEnabled != null) && basicAuthEnabled.booleanValue()) ||
162                            ((actionMapping == null) && (action == null))) {
163    
164                            String lastPath = getLastPath(request);
165    
166                            if (_log.isDebugEnabled()) {
167                                    _log.debug("Last path " + lastPath);
168                            }
169    
170                            response.sendRedirect(lastPath);
171    
172                            return;
173                    }
174    
175                    super.process(request, response);
176    
177                    try {
178                            if (isPortletPath(path)) {
179                                    cleanUp(request);
180                            }
181                    }
182                    catch (Exception e) {
183                            _log.error(e, e);
184                    }
185            }
186    
187            protected void addPaths(Set<String> paths, String propsKey) {
188                    String[] pathsArray = PropsUtil.getArray(propsKey);
189    
190                    for (String path : pathsArray) {
191                            paths.add(path);
192                    }
193            }
194    
195            protected void callParentDoForward(
196                            String uri, HttpServletRequest request,
197                            HttpServletResponse response)
198                    throws IOException, ServletException {
199    
200                    super.doForward(uri, request, response);
201            }
202    
203            protected HttpServletRequest callParentProcessMultipart(
204                    HttpServletRequest request) {
205    
206                    return super.processMultipart(request);
207            }
208    
209            protected String callParentProcessPath(
210                            HttpServletRequest request, HttpServletResponse response)
211                    throws IOException {
212    
213                    return super.processPath(request, response);
214            }
215    
216            protected boolean callParentProcessRoles(
217                            HttpServletRequest request, HttpServletResponse response,
218                            ActionMapping actionMapping)
219                    throws IOException, ServletException {
220    
221                    return super.processRoles(request, response, actionMapping);
222            }
223    
224            protected void cleanUp(HttpServletRequest request) throws Exception {
225    
226                    // Clean up portlet objects that may have been created by defineObjects
227                    // for portlets that are called directly from a Struts path
228    
229                    RenderRequestImpl renderRequestImpl =
230                            (RenderRequestImpl)request.getAttribute(
231                                    JavaConstants.JAVAX_PORTLET_REQUEST);
232    
233                    if (renderRequestImpl != null) {
234                            renderRequestImpl.cleanUp();
235                    }
236            }
237    
238            protected void defineObjects(
239                            HttpServletRequest request, HttpServletResponse response,
240                            Portlet portlet)
241                    throws Exception {
242    
243                    String portletId = portlet.getPortletId();
244    
245                    ServletContext servletContext = (ServletContext)request.getAttribute(
246                            WebKeys.CTX);
247    
248                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
249                            portlet, servletContext);
250    
251                    PortletPreferencesIds portletPreferencesIds =
252                            PortletPreferencesFactoryUtil.getPortletPreferencesIds(
253                                    request, portletId);
254    
255                    PortletPreferences portletPreferences =
256                            PortletPreferencesLocalServiceUtil.getStrictPreferences(
257                                    portletPreferencesIds);
258    
259                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
260                            portlet, servletContext);
261                    PortletContext portletContext = portletConfig.getPortletContext();
262    
263                    RenderRequestImpl renderRequestImpl = RenderRequestFactory.create(
264                            request, portlet, invokerPortlet, portletContext,
265                            WindowState.MAXIMIZED, PortletMode.VIEW, portletPreferences);
266    
267                    RenderResponseImpl renderResponseImpl = RenderResponseFactory.create(
268                            renderRequestImpl, response, portletId, portlet.getCompanyId());
269    
270                    renderRequestImpl.defineObjects(portletConfig, renderResponseImpl);
271    
272                    request.setAttribute(WebKeys.PORTLET_STRUTS_EXECUTE, Boolean.TRUE);
273            }
274    
275            @Override
276            protected void doForward(
277                            String uri, HttpServletRequest request,
278                            HttpServletResponse response)
279                    throws ServletException {
280    
281                    StrutsUtil.forward(uri, getServletContext(), request, response);
282            }
283    
284            @Override
285            protected void doInclude(
286                            String uri, HttpServletRequest request,
287                            HttpServletResponse response)
288                    throws ServletException {
289    
290                    StrutsUtil.include(uri, getServletContext(), request, response);
291            }
292    
293            protected String getFriendlyTrackerPath(
294                            String path, ThemeDisplay themeDisplay, HttpServletRequest request)
295                    throws Exception {
296    
297                    if (!path.equals(_PATH_PORTAL_LAYOUT)) {
298                            return null;
299                    }
300    
301                    long plid = ParamUtil.getLong(request, "p_l_id");
302    
303                    if (plid == 0) {
304                            return null;
305                    }
306    
307                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
308    
309                    String layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
310                            layout, themeDisplay);
311    
312                    String portletId = ParamUtil.getString(request, "p_p_id");
313    
314                    if (Validator.isNull(portletId)) {
315                            return layoutFriendlyURL;
316                    }
317    
318                    long companyId = PortalUtil.getCompanyId(request);
319    
320                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
321                            companyId, portletId);
322    
323                    if (portlet == null) {
324                            String strutsPath = path.substring(
325                                    1, path.lastIndexOf(CharPool.SLASH));
326    
327                            portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
328                                    companyId, strutsPath);
329                    }
330    
331                    if ((portlet == null) || !portlet.isActive()) {
332                            return layoutFriendlyURL.concat(StringPool.QUESTION).concat(
333                                    request.getQueryString());
334                    }
335    
336                    String namespace = PortalUtil.getPortletNamespace(portletId);
337    
338                    FriendlyURLMapper friendlyURLMapper =
339                            portlet.getFriendlyURLMapperInstance();
340    
341                    if (friendlyURLMapper == null) {
342                            return layoutFriendlyURL.concat(StringPool.QUESTION).concat(
343                                    request.getQueryString());
344                    }
345    
346                    PortletURLImpl portletURL = new PortletURLImpl(
347                            request, portletId, plid, PortletRequest.RENDER_PHASE);
348    
349                    Map<String, String[]> parameterMap = request.getParameterMap();
350    
351                    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
352                            String key = entry.getKey();
353    
354                            if (key.startsWith(namespace)) {
355                                    key = key.substring(namespace.length());
356    
357                                    portletURL.setParameter(key, entry.getValue());
358                            }
359                    }
360    
361                    String portletFriendlyURL = friendlyURLMapper.buildPath(portletURL);
362    
363                    if (portletFriendlyURL != null) {
364                            return layoutFriendlyURL.concat(portletFriendlyURL);
365                    }
366                    else {
367                            return layoutFriendlyURL.concat(StringPool.QUESTION).concat(
368                                    request.getQueryString());
369                    }
370            }
371    
372            protected String getLastPath(HttpServletRequest request) {
373                    HttpSession session = request.getSession();
374    
375                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
376                            WebKeys.THEME_DISPLAY);
377    
378                    Boolean httpsInitial = (Boolean)session.getAttribute(
379                            WebKeys.HTTPS_INITIAL);
380    
381                    String portalURL = null;
382    
383                    if (PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS &&
384                            !PropsValues.SESSION_ENABLE_PHISHING_PROTECTION &&
385                            (httpsInitial != null) && !httpsInitial.booleanValue()) {
386    
387                            portalURL = PortalUtil.getPortalURL(request, false);
388                    }
389                    else {
390                            portalURL = PortalUtil.getPortalURL(request);
391                    }
392    
393                    StringBundler sb = new StringBundler();
394    
395                    sb.append(portalURL);
396                    sb.append(themeDisplay.getPathMain());
397                    sb.append(_PATH_PORTAL_LAYOUT);
398    
399                    if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
400                            if (request.getRemoteUser() != null) {
401    
402                                    // If we do not forward by last path and the user is logged in,
403                                    // forward to the user's default layout to prevent a lagging
404                                    // loop
405    
406                                    sb.append(StringPool.QUESTION);
407                                    sb.append("p_l_id");
408                                    sb.append(StringPool.EQUAL);
409                                    sb.append(LayoutConstants.DEFAULT_PLID);
410                            }
411    
412                            return sb.toString();
413                    }
414    
415                    LastPath lastPath = (LastPath)session.getAttribute(WebKeys.LAST_PATH);
416    
417                    if (lastPath == null) {
418                            return sb.toString();
419                    }
420    
421                    Map<String, String[]> parameterMap = lastPath.getParameterMap();
422    
423                    // Only test for existing mappings for last paths that were set when the
424                    // user accessed a layout directly instead of through its friendly URL
425    
426                    if (lastPath.getContextPath().equals(themeDisplay.getPathMain())) {
427                            ActionMapping actionMapping =
428                                    (ActionMapping)moduleConfig.findActionConfig(
429                                            lastPath.getPath());
430    
431                            if ((actionMapping == null) || (parameterMap == null)) {
432                                    return sb.toString();
433                            }
434                    }
435    
436                    StringBundler lastPathSB = new StringBundler(4);
437    
438                    lastPathSB.append(portalURL);
439                    lastPathSB.append(lastPath.getContextPath());
440                    lastPathSB.append(lastPath.getPath());
441                    lastPathSB.append(HttpUtil.parameterMapToString(parameterMap));
442    
443                    return lastPathSB.toString();
444            }
445    
446            protected boolean isPortletPath(String path) {
447                    if ((path != null) &&
448                            !path.equals(_PATH_C) &&
449                            !path.startsWith(_PATH_COMMON) &&
450                            !path.contains(_PATH_J_SECURITY_CHECK) &&
451                            !path.startsWith(_PATH_PORTAL)) {
452    
453                            return true;
454                    }
455                    else {
456                            return false;
457                    }
458            }
459    
460            protected boolean isPublicPath(String path) {
461                    if ((path != null) &&
462                            (_publicPaths.contains(path) || path.startsWith(_PATH_COMMON) ||
463                             AuthPublicPathRegistry.contains(path))) {
464    
465                            return true;
466                    }
467                    else {
468                            return false;
469                    }
470            }
471    
472            @Override
473            protected Action processActionCreate(
474                            HttpServletRequest request, HttpServletResponse response,
475                            ActionMapping actionMapping)
476                    throws IOException {
477    
478                    ActionAdapter actionAdapter =
479                            (ActionAdapter)StrutsActionRegistryUtil.getAction(
480                                    actionMapping.getPath());
481    
482                    if (actionAdapter != null) {
483                            ActionConfig actionConfig = moduleConfig.findActionConfig(
484                                    actionMapping.getPath());
485    
486                            if (actionConfig != null) {
487                                    Action originalAction = super.processActionCreate(
488                                            request, response, actionMapping);
489    
490                                    actionAdapter.setOriginalAction(originalAction);
491                            }
492    
493                            return actionAdapter;
494                    }
495    
496                    return super.processActionCreate(request, response, actionMapping);
497            }
498    
499            @Override
500            protected ActionMapping processMapping(
501                            HttpServletRequest request, HttpServletResponse response,
502                            String path)
503                    throws IOException {
504    
505                    if (path == null) {
506                            return null;
507                    }
508    
509                    Action action = StrutsActionRegistryUtil.getAction(path);
510    
511                    if (action != null) {
512                            ActionMapping actionMapping =
513                                    (ActionMapping)moduleConfig.findActionConfig(path);
514    
515                            if (actionMapping == null) {
516                                    actionMapping = new ActionMapping();
517    
518                                    actionMapping.setModuleConfig(moduleConfig);
519                                    actionMapping.setPath(path);
520    
521                                    request.setAttribute(Globals.MAPPING_KEY, actionMapping);
522                            }
523    
524                            return actionMapping;
525                    }
526    
527                    ActionMapping actionMapping = super.processMapping(
528                            request, response, path);
529    
530                    if (actionMapping == null) {
531                            MessageResources messageResources = getInternal();
532    
533                            String msg = messageResources.getMessage("processInvalid");
534    
535                            _log.error("User ID " + request.getRemoteUser());
536                            _log.error("Current URL " + PortalUtil.getCurrentURL(request));
537                            _log.error("Referer " + request.getHeader("Referer"));
538                            _log.error("Remote address " + request.getRemoteAddr());
539    
540                            _log.error(msg + " " + path);
541                    }
542    
543                    return actionMapping;
544            }
545    
546            @Override
547            protected HttpServletRequest processMultipart(HttpServletRequest request) {
548    
549                    // Disable Struts from automatically wrapping a multipart request
550    
551                    return request;
552            }
553    
554            @Override
555            protected String processPath(
556                            HttpServletRequest request, HttpServletResponse response)
557                    throws IOException {
558    
559                    String path = GetterUtil.getString(
560                            super.processPath(request, response));
561    
562                    HttpSession session = request.getSession();
563    
564                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
565                            WebKeys.THEME_DISPLAY);
566    
567                    // Current users
568    
569                    UserTracker userTracker = LiveUsers.getUserTracker(
570                            themeDisplay.getCompanyId(), session.getId());
571    
572                    if ((userTracker != null) && !path.equals(_PATH_C) &&
573                            !path.contains(_PATH_J_SECURITY_CHECK) &&
574                            !path.contains(_PATH_PORTAL_PROTECTED) &&
575                            !_trackerIgnorePaths.contains(path)) {
576    
577                            String fullPath = null;
578    
579                            try {
580                                    if (PropsValues.SESSION_TRACKER_FRIENDLY_PATHS_ENABLED) {
581                                            fullPath = getFriendlyTrackerPath(
582                                                    path, themeDisplay, request);
583                                    }
584                            }
585                            catch (Exception e) {
586                                    _log.error(e, e);
587                            }
588    
589                            String fullPathWithoutQueryString = fullPath;
590    
591                            if (Validator.isNull(fullPath)) {
592                                    String queryString = request.getQueryString();
593    
594                                    fullPathWithoutQueryString = path;
595    
596                                    if (Validator.isNotNull(queryString)) {
597                                            fullPath = path.concat(StringPool.QUESTION).concat(
598                                                    queryString);
599                                    }
600                                    else {
601                                            fullPath = path;
602                                    }
603                            }
604    
605                            int pos = fullPathWithoutQueryString.indexOf(StringPool.QUESTION);
606    
607                            if (pos != -1) {
608                                    fullPathWithoutQueryString =
609                                            fullPathWithoutQueryString.substring(0, pos);
610                            }
611    
612                            if (!_trackerIgnorePaths.contains(fullPathWithoutQueryString)) {
613                                    UserTrackerPath userTrackerPath = UserTrackerPathUtil.create(0);
614    
615                                    userTrackerPath.setUserTrackerId(
616                                            userTracker.getUserTrackerId());
617                                    userTrackerPath.setPath(fullPath);
618                                    userTrackerPath.setPathDate(new Date());
619    
620                                    userTracker.addPath(userTrackerPath);
621                            }
622                    }
623    
624                    String remoteUser = request.getRemoteUser();
625    
626                    User user = null;
627    
628                    try {
629                            user = PortalUtil.getUser(request);
630                    }
631                    catch (Exception e) {
632                    }
633    
634                    // Last path
635    
636                    if (_lastPaths.contains(path) && !_trackerIgnorePaths.contains(path)) {
637                            boolean saveLastPath = ParamUtil.getBoolean(
638                                    request, "saveLastPath", true);
639    
640                            if (themeDisplay.isLifecycleResource() ||
641                                    themeDisplay.isStateExclusive() ||
642                                    themeDisplay.isStatePopUp() ||
643                                    !request.getMethod().equalsIgnoreCase(HttpMethods.GET)) {
644    
645                                    saveLastPath = false;
646                            }
647    
648                            // Save last path
649    
650                            if (saveLastPath) {
651    
652                                    // Was a last path set by another servlet that dispatched to the
653                                    // MainServlet? If so, use that last path instead.
654    
655                                    LastPath lastPath = (LastPath)request.getAttribute(
656                                            WebKeys.LAST_PATH);
657    
658                                    if (lastPath == null) {
659                                            lastPath = new LastPath(
660                                                    themeDisplay.getPathMain(), path,
661                                                    request.getParameterMap());
662                                    }
663    
664                                    session.setAttribute(WebKeys.LAST_PATH, lastPath);
665                            }
666                    }
667    
668                    // Setup wizard
669    
670                    if (!SetupWizardUtil.isSetupFinished()) {
671                            if (!path.equals(_PATH_PORTAL_LICENSE) &&
672                                    !path.equals(_PATH_PORTAL_STATUS)) {
673    
674                                    return _PATH_PORTAL_SETUP_WIZARD;
675                            }
676                    }
677                    else if (path.equals(_PATH_PORTAL_SETUP_WIZARD)) {
678                            return _PATH_PORTAL_LAYOUT;
679                    }
680    
681                    // Authenticated users can always log out
682    
683                    if (((remoteUser != null) || (user != null)) &&
684                            path.equals(_PATH_PORTAL_LOGOUT)) {
685    
686                            return path;
687                    }
688    
689                    // Authenticated users can always extend or confirm their session
690    
691                    if (((remoteUser != null) || (user != null)) &&
692                            (path.equals(_PATH_PORTAL_EXPIRE_SESSION) ||
693                             path.equals(_PATH_PORTAL_EXTEND_SESSION))) {
694    
695                            return path;
696                    }
697    
698                    // Authenticated users can always agree to terms of use
699    
700                    if (((remoteUser != null) || (user != null)) &&
701                            path.equals(_PATH_PORTAL_UPDATE_TERMS_OF_USE)) {
702    
703                            return path;
704                    }
705    
706                    // Authenticated users must still exist in the system
707    
708                    if ((remoteUser != null) && (user == null)) {
709                            return _PATH_PORTAL_LOGOUT;
710                    }
711    
712                    // Authenticated users must be active
713    
714                    if ((user != null) && !user.isActive()) {
715                            SessionErrors.add(request, UserActiveException.class.getName());
716    
717                            return _PATH_PORTAL_ERROR;
718                    }
719    
720                    if (!path.equals(_PATH_PORTAL_JSON_SERVICE) &&
721                            !path.equals(_PATH_PORTAL_RENDER_PORTLET) &&
722                            !ParamUtil.getBoolean(request, "wsrp") &&
723                            !themeDisplay.isImpersonated()) {
724    
725                            // Authenticated users should agree to Terms of Use
726    
727                            if ((user != null) && !user.isAgreedToTermsOfUse()) {
728                                    boolean termsOfUseRequired = false;
729    
730                                    try {
731                                            termsOfUseRequired = PrefsPropsUtil.getBoolean(
732                                                    user.getCompanyId(), PropsKeys.TERMS_OF_USE_REQUIRED);
733                                    }
734                                    catch (SystemException se) {
735                                            termsOfUseRequired = PropsValues.TERMS_OF_USE_REQUIRED;
736                                    }
737    
738                                    if (termsOfUseRequired) {
739                                            return _PATH_PORTAL_TERMS_OF_USE;
740                                    }
741                            }
742    
743                            // Authenticated users should have a verified email address
744    
745                            boolean emailAddressVerificationRequired = false;
746    
747                            try {
748                                    Company company = PortalUtil.getCompany(request);
749    
750                                    emailAddressVerificationRequired = company.isStrangersVerify();
751                            }
752                            catch (Exception e) {
753                                    _log.error(e, e);
754                            }
755    
756                            if ((user != null) && !user.isEmailAddressVerified() &&
757                                    emailAddressVerificationRequired) {
758    
759                                    if (path.equals(_PATH_PORTAL_UPDATE_EMAIL_ADDRESS)) {
760                                            return _PATH_PORTAL_UPDATE_EMAIL_ADDRESS;
761                                    }
762    
763                                    return _PATH_PORTAL_VERIFY_EMAIL_ADDRESS;
764                            }
765    
766                            // Authenticated users must have a current password
767    
768                            if ((user != null) && user.isPasswordReset()) {
769                                    return _PATH_PORTAL_UPDATE_PASSWORD;
770                            }
771                            else if ((user != null) && !user.isPasswordReset() &&
772                                             path.equals(_PATH_PORTAL_UPDATE_PASSWORD)) {
773    
774                                    return null;
775                            }
776    
777                            // Authenticated users must have an email address
778    
779                            if ((user != null) &&
780                                    (Validator.isNull(user.getEmailAddress()) ||
781                                     (PropsValues.USERS_EMAIL_ADDRESS_REQUIRED &&
782                                      Validator.isNull(user.getDisplayEmailAddress())))) {
783    
784                                    return _PATH_PORTAL_UPDATE_EMAIL_ADDRESS;
785                            }
786    
787                            // Authenticated users should have a reminder query
788    
789                            if ((user != null) && !user.isDefaultUser() &&
790                                    (Validator.isNull(user.getReminderQueryQuestion()) ||
791                                     Validator.isNull(user.getReminderQueryAnswer()))) {
792    
793                                    if (PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
794                                            return _PATH_PORTAL_UPDATE_REMINDER_QUERY;
795                                    }
796                            }
797                    }
798    
799                    // Users must sign in
800    
801                    if (!isPublicPath(path)) {
802                            if (user == null) {
803                                    SessionErrors.add(request, PrincipalException.class.getName());
804    
805                                    return _PATH_PORTAL_LOGIN;
806                            }
807                    }
808    
809                    ActionMapping actionMapping =
810                            (ActionMapping)moduleConfig.findActionConfig(path);
811    
812                    if (actionMapping == null) {
813                            Action strutsAction = StrutsActionRegistryUtil.getAction(path);
814    
815                            if (strutsAction == null) {
816                                    return null;
817                            }
818                    }
819                    else {
820                            path = actionMapping.getPath();
821                    }
822    
823                    // Define the portlet objects
824    
825                    if (isPortletPath(path)) {
826                            try {
827                                    Portlet portlet = null;
828    
829                                    long companyId = PortalUtil.getCompanyId(request);
830                                    String portletId = ParamUtil.getString(request, "p_p_id");
831    
832                                    if (Validator.isNotNull(portletId)) {
833                                            portlet = PortletLocalServiceUtil.getPortletById(
834                                                    companyId, portletId);
835                                    }
836    
837                                    if (portlet == null) {
838                                            String strutsPath = path.substring(
839                                                    1, path.lastIndexOf(CharPool.SLASH));
840    
841                                            portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
842                                                    companyId, strutsPath);
843                                    }
844    
845                                    if ((portlet != null) && portlet.isActive()) {
846                                            defineObjects(request, response, portlet);
847                                    }
848                            }
849                            catch (Exception e) {
850                                    request.setAttribute(PageContext.EXCEPTION, e);
851    
852                                    path = _PATH_COMMON_ERROR;
853                            }
854                    }
855    
856                    // Authenticated users must have access to at least one layout
857    
858                    if (SessionErrors.contains(
859                                    request, LayoutPermissionException.class.getName())) {
860    
861                            return _PATH_PORTAL_ERROR;
862                    }
863    
864                    return path;
865            }
866    
867            @Override
868            protected boolean processRoles(
869                            HttpServletRequest request, HttpServletResponse response,
870                            ActionMapping actionMapping)
871                    throws IOException, ServletException {
872    
873                    String path = actionMapping.getPath();
874    
875                    if (isPublicPath(path)) {
876                            return true;
877                    }
878    
879                    boolean authorized = true;
880    
881                    User user = null;
882    
883                    try {
884                            user = PortalUtil.getUser(request);
885                    }
886                    catch (Exception e) {
887                    }
888    
889                    if ((user != null) && isPortletPath(path)) {
890                            try {
891    
892                                    // Authenticated users can always log out
893    
894                                    if (path.equals(_PATH_PORTAL_LOGOUT)) {
895                                            return true;
896                                    }
897    
898                                    Portlet portlet = null;
899    
900                                    String portletId = ParamUtil.getString(request, "p_p_id");
901    
902                                    if (Validator.isNotNull(portletId)) {
903                                            portlet = PortletLocalServiceUtil.getPortletById(
904                                                    user.getCompanyId(), portletId);
905                                    }
906    
907                                    String strutsPath = path.substring(
908                                            1, path.lastIndexOf(CharPool.SLASH));
909    
910                                    if (portlet != null) {
911                                            if (!strutsPath.equals(portlet.getStrutsPath())) {
912                                                    throw new PrincipalException();
913                                            }
914                                    }
915                                    else {
916                                            portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
917                                                    user.getCompanyId(), strutsPath);
918                                    }
919    
920                                    if ((portlet != null) && portlet.isActive()) {
921                                            ThemeDisplay themeDisplay =
922                                                    (ThemeDisplay)request.getAttribute(
923                                                            WebKeys.THEME_DISPLAY);
924    
925                                            Layout layout = themeDisplay.getLayout();
926                                            PermissionChecker permissionChecker =
927                                                    themeDisplay.getPermissionChecker();
928    
929                                            if (!PortletPermissionUtil.contains(
930                                                            permissionChecker, layout, portlet,
931                                                            ActionKeys.VIEW)) {
932    
933                                                    throw new PrincipalException();
934                                            }
935                                    }
936                                    else if ((portlet != null) && !portlet.isActive()) {
937                                            SessionErrors.add(
938                                                    request, PortletActiveException.class.getName());
939    
940                                            authorized = false;
941                                    }
942                            }
943                            catch (Exception e) {
944                                    SessionErrors.add(request, PrincipalException.class.getName());
945    
946                                    authorized = false;
947                            }
948                    }
949    
950                    if (!authorized) {
951                            ForwardConfig forwardConfig = actionMapping.findForward(
952                                    _PATH_PORTAL_ERROR);
953    
954                            processForwardConfig(request, response, forwardConfig);
955    
956                            return false;
957                    }
958                    else {
959                            return true;
960                    }
961            }
962    
963            private static final String _PATH_C = "/c";
964    
965            private static final String _PATH_COMMON = "/common";
966    
967            private static final String _PATH_COMMON_ERROR = "/common/error";
968    
969            private static final String _PATH_J_SECURITY_CHECK = "/j_security_check";
970    
971            private static final String _PATH_PORTAL = "/portal";
972    
973            private static final String _PATH_PORTAL_API_JSONWS = "/portal/api/jsonws";
974    
975            private static final String _PATH_PORTAL_ERROR = "/portal/error";
976    
977            private static final String _PATH_PORTAL_EXPIRE_SESSION =
978                    "/portal/expire_session";
979    
980            private static final String _PATH_PORTAL_EXTEND_SESSION =
981                    "/portal/extend_session";
982    
983            private static final String _PATH_PORTAL_FLASH = "/portal/flash";
984    
985            private static final String _PATH_PORTAL_J_LOGIN = "/portal/j_login";
986    
987            private static final String _PATH_PORTAL_JSON_SERVICE =
988                    "/portal/json_service";
989    
990            private static final String _PATH_PORTAL_LAYOUT = "/portal/layout";
991    
992            private static final String _PATH_PORTAL_LICENSE = "/portal/license";
993    
994            private static final String _PATH_PORTAL_LOGIN = "/portal/login";
995    
996            private static final String _PATH_PORTAL_LOGOUT = "/portal/logout";
997    
998            private static final String _PATH_PORTAL_PROTECTED = "/portal/protected";
999    
1000            private static final String _PATH_PORTAL_RENDER_PORTLET =
1001                    "/portal/render_portlet";
1002    
1003            private static final String _PATH_PORTAL_RESILIENCY = "/portal/resiliency";
1004    
1005            private static final String _PATH_PORTAL_SETUP_WIZARD =
1006                    "/portal/setup_wizard";
1007    
1008            private static final String _PATH_PORTAL_STATUS = "/portal/status";
1009    
1010            private static final String _PATH_PORTAL_TCK = "/portal/tck";
1011    
1012            private static final String _PATH_PORTAL_TERMS_OF_USE =
1013                    "/portal/terms_of_use";
1014    
1015            private static final String _PATH_PORTAL_UPDATE_EMAIL_ADDRESS =
1016                    "/portal/update_email_address";
1017    
1018            private static final String _PATH_PORTAL_UPDATE_PASSWORD =
1019                    "/portal/update_password";
1020    
1021            private static final String _PATH_PORTAL_UPDATE_REMINDER_QUERY =
1022                    "/portal/update_reminder_query";
1023    
1024            private static final String _PATH_PORTAL_UPDATE_TERMS_OF_USE =
1025                    "/portal/update_terms_of_use";
1026    
1027            private static final String _PATH_PORTAL_VERIFY_EMAIL_ADDRESS =
1028                    "/portal/verify_email_address";
1029    
1030            private static Log _log = LogFactoryUtil.getLog(
1031                    PortalRequestProcessor.class);
1032    
1033            private Set<String> _lastPaths;
1034            private Set<String> _publicPaths;
1035            private Set<String> _trackerIgnorePaths;
1036    
1037    }