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