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.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.StringUtil;
021    import com.liferay.portal.model.Group;
022    import com.liferay.portal.model.Layout;
023    import com.liferay.portal.model.LayoutTypePortlet;
024    import com.liferay.portal.model.Portlet;
025    import com.liferay.portal.model.PortletConstants;
026    import com.liferay.portal.model.ResourceConstants;
027    import com.liferay.portal.model.impl.VirtualLayout;
028    import com.liferay.portal.security.auth.PrincipalException;
029    import com.liferay.portal.security.permission.ActionKeys;
030    import com.liferay.portal.security.permission.PermissionChecker;
031    import com.liferay.portal.security.permission.ResourceActionsUtil;
032    import com.liferay.portal.service.GroupLocalServiceUtil;
033    import com.liferay.portal.service.LayoutLocalServiceUtil;
034    import com.liferay.portal.service.PortletLocalServiceUtil;
035    import com.liferay.portal.service.ResourceLocalServiceUtil;
036    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
037    import com.liferay.portal.util.PortletCategoryKeys;
038    import com.liferay.portlet.ControlPanelEntry;
039    import com.liferay.portlet.exportimport.staging.permission.StagingPermissionUtil;
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                    String name = null;
286                    String primKey = null;
287    
288                    if (layout == null) {
289                            name = portletId;
290                            primKey = portletId;
291    
292                            return permissionChecker.hasPermission(
293                                    groupId, name, primKey, actionId);
294                    }
295    
296                    if ((layout instanceof VirtualLayout) && layout.isTypeControlPanel()) {
297                            VirtualLayout virtualLayout = (VirtualLayout)layout;
298    
299                            layout = virtualLayout.getSourceLayout();
300                    }
301    
302                    if (!actionId.equals(ActionKeys.VIEW) &&
303                            (layout instanceof VirtualLayout)) {
304    
305                            if (actionId.equals(ActionKeys.ADD_TO_PAGE)) {
306                                    return hasAddToPagePermission(
307                                            permissionChecker, layout, portletId, actionId);
308                            }
309    
310                            return hasCustomizePermission(
311                                    permissionChecker, layout, portletId, actionId);
312                    }
313    
314                    Group group = layout.getGroup();
315    
316                    if (!group.isLayoutSetPrototype() &&
317                            actionId.equals(ActionKeys.CONFIGURATION) &&
318                            !SitesUtil.isLayoutUpdateable(layout)) {
319    
320                            return false;
321                    }
322    
323                    groupId = layout.getGroupId();
324    
325                    name = PortletConstants.getRootPortletId(portletId);
326    
327                    if (checkStagingPermission) {
328                            Boolean hasPermission = StagingPermissionUtil.hasPermission(
329                                    permissionChecker, groupId, name, groupId, name, actionId);
330    
331                            if (hasPermission != null) {
332                                    return hasPermission.booleanValue();
333                            }
334                    }
335    
336                    if (group.isControlPanel() && actionId.equals(ActionKeys.VIEW)) {
337                            return true;
338                    }
339    
340                    primKey = getPrimaryKey(layout.getPlid(), portletId);
341    
342                    if (strict) {
343                            return permissionChecker.hasPermission(
344                                    groupId, name, primKey, actionId);
345                    }
346    
347                    if (hasConfigurePermission(
348                                    permissionChecker, layout, portletId, actionId) ||
349                            hasCustomizePermission(
350                                    permissionChecker, layout, portletId, actionId)) {
351    
352                            return true;
353                    }
354    
355                    if (!hasIndividualResource(permissionChecker, name, primKey)) {
356                            ResourceLocalServiceUtil.addResources(
357                                    permissionChecker.getCompanyId(), groupId,
358                                    permissionChecker.getUserId(), name, primKey, true, true, true);
359                    }
360    
361                    return permissionChecker.hasPermission(
362                            groupId, name, primKey, actionId);
363            }
364    
365            public boolean contains(
366                            PermissionChecker permissionChecker, long groupId, long plid,
367                            Portlet portlet, String actionId)
368                    throws PortalException {
369    
370                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
371    
372                    return contains(
373                            permissionChecker, groupId, layout, portlet, actionId,
374                            _STRICT_DEFAULT);
375            }
376    
377            @Override
378            public boolean contains(
379                            PermissionChecker permissionChecker, long groupId, long plid,
380                            Portlet portlet, String actionId, boolean strict)
381                    throws PortalException {
382    
383                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
384    
385                    return contains(
386                            permissionChecker, groupId, layout, portlet, actionId, strict);
387            }
388    
389            public boolean contains(
390                            PermissionChecker permissionChecker, long groupId, long plid,
391                            String portletId, String actionId)
392                    throws PortalException {
393    
394                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
395    
396                    return contains(
397                            permissionChecker, groupId, layout, portletId, actionId,
398                            _STRICT_DEFAULT);
399            }
400    
401            @Override
402            public boolean contains(
403                            PermissionChecker permissionChecker, long groupId, long plid,
404                            String portletId, String actionId, boolean strict)
405                    throws PortalException {
406    
407                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
408    
409                    return contains(
410                            permissionChecker, groupId, layout, portletId, actionId, strict);
411            }
412    
413            @Override
414            public boolean contains(
415                            PermissionChecker permissionChecker, long plid, Portlet portlet,
416                            String actionId)
417                    throws PortalException {
418    
419                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
420    
421                    return contains(
422                            permissionChecker, layout, portlet, actionId, _STRICT_DEFAULT);
423            }
424    
425            @Override
426            public boolean contains(
427                            PermissionChecker permissionChecker, long plid, Portlet portlet,
428                            String actionId, boolean strict)
429                    throws PortalException {
430    
431                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
432    
433                    return contains(
434                            permissionChecker, 0, layout, portlet, actionId, strict);
435            }
436    
437            @Override
438            public boolean contains(
439                            PermissionChecker permissionChecker, long plid, String portletId,
440                            String actionId)
441                    throws PortalException {
442    
443                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
444    
445                    return contains(
446                            permissionChecker, layout, portletId, actionId, _STRICT_DEFAULT);
447            }
448    
449            @Override
450            public boolean contains(
451                            PermissionChecker permissionChecker, long plid, String portletId,
452                            String actionId, boolean strict)
453                    throws PortalException {
454    
455                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
456    
457                    return contains(
458                            permissionChecker, 0, layout, portletId, actionId, strict);
459            }
460    
461            @Override
462            public boolean contains(
463                            PermissionChecker permissionChecker, String portletId,
464                            String actionId)
465                    throws PortalException {
466    
467                    return contains(permissionChecker, 0, portletId, actionId);
468            }
469    
470            @Override
471            public String getPrimaryKey(long plid, String portletId) {
472                    return String.valueOf(plid).concat(
473                            PortletConstants.LAYOUT_SEPARATOR).concat(portletId);
474            }
475    
476            @Override
477            public boolean hasAccessPermission(
478                            PermissionChecker permissionChecker, long scopeGroupId,
479                            Layout layout, Portlet portlet, PortletMode portletMode)
480                    throws PortalException {
481    
482                    if ((layout != null) && layout.isTypeControlPanel()) {
483                            String category = portlet.getControlPanelEntryCategory();
484    
485                            if (StringUtil.startsWith(
486                                            category, PortletCategoryKeys.SITE_ADMINISTRATION)) {
487    
488                                    layout = null;
489                            }
490                    }
491    
492                    boolean access = contains(
493                            permissionChecker, scopeGroupId, layout, portlet, ActionKeys.VIEW);
494    
495                    if (access && portletMode.equals(PortletMode.EDIT)) {
496                            access = contains(
497                                    permissionChecker, scopeGroupId, layout, portlet,
498                                    ActionKeys.PREFERENCES);
499                    }
500    
501                    return access;
502            }
503    
504            @Override
505            public boolean hasConfigurationPermission(
506                            PermissionChecker permissionChecker, long groupId, Layout layout,
507                            String actionId)
508                    throws PortalException {
509    
510                    LayoutTypePortlet layoutTypePortlet =
511                            (LayoutTypePortlet)layout.getLayoutType();
512    
513                    for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
514                            if (contains(
515                                            permissionChecker, groupId, layout, portlet.getPortletId(),
516                                            actionId)) {
517    
518                                    return true;
519                            }
520    
521                            if (contains(
522                                            permissionChecker, groupId, null,
523                                            portlet.getRootPortletId(), actionId)) {
524    
525                                    return true;
526                            }
527                    }
528    
529                    return false;
530            }
531    
532            @Override
533            public boolean hasControlPanelAccessPermission(
534                            PermissionChecker permissionChecker, long groupId,
535                            Collection<Portlet> portlets)
536                    throws PortalException {
537    
538                    for (Portlet portlet : portlets) {
539                            if (hasControlPanelAccessPermission(
540                                            permissionChecker, groupId, portlet)) {
541    
542                                    return true;
543                            }
544                    }
545    
546                    return false;
547            }
548    
549            @Override
550            public boolean hasControlPanelAccessPermission(
551                            PermissionChecker permissionChecker, long scopeGroupId,
552                            Portlet portlet)
553                    throws PortalException {
554    
555                    Group group = GroupLocalServiceUtil.getGroup(scopeGroupId);
556    
557                    ControlPanelEntry controlPanelEntry =
558                            portlet.getControlPanelEntryInstance();
559    
560                    try {
561                            return controlPanelEntry.hasAccessPermission(
562                                    permissionChecker, group, portlet);
563                    }
564                    catch (Exception e) {
565                            if (_log.isWarnEnabled()) {
566                                    _log.warn("Cannot process control panel access permission", e);
567                            }
568    
569                            return false;
570                    }
571            }
572    
573            @Override
574            public boolean hasControlPanelAccessPermission(
575                            PermissionChecker permissionChecker, long scopeGroupId,
576                            String portletId)
577                    throws PortalException {
578    
579                    Portlet portlet = PortletLocalServiceUtil.getPortletById(portletId);
580    
581                    return hasControlPanelAccessPermission(
582                            permissionChecker, scopeGroupId, portlet);
583            }
584    
585            @Override
586            public boolean hasLayoutManagerPermission(
587                    String portletId, String actionId) {
588    
589                    try {
590                            portletId = PortletConstants.getRootPortletId(portletId);
591    
592                            List<String> layoutManagerActions =
593                                    ResourceActionsUtil.getPortletResourceLayoutManagerActions(
594                                            portletId);
595    
596                            return layoutManagerActions.contains(actionId);
597                    }
598                    catch (Exception e) {
599                            _log.error(e, e);
600    
601                            return false;
602                    }
603            }
604    
605            protected boolean hasAddToPagePermission(
606                            PermissionChecker permissionChecker, Layout layout,
607                            String portletId, String actionId)
608                    throws PortalException {
609    
610                    if (LayoutPermissionUtil.contains(
611                                    permissionChecker, layout, ActionKeys.CUSTOMIZE)) {
612    
613                            return contains(
614                                    permissionChecker, portletId, ActionKeys.ADD_TO_PAGE);
615                    }
616    
617                    return false;
618            }
619    
620            protected boolean hasConfigurePermission(
621                            PermissionChecker permissionChecker, Layout layout,
622                            String portletId, String actionId)
623                    throws PortalException {
624    
625                    if (!actionId.equals(ActionKeys.CONFIGURATION) &&
626                            !actionId.equals(ActionKeys.PREFERENCES) &&
627                            !actionId.equals(ActionKeys.GUEST_PREFERENCES)) {
628    
629                            return false;
630                    }
631    
632                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
633                            layout.getCompanyId(), portletId);
634    
635                    if (portlet.isPreferencesUniquePerLayout()) {
636                            return LayoutPermissionUtil.contains(
637                                    permissionChecker, layout, ActionKeys.CONFIGURE_PORTLETS);
638                    }
639    
640                    return GroupPermissionUtil.contains(
641                            permissionChecker, layout.getGroupId(),
642                            ActionKeys.CONFIGURE_PORTLETS);
643            }
644    
645            protected boolean hasCustomizePermission(
646                            PermissionChecker permissionChecker, Layout layout,
647                            String portletId, String actionId)
648                    throws PortalException {
649    
650                    LayoutTypePortlet layoutTypePortlet =
651                            (LayoutTypePortlet)layout.getLayoutType();
652    
653                    if (layoutTypePortlet.isCustomizedView() &&
654                            layoutTypePortlet.isPortletCustomizable(portletId) &&
655                            LayoutPermissionUtil.contains(
656                                    permissionChecker, layout, ActionKeys.CUSTOMIZE)) {
657    
658                            if (actionId.equals(ActionKeys.VIEW)) {
659                                    return true;
660                            }
661                            else if (actionId.equals(ActionKeys.CONFIGURATION)) {
662                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
663                                            layout.getCompanyId(), portletId);
664    
665                                    if (portlet.isInstanceable() ||
666                                            portlet.isPreferencesUniquePerLayout()) {
667    
668                                            return true;
669                                    }
670                            }
671                    }
672    
673                    return false;
674            }
675    
676            protected boolean hasIndividualResource(
677                    PermissionChecker permissionChecker, String name, String primKey) {
678    
679                    int count =
680                            ResourcePermissionLocalServiceUtil.getResourcePermissionsCount(
681                                    permissionChecker.getCompanyId(), name,
682                                    ResourceConstants.SCOPE_INDIVIDUAL, primKey);
683    
684                    if (count == 0) {
685                            return false;
686                    }
687    
688                    return true;
689            }
690    
691            private static final boolean _CHECK_STAGING_PERMISSION_DEFAULT = true;
692    
693            private static final boolean _STRICT_DEFAULT = false;
694    
695            private static final Log _log = LogFactoryUtil.getLog(
696                    PortletPermissionImpl.class);
697    
698    }