1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.struts;
24  
25  import com.liferay.portal.LayoutPermissionException;
26  import com.liferay.portal.PortletActiveException;
27  import com.liferay.portal.RequiredRoleException;
28  import com.liferay.portal.UserActiveException;
29  import com.liferay.portal.kernel.log.Log;
30  import com.liferay.portal.kernel.log.LogFactoryUtil;
31  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
32  import com.liferay.portal.kernel.servlet.HttpMethods;
33  import com.liferay.portal.kernel.servlet.SessionErrors;
34  import com.liferay.portal.kernel.util.GetterUtil;
35  import com.liferay.portal.kernel.util.HttpUtil;
36  import com.liferay.portal.kernel.util.JavaConstants;
37  import com.liferay.portal.kernel.util.ParamUtil;
38  import com.liferay.portal.kernel.util.StringPool;
39  import com.liferay.portal.kernel.util.Validator;
40  import com.liferay.portal.liveusers.LiveUsers;
41  import com.liferay.portal.model.Layout;
42  import com.liferay.portal.model.LayoutConstants;
43  import com.liferay.portal.model.Portlet;
44  import com.liferay.portal.model.PortletPreferencesIds;
45  import com.liferay.portal.model.User;
46  import com.liferay.portal.model.UserTracker;
47  import com.liferay.portal.model.UserTrackerPath;
48  import com.liferay.portal.security.auth.PrincipalException;
49  import com.liferay.portal.security.permission.ActionKeys;
50  import com.liferay.portal.security.permission.PermissionChecker;
51  import com.liferay.portal.service.LayoutLocalServiceUtil;
52  import com.liferay.portal.service.PortletLocalServiceUtil;
53  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
54  import com.liferay.portal.service.permission.PortletPermissionUtil;
55  import com.liferay.portal.service.persistence.UserTrackerPathUtil;
56  import com.liferay.portal.theme.ThemeDisplay;
57  import com.liferay.portal.util.PortalUtil;
58  import com.liferay.portal.util.PropsKeys;
59  import com.liferay.portal.util.PropsUtil;
60  import com.liferay.portal.util.PropsValues;
61  import com.liferay.portal.util.WebKeys;
62  import com.liferay.portlet.InvokerPortlet;
63  import com.liferay.portlet.PortletConfigFactory;
64  import com.liferay.portlet.PortletInstanceFactory;
65  import com.liferay.portlet.PortletPreferencesFactoryUtil;
66  import com.liferay.portlet.PortletURLImpl;
67  import com.liferay.portlet.RenderRequestFactory;
68  import com.liferay.portlet.RenderRequestImpl;
69  import com.liferay.portlet.RenderResponseFactory;
70  import com.liferay.portlet.RenderResponseImpl;
71  
72  import java.io.IOException;
73  
74  import java.util.Date;
75  import java.util.HashSet;
76  import java.util.Iterator;
77  import java.util.Map.Entry;
78  import java.util.Map;
79  import java.util.Set;
80  
81  import javax.portlet.PortletConfig;
82  import javax.portlet.PortletContext;
83  import javax.portlet.PortletMode;
84  import javax.portlet.PortletPreferences;
85  import javax.portlet.PortletRequest;
86  import javax.portlet.WindowState;
87  
88  import javax.servlet.ServletContext;
89  import javax.servlet.ServletException;
90  import javax.servlet.http.HttpServletRequest;
91  import javax.servlet.http.HttpServletResponse;
92  import javax.servlet.http.HttpSession;
93  import javax.servlet.jsp.PageContext;
94  
95  import org.apache.struts.action.ActionMapping;
96  import org.apache.struts.config.ForwardConfig;
97  import org.apache.struts.tiles.TilesRequestProcessor;
98  
99  /**
100  * <a href="PortalRequestProcessor.java.html"><b><i>View Source</i></b></a>
101  *
102  * @author Brian Wing Shun Chan
103  * @author Jorge Ferrer
104  *
105  */
106 public class PortalRequestProcessor extends TilesRequestProcessor {
107 
108     public PortalRequestProcessor() {
109 
110         // auth.forward.last.path.
111 
112         _lastPaths = new HashSet<String>();
113 
114         _lastPaths.add(_PATH_PORTAL_LAYOUT);
115 
116         addPaths(_lastPaths, PropsKeys.AUTH_FORWARD_LAST_PATHS);
117 
118         // auth.public.path.
119 
120         _publicPaths = new HashSet<String>();
121 
122         _publicPaths.add(_PATH_C);
123         _publicPaths.add(_PATH_PORTAL_FLASH);
124         _publicPaths.add(_PATH_PORTAL_J_LOGIN);
125         _publicPaths.add(_PATH_PORTAL_LAYOUT);
126         _publicPaths.add(_PATH_PORTAL_LOGIN);
127         _publicPaths.add(_PATH_PORTAL_LOGIN_CAPTCHA);
128         _publicPaths.add(_PATH_PORTAL_RENDER_PORTLET);
129         _publicPaths.add(_PATH_PORTAL_TCK);
130 
131         addPaths(_publicPaths, PropsKeys.AUTH_PUBLIC_PATHS);
132 
133         _trackerIgnorePaths = new HashSet<String>();
134 
135         addPaths(_trackerIgnorePaths, PropsKeys.SESSION_TRACKER_IGNORE_PATHS);
136     }
137 
138     public void process(
139             HttpServletRequest request, HttpServletResponse response)
140         throws IOException, ServletException {
141 
142         String path = super.processPath(request, response);
143 
144         ActionMapping mapping = (ActionMapping)moduleConfig.findActionConfig(
145             path);
146 
147         if ((mapping == null) && !path.startsWith(_PATH_WSRP)) {
148             String lastPath = getLastPath(request);
149 
150             if (_log.isDebugEnabled()) {
151                 _log.debug("Last path " + lastPath);
152             }
153 
154             response.sendRedirect(lastPath);
155 
156             return;
157         }
158 
159         super.process(request, response);
160 
161         try {
162             if (isPortletPath(path)) {
163                 cleanUp(request);
164             }
165         }
166         catch (Exception e) {
167             _log.error(e, e);
168         }
169     }
170 
171     protected void addPaths(Set<String> paths, String propsKey) {
172         String[] pathsArray = PropsUtil.getArray(propsKey);
173 
174         for (String path : pathsArray) {
175             paths.add(path);
176         }
177     }
178 
179     protected void callParentDoForward(
180             String uri, HttpServletRequest request,
181             HttpServletResponse response)
182         throws IOException, ServletException {
183 
184         super.doForward(uri, request, response);
185     }
186 
187     protected HttpServletRequest callParentProcessMultipart(
188         HttpServletRequest request) {
189 
190         return super.processMultipart(request);
191     }
192 
193     protected String callParentProcessPath(
194             HttpServletRequest request, HttpServletResponse response)
195         throws IOException {
196 
197         return super.processPath(request, response);
198     }
199 
200     protected boolean callParentProcessRoles(
201             HttpServletRequest request, HttpServletResponse response,
202             ActionMapping mapping)
203         throws IOException, ServletException {
204 
205         return super.processRoles(request, response, mapping);
206     }
207 
208     protected void cleanUp(HttpServletRequest request) throws Exception {
209 
210         // Clean up portlet objects that may have been created by defineObjects
211         // for portlets that are called directly from a Struts path
212 
213         RenderRequestImpl renderRequestImpl =
214             (RenderRequestImpl)request.getAttribute(
215                 JavaConstants.JAVAX_PORTLET_REQUEST);
216 
217         if (renderRequestImpl != null) {
218             RenderRequestFactory.recycle(renderRequestImpl);
219         }
220 
221         RenderResponseImpl renderResponseImpl =
222             (RenderResponseImpl)request.getAttribute(
223                 JavaConstants.JAVAX_PORTLET_RESPONSE);
224 
225         if (renderResponseImpl != null) {
226             RenderResponseFactory.recycle(renderResponseImpl);
227         }
228     }
229 
230     protected void defineObjects(
231             HttpServletRequest request, HttpServletResponse response,
232             Portlet portlet)
233         throws Exception {
234 
235         String portletId = portlet.getPortletId();
236 
237         ServletContext servletContext = (ServletContext)request.getAttribute(
238             WebKeys.CTX);
239 
240         InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
241             portlet, servletContext);
242 
243         PortletPreferencesIds portletPreferencesIds =
244             PortletPreferencesFactoryUtil.getPortletPreferencesIds(
245                 request, portletId);
246 
247         PortletPreferences portletPreferences =
248             PortletPreferencesLocalServiceUtil.getPreferences(
249                 portletPreferencesIds);
250 
251         PortletConfig portletConfig = PortletConfigFactory.create(
252             portlet, servletContext);
253         PortletContext portletContext = portletConfig.getPortletContext();
254 
255         RenderRequestImpl renderRequestImpl = RenderRequestFactory.create(
256             request, portlet, invokerPortlet, portletContext,
257             WindowState.MAXIMIZED, PortletMode.VIEW, portletPreferences);
258 
259         RenderResponseImpl renderResponseImpl = RenderResponseFactory.create(
260             renderRequestImpl, response, portletId, portlet.getCompanyId());
261 
262         renderRequestImpl.defineObjects(portletConfig, renderResponseImpl);
263 
264         request.setAttribute(WebKeys.PORTLET_STRUTS_EXECUTE, Boolean.TRUE);
265     }
266 
267     protected void doForward(
268             String uri, HttpServletRequest request,
269             HttpServletResponse response)
270         throws ServletException {
271 
272         StrutsUtil.forward(uri, getServletContext(), request, response);
273     }
274 
275     protected void doInclude(
276             String uri, HttpServletRequest request,
277             HttpServletResponse response)
278         throws ServletException {
279 
280         StrutsUtil.include(uri, getServletContext(), request, response);
281     }
282 
283     protected StringBuilder getFriendlyTrackerPath(
284             String path, ThemeDisplay themeDisplay, HttpServletRequest request)
285         throws Exception {
286 
287         if (!path.equals(_PATH_PORTAL_LAYOUT)) {
288             return null;
289         }
290 
291         long plid = ParamUtil.getLong(request, "p_l_id");
292 
293         if (plid == 0) {
294             return null;
295         }
296 
297         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
298 
299         String layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
300             layout, themeDisplay);
301 
302         StringBuilder sb = new StringBuilder();
303 
304         sb.append(layoutFriendlyURL);
305 
306         String portletId = ParamUtil.getString(request, "p_p_id");
307 
308         if (Validator.isNull(portletId)) {
309             return sb;
310         }
311 
312         long companyId = PortalUtil.getCompanyId(request);
313 
314         Portlet portlet = PortletLocalServiceUtil.getPortletById(
315             companyId, portletId);
316 
317         if (portlet == null) {
318             String strutsPath = path.substring(
319                 1, path.lastIndexOf(StringPool.SLASH));
320 
321             portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
322                 companyId, strutsPath);
323         }
324 
325         if ((portlet == null) || !portlet.isActive()) {
326             sb.append(StringPool.QUESTION);
327             sb.append(request.getQueryString());
328 
329             return sb;
330         }
331 
332         String namespace = PortalUtil.getPortletNamespace(portletId);
333 
334         FriendlyURLMapper friendlyURLMapper =
335             portlet.getFriendlyURLMapperInstance();
336 
337         if (friendlyURLMapper == null) {
338             sb.append(StringPool.QUESTION);
339             sb.append(request.getQueryString());
340 
341             return sb;
342         }
343 
344         PortletURLImpl portletURL = new PortletURLImpl(
345             request, portletId, plid, PortletRequest.RENDER_PHASE);
346 
347         Iterator<Map.Entry<String, String[]>> itr =
348             request.getParameterMap().entrySet().iterator();
349 
350         while (itr.hasNext()) {
351             Entry<String, String[]> entry = itr.next();
352 
353             String key = entry.getKey();
354 
355             if (key.startsWith(namespace)) {
356                 key = key.substring(namespace.length());
357 
358                 portletURL.setParameter(key, entry.getValue());
359             }
360         }
361 
362         String portletFriendlyURL = friendlyURLMapper.buildPath(portletURL);
363 
364         if (portletFriendlyURL != null) {
365             sb.append(portletFriendlyURL);
366         }
367         else {
368             sb.append(StringPool.QUESTION);
369             sb.append(request.getQueryString());
370         }
371 
372         return sb;
373     }
374 
375     protected String getLastPath(HttpServletRequest request) {
376         HttpSession session = request.getSession();
377 
378         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
379             WebKeys.THEME_DISPLAY);
380 
381         Boolean httpsInitial = (Boolean)session.getAttribute(
382             WebKeys.HTTPS_INITIAL);
383 
384         String portalURL = null;
385 
386         if ((PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS) &&
387             (httpsInitial != null) && (!httpsInitial.booleanValue())) {
388 
389             portalURL = PortalUtil.getPortalURL(request, false);
390         }
391         else {
392             portalURL = PortalUtil.getPortalURL(request);
393         }
394 
395         StringBuilder sb = new StringBuilder();
396 
397         sb.append(portalURL);
398         sb.append(themeDisplay.getPathMain());
399         sb.append(_PATH_PORTAL_LAYOUT);
400 
401         if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
402             if (request.getRemoteUser() != null) {
403 
404                 // If we do not forward by last path and the user is logged in,
405                 // forward to the user's default layout to prevent a lagging
406                 // loop
407 
408                 sb.append(StringPool.QUESTION);
409                 sb.append("p_l_id");
410                 sb.append(StringPool.EQUAL);
411                 sb.append(LayoutConstants.DEFAULT_PLID);
412             }
413 
414             return sb.toString();
415         }
416 
417         LastPath lastPath = (LastPath)session.getAttribute(WebKeys.LAST_PATH);
418 
419         if (lastPath == null) {
420             return sb.toString();
421         }
422 
423         Map<String, String[]> parameterMap = lastPath.getParameterMap();
424 
425         // Only test for existing mappings for last paths that were set when the
426         // user accessed a layout directly instead of through its friendly URL
427 
428         if (lastPath.getContextPath().equals(themeDisplay.getPathMain())) {
429             ActionMapping mapping =
430                 (ActionMapping)moduleConfig.findActionConfig(
431                     lastPath.getPath());
432 
433             if ((mapping == null) || (parameterMap == null)) {
434                 return sb.toString();
435             }
436         }
437 
438         StringBuilder lastPathSB = new StringBuilder();
439 
440         lastPathSB.append(portalURL);
441         lastPathSB.append(lastPath.getContextPath());
442         lastPathSB.append(lastPath.getPath());
443         lastPathSB.append(HttpUtil.parameterMapToString(parameterMap));
444 
445         return lastPathSB.toString();
446     }
447 
448     protected boolean isPortletPath(String path) {
449         if ((path != null) &&
450             (!path.equals(_PATH_C)) &&
451             (!path.startsWith(_PATH_COMMON)) &&
452             (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
453             (!path.startsWith(_PATH_PORTAL)) &&
454             (!path.startsWith(_PATH_WSRP))) {
455 
456             return true;
457         }
458         else {
459             return false;
460         }
461     }
462 
463     protected boolean isPublicPath(String path) {
464         if ((path != null) &&
465             (_publicPaths.contains(path)) ||
466             (path.startsWith(_PATH_COMMON)) ||
467             (path.startsWith(_PATH_WSRP))) {
468 
469             return true;
470         }
471         else {
472             return false;
473         }
474     }
475 
476     protected ActionMapping processMapping(
477             HttpServletRequest request, HttpServletResponse response,
478             String path)
479         throws IOException {
480 
481         if (path == null) {
482             return null;
483         }
484 
485         ActionMapping mapping = super.processMapping(request, response, path);
486 
487         if (mapping == null) {
488             String msg = getInternal().getMessage("processInvalid");
489 
490             _log.error("User ID " + request.getRemoteUser());
491             _log.error("Current URL " + PortalUtil.getCurrentURL(request));
492             _log.error("Referer " + request.getHeader("Referer"));
493             _log.error("Remote address " + request.getRemoteAddr());
494 
495             _log.error(msg + " " + path);
496         }
497 
498         return mapping;
499     }
500 
501     protected HttpServletRequest processMultipart(HttpServletRequest request) {
502 
503         // Disable Struts from automatically wrapping a multipart request
504 
505         return request;
506     }
507 
508     protected String processPath(
509             HttpServletRequest request, HttpServletResponse response)
510         throws IOException {
511 
512         String path = GetterUtil.getString(
513             super.processPath(request, response));
514 
515         HttpSession session = request.getSession();
516 
517         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
518             WebKeys.THEME_DISPLAY);
519 
520         // Current users
521 
522         UserTracker userTracker = LiveUsers.getUserTracker(
523             themeDisplay.getCompanyId(), session.getId());
524 
525         if ((userTracker != null) && (!path.equals(_PATH_C)) &&
526             (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
527             (path.indexOf(_PATH_PORTAL_PROTECTED) == -1) &&
528             (!_trackerIgnorePaths.contains(path))) {
529 
530             StringBuilder sb = null;
531 
532             try {
533                 if (PropsValues.SESSION_TRACKER_FRIENDLY_PATHS_ENABLED) {
534                     sb = getFriendlyTrackerPath(path, themeDisplay, request);
535                 }
536             }
537             catch (Exception e) {
538                 _log.error(e, e);
539             }
540 
541             if (sb == null) {
542                 sb = new StringBuilder();
543 
544                 sb.append(path);
545                 sb.append(StringPool.QUESTION);
546                 sb.append(request.getQueryString());
547             }
548 
549             UserTrackerPath userTrackerPath = UserTrackerPathUtil.create(0);
550 
551             userTrackerPath.setUserTrackerId(userTracker.getUserTrackerId());
552             userTrackerPath.setPath(sb.toString());
553             userTrackerPath.setPathDate(new Date());
554 
555             userTracker.addPath(userTrackerPath);
556         }
557 
558         String remoteUser = request.getRemoteUser();
559 
560         User user = null;
561 
562         try {
563             user = PortalUtil.getUser(request);
564         }
565         catch (Exception e) {
566         }
567 
568         // Last path
569 
570         if (_lastPaths.contains(path) && !_trackerIgnorePaths.contains(path)) {
571             boolean saveLastPath = ParamUtil.getBoolean(
572                 request, "saveLastPath", true);
573 
574             if (themeDisplay.isLifecycleResource() ||
575                 themeDisplay.isStateExclusive() ||
576                 themeDisplay.isStatePopUp() ||
577                 !request.getMethod().equalsIgnoreCase(HttpMethods.GET)) {
578 
579                 saveLastPath = false;
580             }
581 
582             // Save last path
583 
584             if (saveLastPath) {
585 
586                 // Was a last path set by another servlet that dispatched to
587                 // the MainServlet? If so, use that last path instead.
588 
589                 LastPath lastPath = (LastPath)request.getAttribute(
590                     WebKeys.LAST_PATH);
591 
592                 if (lastPath == null) {
593                     lastPath = new LastPath(
594                         themeDisplay.getPathMain(), path,
595                         request.getParameterMap());
596                 }
597 
598                 session.setAttribute(WebKeys.LAST_PATH, lastPath);
599             }
600         }
601 
602         // Authenticated users can always log out
603 
604         if (((remoteUser != null) || (user != null)) &&
605             (path.equals(_PATH_PORTAL_LOGOUT))) {
606 
607             return path;
608         }
609 
610         // Authenticated users can always extend or confirm their session
611 
612         if (((remoteUser != null) || (user != null)) &&
613             (path.equals(_PATH_PORTAL_EXPIRE_SESSION) ||
614              path.equals(_PATH_PORTAL_EXTEND_SESSION))) {
615 
616             return path;
617         }
618 
619         // Authenticated users can always agree to terms of use
620 
621         if (((remoteUser != null) || (user != null)) &&
622             (path.equals(_PATH_PORTAL_UPDATE_TERMS_OF_USE))) {
623 
624             return path;
625         }
626 
627         // Authenticated users must still exist in the system
628 
629         if ((remoteUser != null) && (user == null)) {
630             return _PATH_PORTAL_LOGOUT;
631         }
632 
633         // Authenticated users must be active
634 
635         if ((user != null) && !user.isActive()) {
636             SessionErrors.add(request, UserActiveException.class.getName());
637 
638             return _PATH_PORTAL_ERROR;
639         }
640 
641         if (!path.equals(_PATH_PORTAL_RENDER_PORTLET)) {
642 
643             // Authenticated users should agree to Terms of Use
644 
645             if ((user != null) && !user.isAgreedToTermsOfUse()) {
646                 if (PropsValues.TERMS_OF_USE_REQUIRED) {
647                     return _PATH_PORTAL_TERMS_OF_USE;
648                 }
649             }
650 
651             // Authenticated users must have a current password
652 
653             if ((user != null) && user.isPasswordReset()) {
654                 return _PATH_PORTAL_CHANGE_PASSWORD;
655             }
656         }
657 
658         // Users must sign in
659 
660         if (!isPublicPath(path)) {
661             if (user == null) {
662                 SessionErrors.add(request, PrincipalException.class.getName());
663 
664                 return _PATH_PORTAL_LOGIN;
665             }
666         }
667 
668         ActionMapping mapping =
669             (ActionMapping)moduleConfig.findActionConfig(path);
670 
671         if (path.startsWith(_PATH_WSRP)) {
672             path = _PATH_WSRP;
673         }
674         else {
675             path = mapping.getPath();
676         }
677 
678         // Authenticated users must have at least one role
679 
680         if (user != null) {
681             try {
682 
683                 // FIX ME
684 
685                 if (false) {
686                     SessionErrors.add(
687                         request, RequiredRoleException.class.getName());
688 
689                     return _PATH_PORTAL_ERROR;
690                 }
691             }
692             catch (Exception e) {
693                 e.printStackTrace();
694             }
695         }
696 
697         // Define the portlet objects
698 
699         if (isPortletPath(path)) {
700             try {
701                 Portlet portlet = null;
702 
703                 long companyId = PortalUtil.getCompanyId(request);
704                 String portletId = ParamUtil.getString(request, "p_p_id");
705 
706                 if (Validator.isNotNull(portletId)) {
707                     portlet = PortletLocalServiceUtil.getPortletById(
708                         companyId, portletId);
709                 }
710 
711                 if (portlet == null) {
712                     String strutsPath = path.substring(
713                         1, path.lastIndexOf(StringPool.SLASH));
714 
715                     portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
716                         companyId, strutsPath);
717                 }
718 
719                 if ((portlet != null) && portlet.isActive()) {
720                     defineObjects(request, response, portlet);
721                 }
722             }
723             catch (Exception e) {
724                 request.setAttribute(PageContext.EXCEPTION, e);
725 
726                 path = _PATH_COMMON_ERROR;
727             }
728         }
729 
730         // Authenticated users must have access to at least one layout
731 
732         if (SessionErrors.contains(
733                 request, LayoutPermissionException.class.getName())) {
734 
735             return _PATH_PORTAL_ERROR;
736         }
737 
738         return path;
739     }
740 
741     protected boolean processRoles(
742             HttpServletRequest request, HttpServletResponse response,
743             ActionMapping mapping)
744         throws IOException, ServletException {
745 
746         String path = mapping.getPath();
747 
748         if (isPublicPath(path)) {
749             return true;
750         }
751 
752         boolean authorized = true;
753 
754         User user = null;
755 
756         try {
757             user = PortalUtil.getUser(request);
758         }
759         catch (Exception e) {
760         }
761 
762         if ((user != null) && isPortletPath(path)) {
763             try {
764 
765                 // Authenticated users can always log out
766 
767                 if (path.equals(_PATH_PORTAL_LOGOUT)) {
768                     return true;
769                 }
770 
771                 Portlet portlet = null;
772 
773                 String portletId = ParamUtil.getString(request, "p_p_id");
774 
775                 if (Validator.isNotNull(portletId)) {
776                     portlet = PortletLocalServiceUtil.getPortletById(
777                         user.getCompanyId(), portletId);
778                 }
779 
780                 String strutsPath = path.substring(
781                     1, path.lastIndexOf(StringPool.SLASH));
782 
783                 if (portlet != null) {
784                     if (!strutsPath.equals(portlet.getStrutsPath())) {
785                         throw new PrincipalException();
786                     }
787                 }
788                 else {
789                     portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
790                         user.getCompanyId(), strutsPath);
791                 }
792 
793                 if ((portlet != null) && portlet.isActive()) {
794                     ThemeDisplay themeDisplay =
795                         (ThemeDisplay)request.getAttribute(
796                             WebKeys.THEME_DISPLAY);
797 
798                     Layout layout = themeDisplay.getLayout();
799                     PermissionChecker permissionChecker =
800                         themeDisplay.getPermissionChecker();
801 
802                     if (!PortletPermissionUtil.contains(
803                             permissionChecker, layout.getPlid(), portlet,
804                             ActionKeys.VIEW)) {
805 
806                         throw new PrincipalException();
807                     }
808                 }
809                 else if (portlet != null && !portlet.isActive()) {
810                     SessionErrors.add(
811                         request, PortletActiveException.class.getName());
812 
813                     authorized = false;
814                 }
815             }
816             catch (Exception e) {
817                 SessionErrors.add(request, PrincipalException.class.getName());
818 
819                 authorized = false;
820             }
821         }
822 
823         if (!authorized) {
824             ForwardConfig forwardConfig =
825                 mapping.findForward(_PATH_PORTAL_ERROR);
826 
827             processForwardConfig(request, response, forwardConfig);
828 
829             return false;
830         }
831         else {
832             return true;
833         }
834     }
835 
836     private static String _PATH_C = "/c";
837 
838     private static String _PATH_COMMON = "/common";
839 
840     private static String _PATH_COMMON_ERROR = "/common/error";
841 
842     private static String _PATH_J_SECURITY_CHECK = "/j_security_check";
843 
844     private static String _PATH_PORTAL = "/portal";
845 
846     private static String _PATH_PORTAL_CHANGE_PASSWORD =
847         "/portal/change_password";
848 
849     private static String _PATH_PORTAL_ERROR = "/portal/error";
850 
851     private static String _PATH_PORTAL_EXPIRE_SESSION =
852         "/portal/expire_session";
853 
854     private static String _PATH_PORTAL_EXTEND_SESSION =
855         "/portal/extend_session";
856 
857     private static String _PATH_PORTAL_FLASH = "/portal/flash";
858 
859     private static String _PATH_PORTAL_J_LOGIN = "/portal/j_login";
860 
861     private static String _PATH_PORTAL_LAYOUT = "/portal/layout";
862 
863     private static String _PATH_PORTAL_LOGIN = "/portal/login";
864 
865     private static String _PATH_PORTAL_LOGIN_CAPTCHA = "/portal/login_captcha";
866 
867     private static String _PATH_PORTAL_LOGOUT = "/portal/logout";
868 
869     private static String _PATH_PORTAL_PROTECTED = "/portal/protected";
870 
871     private static String _PATH_PORTAL_RENDER_PORTLET =
872         "/portal/render_portlet";
873 
874     private static String _PATH_PORTAL_TCK = "/portal/tck";
875 
876     private static String _PATH_PORTAL_TERMS_OF_USE = "/portal/terms_of_use";
877 
878     private static String _PATH_PORTAL_UPDATE_TERMS_OF_USE =
879         "/portal/update_terms_of_use";
880 
881     private static String _PATH_WSRP = "/wsrp";
882 
883     private static Log _log =
884         LogFactoryUtil.getLog(PortalRequestProcessor.class);
885 
886     private Set<String> _lastPaths;
887     private Set<String> _publicPaths;
888     private Set<String> _trackerIgnorePaths;
889 
890 }