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