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