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                    Group group = null;
555    
556                    try {
557                            if (groupId > 0) {
558                                    group = GroupLocalServiceUtil.getGroup(groupId);
559    
560                                    // If the group is a scope group for a layout, check the
561                                    // original group.
562    
563                                    if (group.isLayout() &&
564                                            !ResourceBlockLocalServiceUtil.isSupported(name)) {
565    
566                                            Layout layout = LayoutLocalServiceUtil.getLayout(
567                                                    group.getClassPK());
568    
569                                            groupId = layout.getGroupId();
570    
571                                            group = GroupLocalServiceUtil.getGroup(groupId);
572                                    }
573                                    else if (group.isUserPersonalSite()) {
574                                            return false;
575                                    }
576    
577                                    // If the group is a personal site, check the "User Personal
578                                    // Site" group.
579    
580                                    if (group.isUser() && (group.getClassPK() == getUserId())) {
581                                            group = GroupLocalServiceUtil.getGroup(
582                                                    getCompanyId(), GroupConstants.USER_PERSONAL_SITE);
583    
584                                            groupId = group.getGroupId();
585                                    }
586    
587                                    // If the group is a staging group, check the live group.
588    
589                                    if (group.isStagingGroup()) {
590                                            if (primKey.equals(String.valueOf(groupId))) {
591                                                    primKey = String.valueOf(group.getLiveGroupId());
592                                            }
593    
594                                            groupId = group.getLiveGroupId();
595                                            group = group.getLiveGroup();
596                                    }
597                            }
598                    }
599                    catch (Exception e) {
600                            _log.error(e, e);
601                    }
602    
603                    Boolean value = PermissionCacheUtil.getPermission(
604                            user.getUserId(), signedIn, groupId, name, primKey, actionId);
605    
606                    if (value != null) {
607                            return value.booleanValue();
608                    }
609    
610                    try {
611                            value = Boolean.valueOf(
612                                    hasPermissionImpl(groupId, name, primKey, actionId));
613    
614                            if (_log.isDebugEnabled()) {
615                                    _log.debug(
616                                            "Checking permission for " + groupId + " " + name +
617                                                    " " + primKey + " " + actionId + " takes " +
618                                                            stopWatch.getTime() + " ms");
619                            }
620                    }
621                    finally {
622                            if (value == null) {
623                                    value = Boolean.FALSE;
624                            }
625    
626                            PermissionCacheUtil.putPermission(
627                                    user.getUserId(), signedIn, groupId, name, primKey, actionId,
628                                    value);
629                    }
630    
631                    return value.booleanValue();
632            }
633    
634            @Override
635            public boolean hasUserPermission(
636                    long groupId, String name, String primKey, String actionId,
637                    boolean checkAdmin) {
638    
639                    try {
640                            return hasUserPermissionImpl(
641                                    groupId, name, primKey, actionId, checkAdmin);
642                    }
643                    catch (Exception e) {
644                            _log.error(e, e);
645    
646                            return false;
647                    }
648            }
649    
650            @Override
651            public boolean isCompanyAdmin() {
652                    try {
653                            return isCompanyAdminImpl();
654                    }
655                    catch (Exception e) {
656                            _log.error(e, e);
657    
658                            return false;
659                    }
660            }
661    
662            @Override
663            public boolean isCompanyAdmin(long companyId) {
664                    try {
665                            return isCompanyAdminImpl(companyId);
666                    }
667                    catch (Exception e) {
668                            _log.error(e, e);
669    
670                            return false;
671                    }
672            }
673    
674            @Override
675            public boolean isContentReviewer(long companyId, long groupId) {
676                    try {
677                            return isContentReviewerImpl(companyId, groupId);
678                    }
679                    catch (Exception e) {
680                            _log.error(e, e);
681                    }
682    
683                    return false;
684            }
685    
686            @Override
687            public boolean isGroupAdmin(long groupId) {
688                    try {
689                            return isGroupAdminImpl(groupId);
690                    }
691                    catch (Exception e) {
692                            _log.error(e, e);
693    
694                            return false;
695                    }
696            }
697    
698            @Override
699            public boolean isGroupMember(long groupId) {
700                    try {
701                            return isGroupMemberImpl(groupId);
702                    }
703                    catch (Exception e) {
704                            _log.error(e, e);
705    
706                            return false;
707                    }
708            }
709    
710            @Override
711            public boolean isGroupOwner(long groupId) {
712                    try {
713                            return isGroupOwnerImpl(groupId);
714                    }
715                    catch (Exception e) {
716                            _log.error(e, e);
717    
718                            return false;
719                    }
720            }
721    
722            @Override
723            public boolean isOrganizationAdmin(long organizationId) {
724                    try {
725                            return isOrganizationAdminImpl(organizationId);
726                    }
727                    catch (Exception e) {
728                            _log.error(e, e);
729    
730                            return false;
731                    }
732            }
733    
734            @Override
735            public boolean isOrganizationOwner(long organizationId) {
736                    try {
737                            return isOrganizationOwnerImpl(organizationId);
738                    }
739                    catch (Exception e) {
740                            _log.error(e, e);
741    
742                            return false;
743                    }
744            }
745    
746            protected void addTeamRoles(long userId, Group group, List<Role> roles)
747                    throws Exception {
748    
749                    List<Team> userTeams = TeamLocalServiceUtil.getUserTeams(
750                            userId, group.getGroupId());
751    
752                    for (Team team : userTeams) {
753                            Role role = RoleLocalServiceUtil.getTeamRole(
754                                    team.getCompanyId(), team.getTeamId());
755    
756                            roles.add(role);
757                    }
758    
759                    LinkedHashMap<String, Object> teamParams =
760                            new LinkedHashMap<String, Object>();
761    
762                    teamParams.put("usersUserGroups", userId);
763    
764                    List<Team> userGroupTeams = TeamLocalServiceUtil.search(
765                            group.getGroupId(), null, null, teamParams, QueryUtil.ALL_POS,
766                            QueryUtil.ALL_POS, null);
767    
768                    for (Team team : userGroupTeams) {
769                            Role role = RoleLocalServiceUtil.getTeamRole(
770                                    team.getCompanyId(), team.getTeamId());
771    
772                            roles.add(role);
773                    }
774            }
775    
776            protected boolean doCheckPermission(
777                            long companyId, long groupId, String name, String primKey,
778                            String actionId, StopWatch stopWatch)
779                    throws Exception {
780    
781                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
782    
783                    if (ResourceBlockLocalServiceUtil.isSupported(name)) {
784                            ResourceBlockIdsBag resourceBlockIdsBag = getResourceBlockIdsBag(
785                                    companyId, groupId, getUserId(), name);
786    
787                            boolean value = ResourceBlockLocalServiceUtil.hasPermission(
788                                    name, GetterUtil.getLong(primKey), actionId,
789                                    resourceBlockIdsBag);
790    
791                            logHasUserPermission(
792                                    groupId, name, primKey, actionId, stopWatch, 2);
793    
794                            return value;
795                    }
796    
797                    List<Resource> resources = getResources(
798                            companyId, groupId, name, primKey, actionId);
799    
800                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
801    
802                    // Check if user has access to perform the action on the given resource
803                    // scopes. The resources are scoped to check first for an individual
804                    // class, then for the group that the class may belong to, and then for
805                    // the company that the class belongs to.
806    
807                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
808    
809                    boolean value = ResourceLocalServiceUtil.hasUserPermissions(
810                            user.getUserId(), groupId, resources, actionId, bag.getRoleIds());
811    
812                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 4);
813    
814                    return value;
815            }
816    
817            /**
818             * Returns representations of the resource at each scope level.
819             *
820             * <p>
821             * For example, if the class name and primary key of a blog entry were
822             * passed to this method, it would return a resource for the blog entry
823             * itself (individual scope), a resource representing all blog entries
824             * within its group (group scope), a resource standing for all blog entries
825             * within a group the user has a suitable role in (group-template scope),
826             * and a resource signifying all blog entries within the company (company
827             * scope).
828             * </p>
829             *
830             * @param  companyId the primary key of the company
831             * @param  groupId the primary key of the group containing the resource
832             * @param  name the resource's name, which can be either a class name or a
833             *         portlet ID
834             * @param  primKey the primary key of the resource
835             * @param  actionId unused
836             * @return representations of the resource at each scope level
837             * @throws Exception if an exception occurred
838             */
839            protected List<Resource> getResources(
840                            long companyId, long groupId, String name, String primKey,
841                            String actionId)
842                    throws Exception {
843    
844                    // Individual
845    
846                    List<Resource> resources = new ArrayList<Resource>(4);
847    
848                    Resource individualResource = ResourceLocalServiceUtil.getResource(
849                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
850    
851                    resources.add(individualResource);
852    
853                    // Group
854    
855                    if (groupId > 0) {
856                            Resource groupResource = ResourceLocalServiceUtil.getResource(
857                                    companyId, name, ResourceConstants.SCOPE_GROUP,
858                                    String.valueOf(groupId));
859    
860                            resources.add(groupResource);
861                    }
862    
863                    // Group template
864    
865                    if (signedIn && (groupId > 0)) {
866                            Resource groupTemplateResource =
867                                    ResourceLocalServiceUtil.getResource(
868                                            companyId, name, ResourceConstants.SCOPE_GROUP_TEMPLATE,
869                                            String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
870    
871                            resources.add(groupTemplateResource);
872                    }
873    
874                    // Company
875    
876                    Resource companyResource = ResourceLocalServiceUtil.getResource(
877                            companyId, name, ResourceConstants.SCOPE_COMPANY,
878                            String.valueOf(companyId));
879    
880                    resources.add(companyResource);
881    
882                    return resources;
883            }
884    
885            /**
886             * Returns all of the organizations that the user is a member of, including
887             * their parent organizations.
888             *
889             * @param  userId the primary key of the user
890             * @return all of the organizations that the user is a member of, including
891             *         their parent organizations
892             * @throws Exception if a user with the primary key could not be found
893             */
894            protected List<Organization> getUserOrgs(long userId) throws Exception {
895                    List<Organization> userOrgs =
896                            OrganizationLocalServiceUtil.getUserOrganizations(userId);
897    
898                    if (userOrgs.size() == 0) {
899                            return userOrgs;
900                    }
901    
902                    List<Organization> organizations = new UniqueList<Organization>();
903    
904                    for (Organization organization : userOrgs) {
905                            if (!organizations.contains(organization)) {
906                                    organizations.add(organization);
907    
908                                    List<Organization> ancestorOrganizations =
909                                            OrganizationLocalServiceUtil.getParentOrganizations(
910                                                    organization.getOrganizationId());
911    
912                                    organizations.addAll(ancestorOrganizations);
913                            }
914                    }
915    
916                    return organizations;
917            }
918    
919            protected boolean hasGuestPermission(
920                            long groupId, String name, String primKey, String actionId)
921                    throws Exception {
922    
923                    ResourceActionsUtil.checkAction(name, actionId);
924    
925                    if (name.indexOf(CharPool.PERIOD) != -1) {
926    
927                            // Check unsupported model actions
928    
929                            List<String> actions =
930                                    ResourceActionsUtil.getModelResourceGuestUnsupportedActions(
931                                            name);
932    
933                            if (actions.contains(actionId)) {
934                                    return false;
935                            }
936                    }
937                    else {
938    
939                            // Check unsupported portlet actions
940    
941                            List<String> actions =
942                                    ResourceActionsUtil.getPortletResourceGuestUnsupportedActions(
943                                            name);
944    
945                            if (actions.contains(actionId)) {
946                                    return false;
947                            }
948                    }
949    
950                    long companyId = user.getCompanyId();
951    
952                    List<Resource> resources = getResources(
953                            companyId, groupId, name, primKey, actionId);
954    
955                    PermissionCheckerBag bag = getGuestUserBag();
956    
957                    try {
958                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
959                                    ResourceBlockIdsBag resourceBlockIdsBag =
960                                            getGuestResourceBlockIdsBag(companyId, groupId, name);
961    
962                                    return ResourceBlockLocalServiceUtil.hasPermission(
963                                            name, GetterUtil.getLong(primKey), actionId,
964                                            resourceBlockIdsBag);
965                            }
966    
967                            return ResourceLocalServiceUtil.hasUserPermissions(
968                                    defaultUserId, groupId, resources, actionId, bag.getRoleIds());
969                    }
970                    catch (Exception e) {
971                            _log.error(e, e);
972    
973                            return false;
974                    }
975            }
976    
977            protected boolean hasPermissionImpl(
978                    long groupId, String name, String primKey, String actionId) {
979    
980                    try {
981                            if (!signedIn) {
982                                    return hasGuestPermission(groupId, name, primKey, actionId);
983                            }
984    
985                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
986    
987                                    // It is not necessary to check guest permissions separately, as
988                                    // the user's resource block IDs bag will already have the guest
989                                    // permissions in it if checkGuest is true.
990    
991                                    return hasUserPermission(
992                                            groupId, name, primKey, actionId, true);
993                            }
994    
995                            boolean value = false;
996    
997                            if (checkGuest) {
998                                    value = hasGuestPermission(groupId, name, primKey, actionId);
999                            }
1000    
1001                            if (!value) {
1002                                    value = hasUserPermission(
1003                                            groupId, name, primKey, actionId, true);
1004                            }
1005    
1006                            return value;
1007                    }
1008                    catch (Exception e) {
1009                            _log.error(e, e);
1010    
1011                            return false;
1012                    }
1013            }
1014    
1015            protected boolean hasUserPermissionImpl(
1016                            long groupId, String name, String primKey, String actionId,
1017                            boolean checkAdmin)
1018                    throws Exception {
1019    
1020                    StopWatch stopWatch = new StopWatch();
1021    
1022                    stopWatch.start();
1023    
1024                    long companyId = user.getCompanyId();
1025    
1026                    if (groupId > 0) {
1027                            Group group = GroupLocalServiceUtil.getGroup(groupId);
1028    
1029                            companyId = group.getCompanyId();
1030                    }
1031    
1032                    boolean hasLayoutManagerPermission = true;
1033    
1034                    // Check if the layout manager has permission to do this action for the
1035                    // current portlet
1036    
1037                    if (Validator.isNotNull(name) && Validator.isNotNull(primKey) &&
1038                            primKey.contains(PortletConstants.LAYOUT_SEPARATOR)) {
1039    
1040                            hasLayoutManagerPermission =
1041                                    PortletPermissionUtil.hasLayoutManagerPermission(
1042                                            name, actionId);
1043                    }
1044    
1045                    if (checkAdmin) {
1046                            if (isCompanyAdminImpl(companyId)) {
1047                                    return true;
1048                            }
1049    
1050                            if (name.equals(Organization.class.getName())) {
1051                                    long organizationId = GetterUtil.getInteger(primKey);
1052    
1053                                    if (isOrganizationAdminImpl(organizationId)) {
1054                                            return true;
1055                                    }
1056                            }
1057                            else if (isGroupAdminImpl(groupId) && hasLayoutManagerPermission) {
1058                                    return true;
1059                            }
1060                    }
1061    
1062                    return doCheckPermission(
1063                            companyId, groupId, name, primKey, actionId, stopWatch);
1064            }
1065    
1066            protected boolean isCompanyAdminImpl() throws Exception {
1067                    return isCompanyAdminImpl(user.getCompanyId());
1068            }
1069    
1070            protected boolean isCompanyAdminImpl(long companyId) throws Exception {
1071                    if (!signedIn) {
1072                            return false;
1073                    }
1074    
1075                    if (isOmniadmin()) {
1076                            return true;
1077                    }
1078    
1079                    Boolean value = companyAdmins.get(companyId);
1080    
1081                    if (value == null) {
1082                            boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
1083                                    user.getUserId(), companyId, RoleConstants.ADMINISTRATOR, true);
1084    
1085                            value = Boolean.valueOf(hasAdminRole);
1086    
1087                            companyAdmins.put(companyId, value);
1088                    }
1089    
1090                    return value.booleanValue();
1091            }
1092    
1093            protected boolean isContentReviewerImpl(long companyId, long groupId)
1094                    throws Exception {
1095    
1096                    if (!signedIn) {
1097                            return false;
1098                    }
1099    
1100                    if (isOmniadmin()) {
1101                            return true;
1102                    }
1103    
1104                    if (isCompanyAdmin(companyId)) {
1105                            return true;
1106                    }
1107    
1108                    if (groupId <= 0) {
1109                            return false;
1110                    }
1111    
1112                    if (isGroupAdmin(groupId)) {
1113                            return true;
1114                    }
1115    
1116                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1117    
1118                    if (bag == null) {
1119                            _log.error("Bag should never be null");
1120                    }
1121    
1122                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1123    
1124                    if (bag.isContentReviewer(this, group)) {
1125                            return true;
1126                    }
1127                    else {
1128                            return false;
1129                    }
1130            }
1131    
1132            protected boolean isGroupAdminImpl(long groupId) throws Exception {
1133                    if (!signedIn) {
1134                            return false;
1135                    }
1136    
1137                    if (isOmniadmin()) {
1138                            return true;
1139                    }
1140    
1141                    if (groupId <= 0) {
1142                            return false;
1143                    }
1144    
1145                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1146    
1147                    if (isCompanyAdmin(group.getCompanyId())) {
1148                            return true;
1149                    }
1150    
1151                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1152    
1153                    if (bag == null) {
1154                            _log.error("Bag should never be null");
1155                    }
1156    
1157                    if (bag.isGroupAdmin(this, group)) {
1158                            return true;
1159                    }
1160    
1161                    StopWatch stopWatch = new StopWatch();
1162    
1163                    stopWatch.start();
1164    
1165                    if (group.isOrganization()) {
1166                            Organization organization =
1167                                    OrganizationLocalServiceUtil.getOrganization(
1168                                            group.getOrganizationId());
1169    
1170                            while (!organization.isRoot()) {
1171                                    Organization parentOrganization =
1172                                            organization.getParentOrganization();
1173    
1174                                    Group parentGroup = parentOrganization.getGroup();
1175    
1176                                    if (doCheckPermission(
1177                                                    parentGroup.getCompanyId(), parentGroup.getGroupId(),
1178                                                    Organization.class.getName(),
1179                                                    String.valueOf(parentOrganization.getOrganizationId()),
1180                                                    ActionKeys.MANAGE_SUBORGANIZATIONS, stopWatch)) {
1181    
1182                                            return true;
1183                                    }
1184    
1185                                    organization = parentOrganization;
1186                            }
1187                    }
1188    
1189                    if (group.isSite()) {
1190                            while (!group.isRoot()) {
1191                                    Group parentGroup = group.getParentGroup();
1192    
1193                                    if (doCheckPermission(
1194                                                    parentGroup.getCompanyId(), parentGroup.getGroupId(),
1195                                                    Group.class.getName(),
1196                                                    String.valueOf(parentGroup.getGroupId()),
1197                                                    ActionKeys.MANAGE_SUBGROUPS, stopWatch)) {
1198    
1199                                            return true;
1200                                    }
1201    
1202                                    group = parentGroup;
1203                            }
1204                    }
1205    
1206                    return false;
1207            }
1208    
1209            protected boolean isGroupMemberImpl(long groupId) throws Exception {
1210                    if (!signedIn) {
1211                            return false;
1212                    }
1213    
1214                    if (groupId <= 0) {
1215                            return false;
1216                    }
1217    
1218                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1219    
1220                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1221    
1222                    if (bag == null) {
1223                            _log.error("Bag should never be null");
1224                    }
1225    
1226                    if (bag.isGroupMember(this, group)) {
1227                            return true;
1228                    }
1229                    else {
1230                            return false;
1231                    }
1232            }
1233    
1234            protected boolean isGroupOwnerImpl(long groupId) throws Exception {
1235                    if (!signedIn) {
1236                            return false;
1237                    }
1238    
1239                    if (isOmniadmin()) {
1240                            return true;
1241                    }
1242    
1243                    if (groupId <= 0) {
1244                            return false;
1245                    }
1246    
1247                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1248    
1249                    if (isCompanyAdmin(group.getCompanyId())) {
1250                            return true;
1251                    }
1252    
1253                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1254    
1255                    if (bag == null) {
1256                            _log.error("Bag should never be null");
1257                    }
1258    
1259                    if (bag.isGroupOwner(this, group)) {
1260                            return true;
1261                    }
1262                    else {
1263                            return false;
1264                    }
1265            }
1266    
1267            protected boolean isOrganizationAdminImpl(long organizationId)
1268                    throws Exception {
1269    
1270                    if (!signedIn) {
1271                            return false;
1272                    }
1273    
1274                    if (isOmniadmin()) {
1275                            return true;
1276                    }
1277    
1278                    if (organizationId <= 0) {
1279                            return false;
1280                    }
1281    
1282                    Organization organization =
1283                            OrganizationLocalServiceUtil.fetchOrganization(organizationId);
1284    
1285                    if (organization == null) {
1286                            return false;
1287                    }
1288    
1289                    if (isCompanyAdmin(organization.getCompanyId())) {
1290                            return true;
1291                    }
1292    
1293                    PermissionCheckerBag bag = getUserBag(
1294                            user.getUserId(), organization.getGroupId());
1295    
1296                    if (bag == null) {
1297                            _log.error("Bag should never be null");
1298                    }
1299    
1300                    if (bag.isOrganizationAdmin(this, organization)) {
1301                            return true;
1302                    }
1303                    else {
1304                            return false;
1305                    }
1306            }
1307    
1308            protected boolean isOrganizationOwnerImpl(long organizationId)
1309                    throws Exception {
1310    
1311                    if (!signedIn) {
1312                            return false;
1313                    }
1314    
1315                    if (isOmniadmin()) {
1316                            return true;
1317                    }
1318    
1319                    if (organizationId <= 0) {
1320                            return false;
1321                    }
1322    
1323                    Organization organization =
1324                            OrganizationLocalServiceUtil.fetchOrganization(organizationId);
1325    
1326                    if (organization == null) {
1327                            return false;
1328                    }
1329    
1330                    if (isCompanyAdmin(organization.getCompanyId())) {
1331                            return true;
1332                    }
1333    
1334                    PermissionCheckerBag bag = getUserBag(
1335                            user.getUserId(), organization.getGroupId());
1336    
1337                    if (bag == null) {
1338                            _log.error("Bag should never be null");
1339                    }
1340    
1341                    if (bag.isOrganizationOwner(this, organization)) {
1342                            return true;
1343                    }
1344                    else {
1345                            return false;
1346                    }
1347            }
1348    
1349            protected void logHasUserPermission(
1350                    long groupId, String name, String primKey, String actionId,
1351                    StopWatch stopWatch, int block) {
1352    
1353                    if (!_log.isDebugEnabled()) {
1354                            return;
1355                    }
1356    
1357                    _log.debug(
1358                            "Checking user permission block " + block + " for " + groupId +
1359                                    " " + name + " " + primKey + " " + actionId + " takes " +
1360                                            stopWatch.getTime() + " ms");
1361            }
1362    
1363            /**
1364             * @deprecated As of 6.1.0
1365             */
1366            @Deprecated
1367            protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
1368    
1369            protected Map<Long, Boolean> companyAdmins = new HashMap<Long, Boolean>();
1370    
1371            private static Log _log = LogFactoryUtil.getLog(
1372                    AdvancedPermissionChecker.class);
1373    
1374    }