1
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.portlet.LiferayWindowState;
31 import com.liferay.portal.kernel.security.permission.ActionKeys;
32 import com.liferay.portal.kernel.security.permission.PermissionChecker;
33 import com.liferay.portal.kernel.util.GetterUtil;
34 import com.liferay.portal.kernel.util.JavaConstants;
35 import com.liferay.portal.kernel.util.ParamUtil;
36 import com.liferay.portal.kernel.util.StringMaker;
37 import com.liferay.portal.kernel.util.StringPool;
38 import com.liferay.portal.kernel.util.Validator;
39 import com.liferay.portal.model.Layout;
40 import com.liferay.portal.model.Portlet;
41 import com.liferay.portal.model.PortletPreferencesIds;
42 import com.liferay.portal.model.User;
43 import com.liferay.portal.model.UserTracker;
44 import com.liferay.portal.model.UserTrackerPath;
45 import com.liferay.portal.model.impl.LayoutImpl;
46 import com.liferay.portal.security.auth.PrincipalException;
47 import com.liferay.portal.service.PortletLocalServiceUtil;
48 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
49 import com.liferay.portal.service.permission.PortletPermissionUtil;
50 import com.liferay.portal.service.persistence.UserTrackerPathUtil;
51 import com.liferay.portal.theme.ThemeDisplay;
52 import com.liferay.portal.util.LiveUsers;
53 import com.liferay.portal.util.PortalUtil;
54 import com.liferay.portal.util.PropsUtil;
55 import com.liferay.portal.util.WebKeys;
56 import com.liferay.portlet.CachePortlet;
57 import com.liferay.portlet.PortletConfigFactory;
58 import com.liferay.portlet.PortletInstanceFactory;
59 import com.liferay.portlet.PortletPreferencesFactoryUtil;
60 import com.liferay.portlet.RenderRequestFactory;
61 import com.liferay.portlet.RenderRequestImpl;
62 import com.liferay.portlet.RenderResponseFactory;
63 import com.liferay.portlet.RenderResponseImpl;
64 import com.liferay.util.CollectionFactory;
65 import com.liferay.util.HttpUtil;
66 import com.liferay.util.servlet.SessionErrors;
67
68 import java.io.IOException;
69
70 import java.util.Date;
71 import java.util.List;
72 import java.util.Map;
73 import java.util.Set;
74
75 import javax.portlet.PortletConfig;
76 import javax.portlet.PortletContext;
77 import javax.portlet.PortletMode;
78 import javax.portlet.PortletPreferences;
79 import javax.portlet.WindowState;
80
81 import javax.servlet.ServletContext;
82 import javax.servlet.ServletException;
83 import javax.servlet.http.HttpServletRequest;
84 import javax.servlet.http.HttpServletResponse;
85 import javax.servlet.http.HttpSession;
86 import javax.servlet.jsp.PageContext;
87
88 import org.apache.commons.logging.Log;
89 import org.apache.commons.logging.LogFactory;
90 import org.apache.struts.action.ActionMapping;
91 import org.apache.struts.config.ForwardConfig;
92 import org.apache.struts.tiles.TilesRequestProcessor;
93
94
101 public class PortalRequestProcessor extends TilesRequestProcessor {
102
103 public PortalRequestProcessor() {
104
105
107 _lastPaths = CollectionFactory.getHashSet();
108
109 _lastPaths.add(_PATH_PORTAL_LAYOUT);
110
111 _addPaths(_lastPaths, PropsUtil.AUTH_FORWARD_LAST_PATHS);
112
113
115 _publicPaths = CollectionFactory.getHashSet();
116
117 _publicPaths.add(_PATH_C);
118 _publicPaths.add(_PATH_PORTAL_CSS);
119 _publicPaths.add(_PATH_PORTAL_CSS_CACHED);
120 _publicPaths.add(_PATH_PORTAL_FLASH);
121 _publicPaths.add(_PATH_PORTAL_J_LOGIN);
122 _publicPaths.add(_PATH_PORTAL_JAVASCRIPT);
123 _publicPaths.add(_PATH_PORTAL_JAVASCRIPT_CACHED);
124 _publicPaths.add(_PATH_PORTAL_LAYOUT);
125 _publicPaths.add(_PATH_PORTAL_LOGIN);
126 _publicPaths.add(_PATH_PORTAL_LOGIN_CAPTCHA);
127 _publicPaths.add(_PATH_PORTAL_RENDER_PORTLET);
128 _publicPaths.add(_PATH_PORTAL_TCK);
129
130 _addPaths(_publicPaths, PropsUtil.AUTH_PUBLIC_PATHS);
131
132 _trackerIgnorePaths = CollectionFactory.getHashSet();
133
134 _addPaths(_trackerIgnorePaths, PropsUtil.SESSION_TRACKER_IGNORE_PATHS);
135 }
136
137 public void process(HttpServletRequest req, HttpServletResponse res)
138 throws IOException, ServletException {
139
140 String path = super.processPath(req, res);
141
142 ActionMapping mapping =
143 (ActionMapping)moduleConfig.findActionConfig(path);
144
145 if ((mapping == null) && !path.startsWith(_PATH_WSRP)) {
146 String lastPath = getLastPath(req);
147
148 if (_log.isDebugEnabled()) {
149 _log.debug("Last path " + lastPath);
150 }
151
152 res.sendRedirect(lastPath);
153
154 return;
155 }
156
157 super.process(req, res);
158
159 try {
160 if (isPortletPath(path)) {
161 cleanUp(req);
162 }
163 }
164 catch (Exception e) {
165 _log.error(e, e);
166 }
167 }
168
169 protected void callParentDoForward(
170 String uri, HttpServletRequest req, HttpServletResponse res)
171 throws IOException, ServletException {
172
173 super.doForward(uri, req, res);
174 }
175
176 protected void doForward(
177 String uri, HttpServletRequest req, HttpServletResponse res)
178 throws IOException, ServletException {
179
180 StrutsUtil.forward(uri, getServletContext(), req, res);
181 }
182
183 protected void doInclude(
184 String uri, HttpServletRequest req, HttpServletResponse res)
185 throws IOException, ServletException {
186
187 StrutsUtil.include(uri, getServletContext(), req, res);
188 }
189
190 protected HttpServletRequest callParentProcessMultipart(
191 HttpServletRequest req) {
192
193 return super.processMultipart(req);
194 }
195
196 protected HttpServletRequest processMultipart(HttpServletRequest req) {
197
198
200 return req;
201 }
202
203 protected String callParentProcessPath(
204 HttpServletRequest req, HttpServletResponse res)
205 throws IOException {
206
207 return super.processPath(req, res);
208 }
209
210 protected String processPath(
211 HttpServletRequest req, HttpServletResponse res)
212 throws IOException {
213
214 String path = super.processPath(req, res);
215
216 HttpSession ses = req.getSession();
217
218 ThemeDisplay themeDisplay =
219 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
220
221
223 UserTracker userTracker = LiveUsers.getUserTracker(ses.getId());
224
225 if ((userTracker != null) && (path != null) &&
226 (!path.equals(_PATH_C)) &&
227 (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
228 (path.indexOf(_PATH_PORTAL_PROTECTED) == -1) &&
229 (!_trackerIgnorePaths.contains(path))) {
230
231 StringMaker fullPathSM = new StringMaker();
232
233 fullPathSM.append(path);
234 fullPathSM.append(StringPool.QUESTION);
235 fullPathSM.append(req.getQueryString());
236
237 UserTrackerPath userTrackerPath = UserTrackerPathUtil.create(0);
238
239 userTrackerPath.setUserTrackerId(userTracker.getUserTrackerId());
240 userTrackerPath.setPath(fullPathSM.toString());
241 userTrackerPath.setPathDate(new Date());
242
243 userTracker.addPath(userTrackerPath);
244 }
245
246 String remoteUser = req.getRemoteUser();
247
248 User user = null;
249
250 try {
251 user = PortalUtil.getUser(req);
252 }
253 catch (Exception e) {
254 }
255
256
258 if ((path != null) && (_lastPaths.contains(path)) &&
259 (!_trackerIgnorePaths.contains(path))) {
260
261 boolean saveLastPath = ParamUtil.getBoolean(
262 req, "save_last_path", true);
263
264
267 if (LiferayWindowState.isExclusive(req) ||
268 LiferayWindowState.isPopUp(req)) {
269
270 saveLastPath = false;
271 }
272
273
275 if (saveLastPath) {
276
277
280 LastPath lastPath =
281 (LastPath)req.getAttribute(WebKeys.LAST_PATH);
282
283 if (lastPath == null) {
284 lastPath = new LastPath(
285 themeDisplay.getPathMain(), path,
286 req.getParameterMap());
287 }
288
289 ses.setAttribute(WebKeys.LAST_PATH, lastPath);
290 }
291 }
292
293
295 if ((remoteUser != null || user != null) && (path != null) &&
296 (path.equals(_PATH_PORTAL_LOGOUT))) {
297
298 return _PATH_PORTAL_LOGOUT;
299 }
300
301
303 if ((remoteUser != null || user != null) && (path != null) &&
304 (path.equals(_PATH_PORTAL_CSS) ||
305 path.equals(_PATH_PORTAL_CSS_CACHED) ||
306 path.equals(_PATH_PORTAL_JAVASCRIPT) ||
307 path.equals(_PATH_PORTAL_JAVASCRIPT_CACHED))) {
308
309 return path;
310 }
311
312
314 if ((remoteUser != null || user != null) && (path != null) &&
315 (path.equals(_PATH_PORTAL_UPDATE_TERMS_OF_USE))) {
316
317 return _PATH_PORTAL_UPDATE_TERMS_OF_USE;
318 }
319
320
322 if ((remoteUser != null) && (user == null)) {
323 return _PATH_PORTAL_LOGOUT;
324 }
325
326
328 if ((user != null) && (!user.isAgreedToTermsOfUse())) {
329 boolean termsOfUseRequired = GetterUtil.getBoolean(
330 PropsUtil.get(PropsUtil.TERMS_OF_USE_REQUIRED), true);
331
332 if (termsOfUseRequired) {
333 return _PATH_PORTAL_TERMS_OF_USE;
334 }
335 }
336
337
339 if ((user != null) && (!user.isActive())) {
340 SessionErrors.add(req, UserActiveException.class.getName());
341
342 return _PATH_PORTAL_ERROR;
343 }
344
345
347 boolean simultaenousLogins = GetterUtil.getBoolean(
348 PropsUtil.get(PropsUtil.AUTH_SIMULTANEOUS_LOGINS), true);
349
350 if (!simultaenousLogins) {
351 Boolean staleSession =
352 (Boolean)ses.getAttribute(WebKeys.STALE_SESSION);
353
354 if ((user != null) && (staleSession != null) &&
355 (staleSession.booleanValue())) {
356
357 return _PATH_PORTAL_ERROR;
358 }
359 }
360
361
363 if ((user != null) && (user.isPasswordReset())) {
364 return _PATH_PORTAL_CHANGE_PASSWORD;
365 }
366
367
369 if (user != null) {
370 List layouts = themeDisplay.getLayouts();
371
372 if ((layouts == null) || (layouts.size() == 0)) {
373 SessionErrors.add(
374 req, RequiredLayoutException.class.getName());
375
376 return _PATH_PORTAL_ERROR;
377 }
378 }
379
380
382 if (!isPublicPath(path)) {
383 if (user == null) {
384 SessionErrors.add(req, PrincipalException.class.getName());
385
386 return _PATH_PORTAL_LOGIN;
387 }
388 }
389
390 ActionMapping mapping =
391 (ActionMapping)moduleConfig.findActionConfig(path);
392
393 if (path.startsWith(_PATH_WSRP)) {
394 path = _PATH_WSRP;
395 }
396 else {
397 path = mapping.getPath();
398 }
399
400
402 if (user != null) {
403 try {
404
405
407 if (false) {
408 SessionErrors.add(
409 req, RequiredRoleException.class.getName());
410
411 return _PATH_PORTAL_ERROR;
412 }
413 }
414 catch (Exception e) {
415 e.printStackTrace();
416 }
417 }
418
419
421 if (isPortletPath(path)) {
422 try {
423 Portlet portlet = null;
424
425 long companyId = PortalUtil.getCompanyId(req);
426 String portletId = ParamUtil.getString(req, "p_p_id");
427
428 if (Validator.isNotNull(portletId)) {
429 portlet = PortletLocalServiceUtil.getPortletById(
430 companyId, portletId);
431 }
432
433 if (portlet == null) {
434 String strutsPath = path.substring(
435 1, path.lastIndexOf(StringPool.SLASH));
436
437 portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
438 companyId, strutsPath);
439 }
440
441 if (portlet != null && portlet.isActive()) {
442 defineObjects(req, res, portlet);
443 }
444 }
445 catch (Exception e) {
446 req.setAttribute(PageContext.EXCEPTION, e);
447
448 path = _PATH_COMMON_ERROR;
449 }
450 }
451
452
454 if (SessionErrors.contains(
455 req, LayoutPermissionException.class.getName())) {
456
457 return _PATH_PORTAL_ERROR;
458 }
459
460 return path;
461 }
462
463 protected boolean callParentProcessRoles(
464 HttpServletRequest req, HttpServletResponse res,
465 ActionMapping mapping)
466 throws IOException, ServletException {
467
468 return super.processRoles(req, res, mapping);
469 }
470
471 protected boolean processRoles(
472 HttpServletRequest req, HttpServletResponse res,
473 ActionMapping mapping)
474 throws IOException, ServletException {
475
476 String path = mapping.getPath();
477
478 if (isPublicPath(path)) {
479 return true;
480 }
481
482 boolean authorized = true;
483
484 User user = null;
485
486 try {
487 user = PortalUtil.getUser(req);
488 }
489 catch (Exception e) {
490 }
491
492 if ((user != null) && isPortletPath(path)) {
493 try {
494
495
497 if (path.equals(_PATH_PORTAL_LOGOUT)) {
498 return true;
499 }
500
501 Portlet portlet = null;
502
503 String portletId = ParamUtil.getString(req, "p_p_id");
504
505 if (Validator.isNotNull(portletId)) {
506 portlet = PortletLocalServiceUtil.getPortletById(
507 user.getCompanyId(), portletId);
508 }
509
510 String strutsPath = path.substring(
511 1, path.lastIndexOf(StringPool.SLASH));
512
513 if (portlet != null) {
514 if (!strutsPath.equals(portlet.getStrutsPath())) {
515 throw new PrincipalException();
516 }
517 }
518 else {
519 portlet = PortletLocalServiceUtil.getPortletByStrutsPath(
520 user.getCompanyId(), strutsPath);
521 }
522
523 if ((portlet != null) && portlet.isActive()) {
524 ThemeDisplay themeDisplay =
525 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
526
527 Layout layout = themeDisplay.getLayout();
528 PermissionChecker permissionChecker =
529 themeDisplay.getPermissionChecker();
530
531 if (!PortletPermissionUtil.contains(
532 permissionChecker, layout.getPlid(), portlet,
533 ActionKeys.VIEW)) {
534
535 throw new PrincipalException();
536 }
537 }
538 else if (portlet != null && !portlet.isActive()) {
539 SessionErrors.add(
540 req, PortletActiveException.class.getName());
541
542 authorized = false;
543 }
544 }
545 catch (Exception e) {
546 SessionErrors.add(req, PrincipalException.class.getName());
547
548 authorized = false;
549 }
550 }
551
552 if (!authorized) {
553 ForwardConfig forwardConfig =
554 mapping.findForward(_PATH_PORTAL_ERROR);
555
556 processForwardConfig(req, res, forwardConfig);
557
558 return false;
559 }
560 else {
561 return true;
562 }
563 }
564
565 protected String getLastPath(HttpServletRequest req) {
566 HttpSession ses = req.getSession();
567
568 ThemeDisplay themeDisplay =
569 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
570
571 boolean requiresHttps = GetterUtil.getBoolean(
572 PropsUtil.get(PropsUtil.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS));
573
574 Boolean httpsInitial = (Boolean)ses.getAttribute(WebKeys.HTTPS_INITIAL);
575
576 String portalURL = null;
577
578 if ((requiresHttps) && (httpsInitial != null) &&
579 (!httpsInitial.booleanValue())) {
580
581 portalURL = PortalUtil.getPortalURL(req, false);
582 }
583 else {
584 portalURL = PortalUtil.getPortalURL(req);
585 }
586
587 StringMaker defaultPathSM = new StringMaker();
588
589 defaultPathSM.append(portalURL);
590 defaultPathSM.append(themeDisplay.getPathMain());
591 defaultPathSM.append(_PATH_PORTAL_LAYOUT);
592
593 boolean forwardByLastPath = GetterUtil.getBoolean(
594 PropsUtil.get(PropsUtil.AUTH_FORWARD_BY_LAST_PATH), true);
595
596 if (!forwardByLastPath) {
597 if (req.getRemoteUser() != null) {
598
599
603 defaultPathSM.append(StringPool.QUESTION);
604 defaultPathSM.append("p_l_id");
605 defaultPathSM.append(StringPool.EQUAL);
606 defaultPathSM.append(LayoutImpl.DEFAULT_PLID);
607 }
608
609 return defaultPathSM.toString();
610 }
611
612 LastPath lastPath = (LastPath)ses.getAttribute(WebKeys.LAST_PATH);
613
614 if (lastPath == null) {
615 return defaultPathSM.toString();
616 }
617
618 Map parameterMap = lastPath.getParameterMap();
619
620
623 if (lastPath.getContextPath().equals(themeDisplay.getPathMain())) {
624 ActionMapping mapping =
625 (ActionMapping)moduleConfig.findActionConfig(
626 lastPath.getPath());
627
628 if ((mapping == null) || (parameterMap == null)) {
629 return defaultPathSM.toString();
630 }
631 }
632
633 StringMaker lastPathSM = new StringMaker();
634
635 lastPathSM.append(portalURL);
636 lastPathSM.append(lastPath.getContextPath());
637 lastPathSM.append(lastPath.getPath());
638 lastPathSM.append(HttpUtil.parameterMapToString(parameterMap));
639
640 return lastPathSM.toString();
641 }
642
643 protected boolean isPortletPath(String path) {
644 if ((path != null) &&
645 (!path.equals(_PATH_C)) &&
646 (!path.startsWith(_PATH_COMMON)) &&
647 (path.indexOf(_PATH_J_SECURITY_CHECK) == -1) &&
648 (!path.startsWith(_PATH_PORTAL)) &&
649 (!path.startsWith(_PATH_WSRP))) {
650
651 return true;
652 }
653 else {
654 return false;
655 }
656 }
657
658 protected boolean isPublicPath(String path) {
659 if ((path != null) &&
660 (_publicPaths.contains(path)) ||
661 (path.startsWith(_PATH_COMMON)) ||
662 (path.startsWith(_PATH_WSRP))) {
663
664 return true;
665 }
666 else {
667 return false;
668 }
669 }
670
671 protected void defineObjects(
672 HttpServletRequest req, HttpServletResponse res, Portlet portlet)
673 throws Exception {
674
675 String portletId = portlet.getPortletId();
676
677 ServletContext ctx =
678 (ServletContext)req.getAttribute(WebKeys.CTX);
679
680 CachePortlet cachePortlet = PortletInstanceFactory.create(portlet, ctx);
681
682 PortletPreferencesIds portletPreferencesIds =
683 PortletPreferencesFactoryUtil.getPortletPreferencesIds(
684 req, portletId);
685
686 PortletPreferences portletPreferences =
687 PortletPreferencesLocalServiceUtil.getPreferences(
688 portletPreferencesIds);
689
690 PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
691 PortletContext portletCtx =
692 portletConfig.getPortletContext();
693
694 RenderRequestImpl renderRequestImpl = RenderRequestFactory.create(
695 req, portlet, cachePortlet, portletCtx, WindowState.MAXIMIZED,
696 PortletMode.VIEW, portletPreferences);
697
698 RenderResponseImpl renderResponseImpl = RenderResponseFactory.create(
699 renderRequestImpl, res, portletId, portlet.getCompanyId());
700
701 renderRequestImpl.defineObjects(portletConfig, renderResponseImpl);
702
703 req.setAttribute(WebKeys.PORTLET_STRUTS_EXECUTE, Boolean.TRUE);
704 }
705
706 protected void cleanUp(HttpServletRequest req) throws Exception {
707
708
711 RenderRequestImpl renderRequestImpl =
712 (RenderRequestImpl)req.getAttribute(
713 JavaConstants.JAVAX_PORTLET_REQUEST);
714
715 if (renderRequestImpl != null) {
716 RenderRequestFactory.recycle(renderRequestImpl);
717 }
718
719 RenderResponseImpl renderResponseImpl =
720 (RenderResponseImpl)req.getAttribute(
721 JavaConstants.JAVAX_PORTLET_RESPONSE);
722
723 if (renderResponseImpl != null) {
724 RenderResponseFactory.recycle(renderResponseImpl);
725 }
726 }
727
728 private void _addPaths(Set paths, String propsKey) {
729 String[] pathsArray = PropsUtil.getArray(propsKey);
730
731 for (int i = 0; i < pathsArray.length; i++) {
732 paths.add(pathsArray[i]);
733 }
734 }
735
736 private static String _PATH_C = "/c";
737
738 private static String _PATH_COMMON = "/common";
739
740 private static String _PATH_COMMON_ERROR = "/common/error";
741
742 private static String _PATH_J_SECURITY_CHECK = "/j_security_check";
743
744 private static String _PATH_PORTAL = "/portal";
745
746 private static String _PATH_PORTAL_CHANGE_PASSWORD =
747 "/portal/change_password";
748
749 private static String _PATH_PORTAL_CSS = "/portal/css";
750
751 private static String _PATH_PORTAL_CSS_CACHED = "/portal/css_cached";
752
753 private static String _PATH_PORTAL_ERROR = "/portal/error";
754
755 private static String _PATH_PORTAL_FLASH = "/portal/flash";
756
757 private static String _PATH_PORTAL_J_LOGIN = "/portal/j_login";
758
759 private static String _PATH_PORTAL_JAVASCRIPT = "/portal/javascript";
760
761 private static String _PATH_PORTAL_JAVASCRIPT_CACHED =
762 "/portal/javascript_cached";
763
764 private static String _PATH_PORTAL_LAYOUT = "/portal/layout";
765
766 private static String _PATH_PORTAL_LOGIN = "/portal/login";
767
768 private static String _PATH_PORTAL_LOGIN_CAPTCHA = "/portal/login_captcha";
769
770 private static String _PATH_PORTAL_LOGOUT = "/portal/logout";
771
772 private static String _PATH_PORTAL_PROTECTED = "/portal/protected";
773
774 private static String _PATH_PORTAL_RENDER_PORTLET =
775 "/portal/render_portlet";
776
777 private static String _PATH_PORTAL_TCK = "/portal/tck";
778
779 private static String _PATH_PORTAL_TERMS_OF_USE = "/portal/terms_of_use";
780
781 private static String _PATH_PORTAL_UPDATE_TERMS_OF_USE =
782 "/portal/update_terms_of_use";
783
784 private static String _PATH_WSRP = "/wsrp";
785
786 private static Log _log = LogFactory.getLog(PortalRequestProcessor.class);
787
788 private Set _lastPaths;
789 private Set _publicPaths;
790 private Set _trackerIgnorePaths;
791
792 }