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