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