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.RequiredLayoutException;
28  import com.liferay.portal.RequiredRoleException;
29  import com.liferay.portal.UserActiveException;
30  import com.liferay.portal.kernel.log.Log;
31  import com.liferay.portal.kernel.log.LogFactoryUtil;
32  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
33  import com.liferay.portal.kernel.servlet.HttpMethods;
34  import com.liferay.portal.kernel.servlet.SessionErrors;
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.PortletInstanceFactoryUtil;
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.List;
78  import java.util.Map.Entry;
79  import java.util.Map;
80  import java.util.Set;
81  
82  import javax.portlet.PortletConfig;
83  import javax.portlet.PortletContext;
84  import javax.portlet.PortletMode;
85  import javax.portlet.PortletPreferences;
86  import javax.portlet.PortletRequest;
87  import javax.portlet.WindowState;
88  
89  import javax.servlet.ServletContext;
90  import javax.servlet.ServletException;
91  import javax.servlet.http.HttpServletRequest;
92  import javax.servlet.http.HttpServletResponse;
93  import javax.servlet.http.HttpSession;
94  import javax.servlet.jsp.PageContext;
95  
96  import org.apache.struts.action.ActionMapping;
97  import org.apache.struts.config.ForwardConfig;
98  import org.apache.struts.tiles.TilesRequestProcessor;
99  
100 /**
101  * <a href="PortalRequestProcessor.java.html"><b><i>View Source</i></b></a>
102  *
103  * @author Brian Wing Shun Chan
104  * @author Jorge Ferrer
105  *
106  */
107 public class PortalRequestProcessor extends TilesRequestProcessor {
108 
109     public PortalRequestProcessor() {
110 
111         // auth.forward.last.path.
112 
113         _lastPaths = new HashSet<String>();
114 
115         _lastPaths.add(_PATH_PORTAL_LAYOUT);
116 
117         addPaths(_lastPaths, PropsKeys.AUTH_FORWARD_LAST_PATHS);
118 
119         // auth.public.path.
120 
121         _publicPaths = new HashSet<String>();
122 
123         _publicPaths.add(_PATH_C);
124         _publicPaths.add(_PATH_PORTAL_FLASH);
125         _publicPaths.add(_PATH_PORTAL_J_LOGIN);
126         _publicPaths.add(_PATH_PORTAL_LAYOUT);
127         _publicPaths.add(_PATH_PORTAL_LOGIN);
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) {
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             renderRequestImpl.cleanUp();
219         }
220     }
221 
222     protected void defineObjects(
223             HttpServletRequest request, HttpServletResponse response,
224             Portlet portlet)
225         throws Exception {
226 
227         String portletId = portlet.getPortletId();
228 
229         ServletContext servletContext = (ServletContext)request.getAttribute(
230             WebKeys.CTX);
231 
232         InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
233             portlet, servletContext);
234 
235         PortletPreferencesIds portletPreferencesIds =
236             PortletPreferencesFactoryUtil.getPortletPreferencesIds(
237                 request, portletId);
238 
239         PortletPreferences portletPreferences =
240             PortletPreferencesLocalServiceUtil.getPreferences(
241                 portletPreferencesIds);
242 
243         PortletConfig portletConfig = PortletConfigFactory.create(
244             portlet, servletContext);
245         PortletContext portletContext = portletConfig.getPortletContext();
246 
247         RenderRequestImpl renderRequestImpl = RenderRequestFactory.create(
248             request, portlet, invokerPortlet, portletContext,
249             WindowState.MAXIMIZED, PortletMode.VIEW, portletPreferences);
250 
251         RenderResponseImpl renderResponseImpl = RenderResponseFactory.create(
252             renderRequestImpl, response, portletId, portlet.getCompanyId());
253 
254         renderRequestImpl.defineObjects(portletConfig, renderResponseImpl);
255 
256         request.setAttribute(WebKeys.PORTLET_STRUTS_EXECUTE, Boolean.TRUE);
257     }
258 
259     protected void doForward(
260             String uri, HttpServletRequest request,
261             HttpServletResponse response)
262         throws ServletException {
263 
264         StrutsUtil.forward(uri, getServletContext(), request, response);
265     }
266 
267     protected void doInclude(
268             String uri, HttpServletRequest request,
269             HttpServletResponse response)
270         throws ServletException {
271 
272         StrutsUtil.include(uri, getServletContext(), request, response);
273     }
274 
275     protected StringBuilder getFriendlyTrackerPath(
276             String path, ThemeDisplay themeDisplay, HttpServletRequest request)
277         throws Exception {
278 
279         if (!path.equals(_PATH_PORTAL_LAYOUT)) {
280             return null;
281         }
282 
283         long plid = ParamUtil.getLong(request, "p_l_id");
284 
285         if (plid == 0) {
286             return null;
287         }
288 
289         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
290 
291         String layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
292             layout, themeDisplay);
293 
294         StringBuilder sb = new StringBuilder();
295 
296         sb.append(layoutFriendlyURL);
297 
298         String portletId = ParamUtil.getString(request, "p_p_id");
299 
300         if (Validator.isNull(portletId)) {
301             return sb;
302         }
303 
304         long companyId = PortalUtil.getCompanyId(request);
305 
306         Portlet portlet = PortletLocalServiceUtil.getPortletById(
307             companyId, portletId);
308 
309         if (portlet == null) {
310             String strutsPath = path.substring(
311                 1, path.lastIndexOf(StringPool.SLASH));
312 
313             portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
314                 companyId, strutsPath);
315         }
316 
317         if ((portlet == null) || !portlet.isActive()) {
318             sb.append(StringPool.QUESTION);
319             sb.append(request.getQueryString());
320 
321             return sb;
322         }
323 
324         String namespace = PortalUtil.getPortletNamespace(portletId);
325 
326         FriendlyURLMapper friendlyURLMapper =
327             portlet.getFriendlyURLMapperInstance();
328 
329         if (friendlyURLMapper == null) {
330             sb.append(StringPool.QUESTION);
331             sb.append(request.getQueryString());
332 
333             return sb;
334         }
335 
336         PortletURLImpl portletURL = new PortletURLImpl(
337             request, portletId, plid, PortletRequest.RENDER_PHASE);
338 
339         Iterator<Map.Entry<String, String[]>> itr =
340             request.getParameterMap().entrySet().iterator();
341 
342         while (itr.hasNext()) {
343             Entry<String, String[]> entry = itr.next();
344 
345             String key = entry.getKey();
346 
347             if (key.startsWith(namespace)) {
348                 key = key.substring(namespace.length());
349 
350                 portletURL.setParameter(key, entry.getValue());
351             }
352         }
353 
354         String portletFriendlyURL = friendlyURLMapper.buildPath(portletURL);
355 
356         if (portletFriendlyURL != null) {
357             sb.append(portletFriendlyURL);
358         }
359         else {
360             sb.append(StringPool.QUESTION);
361             sb.append(request.getQueryString());
362         }
363 
364         return sb;
365     }
366 
367     protected String getLastPath(HttpServletRequest request) {
368         HttpSession session = request.getSession();
369 
370         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
371             WebKeys.THEME_DISPLAY);
372 
373         Boolean httpsInitial = (Boolean)session.getAttribute(
374             WebKeys.HTTPS_INITIAL);
375 
376         String portalURL = null;
377 
378         if ((PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS) &&
379             (httpsInitial != null) && (!httpsInitial.booleanValue())) {
380 
381             portalURL = PortalUtil.getPortalURL(request, false);
382         }
383         else {
384             portalURL = PortalUtil.getPortalURL(request);
385         }
386 
387         StringBuilder sb = new StringBuilder();
388 
389         sb.append(portalURL);
390         sb.append(themeDisplay.getPathMain());
391         sb.append(_PATH_PORTAL_LAYOUT);
392 
393         if (!PropsValues.AUTH_FORWARD_BY_LAST_PATH) {
394             if (request.getRemoteUser() != null) {
395 
396                 // If we do not forward by last path and the user is logged in,
397                 // forward to the user's default layout to prevent a lagging
398                 // loop
399 
400                 sb.append(StringPool.QUESTION);
401                 sb.append("p_l_id");
402                 sb.append(StringPool.EQUAL);
403                 sb.append(LayoutConstants.DEFAULT_PLID);
404             }
405 
406             return sb.toString();
407         }
408 
409         LastPath lastPath = (LastPath)session.getAttribute(WebKeys.LAST_PATH);
410 
411         if (lastPath == null) {
412             return sb.toString();
413         }
414 
415         Map<String, String[]> parameterMap = lastPath.getParameterMap();
416 
417         // Only test for existing mappings for last paths that were set when the
418         // user accessed a layout directly instead of through its friendly URL
419 
420         if (lastPath.getContextPath().equals(themeDisplay.getPathMain())) {
421             ActionMapping mapping =
422                 (ActionMapping)moduleConfig.findActionConfig(
423                     lastPath.getPath());
424 
425             if ((mapping == null) || (parameterMap == null)) {
426                 return sb.toString();
427             }
428         }
429 
430         StringBuilder lastPathSB = new StringBuilder();
431 
432         lastPathSB.append(portalURL);
433         lastPathSB.append(lastPath.getContextPath());
434         lastPathSB.append(lastPath.getPath());
435         lastPathSB.append(HttpUtil.parameterMapToString(parameterMap));
436 
437         return lastPathSB.toString();
438     }
439 
440     protected boolean isPortletPath(String path) {
441         if ((path != null) &&
442             (!path.equals(_PATH_C)) &&
443             (!path.startsWith(_PATH_COMMON)) &&
444             (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
445             (!path.startsWith(_PATH_PORTAL))) {
446 
447             return true;
448         }
449         else {
450             return false;
451         }
452     }
453 
454     protected boolean isPublicPath(String path) {
455         if ((path != null) &&
456             (_publicPaths.contains(path)) ||
457             (path.startsWith(_PATH_COMMON))) {
458 
459             return true;
460         }
461         else {
462             return false;
463         }
464     }
465 
466     protected ActionMapping processMapping(
467             HttpServletRequest request, HttpServletResponse response,
468             String path)
469         throws IOException {
470 
471         if (path == null) {
472             return null;
473         }
474 
475         ActionMapping mapping = super.processMapping(request, response, path);
476 
477         if (mapping == null) {
478             String msg = getInternal().getMessage("processInvalid");
479 
480             _log.error("User ID " + request.getRemoteUser());
481             _log.error("Current URL " + PortalUtil.getCurrentURL(request));
482             _log.error("Referer " + request.getHeader("Referer"));
483             _log.error("Remote address " + request.getRemoteAddr());
484 
485             _log.error(msg + " " + path);
486         }
487 
488         return mapping;
489     }
490 
491     protected HttpServletRequest processMultipart(HttpServletRequest request) {
492 
493         // Disable Struts from automatically wrapping a multipart request
494 
495         return request;
496     }
497 
498     protected String processPath(
499             HttpServletRequest request, HttpServletResponse response)
500         throws IOException {
501 
502         String path = super.processPath(request, response);
503 
504         HttpSession session = request.getSession();
505 
506         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
507             WebKeys.THEME_DISPLAY);
508 
509         // Current users
510 
511         UserTracker userTracker = LiveUsers.getUserTracker(
512             themeDisplay.getCompanyId(), session.getId());
513 
514         if ((userTracker != null) && (path != null) &&
515             (!path.equals(_PATH_C)) &&
516             (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
517             (path.indexOf(_PATH_PORTAL_PROTECTED) == -1) &&
518             (!_trackerIgnorePaths.contains(path))) {
519 
520             StringBuilder sb = null;
521 
522             try {
523                 if (PropsValues.SESSION_TRACKER_FRIENDLY_PATHS_ENABLED) {
524                     sb = getFriendlyTrackerPath(path, themeDisplay, request);
525                 }
526             }
527             catch (Exception e) {
528                 _log.error(e, e);
529             }
530 
531             if (sb == null) {
532                 sb = new StringBuilder();
533 
534                 sb.append(path);
535                 sb.append(StringPool.QUESTION);
536                 sb.append(request.getQueryString());
537             }
538 
539             UserTrackerPath userTrackerPath = UserTrackerPathUtil.create(0);
540 
541             userTrackerPath.setUserTrackerId(userTracker.getUserTrackerId());
542             userTrackerPath.setPath(sb.toString());
543             userTrackerPath.setPathDate(new Date());
544 
545             userTracker.addPath(userTrackerPath);
546         }
547 
548         String remoteUser = request.getRemoteUser();
549 
550         User user = null;
551 
552         try {
553             user = PortalUtil.getUser(request);
554         }
555         catch (Exception e) {
556         }
557 
558         // Last path
559 
560         if ((path != null) && (_lastPaths.contains(path)) &&
561             (!_trackerIgnorePaths.contains(path))) {
562 
563             boolean saveLastPath = ParamUtil.getBoolean(
564                 request, "saveLastPath", true);
565 
566             if (themeDisplay.isLifecycleResource() ||
567                 themeDisplay.isStateExclusive() ||
568                 themeDisplay.isStatePopUp() ||
569                 !request.getMethod().equalsIgnoreCase(HttpMethods.GET)) {
570 
571                 saveLastPath = false;
572             }
573 
574             // Save last path
575 
576             if (saveLastPath) {
577 
578                 // Was a last path set by another servlet that dispatched to
579                 // the MainServlet? If so, use that last path instead.
580 
581                 LastPath lastPath = (LastPath)request.getAttribute(
582                     WebKeys.LAST_PATH);
583 
584                 if (lastPath == null) {
585                     lastPath = new LastPath(
586                         themeDisplay.getPathMain(), path,
587                         request.getParameterMap());
588                 }
589 
590                 session.setAttribute(WebKeys.LAST_PATH, lastPath);
591             }
592         }
593 
594         // Authenticated users can always log out
595 
596         if (((remoteUser != null) || (user != null)) && (path != null) &&
597             (path.equals(_PATH_PORTAL_LOGOUT))) {
598 
599             return path;
600         }
601 
602         // Authenticated users can always extend or confirm their session
603 
604         if (((remoteUser != null) || (user != null)) && (path != null) &&
605             (path.equals(_PATH_PORTAL_EXPIRE_SESSION) ||
606              path.equals(_PATH_PORTAL_EXTEND_SESSION))) {
607 
608             return path;
609         }
610 
611         // Authenticated users can always agree to terms of use
612 
613         if (((remoteUser != null) || (user != null)) && (path != null) &&
614             (path.equals(_PATH_PORTAL_UPDATE_TERMS_OF_USE))) {
615 
616             return path;
617         }
618 
619         // Authenticated users must still exist in the system
620 
621         if ((remoteUser != null) && (user == null)) {
622             return _PATH_PORTAL_LOGOUT;
623         }
624 
625         // Authenticated users should agree to Terms of Use
626 
627         if ((user != null) && !user.isAgreedToTermsOfUse()) {
628             if (PropsValues.TERMS_OF_USE_REQUIRED) {
629                 return _PATH_PORTAL_TERMS_OF_USE;
630             }
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         // Authenticated users must have a current password
642 
643         if ((user != null) && user.isPasswordReset()) {
644             return _PATH_PORTAL_UPDATE_PASSWORD;
645         }
646 
647         // Authenticated users must have an email address
648 
649         if ((user != null) && Validator.isNull(user.getEmailAddress())) {
650             return _PATH_PORTAL_UPDATE_EMAIL_ADDRESS;
651         }
652 
653         // Authenticated users should have a reminder query
654 
655         if ((user != null) &&
656             (Validator.isNull(user.getReminderQueryQuestion()) ||
657              Validator.isNull(user.getReminderQueryAnswer()))) {
658 
659             if (PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
660                 return _PATH_PORTAL_UPDATE_REMINDER_QUERY;
661             }
662         }
663 
664         // Authenticated users must have at least one personalized page
665 
666         if (user != null) {
667             List<Layout> layouts = themeDisplay.getLayouts();
668 
669             if ((layouts == null) || (layouts.size() == 0)) {
670                 SessionErrors.add(
671                     request, RequiredLayoutException.class.getName());
672 
673                 return _PATH_PORTAL_ERROR;
674             }
675         }
676 
677         // Users must sign in
678 
679         if (!isPublicPath(path)) {
680             if (user == null) {
681                 SessionErrors.add(request, PrincipalException.class.getName());
682 
683                 return _PATH_PORTAL_LOGIN;
684             }
685         }
686 
687         ActionMapping mapping =
688             (ActionMapping)moduleConfig.findActionConfig(path);
689 
690         path = mapping.getPath();
691 
692         // Authenticated users must have at least one role
693 
694         if (user != null) {
695             try {
696 
697                 // FIX ME
698 
699                 if (false) {
700                     SessionErrors.add(
701                         request, RequiredRoleException.class.getName());
702 
703                     return _PATH_PORTAL_ERROR;
704                 }
705             }
706             catch (Exception e) {
707                 e.printStackTrace();
708             }
709         }
710 
711         // Define the portlet objects
712 
713         if (isPortletPath(path)) {
714             try {
715                 Portlet portlet = null;
716 
717                 long companyId = PortalUtil.getCompanyId(request);
718                 String portletId = ParamUtil.getString(request, "p_p_id");
719 
720                 if (Validator.isNotNull(portletId)) {
721                     portlet = PortletLocalServiceUtil.getPortletById(
722                         companyId, portletId);
723                 }
724 
725                 if (portlet == null) {
726                     String strutsPath = path.substring(
727                         1, path.lastIndexOf(StringPool.SLASH));
728 
729                     portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
730                         companyId, strutsPath);
731                 }
732 
733                 if ((portlet != null) && portlet.isActive()) {
734                     defineObjects(request, response, portlet);
735                 }
736             }
737             catch (Exception e) {
738                 request.setAttribute(PageContext.EXCEPTION, e);
739 
740                 path = _PATH_COMMON_ERROR;
741             }
742         }
743 
744         // Authenticated users must have access to at least one layout
745 
746         if (SessionErrors.contains(
747                 request, LayoutPermissionException.class.getName())) {
748 
749             return _PATH_PORTAL_ERROR;
750         }
751 
752         return path;
753     }
754 
755     protected boolean processRoles(
756             HttpServletRequest request, HttpServletResponse response,
757             ActionMapping mapping)
758         throws IOException, ServletException {
759 
760         String path = mapping.getPath();
761 
762         if (isPublicPath(path)) {
763             return true;
764         }
765 
766         boolean authorized = true;
767 
768         User user = null;
769 
770         try {
771             user = PortalUtil.getUser(request);
772         }
773         catch (Exception e) {
774         }
775 
776         if ((user != null) && isPortletPath(path)) {
777             try {
778 
779                 // Authenticated users can always log out
780 
781                 if (path.equals(_PATH_PORTAL_LOGOUT)) {
782                     return true;
783                 }
784 
785                 Portlet portlet = null;
786 
787                 String portletId = ParamUtil.getString(request, "p_p_id");
788 
789                 if (Validator.isNotNull(portletId)) {
790                     portlet = PortletLocalServiceUtil.getPortletById(
791                         user.getCompanyId(), portletId);
792                 }
793 
794                 String strutsPath = path.substring(
795                     1, path.lastIndexOf(StringPool.SLASH));
796 
797                 if (portlet != null) {
798                     if (!strutsPath.equals(portlet.getStrutsPath())) {
799                         throw new PrincipalException();
800                     }
801                 }
802                 else {
803                     portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
804                         user.getCompanyId(), strutsPath);
805                 }
806 
807                 if ((portlet != null) && portlet.isActive()) {
808                     ThemeDisplay themeDisplay =
809                         (ThemeDisplay)request.getAttribute(
810                             WebKeys.THEME_DISPLAY);
811 
812                     Layout layout = themeDisplay.getLayout();
813                     PermissionChecker permissionChecker =
814                         themeDisplay.getPermissionChecker();
815 
816                     if (!PortletPermissionUtil.contains(
817                             permissionChecker, layout.getPlid(), portlet,
818                             ActionKeys.VIEW)) {
819 
820                         throw new PrincipalException();
821                     }
822                 }
823                 else if (portlet != null && !portlet.isActive()) {
824                     SessionErrors.add(
825                         request, PortletActiveException.class.getName());
826 
827                     authorized = false;
828                 }
829             }
830             catch (Exception e) {
831                 SessionErrors.add(request, PrincipalException.class.getName());
832 
833                 authorized = false;
834             }
835         }
836 
837         if (!authorized) {
838             ForwardConfig forwardConfig =
839                 mapping.findForward(_PATH_PORTAL_ERROR);
840 
841             processForwardConfig(request, response, forwardConfig);
842 
843             return false;
844         }
845         else {
846             return true;
847         }
848     }
849 
850     private static String _PATH_C = "/c";
851 
852     private static String _PATH_COMMON = "/common";
853 
854     private static String _PATH_COMMON_ERROR = "/common/error";
855 
856     private static String _PATH_J_SECURITY_CHECK = "/j_security_check";
857 
858     private static String _PATH_PORTAL = "/portal";
859 
860     private static String _PATH_PORTAL_ERROR = "/portal/error";
861 
862     private static String _PATH_PORTAL_EXPIRE_SESSION =
863         "/portal/expire_session";
864 
865     private static String _PATH_PORTAL_EXTEND_SESSION =
866         "/portal/extend_session";
867 
868     private static String _PATH_PORTAL_FLASH = "/portal/flash";
869 
870     private static String _PATH_PORTAL_J_LOGIN = "/portal/j_login";
871 
872     private static String _PATH_PORTAL_LAYOUT = "/portal/layout";
873 
874     private static String _PATH_PORTAL_LOGIN = "/portal/login";
875 
876     private static String _PATH_PORTAL_LOGOUT = "/portal/logout";
877 
878     private static String _PATH_PORTAL_PROTECTED = "/portal/protected";
879 
880     private static String _PATH_PORTAL_RENDER_PORTLET =
881         "/portal/render_portlet";
882 
883     private static String _PATH_PORTAL_TCK = "/portal/tck";
884 
885     private static String _PATH_PORTAL_TERMS_OF_USE = "/portal/terms_of_use";
886 
887     private static String _PATH_PORTAL_UPDATE_EMAIL_ADDRESS =
888         "/portal/update_email_address";
889 
890     private static String _PATH_PORTAL_UPDATE_PASSWORD =
891         "/portal/update_password";
892 
893     private static String _PATH_PORTAL_UPDATE_REMINDER_QUERY =
894         "/portal/update_reminder_query";
895 
896     private static String _PATH_PORTAL_UPDATE_TERMS_OF_USE =
897         "/portal/update_terms_of_use";
898 
899     private static Log _log =
900          LogFactoryUtil.getLog(PortalRequestProcessor.class);
901 
902     private Set<String> _lastPaths;
903     private Set<String> _publicPaths;
904     private Set<String> _trackerIgnorePaths;
905 
906 }