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