001    /**
002     * Copyright (c) 2000-present 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.service.permission;
016    
017    import com.liferay.exportimport.kernel.staging.permission.StagingPermissionUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.model.Group;
022    import com.liferay.portal.kernel.model.Layout;
023    import com.liferay.portal.kernel.model.LayoutTypePortlet;
024    import com.liferay.portal.kernel.model.Portlet;
025    import com.liferay.portal.kernel.model.PortletConstants;
026    import com.liferay.portal.kernel.model.impl.VirtualLayout;
027    import com.liferay.portal.kernel.portlet.ControlPanelEntry;
028    import com.liferay.portal.kernel.security.auth.PrincipalException;
029    import com.liferay.portal.kernel.security.permission.ActionKeys;
030    import com.liferay.portal.kernel.security.permission.PermissionChecker;
031    import com.liferay.portal.kernel.security.permission.ResourceActionsUtil;
032    import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
033    import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
034    import com.liferay.portal.kernel.service.PortletLocalServiceUtil;
035    import com.liferay.portal.kernel.service.permission.GroupPermissionUtil;
036    import com.liferay.portal.kernel.service.permission.LayoutPermissionUtil;
037    import com.liferay.portal.kernel.service.permission.PortletPermission;
038    import com.liferay.portal.kernel.util.PortletCategoryKeys;
039    import com.liferay.portal.kernel.util.StringUtil;
040    import com.liferay.sites.kernel.util.SitesUtil;
041    
042    import java.util.Collection;
043    import java.util.List;
044    
045    import javax.portlet.PortletMode;
046    
047    /**
048     * @author Brian Wing Shun Chan
049     * @author Raymond Aug??
050     */
051    public class PortletPermissionImpl implements PortletPermission {
052    
053            @Override
054            public void check(
055                            PermissionChecker permissionChecker, Layout layout,
056                            String portletId, String actionId)
057                    throws PortalException {
058    
059                    if (!contains(
060                                    permissionChecker, 0, layout, portletId, actionId,
061                                    _STRICT_DEFAULT)) {
062    
063                            throw new PrincipalException.MustHavePermission(
064                                    permissionChecker, Portlet.class.getName(), portletId,
065                                    actionId);
066                    }
067            }
068    
069            @Override
070            public void check(
071                            PermissionChecker permissionChecker, Layout layout,
072                            String portletId, String actionId, boolean strict)
073                    throws PortalException {
074    
075                    if (!contains(
076                                    permissionChecker, 0, layout, portletId, actionId, strict)) {
077    
078                            throw new PrincipalException.MustHavePermission(
079                                    permissionChecker, Portlet.class.getName(), portletId,
080                                    actionId);
081                    }
082            }
083    
084            @Override
085            public void check(
086                            PermissionChecker permissionChecker, long groupId, Layout layout,
087                            String portletId, String actionId)
088                    throws PortalException {
089    
090                    if (!contains(
091                                    permissionChecker, groupId, layout, portletId, actionId,
092                                    _STRICT_DEFAULT)) {
093    
094                            throw new PrincipalException.MustHavePermission(
095                                    permissionChecker, Portlet.class.getName(), portletId,
096                                    actionId);
097                    }
098            }
099    
100            @Override
101            public void check(
102                            PermissionChecker permissionChecker, long groupId, Layout layout,
103                            String portletId, String actionId, boolean strict)
104                    throws PortalException {
105    
106                    check(
107                            permissionChecker, groupId, layout, portletId, actionId, strict,
108                            _CHECK_STAGING_PERMISSION_DEFAULT);
109            }
110    
111            @Override
112            public void check(
113                            PermissionChecker permissionChecker, long groupId, Layout layout,
114                            String portletId, String actionId, boolean strict,
115                            boolean checkStagingPermission)
116                    throws PortalException {
117    
118                    if (!contains(
119                                    permissionChecker, groupId, layout, portletId, actionId, strict,
120                                    checkStagingPermission)) {
121    
122                            throw new PrincipalException.MustHavePermission(
123                                    permissionChecker, Portlet.class.getName(), portletId,
124                                    actionId);
125                    }
126            }
127    
128            @Override
129            public void check(
130                            PermissionChecker permissionChecker, long groupId, long plid,
131                            String portletId, String actionId)
132                    throws PortalException {
133    
134                    check(
135                            permissionChecker, groupId, plid, portletId, actionId,
136                            _STRICT_DEFAULT);
137            }
138    
139            @Override
140            public void check(
141                            PermissionChecker permissionChecker, long groupId, long plid,
142                            String portletId, String actionId, boolean strict)
143                    throws PortalException {
144    
145                    if (!contains(
146                                    permissionChecker, groupId, plid, portletId, actionId,
147                                    strict)) {
148    
149                            throw new PrincipalException.MustHavePermission(
150                                    permissionChecker, Portlet.class.getName(), portletId,
151                                    actionId);
152                    }
153            }
154    
155            @Override
156            public void check(
157                            PermissionChecker permissionChecker, long plid, String portletId,
158                            String actionId)
159                    throws PortalException {
160    
161                    check(permissionChecker, plid, portletId, actionId, _STRICT_DEFAULT);
162            }
163    
164            @Override
165            public void check(
166                            PermissionChecker permissionChecker, long plid, String portletId,
167                            String actionId, boolean strict)
168                    throws PortalException {
169    
170                    if (!contains(permissionChecker, plid, portletId, actionId, strict)) {
171                            throw new PrincipalException.MustHavePermission(
172                                    permissionChecker, Portlet.class.getName(), portletId,
173                                    actionId);
174                    }
175            }
176    
177            @Override
178            public void check(
179                            PermissionChecker permissionChecker, String portletId,
180                            String actionId)
181                    throws PortalException {
182    
183                    if (!contains(permissionChecker, portletId, actionId)) {
184                            throw new PrincipalException.MustHavePermission(
185                                    permissionChecker, Portlet.class.getName(), portletId,
186                                    actionId);
187                    }
188            }
189    
190            @Override
191            public boolean contains(
192                            PermissionChecker permissionChecker, Layout layout, Portlet portlet,
193                            String actionId)
194                    throws PortalException {
195    
196                    return contains(
197                            permissionChecker, layout, portlet, actionId, _STRICT_DEFAULT);
198            }
199    
200            @Override
201            public boolean contains(
202                            PermissionChecker permissionChecker, Layout layout, Portlet portlet,
203                            String actionId, boolean strict)
204                    throws PortalException {
205    
206                    return contains(
207                            permissionChecker, 0, layout, portlet, actionId, strict);
208            }
209    
210            @Override
211            public boolean contains(
212                            PermissionChecker permissionChecker, Layout layout,
213                            String portletId, String actionId)
214                    throws PortalException {
215    
216                    return contains(
217                            permissionChecker, layout, portletId, actionId, _STRICT_DEFAULT);
218            }
219    
220            @Override
221            public boolean contains(
222                            PermissionChecker permissionChecker, Layout layout,
223                            String portletId, String actionId, boolean strict)
224                    throws PortalException {
225    
226                    return contains(
227                            permissionChecker, 0, layout, portletId, actionId, strict);
228            }
229    
230            @Override
231            public boolean contains(
232                            PermissionChecker permissionChecker, long groupId, Layout layout,
233                            Portlet portlet, String actionId)
234                    throws PortalException {
235    
236                    return contains(
237                            permissionChecker, groupId, layout, portlet, actionId,
238                            _STRICT_DEFAULT);
239            }
240    
241            @Override
242            public boolean contains(
243                            PermissionChecker permissionChecker, long groupId, Layout layout,
244                            Portlet portlet, String actionId, boolean strict)
245                    throws PortalException {
246    
247                    if (portlet.isUndeployedPortlet()) {
248                            return false;
249                    }
250    
251                    return contains(
252                            permissionChecker, groupId, layout, portlet.getPortletId(),
253                            actionId, strict);
254            }
255    
256            @Override
257            public boolean contains(
258                            PermissionChecker permissionChecker, long groupId, Layout layout,
259                            String portletId, String actionId)
260                    throws PortalException {
261    
262                    return contains(
263                            permissionChecker, groupId, layout, portletId, actionId,
264                            _STRICT_DEFAULT);
265            }
266    
267            @Override
268            public boolean contains(
269                            PermissionChecker permissionChecker, long groupId, Layout layout,
270                            String portletId, String actionId, boolean strict)
271                    throws PortalException {
272    
273                    return contains(
274                            permissionChecker, groupId, layout, portletId, actionId, strict,
275                            _CHECK_STAGING_PERMISSION_DEFAULT);
276            }
277    
278            @Override
279            public boolean contains(
280                            PermissionChecker permissionChecker, long groupId, Layout layout,
281                            String portletId, String actionId, boolean strict,
282                            boolean checkStagingPermission)
283                    throws PortalException {
284    
285                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
286                            permissionChecker.getCompanyId(), portletId);
287    
288                    if ((portlet == null) || portlet.isUndeployedPortlet()) {
289                            return false;
290                    }
291    
292                    String name = null;
293                    String resourcePermissionPrimKey = null;
294    
295                    if (layout == null) {
296                            name = portletId;
297                            resourcePermissionPrimKey = portletId;
298    
299                            return permissionChecker.hasPermission(
300                                    groupId, name, resourcePermissionPrimKey, actionId);
301                    }
302    
303                    Group group = GroupLocalServiceUtil.fetchGroup(groupId);
304    
305                    if (group == null) {
306                            group = layout.getGroup();
307    
308                            groupId = layout.getGroupId();
309                    }
310    
311                    if ((group.isControlPanel() || layout.isTypeControlPanel()) &&
312                            actionId.equals(ActionKeys.VIEW)) {
313    
314                            return true;
315                    }
316    
317                    if (layout instanceof VirtualLayout) {
318                            if (layout.isCustomizable() && !actionId.equals(ActionKeys.VIEW)) {
319                                    if (actionId.equals(ActionKeys.ADD_TO_PAGE)) {
320                                            return hasAddToPagePermission(
321                                                    permissionChecker, layout, portletId, actionId);
322                                    }
323    
324                                    return hasCustomizePermission(
325                                            permissionChecker, layout, portletId, actionId);
326                            }
327    
328                            VirtualLayout virtualLayout = (VirtualLayout)layout;
329    
330                            layout = virtualLayout.getSourceLayout();
331                    }
332    
333                    if (!group.isLayoutSetPrototype() &&
334                            actionId.equals(ActionKeys.CONFIGURATION) &&
335                            !SitesUtil.isLayoutUpdateable(layout)) {
336    
337                            return false;
338                    }
339    
340                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
341    
342                    if (checkStagingPermission) {
343                            Boolean hasPermission = StagingPermissionUtil.hasPermission(
344                                    permissionChecker, groupId, rootPortletId, groupId,
345                                    rootPortletId, actionId);
346    
347                            if (hasPermission != null) {
348                                    return hasPermission.booleanValue();
349                            }
350                    }
351    
352                    resourcePermissionPrimKey = getPrimaryKey(layout.getPlid(), portletId);
353    
354                    if (strict) {
355                            return permissionChecker.hasPermission(
356                                    groupId, rootPortletId, resourcePermissionPrimKey, actionId);
357                    }
358    
359                    if (hasConfigurePermission(
360                                    permissionChecker, layout, portletId, actionId) ||
361                            hasCustomizePermission(
362                                    permissionChecker, layout, portletId, actionId)) {
363    
364                            return true;
365                    }
366    
367                    return permissionChecker.hasPermission(
368                            groupId, rootPortletId, resourcePermissionPrimKey, actionId);
369            }
370    
371            public boolean contains(
372                            PermissionChecker permissionChecker, long groupId, long plid,
373                            Portlet portlet, String actionId)
374                    throws PortalException {
375    
376                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
377    
378                    return contains(
379                            permissionChecker, groupId, layout, portlet, actionId,
380                            _STRICT_DEFAULT);
381            }
382    
383            @Override
384            public boolean contains(
385                            PermissionChecker permissionChecker, long groupId, long plid,
386                            Portlet portlet, String actionId, boolean strict)
387                    throws PortalException {
388    
389                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
390    
391                    return contains(
392                            permissionChecker, groupId, layout, portlet, actionId, strict);
393            }
394    
395            public boolean contains(
396                            PermissionChecker permissionChecker, long groupId, long plid,
397                            String portletId, String actionId)
398                    throws PortalException {
399    
400                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
401    
402                    return contains(
403                            permissionChecker, groupId, layout, portletId, actionId,
404                            _STRICT_DEFAULT);
405            }
406    
407            @Override
408            public boolean contains(
409                            PermissionChecker permissionChecker, long groupId, long plid,
410                            String portletId, String actionId, boolean strict)
411                    throws PortalException {
412    
413                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
414    
415                    return contains(
416                            permissionChecker, groupId, layout, portletId, actionId, strict);
417            }
418    
419            @Override
420            public boolean contains(
421                            PermissionChecker permissionChecker, long plid, Portlet portlet,
422                            String actionId)
423                    throws PortalException {
424    
425                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
426    
427                    return contains(
428                            permissionChecker, layout, portlet, actionId, _STRICT_DEFAULT);
429            }
430    
431            @Override
432            public boolean contains(
433                            PermissionChecker permissionChecker, long plid, Portlet portlet,
434                            String actionId, boolean strict)
435                    throws PortalException {
436    
437                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
438    
439                    return contains(
440                            permissionChecker, 0, layout, portlet, actionId, strict);
441            }
442    
443            @Override
444            public boolean contains(
445                            PermissionChecker permissionChecker, long plid, String portletId,
446                            String actionId)
447                    throws PortalException {
448    
449                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
450    
451                    return contains(
452                            permissionChecker, layout, portletId, actionId, _STRICT_DEFAULT);
453            }
454    
455            @Override
456            public boolean contains(
457                            PermissionChecker permissionChecker, long plid, String portletId,
458                            String actionId, boolean strict)
459                    throws PortalException {
460    
461                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
462    
463                    return contains(
464                            permissionChecker, 0, layout, portletId, actionId, strict);
465            }
466    
467            @Override
468            public boolean contains(
469                            PermissionChecker permissionChecker, String portletId,
470                            String actionId)
471                    throws PortalException {
472    
473                    return contains(permissionChecker, 0, portletId, actionId);
474            }
475    
476            @Override
477            public String getPrimaryKey(long plid, String portletId) {
478                    return String.valueOf(plid).concat(
479                            PortletConstants.LAYOUT_SEPARATOR).concat(portletId);
480            }
481    
482            @Override
483            public boolean hasAccessPermission(
484                            PermissionChecker permissionChecker, long scopeGroupId,
485                            Layout layout, Portlet portlet, PortletMode portletMode)
486                    throws PortalException {
487    
488                    if ((layout != null) && layout.isTypeControlPanel()) {
489                            String category = portlet.getControlPanelEntryCategory();
490    
491                            if (StringUtil.startsWith(
492                                            category, PortletCategoryKeys.SITE_ADMINISTRATION)) {
493    
494                                    layout = null;
495                            }
496                    }
497    
498                    boolean access = contains(
499                            permissionChecker, scopeGroupId, layout, portlet, ActionKeys.VIEW);
500    
501                    if (access && portletMode.equals(PortletMode.EDIT)) {
502                            access = contains(
503                                    permissionChecker, scopeGroupId, layout, portlet,
504                                    ActionKeys.PREFERENCES);
505                    }
506    
507                    return access;
508            }
509    
510            @Override
511            public boolean hasConfigurationPermission(
512                            PermissionChecker permissionChecker, long groupId, Layout layout,
513                            String actionId)
514                    throws PortalException {
515    
516                    LayoutTypePortlet layoutTypePortlet =
517                            (LayoutTypePortlet)layout.getLayoutType();
518    
519                    for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
520                            if (contains(
521                                            permissionChecker, groupId, layout, portlet.getPortletId(),
522                                            actionId)) {
523    
524                                    return true;
525                            }
526    
527                            if (contains(
528                                            permissionChecker, groupId, null,
529                                            portlet.getRootPortletId(), actionId)) {
530    
531                                    return true;
532                            }
533                    }
534    
535                    return false;
536            }
537    
538            @Override
539            public boolean hasControlPanelAccessPermission(
540                            PermissionChecker permissionChecker, long groupId,
541                            Collection<Portlet> portlets)
542                    throws PortalException {
543    
544                    for (Portlet portlet : portlets) {
545                            if (hasControlPanelAccessPermission(
546                                            permissionChecker, groupId, portlet)) {
547    
548                                    return true;
549                            }
550                    }
551    
552                    return false;
553            }
554    
555            @Override
556            public boolean hasControlPanelAccessPermission(
557                            PermissionChecker permissionChecker, long scopeGroupId,
558                            Portlet portlet)
559                    throws PortalException {
560    
561                    Group group = GroupLocalServiceUtil.getGroup(scopeGroupId);
562    
563                    ControlPanelEntry controlPanelEntry =
564                            portlet.getControlPanelEntryInstance();
565    
566                    try {
567                            return controlPanelEntry.hasAccessPermission(
568                                    permissionChecker, group, portlet);
569                    }
570                    catch (Exception e) {
571                            if (_log.isWarnEnabled()) {
572                                    _log.warn("Cannot process control panel access permission", e);
573                            }
574    
575                            return false;
576                    }
577            }
578    
579            @Override
580            public boolean hasControlPanelAccessPermission(
581                            PermissionChecker permissionChecker, long scopeGroupId,
582                            String portletId)
583                    throws PortalException {
584    
585                    Portlet portlet = PortletLocalServiceUtil.getPortletById(portletId);
586    
587                    return hasControlPanelAccessPermission(
588                            permissionChecker, scopeGroupId, portlet);
589            }
590    
591            @Override
592            public boolean hasLayoutManagerPermission(
593                    String portletId, String actionId) {
594    
595                    try {
596                            portletId = PortletConstants.getRootPortletId(portletId);
597    
598                            List<String> layoutManagerActions =
599                                    ResourceActionsUtil.getPortletResourceLayoutManagerActions(
600                                            portletId);
601    
602                            return layoutManagerActions.contains(actionId);
603                    }
604                    catch (Exception e) {
605                            _log.error(e, e);
606    
607                            return false;
608                    }
609            }
610    
611            protected boolean hasAddToPagePermission(
612                            PermissionChecker permissionChecker, Layout layout,
613                            String portletId, String actionId)
614                    throws PortalException {
615    
616                    if (LayoutPermissionUtil.contains(
617                                    permissionChecker, layout, ActionKeys.CUSTOMIZE)) {
618    
619                            return contains(
620                                    permissionChecker, portletId, ActionKeys.ADD_TO_PAGE);
621                    }
622    
623                    return false;
624            }
625    
626            protected boolean hasConfigurePermission(
627                            PermissionChecker permissionChecker, Layout layout,
628                            String portletId, String actionId)
629                    throws PortalException {
630    
631                    if (!actionId.equals(ActionKeys.CONFIGURATION) &&
632                            !actionId.equals(ActionKeys.PREFERENCES) &&
633                            !actionId.equals(ActionKeys.GUEST_PREFERENCES)) {
634    
635                            return false;
636                    }
637    
638                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
639                            layout.getCompanyId(), portletId);
640    
641                    if (portlet.isPreferencesUniquePerLayout()) {
642                            return LayoutPermissionUtil.contains(
643                                    permissionChecker, layout, ActionKeys.CONFIGURE_PORTLETS);
644                    }
645    
646                    return GroupPermissionUtil.contains(
647                            permissionChecker, layout.getGroupId(),
648                            ActionKeys.CONFIGURE_PORTLETS);
649            }
650    
651            protected boolean hasCustomizePermission(
652                            PermissionChecker permissionChecker, Layout layout,
653                            String portletId, String actionId)
654                    throws PortalException {
655    
656                    LayoutTypePortlet layoutTypePortlet =
657                            (LayoutTypePortlet)layout.getLayoutType();
658    
659                    if (layoutTypePortlet.isCustomizedView() &&
660                            layoutTypePortlet.isPortletCustomizable(portletId) &&
661                            LayoutPermissionUtil.contains(
662                                    permissionChecker, layout, ActionKeys.CUSTOMIZE)) {
663    
664                            if (actionId.equals(ActionKeys.VIEW)) {
665                                    return true;
666                            }
667                            else if (actionId.equals(ActionKeys.CONFIGURATION)) {
668                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
669                                            layout.getCompanyId(), portletId);
670    
671                                    if (portlet.isInstanceable() ||
672                                            portlet.isPreferencesUniquePerLayout()) {
673    
674                                            return true;
675                                    }
676                            }
677                    }
678    
679                    return false;
680            }
681    
682            private static final boolean _CHECK_STAGING_PERMISSION_DEFAULT = true;
683    
684            private static final boolean _STRICT_DEFAULT = false;
685    
686            private static final Log _log = LogFactoryUtil.getLog(
687                    PortletPermissionImpl.class);
688    
689    }