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.security.permission;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
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.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.CharPool;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.kernel.util.SetUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.Group;
028    import com.liferay.portal.model.GroupConstants;
029    import com.liferay.portal.model.GroupedModel;
030    import com.liferay.portal.model.Layout;
031    import com.liferay.portal.model.Organization;
032    import com.liferay.portal.model.OrganizationConstants;
033    import com.liferay.portal.model.PermissionedModel;
034    import com.liferay.portal.model.PortletConstants;
035    import com.liferay.portal.model.Resource;
036    import com.liferay.portal.model.ResourceBlockConstants;
037    import com.liferay.portal.model.ResourceConstants;
038    import com.liferay.portal.model.Role;
039    import com.liferay.portal.model.RoleConstants;
040    import com.liferay.portal.model.Team;
041    import com.liferay.portal.model.User;
042    import com.liferay.portal.service.GroupLocalServiceUtil;
043    import com.liferay.portal.service.LayoutLocalServiceUtil;
044    import com.liferay.portal.service.OrganizationLocalServiceUtil;
045    import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
046    import com.liferay.portal.service.ResourceLocalServiceUtil;
047    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
048    import com.liferay.portal.service.RoleLocalServiceUtil;
049    import com.liferay.portal.service.TeamLocalServiceUtil;
050    import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
051    import com.liferay.portal.service.UserLocalServiceUtil;
052    import com.liferay.portal.service.permission.LayoutPrototypePermissionUtil;
053    import com.liferay.portal.service.permission.LayoutSetPrototypePermissionUtil;
054    import com.liferay.portal.service.permission.PortletPermissionUtil;
055    
056    import java.util.ArrayList;
057    import java.util.Arrays;
058    import java.util.Collections;
059    import java.util.HashSet;
060    import java.util.LinkedHashMap;
061    import java.util.List;
062    import java.util.Set;
063    
064    import org.apache.commons.lang.time.StopWatch;
065    
066    /**
067     * @author Charles May
068     * @author Brian Wing Shun Chan
069     * @author Raymond Aug??
070     * @author Wesley Gong
071     * @author Connor McKay
072     */
073    public class AdvancedPermissionChecker extends BasePermissionChecker {
074    
075            @Override
076            public AdvancedPermissionChecker clone() {
077                    return new AdvancedPermissionChecker();
078            }
079    
080            public ResourceBlockIdsBag getGuestResourceBlockIdsBag(
081                            long companyId, long groupId, String name)
082                    throws Exception {
083    
084                    ResourceBlockIdsBag resourceBlockIdsBag =
085                            PermissionCacheUtil.getResourceBlockIdsBag(
086                                    companyId, groupId, defaultUserId, name);
087    
088                    if (resourceBlockIdsBag != null) {
089                            return resourceBlockIdsBag;
090                    }
091    
092                    try {
093                            resourceBlockIdsBag =
094                                    ResourceBlockLocalServiceUtil.getResourceBlockIdsBag(
095                                            getCompanyId(), groupId, name, getGuestUserRoleIds());
096    
097                            PermissionCacheUtil.putResourceBlockIdsBag(
098                                    companyId, groupId, defaultUserId, name, resourceBlockIdsBag);
099    
100                            return resourceBlockIdsBag;
101                    }
102                    catch (Exception e) {
103                            PermissionCacheUtil.removeResourceBlockIdsBag(
104                                    getCompanyId(), groupId, defaultUserId, name);
105    
106                            throw e;
107                    }
108            }
109    
110            /**
111             * Returns the permission checker bag for the guest user.
112             *
113             * @return the permission checker bag for the guest user
114             * @throws Exception if an exception occurred
115             */
116            public long[] getGuestUserRoleIds() throws Exception {
117                    Group guestGroup = GroupLocalServiceUtil.getGroup(
118                            getCompanyId(), GroupConstants.GUEST);
119    
120                    long[] roleIds = PermissionCacheUtil.getUserGroupRoleIds(
121                            defaultUserId, guestGroup.getGroupId());
122    
123                    if (roleIds != null) {
124                            return roleIds;
125                    }
126    
127                    try {
128                            List<Role> roles = RoleLocalServiceUtil.getUserRelatedRoles(
129                                    defaultUserId, Collections.singletonList(guestGroup));
130    
131                            // Only use the guest group for deriving the roles for
132                            // unauthenticated users. Do not add the group to the permission bag
133                            // as this implies group membership which is incorrect in the case
134                            // of unauthenticated users.
135    
136                            roleIds = ListUtil.toLongArray(roles, Role.ROLE_ID_ACCESSOR);
137    
138                            Arrays.sort(roleIds);
139    
140                            PermissionCacheUtil.putUserGroupRoleIds(
141                                    defaultUserId, guestGroup.getGroupId(), roleIds);
142                    }
143                    catch (Exception e) {
144                            PermissionCacheUtil.removeUserGroupRoleIds(
145                                    defaultUserId, guestGroup.getGroupId());
146    
147                            throw e;
148                    }
149    
150                    return roleIds;
151            }
152    
153            @Override
154            public List<Long> getOwnerResourceBlockIds(
155                    long companyId, long groupId, String name, String actionId) {
156    
157                    try {
158                            ResourceBlockIdsBag resourceBlockIdsBag =
159                                    getOwnerResourceBlockIdsBag(companyId, groupId, name);
160    
161                            return ResourceBlockLocalServiceUtil.getResourceBlockIds(
162                                    resourceBlockIdsBag, name, actionId);
163                    }
164                    catch (Exception e) {
165                    }
166    
167                    return Collections.emptyList();
168            }
169    
170            public ResourceBlockIdsBag getOwnerResourceBlockIdsBag(
171                    long companyId, long groupId, String name) {
172    
173                    ResourceBlockIdsBag resourceBlockIdsBag =
174                            PermissionCacheUtil.getResourceBlockIdsBag(
175                                    companyId, groupId, ResourceBlockConstants.OWNER_USER_ID, name);
176    
177                    if (resourceBlockIdsBag != null) {
178                            return resourceBlockIdsBag;
179                    }
180    
181                    try {
182                            long[] roleIds = {getOwnerRoleId()};
183    
184                            resourceBlockIdsBag =
185                                    ResourceBlockLocalServiceUtil.getResourceBlockIdsBag(
186                                            getCompanyId(), groupId, name, roleIds);
187    
188                            PermissionCacheUtil.putResourceBlockIdsBag(
189                                    companyId, groupId, ResourceBlockConstants.OWNER_USER_ID, name,
190                                    resourceBlockIdsBag);
191    
192                            return resourceBlockIdsBag;
193                    }
194                    catch (Exception e) {
195                            PermissionCacheUtil.removeResourceBlockIdsBag(
196                                    companyId, groupId, ResourceBlockConstants.OWNER_USER_ID, name);
197    
198                            throw e;
199                    }
200            }
201    
202            @Override
203            public List<Long> getResourceBlockIds(
204                    long companyId, long groupId, long userId, String name,
205                    String actionId) {
206    
207                    try {
208                            ResourceBlockIdsBag resourceBlockIdsBag = getResourceBlockIdsBag(
209                                    companyId, groupId, userId, name);
210    
211                            return ResourceBlockLocalServiceUtil.getResourceBlockIds(
212                                    resourceBlockIdsBag, name, actionId);
213                    }
214                    catch (Exception e) {
215                    }
216    
217                    return Collections.emptyList();
218            }
219    
220            public ResourceBlockIdsBag getResourceBlockIdsBag(
221                            long companyId, long groupId, long userId, String name)
222                    throws Exception {
223    
224                    ResourceBlockIdsBag resourceBlockIdsBag =
225                            PermissionCacheUtil.getResourceBlockIdsBag(
226                                    companyId, groupId, userId, name);
227    
228                    if (resourceBlockIdsBag != null) {
229                            return resourceBlockIdsBag;
230                    }
231    
232                    try {
233                            long[] roleIds = getRoleIds(userId, groupId);
234    
235                            resourceBlockIdsBag =
236                                    ResourceBlockLocalServiceUtil.getResourceBlockIdsBag(
237                                            getCompanyId(), groupId, name, roleIds);
238    
239                            PermissionCacheUtil.putResourceBlockIdsBag(
240                                    companyId, groupId, userId, name, resourceBlockIdsBag);
241    
242                            return resourceBlockIdsBag;
243                    }
244                    catch (Exception e) {
245                            PermissionCacheUtil.removeResourceBlockIdsBag(
246                                    companyId, groupId, userId, name);
247    
248                            throw e;
249                    }
250            }
251    
252            @Override
253            public long[] getRoleIds(long userId, long groupId) {
254                    long[] roleIds = null;
255    
256                    try {
257                            roleIds = doGetRoleIds(userId, groupId);
258                    }
259                    catch (Exception e) {
260                            return PermissionChecker.DEFAULT_ROLE_IDS;
261                    }
262    
263                    if (!checkGuest) {
264                            return roleIds;
265                    }
266    
267                    Set<Long> roleIdsSet = SetUtil.fromArray(roleIds);
268    
269                    try {
270                            for (long roleId : getGuestUserRoleIds()) {
271                                    roleIdsSet.add(roleId);
272                            }
273                    }
274                    catch (Exception e) {
275                    }
276    
277                    return ArrayUtil.toArray(
278                            roleIdsSet.toArray(new Long[roleIdsSet.size()]));
279            }
280    
281            @Override
282            public UserBag getUserBag() throws PortalException {
283                    return UserBagFactoryUtil.create(getUserId());
284            }
285    
286            @Override
287            public boolean hasOwnerPermission(
288                    long companyId, String name, String primKey, long ownerId,
289                    String actionId) {
290    
291                    if (ownerId != getUserId()) {
292                            return false;
293                    }
294    
295                    if (ownerId == defaultUserId) {
296                            if (actionId.equals(ActionKeys.VIEW)) {
297                                    return true;
298                            }
299                            else {
300                                    return false;
301                            }
302                    }
303    
304                    try {
305                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
306                                    PermissionedModel permissionedModel =
307                                            ResourceBlockLocalServiceUtil.getPermissionedModel(
308                                                    name, GetterUtil.getLong(primKey));
309    
310                                    long groupId = 0;
311    
312                                    if (permissionedModel instanceof GroupedModel) {
313                                            GroupedModel groupedModel = (GroupedModel)permissionedModel;
314    
315                                            groupId = groupedModel.getGroupId();
316                                    }
317    
318                                    ResourceBlockIdsBag resourceBlockIdsBag =
319                                            getOwnerResourceBlockIdsBag(companyId, groupId, name);
320    
321                                    return ResourceBlockLocalServiceUtil.hasPermission(
322                                            name, permissionedModel, actionId, resourceBlockIdsBag);
323                            }
324    
325                            return ResourcePermissionLocalServiceUtil.hasResourcePermission(
326                                    companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey,
327                                    getOwnerRoleId(), actionId);
328                    }
329                    catch (Exception e) {
330                            if (_log.isDebugEnabled()) {
331                                    _log.debug(e, e);
332                            }
333                    }
334    
335                    return false;
336            }
337    
338            @Override
339            public boolean hasPermission(
340                    long groupId, String name, String primKey, String actionId) {
341    
342                    StopWatch stopWatch = new StopWatch();
343    
344                    stopWatch.start();
345    
346                    Group group = null;
347    
348                    try {
349                            if (groupId > 0) {
350                                    group = GroupLocalServiceUtil.getGroup(groupId);
351    
352                                    // If the group is a scope group for a layout, check the
353                                    // original group.
354    
355                                    if (group.isLayout() &&
356                                            !ResourceBlockLocalServiceUtil.isSupported(name)) {
357    
358                                            Layout layout = LayoutLocalServiceUtil.getLayout(
359                                                    group.getClassPK());
360    
361                                            groupId = layout.getGroupId();
362    
363                                            group = GroupLocalServiceUtil.getGroup(groupId);
364                                    }
365    
366                                    // If the group is a personal site, check the "User Personal
367                                    // Site" group.
368    
369                                    if (group.isUser() && (group.getClassPK() == getUserId())) {
370                                            group = GroupLocalServiceUtil.getGroup(
371                                                    getCompanyId(), GroupConstants.USER_PERSONAL_SITE);
372    
373                                            groupId = group.getGroupId();
374                                    }
375    
376                                    // If the group is a staging group, check the live group.
377    
378                                    if (group.isStagingGroup()) {
379                                            if (primKey.equals(String.valueOf(groupId))) {
380                                                    primKey = String.valueOf(group.getLiveGroupId());
381                                            }
382    
383                                            groupId = group.getLiveGroupId();
384                                            group = group.getLiveGroup();
385                                    }
386                            }
387                    }
388                    catch (Exception e) {
389                            _log.error(e, e);
390                    }
391    
392                    Boolean value = PermissionCacheUtil.getPermission(
393                            user.getUserId(), signedIn, groupId, name, primKey, actionId);
394    
395                    if (value != null) {
396                            return value;
397                    }
398    
399                    try {
400                            value = hasPermissionImpl(groupId, name, primKey, actionId);
401    
402                            if (_log.isDebugEnabled()) {
403                                    _log.debug(
404                                            "Checking permission for " + groupId + " " + name +
405                                                    " " + primKey + " " + actionId + " takes " +
406                                                            stopWatch.getTime() + " ms");
407                            }
408    
409                            PermissionCacheUtil.putPermission(
410                                    user.getUserId(), signedIn, groupId, name, primKey, actionId,
411                                    value);
412                    }
413                    catch (Exception e) {
414                            PermissionCacheUtil.removePermission(
415                                    user.getUserId(), signedIn, groupId, name, primKey, actionId);
416    
417                            throw e;
418                    }
419    
420                    return value;
421            }
422    
423            @Override
424            public boolean hasUserPermission(
425                    long groupId, String name, String primKey, String actionId,
426                    boolean checkAdmin) {
427    
428                    try {
429                            return hasUserPermissionImpl(
430                                    groupId, name, primKey, actionId, checkAdmin);
431                    }
432                    catch (Exception e) {
433                            _log.error(e, e);
434    
435                            return false;
436                    }
437            }
438    
439            @Override
440            public boolean isCompanyAdmin() {
441                    try {
442                            return isCompanyAdminImpl(user.getCompanyId());
443                    }
444                    catch (Exception e) {
445                            _log.error(e, e);
446    
447                            return false;
448                    }
449            }
450    
451            @Override
452            public boolean isCompanyAdmin(long companyId) {
453                    try {
454                            return isCompanyAdminImpl(companyId);
455                    }
456                    catch (Exception e) {
457                            _log.error(e, e);
458    
459                            return false;
460                    }
461            }
462    
463            @Override
464            public boolean isContentReviewer(long companyId, long groupId) {
465                    try {
466                            return isContentReviewerImpl(companyId, groupId);
467                    }
468                    catch (Exception e) {
469                            _log.error(e, e);
470                    }
471    
472                    return false;
473            }
474    
475            @Override
476            public boolean isGroupAdmin(long groupId) {
477                    try {
478                            return isGroupAdminImpl(groupId);
479                    }
480                    catch (Exception e) {
481                            _log.error(e, e);
482    
483                            return false;
484                    }
485            }
486    
487            @Override
488            public boolean isGroupMember(long groupId) {
489                    try {
490                            return isGroupMemberImpl(groupId);
491                    }
492                    catch (Exception e) {
493                            _log.error(e, e);
494    
495                            return false;
496                    }
497            }
498    
499            @Override
500            public boolean isGroupOwner(long groupId) {
501                    try {
502                            return isGroupOwnerImpl(groupId);
503                    }
504                    catch (Exception e) {
505                            _log.error(e, e);
506    
507                            return false;
508                    }
509            }
510    
511            @Override
512            public boolean isOrganizationAdmin(long organizationId) {
513                    try {
514                            return isOrganizationAdminImpl(organizationId);
515                    }
516                    catch (Exception e) {
517                            _log.error(e, e);
518    
519                            return false;
520                    }
521            }
522    
523            @Override
524            public boolean isOrganizationOwner(long organizationId) {
525                    try {
526                            return isOrganizationOwnerImpl(organizationId);
527                    }
528                    catch (Exception e) {
529                            _log.error(e, e);
530    
531                            return false;
532                    }
533            }
534    
535            protected void addTeamRoles(long userId, Group group, Set<Role> roles)
536                    throws Exception {
537    
538                    List<Team> userTeams = TeamLocalServiceUtil.getUserTeams(
539                            userId, group.getGroupId());
540    
541                    for (Team team : userTeams) {
542                            Role role = RoleLocalServiceUtil.getTeamRole(
543                                    team.getCompanyId(), team.getTeamId());
544    
545                            roles.add(role);
546                    }
547    
548                    LinkedHashMap<String, Object> teamParams = new LinkedHashMap<>();
549    
550                    teamParams.put("usersUserGroups", userId);
551    
552                    List<Team> userGroupTeams = TeamLocalServiceUtil.search(
553                            group.getGroupId(), null, null, teamParams, QueryUtil.ALL_POS,
554                            QueryUtil.ALL_POS, null);
555    
556                    for (Team team : userGroupTeams) {
557                            Role role = RoleLocalServiceUtil.getTeamRole(
558                                    team.getCompanyId(), team.getTeamId());
559    
560                            roles.add(role);
561                    }
562            }
563    
564            protected boolean doCheckPermission(
565                            long companyId, long groupId, String name, String primKey,
566                            String actionId, StopWatch stopWatch)
567                    throws Exception {
568    
569                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
570    
571                    if (ResourceBlockLocalServiceUtil.isSupported(name)) {
572                            ResourceBlockIdsBag resourceBlockIdsBag = getResourceBlockIdsBag(
573                                    companyId, groupId, getUserId(), name);
574    
575                            boolean value = ResourceBlockLocalServiceUtil.hasPermission(
576                                    name, GetterUtil.getLong(primKey), actionId,
577                                    resourceBlockIdsBag);
578    
579                            logHasUserPermission(
580                                    groupId, name, primKey, actionId, stopWatch, 2);
581    
582                            return value;
583                    }
584    
585                    List<Resource> resources = getResources(
586                            companyId, groupId, name, primKey, actionId);
587    
588                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
589    
590                    // Check if user has access to perform the action on the given resource
591                    // scopes. The resources are scoped to check first for an individual
592                    // class, then for the group that the class may belong to, and then for
593                    // the company that the class belongs to.
594    
595                    boolean value = ResourceLocalServiceUtil.hasUserPermissions(
596                            user.getUserId(), groupId, resources, actionId,
597                            doGetRoleIds(user.getUserId(), groupId));
598    
599                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 4);
600    
601                    return value;
602            }
603    
604            protected long[] doGetRoleIds(long userId, long groupId) throws Exception {
605                    long[] roleIds = PermissionCacheUtil.getUserGroupRoleIds(
606                            userId, groupId);
607    
608                    if (roleIds != null) {
609                            return roleIds;
610                    }
611    
612                    try {
613                            Group group = null;
614    
615                            long parentGroupId = 0;
616    
617                            if (groupId > 0) {
618                                    group = GroupLocalServiceUtil.getGroup(groupId);
619    
620                                    if (group.isLayout()) {
621                                            parentGroupId = group.getParentGroupId();
622    
623                                            if (parentGroupId > 0) {
624                                                    group = GroupLocalServiceUtil.getGroup(parentGroupId);
625                                            }
626                                    }
627                            }
628    
629                            UserBag userBag = getUserBag();
630    
631                            Set<Role> roles = new HashSet<>();
632    
633                            roles.addAll(userBag.getRoles());
634    
635                            List<Role> userGroupRoles = RoleLocalServiceUtil.getUserGroupRoles(
636                                    userId, groupId);
637    
638                            roles.addAll(userGroupRoles);
639    
640                            if (parentGroupId > 0) {
641                                    userGroupRoles = RoleLocalServiceUtil.getUserGroupRoles(
642                                            userId, parentGroupId);
643    
644                                    roles.addAll(userGroupRoles);
645                            }
646    
647                            List<Role> userGroupGroupRoles =
648                                    RoleLocalServiceUtil.getUserGroupGroupRoles(userId, groupId);
649    
650                            roles.addAll(userGroupGroupRoles);
651    
652                            if (parentGroupId > 0) {
653                                    userGroupGroupRoles =
654                                            RoleLocalServiceUtil.getUserGroupGroupRoles(
655                                                    userId, parentGroupId);
656    
657                                    roles.addAll(userGroupGroupRoles);
658                            }
659    
660                            if (group != null) {
661                                    Set<Group> userOrgGroups = userBag.getUserOrgGroups();
662    
663                                    if (group.isOrganization() && userOrgGroups.contains(group)) {
664                                            Role organizationUserRole = RoleLocalServiceUtil.getRole(
665                                                    group.getCompanyId(), RoleConstants.ORGANIZATION_USER);
666    
667                                            roles.add(organizationUserRole);
668                                    }
669    
670                                    Set<Group> userGroups = userBag.getUserGroups();
671    
672                                    if ((group.isSite() &&
673                                             (userGroups.contains(group) ||
674                                              userOrgGroups.contains(group))) ||
675                                            group.isUserPersonalSite()) {
676    
677                                            Role siteMemberRole = RoleLocalServiceUtil.getRole(
678                                                    group.getCompanyId(), RoleConstants.SITE_MEMBER);
679    
680                                            roles.add(siteMemberRole);
681                                    }
682    
683                                    if ((group.isOrganization() && userOrgGroups.contains(group)) ||
684                                            (group.isSite() && userGroups.contains(group))) {
685    
686                                            addTeamRoles(userId, group, roles);
687                                    }
688                            }
689    
690                            roleIds = ListUtil.toLongArray(
691                                    new ArrayList<>(roles), Role.ROLE_ID_ACCESSOR);
692    
693                            Arrays.sort(roleIds);
694    
695                            PermissionCacheUtil.putUserGroupRoleIds(userId, groupId, roleIds);
696    
697                            return roleIds;
698                    }
699                    catch (Exception e) {
700                            PermissionCacheUtil.removeUserGroupRoleIds(userId, groupId);
701    
702                            throw e;
703                    }
704            }
705    
706            /**
707             * Returns representations of the resource at each scope level.
708             *
709             * <p>
710             * For example, if the class name and primary key of a blog entry were
711             * passed to this method, it would return a resource for the blog entry
712             * itself (individual scope), a resource representing all blog entries
713             * within its group (group scope), a resource standing for all blog entries
714             * within a group the user has a suitable role in (group-template scope),
715             * and a resource signifying all blog entries within the company (company
716             * scope).
717             * </p>
718             *
719             * @param  companyId the primary key of the company
720             * @param  groupId the primary key of the group containing the resource
721             * @param  name the resource's name, which can be either a class name or a
722             *         portlet ID
723             * @param  primKey the primary key of the resource
724             * @param  actionId unused
725             * @return representations of the resource at each scope level
726             * @throws Exception if an exception occurred
727             */
728            protected List<Resource> getResources(
729                            long companyId, long groupId, String name, String primKey,
730                            String actionId)
731                    throws Exception {
732    
733                    // Individual
734    
735                    List<Resource> resources = new ArrayList<>(4);
736    
737                    Resource individualResource = ResourceLocalServiceUtil.getResource(
738                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
739    
740                    resources.add(individualResource);
741    
742                    // Group
743    
744                    if (groupId > 0) {
745                            Resource groupResource = ResourceLocalServiceUtil.getResource(
746                                    companyId, name, ResourceConstants.SCOPE_GROUP,
747                                    String.valueOf(groupId));
748    
749                            resources.add(groupResource);
750                    }
751    
752                    // Group template
753    
754                    if (signedIn && (groupId > 0)) {
755                            Resource groupTemplateResource =
756                                    ResourceLocalServiceUtil.getResource(
757                                            companyId, name, ResourceConstants.SCOPE_GROUP_TEMPLATE,
758                                            String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
759    
760                            resources.add(groupTemplateResource);
761                    }
762    
763                    // Company
764    
765                    Resource companyResource = ResourceLocalServiceUtil.getResource(
766                            companyId, name, ResourceConstants.SCOPE_COMPANY,
767                            String.valueOf(companyId));
768    
769                    resources.add(companyResource);
770    
771                    return resources;
772            }
773    
774            protected boolean hasGuestPermission(
775                            long groupId, String name, String primKey, String actionId)
776                    throws Exception {
777    
778                    try {
779                            ResourceActionsUtil.checkAction(name, actionId);
780                    }
781                    catch (Exception e) {
782                            if (_log.isDebugEnabled()) {
783                                    _log.debug(
784                                            "Guest does not have permission to " + actionId + " on " +
785                                                    name + " with primary key " + primKey);
786                            }
787    
788                            return false;
789                    }
790    
791                    if (name.indexOf(CharPool.PERIOD) != -1) {
792    
793                            // Check unsupported model actions
794    
795                            List<String> actions =
796                                    ResourceActionsUtil.getModelResourceGuestUnsupportedActions(
797                                            name);
798    
799                            if (actions.contains(actionId)) {
800                                    return false;
801                            }
802                    }
803                    else {
804    
805                            // Check unsupported portlet actions
806    
807                            List<String> actions =
808                                    ResourceActionsUtil.getPortletResourceGuestUnsupportedActions(
809                                            name);
810    
811                            if (actions.contains(actionId)) {
812                                    return false;
813                            }
814                    }
815    
816                    long companyId = user.getCompanyId();
817    
818                    List<Resource> resources = getResources(
819                            companyId, groupId, name, primKey, actionId);
820    
821                    try {
822                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
823                                    ResourceBlockIdsBag resourceBlockIdsBag =
824                                            getGuestResourceBlockIdsBag(companyId, groupId, name);
825    
826                                    return ResourceBlockLocalServiceUtil.hasPermission(
827                                            name, GetterUtil.getLong(primKey), actionId,
828                                            resourceBlockIdsBag);
829                            }
830    
831                            return ResourceLocalServiceUtil.hasUserPermissions(
832                                    defaultUserId, groupId, resources, actionId,
833                                    getGuestUserRoleIds());
834                    }
835                    catch (Exception e) {
836                            _log.error(e, e);
837    
838                            return false;
839                    }
840            }
841    
842            protected boolean hasPermissionImpl(
843                    long groupId, String name, String primKey, String actionId) {
844    
845                    try {
846                            if (!signedIn) {
847                                    return hasGuestPermission(groupId, name, primKey, actionId);
848                            }
849    
850                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
851    
852                                    // It is not necessary to check guest permissions separately, as
853                                    // the user's resource block IDs bag will already have the guest
854                                    // permissions in it if checkGuest is true.
855    
856                                    return hasUserPermission(
857                                            groupId, name, primKey, actionId, true);
858                            }
859    
860                            boolean value = false;
861    
862                            if (checkGuest) {
863                                    value = hasGuestPermission(groupId, name, primKey, actionId);
864                            }
865    
866                            if (!value) {
867                                    value = hasUserPermission(
868                                            groupId, name, primKey, actionId, true);
869                            }
870    
871                            return value;
872                    }
873                    catch (Exception e) {
874                            _log.error(e, e);
875    
876                            return false;
877                    }
878            }
879    
880            protected boolean hasUserPermissionImpl(
881                            long groupId, String name, String primKey, String actionId,
882                            boolean checkAdmin)
883                    throws Exception {
884    
885                    StopWatch stopWatch = new StopWatch();
886    
887                    stopWatch.start();
888    
889                    long companyId = user.getCompanyId();
890    
891                    if (groupId > 0) {
892                            Group group = GroupLocalServiceUtil.getGroup(groupId);
893    
894                            companyId = group.getCompanyId();
895                    }
896                    else if (name.equals(User.class.getName())) {
897                            User user = UserLocalServiceUtil.fetchUser(
898                                    GetterUtil.getLong(primKey));
899    
900                            if (user != null) {
901                                    companyId = user.getCompanyId();
902                            }
903                    }
904    
905                    boolean hasLayoutManagerPermission = true;
906    
907                    // Check if the layout manager has permission to do this action for the
908                    // current portlet
909    
910                    if (Validator.isNotNull(name) && Validator.isNotNull(primKey) &&
911                            primKey.contains(PortletConstants.LAYOUT_SEPARATOR)) {
912    
913                            hasLayoutManagerPermission =
914                                    PortletPermissionUtil.hasLayoutManagerPermission(
915                                            name, actionId);
916                    }
917    
918                    if (checkAdmin) {
919                            if (isCompanyAdminImpl(companyId)) {
920                                    return true;
921                            }
922    
923                            if (name.equals(Organization.class.getName())) {
924                                    if (isOrganizationAdminImpl(GetterUtil.getLong(primKey))) {
925                                            return true;
926                                    }
927                            }
928                            else if (isGroupAdminImpl(groupId) && hasLayoutManagerPermission) {
929                                    return true;
930                            }
931                    }
932    
933                    return doCheckPermission(
934                            companyId, groupId, name, primKey, actionId, stopWatch);
935            }
936    
937            protected boolean isCompanyAdminImpl(long companyId) throws Exception {
938                    if (!signedIn) {
939                            return false;
940                    }
941    
942                    if (isOmniadmin()) {
943                            return true;
944                    }
945    
946                    Boolean value = PermissionCacheUtil.getUserPrimaryKeyRole(
947                            getUserId(), companyId, RoleConstants.ADMINISTRATOR);
948    
949                    try {
950                            if (value == null) {
951                                    value = RoleLocalServiceUtil.hasUserRole(
952                                            user.getUserId(), companyId, RoleConstants.ADMINISTRATOR,
953                                            true);
954    
955                                    PermissionCacheUtil.putUserPrimaryKeyRole(
956                                            getUserId(), companyId, RoleConstants.ADMINISTRATOR, value);
957                            }
958                    }
959                    catch (Exception e) {
960                            PermissionCacheUtil.removeUserPrimaryKeyRole(
961                                    getUserId(), companyId, RoleConstants.ADMINISTRATOR);
962    
963                            throw e;
964                    }
965    
966                    return value;
967            }
968    
969            protected boolean isContentReviewerImpl(long groupId)
970                    throws PortalException {
971    
972                    if (isCompanyAdmin() || isGroupAdmin(groupId)) {
973                            return true;
974                    }
975    
976                    Group group = GroupLocalServiceUtil.getGroup(groupId);
977    
978                    if (RoleLocalServiceUtil.hasUserRole(
979                                    getUserId(), group.getCompanyId(),
980                                    RoleConstants.PORTAL_CONTENT_REVIEWER, true)) {
981    
982                            return true;
983                    }
984    
985                    if (group.isSite()) {
986                            if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
987                                            getUserId(), groupId, RoleConstants.SITE_CONTENT_REVIEWER,
988                                            true)) {
989    
990                                    return true;
991                            }
992                    }
993    
994                    return false;
995            }
996    
997            protected boolean isContentReviewerImpl(long companyId, long groupId)
998                    throws Exception {
999    
1000                    if (!signedIn) {
1001                            return false;
1002                    }
1003    
1004                    if (isOmniadmin()) {
1005                            return true;
1006                    }
1007    
1008                    if (isCompanyAdmin(companyId)) {
1009                            return true;
1010                    }
1011    
1012                    if (groupId <= 0) {
1013                            return false;
1014                    }
1015    
1016                    if (isGroupAdmin(groupId)) {
1017                            return true;
1018                    }
1019    
1020                    Boolean value = PermissionCacheUtil.getUserPrimaryKeyRole(
1021                            getUserId(), groupId, RoleConstants.SITE_CONTENT_REVIEWER);
1022    
1023                    try {
1024                            if (value == null) {
1025                                    value = isContentReviewerImpl(groupId);
1026    
1027                                    PermissionCacheUtil.putUserPrimaryKeyRole(
1028                                            getUserId(), groupId, RoleConstants.SITE_CONTENT_REVIEWER,
1029                                            value);
1030                            }
1031                    }
1032                    catch (Exception e) {
1033                            PermissionCacheUtil.removeUserPrimaryKeyRole(
1034                                    getUserId(), groupId, RoleConstants.SITE_CONTENT_REVIEWER);
1035    
1036                            throw e;
1037                    }
1038    
1039                    return value;
1040            }
1041    
1042            protected boolean isGroupAdminImpl(Group group) throws Exception {
1043                    if (group.isLayout()) {
1044                            long parentGroupId = group.getParentGroupId();
1045    
1046                            if (parentGroupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
1047                                    return false;
1048                            }
1049    
1050                            group = GroupLocalServiceUtil.getGroup(parentGroupId);
1051                    }
1052    
1053                    if (group.isSite()) {
1054                            if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1055                                            getUserId(), group.getGroupId(),
1056                                            RoleConstants.SITE_ADMINISTRATOR, true) ||
1057                                    UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1058                                            getUserId(), group.getGroupId(), RoleConstants.SITE_OWNER,
1059                                            true)) {
1060    
1061                                    return true;
1062                            }
1063    
1064                            StopWatch stopWatch = new StopWatch();
1065    
1066                            stopWatch.start();
1067    
1068                            while (!group.isRoot()) {
1069                                    Group parentGroup = group.getParentGroup();
1070    
1071                                    if (doCheckPermission(
1072                                                    parentGroup.getCompanyId(), parentGroup.getGroupId(),
1073                                                    Group.class.getName(),
1074                                                    String.valueOf(parentGroup.getGroupId()),
1075                                                    ActionKeys.MANAGE_SUBGROUPS, stopWatch)) {
1076    
1077                                            return true;
1078                                    }
1079    
1080                                    group = parentGroup;
1081                            }
1082                    }
1083    
1084                    if (group.isCompany()) {
1085                            if (isCompanyAdmin()) {
1086                                    return true;
1087                            }
1088                            else {
1089                                    return false;
1090                            }
1091                    }
1092                    else if (group.isLayoutPrototype()) {
1093                            if (LayoutPrototypePermissionUtil.contains(
1094                                            this, group.getClassPK(), ActionKeys.UPDATE)) {
1095    
1096                                    return true;
1097                            }
1098                            else {
1099                                    return false;
1100                            }
1101                    }
1102                    else if (group.isLayoutSetPrototype()) {
1103                            if (LayoutSetPrototypePermissionUtil.contains(
1104                                            this, group.getClassPK(), ActionKeys.UPDATE)) {
1105    
1106                                    return true;
1107                            }
1108                            else {
1109                                    return false;
1110                            }
1111                    }
1112                    else if (group.isOrganization()) {
1113                            long organizationId = group.getOrganizationId();
1114    
1115                            while (organizationId !=
1116                                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1117    
1118                                    Organization organization =
1119                                            OrganizationLocalServiceUtil.getOrganization(
1120                                                    organizationId);
1121    
1122                                    long organizationGroupId = organization.getGroupId();
1123    
1124                                    if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1125                                                    getUserId(), organizationGroupId,
1126                                                    RoleConstants.ORGANIZATION_ADMINISTRATOR, true) ||
1127                                            UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1128                                                    getUserId(), organizationGroupId,
1129                                                    RoleConstants.ORGANIZATION_OWNER, true)) {
1130    
1131                                            return true;
1132                                    }
1133    
1134                                    organizationId = organization.getParentOrganizationId();
1135                            }
1136    
1137                            StopWatch stopWatch = new StopWatch();
1138    
1139                            stopWatch.start();
1140    
1141                            Organization organization =
1142                                    OrganizationLocalServiceUtil.getOrganization(
1143                                            group.getOrganizationId());
1144    
1145                            while (!organization.isRoot()) {
1146                                    Organization parentOrganization =
1147                                            organization.getParentOrganization();
1148    
1149                                    Group parentGroup = parentOrganization.getGroup();
1150    
1151                                    if (doCheckPermission(
1152                                                    parentGroup.getCompanyId(), parentGroup.getGroupId(),
1153                                                    Organization.class.getName(),
1154                                                    String.valueOf(parentOrganization.getOrganizationId()),
1155                                                    ActionKeys.MANAGE_SUBORGANIZATIONS, stopWatch)) {
1156    
1157                                            return true;
1158                                    }
1159    
1160                                    organization = parentOrganization;
1161                            }
1162                    }
1163    
1164                    return false;
1165            }
1166    
1167            protected boolean isGroupAdminImpl(long groupId) throws Exception {
1168                    if (!signedIn) {
1169                            return false;
1170                    }
1171    
1172                    if (isOmniadmin()) {
1173                            return true;
1174                    }
1175    
1176                    if (groupId <= 0) {
1177                            return false;
1178                    }
1179    
1180                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1181    
1182                    if (isCompanyAdmin(group.getCompanyId())) {
1183                            return true;
1184                    }
1185    
1186                    Boolean value = PermissionCacheUtil.getUserPrimaryKeyRole(
1187                            getUserId(), group.getGroupId(), RoleConstants.SITE_ADMINISTRATOR);
1188    
1189                    try {
1190                            if (value == null) {
1191                                    value = isGroupAdminImpl(group);
1192    
1193                                    PermissionCacheUtil.putUserPrimaryKeyRole(
1194                                            getUserId(), group.getGroupId(),
1195                                            RoleConstants.SITE_ADMINISTRATOR, value);
1196                            }
1197                    }
1198                    catch (Exception e) {
1199                            PermissionCacheUtil.removeUserPrimaryKeyRole(
1200                                    getUserId(), group.getGroupId(),
1201                                    RoleConstants.SITE_ADMINISTRATOR);
1202    
1203                            throw e;
1204                    }
1205    
1206                    return value;
1207            }
1208    
1209            protected boolean isGroupMemberImpl(long groupId) throws Exception {
1210                    if (!signedIn) {
1211                            return false;
1212                    }
1213    
1214                    if (groupId <= 0) {
1215                            return false;
1216                    }
1217    
1218                    List<Role> roles = RoleLocalServiceUtil.getRoles(
1219                            doGetRoleIds(getUserId(), groupId));
1220    
1221                    for (Role role : roles) {
1222                            String roleName = role.getName();
1223    
1224                            if (roleName.equals(RoleConstants.SITE_MEMBER)) {
1225                                    return true;
1226                            }
1227                    }
1228    
1229                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1230    
1231                    UserBag userBag = getUserBag();
1232    
1233                    Set<Group> groups = userBag.getUserGroups();
1234    
1235                    if (groups.contains(group)) {
1236                            return true;
1237                    }
1238                    else {
1239                            return false;
1240                    }
1241            }
1242    
1243            protected boolean isGroupOwnerImpl(Group group) throws PortalException {
1244                    if (group.isSite()) {
1245                            if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1246                                            getUserId(), group.getGroupId(), RoleConstants.SITE_OWNER,
1247                                            true)) {
1248    
1249                                    return true;
1250                            }
1251                    }
1252    
1253                    if (group.isLayoutPrototype()) {
1254                            if (LayoutPrototypePermissionUtil.contains(
1255                                            this, group.getClassPK(), ActionKeys.UPDATE)) {
1256    
1257                                    return true;
1258                            }
1259                            else {
1260                                    return false;
1261                            }
1262                    }
1263                    else if (group.isLayoutSetPrototype()) {
1264                            if (LayoutSetPrototypePermissionUtil.contains(
1265                                            this, group.getClassPK(), ActionKeys.UPDATE)) {
1266    
1267                                    return true;
1268                            }
1269                            else {
1270                                    return false;
1271                            }
1272                    }
1273                    else if (group.isOrganization()) {
1274                            long organizationId = group.getOrganizationId();
1275    
1276                            while (organizationId !=
1277                                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1278    
1279                                    Organization organization =
1280                                            OrganizationLocalServiceUtil.getOrganization(
1281                                                    organizationId);
1282    
1283                                    long organizationGroupId = organization.getGroupId();
1284    
1285                                    if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1286                                                    getUserId(), organizationGroupId,
1287                                                    RoleConstants.ORGANIZATION_OWNER, true)) {
1288    
1289                                            return true;
1290                                    }
1291    
1292                                    organizationId = organization.getParentOrganizationId();
1293                            }
1294                    }
1295                    else if (group.isUser()) {
1296                            long groupUserId = group.getClassPK();
1297    
1298                            if (getUserId() == groupUserId) {
1299                                    return true;
1300                            }
1301                    }
1302    
1303                    return false;
1304            }
1305    
1306            protected boolean isGroupOwnerImpl(long groupId) throws Exception {
1307                    if (!signedIn) {
1308                            return false;
1309                    }
1310    
1311                    if (isOmniadmin()) {
1312                            return true;
1313                    }
1314    
1315                    if (groupId <= 0) {
1316                            return false;
1317                    }
1318    
1319                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1320    
1321                    if (isCompanyAdmin(group.getCompanyId())) {
1322                            return true;
1323                    }
1324    
1325                    Boolean value = PermissionCacheUtil.getUserPrimaryKeyRole(
1326                            getUserId(), group.getGroupId(), RoleConstants.SITE_OWNER);
1327    
1328                    try {
1329                            if (value == null) {
1330                                    value = isGroupOwnerImpl(group);
1331    
1332                                    PermissionCacheUtil.putUserPrimaryKeyRole(
1333                                            getUserId(), group.getGroupId(), RoleConstants.SITE_OWNER,
1334                                            value);
1335                            }
1336                    }
1337                    catch (Exception e) {
1338                            PermissionCacheUtil.removeUserPrimaryKeyRole(
1339                                    getUserId(), group.getGroupId(), RoleConstants.SITE_OWNER);
1340    
1341                            throw e;
1342                    }
1343    
1344                    return value;
1345            }
1346    
1347            protected boolean isOrganizationAdminImpl(long organizationId)
1348                    throws Exception {
1349    
1350                    if (!signedIn) {
1351                            return false;
1352                    }
1353    
1354                    if (isOmniadmin()) {
1355                            return true;
1356                    }
1357    
1358                    if (organizationId <= 0) {
1359                            return false;
1360                    }
1361    
1362                    Organization organization =
1363                            OrganizationLocalServiceUtil.fetchOrganization(organizationId);
1364    
1365                    if (organization == null) {
1366                            return false;
1367                    }
1368    
1369                    if (isCompanyAdmin(organization.getCompanyId())) {
1370                            return true;
1371                    }
1372    
1373                    Boolean value = PermissionCacheUtil.getUserPrimaryKeyRole(
1374                            getUserId(), organization.getOrganizationId(),
1375                            RoleConstants.ORGANIZATION_ADMINISTRATOR);
1376    
1377                    try {
1378                            if (value == null) {
1379                                    value = isOrganizationAdminImpl(organization);
1380    
1381                                    PermissionCacheUtil.putUserPrimaryKeyRole(
1382                                            getUserId(), organization.getOrganizationId(),
1383                                            RoleConstants.ORGANIZATION_ADMINISTRATOR, value);
1384                            }
1385                    }
1386                    catch (Exception e) {
1387                            PermissionCacheUtil.removeUserPrimaryKeyRole(
1388                                    getUserId(), organization.getOrganizationId(),
1389                                    RoleConstants.ORGANIZATION_ADMINISTRATOR);
1390    
1391                            throw e;
1392                    }
1393    
1394                    return value;
1395            }
1396    
1397            protected boolean isOrganizationAdminImpl(Organization organization)
1398                    throws PortalException {
1399    
1400                    while (organization != null) {
1401                            long organizationGroupId = organization.getGroupId();
1402    
1403                            long userId = getUserId();
1404    
1405                            if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1406                                            userId, organizationGroupId,
1407                                            RoleConstants.ORGANIZATION_ADMINISTRATOR, true) ||
1408                                    UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1409                                            userId, organizationGroupId,
1410                                            RoleConstants.ORGANIZATION_OWNER, true)) {
1411    
1412                                    return true;
1413                            }
1414    
1415                            organization = organization.getParentOrganization();
1416                    }
1417    
1418                    return false;
1419            }
1420    
1421            protected boolean isOrganizationOwnerImpl(long organizationId)
1422                    throws Exception {
1423    
1424                    if (!signedIn) {
1425                            return false;
1426                    }
1427    
1428                    if (isOmniadmin()) {
1429                            return true;
1430                    }
1431    
1432                    if (organizationId <= 0) {
1433                            return false;
1434                    }
1435    
1436                    Organization organization =
1437                            OrganizationLocalServiceUtil.fetchOrganization(organizationId);
1438    
1439                    if (organization == null) {
1440                            return false;
1441                    }
1442    
1443                    if (isCompanyAdmin(organization.getCompanyId())) {
1444                            return true;
1445                    }
1446    
1447                    Boolean value = PermissionCacheUtil.getUserPrimaryKeyRole(
1448                            getUserId(), organization.getOrganizationId(),
1449                            RoleConstants.ORGANIZATION_OWNER);
1450    
1451                    try {
1452                            if (value == null) {
1453                                    value = isOrganizationOwnerImpl(organization);
1454    
1455                                    PermissionCacheUtil.putUserPrimaryKeyRole(
1456                                            getUserId(), organization.getOrganizationId(),
1457                                            RoleConstants.ORGANIZATION_OWNER, value);
1458                            }
1459                    }
1460                    catch (Exception e) {
1461                            PermissionCacheUtil.removeUserPrimaryKeyRole(
1462                                    getUserId(), organization.getOrganizationId(),
1463                                    RoleConstants.ORGANIZATION_OWNER);
1464    
1465                            throw e;
1466                    }
1467    
1468                    return value;
1469            }
1470    
1471            protected boolean isOrganizationOwnerImpl(Organization organization)
1472                    throws PortalException {
1473    
1474                    while (organization != null) {
1475                            long organizationGroupId = organization.getGroupId();
1476    
1477                            long userId = getUserId();
1478    
1479                            if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1480                                            userId, organizationGroupId,
1481                                            RoleConstants.ORGANIZATION_OWNER, true)) {
1482    
1483                                    return true;
1484                            }
1485    
1486                            organization = organization.getParentOrganization();
1487                    }
1488    
1489                    return false;
1490            }
1491    
1492            protected void logHasUserPermission(
1493                    long groupId, String name, String primKey, String actionId,
1494                    StopWatch stopWatch, int block) {
1495    
1496                    if (!_log.isDebugEnabled()) {
1497                            return;
1498                    }
1499    
1500                    _log.debug(
1501                            "Checking user permission block " + block + " for " + groupId +
1502                                    " " + name + " " + primKey + " " + actionId + " takes " +
1503                                            stopWatch.getTime() + " ms");
1504            }
1505    
1506            /**
1507             * @deprecated As of 6.1.0
1508             */
1509            @Deprecated
1510            protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
1511    
1512            private static final Log _log = LogFactoryUtil.getLog(
1513                    AdvancedPermissionChecker.class);
1514    
1515    }