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