001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.permission;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.ArrayUtil;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.ListUtil;
024    import com.liferay.portal.kernel.util.SetUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.model.Group;
027    import com.liferay.portal.model.GroupConstants;
028    import com.liferay.portal.model.GroupedModel;
029    import com.liferay.portal.model.Layout;
030    import com.liferay.portal.model.Organization;
031    import com.liferay.portal.model.PermissionedModel;
032    import com.liferay.portal.model.PortletConstants;
033    import com.liferay.portal.model.Resource;
034    import com.liferay.portal.model.ResourceBlockConstants;
035    import com.liferay.portal.model.ResourceConstants;
036    import com.liferay.portal.model.Role;
037    import com.liferay.portal.model.RoleConstants;
038    import com.liferay.portal.model.Team;
039    import com.liferay.portal.model.UserGroup;
040    import com.liferay.portal.service.GroupLocalServiceUtil;
041    import com.liferay.portal.service.LayoutLocalServiceUtil;
042    import com.liferay.portal.service.OrganizationLocalServiceUtil;
043    import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
044    import com.liferay.portal.service.ResourceLocalServiceUtil;
045    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
046    import com.liferay.portal.service.RoleLocalServiceUtil;
047    import com.liferay.portal.service.TeamLocalServiceUtil;
048    import com.liferay.portal.service.UserGroupLocalServiceUtil;
049    import com.liferay.portal.service.permission.PortletPermissionUtil;
050    
051    import java.util.ArrayList;
052    import java.util.Collections;
053    import java.util.HashMap;
054    import java.util.HashSet;
055    import java.util.LinkedHashMap;
056    import java.util.LinkedHashSet;
057    import java.util.List;
058    import java.util.Map;
059    import java.util.Set;
060    
061    import org.apache.commons.lang.time.StopWatch;
062    
063    /**
064     * @author Charles May
065     * @author Brian Wing Shun Chan
066     * @author Raymond Aug??
067     * @author Wesley Gong
068     * @author Connor McKay
069     */
070    public class AdvancedPermissionChecker extends BasePermissionChecker {
071    
072            @Override
073            public AdvancedPermissionChecker clone() {
074                    return new AdvancedPermissionChecker();
075            }
076    
077            @Override
078            public List<Long> getGuestResourceBlockIds(
079                    long companyId, long groupId, String name, String actionId) {
080    
081                    try {
082                            ResourceBlockIdsBag resourceBlockIdsBag =
083                                    getGuestResourceBlockIdsBag(companyId, groupId, name);
084    
085                            return ResourceBlockLocalServiceUtil.getResourceBlockIds(
086                                    resourceBlockIdsBag, name, actionId);
087                    }
088                    catch (Exception e) {
089                    }
090    
091                    return Collections.emptyList();
092            }
093    
094            public ResourceBlockIdsBag getGuestResourceBlockIdsBag(
095                            long companyId, long groupId, String name)
096                    throws Exception {
097    
098                    ResourceBlockIdsBag resourceBlockIdsBag =
099                            PermissionCacheUtil.getResourceBlockIdsBag(
100                                    companyId, groupId, defaultUserId, name);
101    
102                    if (resourceBlockIdsBag != null) {
103                            return resourceBlockIdsBag;
104                    }
105    
106                    try {
107                            PermissionCheckerBag bag = getGuestUserBag();
108    
109                            long[] roleIds = bag.getRoleIds();
110    
111                            resourceBlockIdsBag =
112                                    ResourceBlockLocalServiceUtil.getResourceBlockIdsBag(
113                                            getCompanyId(), groupId, name, roleIds);
114    
115                            PermissionCacheUtil.putResourceBlockIdsBag(
116                                    companyId, groupId, defaultUserId, name, resourceBlockIdsBag);
117    
118                            return resourceBlockIdsBag;
119                    }
120                    finally {
121                            if (resourceBlockIdsBag == null) {
122                                    resourceBlockIdsBag = new ResourceBlockIdsBag();
123                            }
124    
125                            PermissionCacheUtil.putResourceBlockIdsBag(
126                                    companyId, defaultUserId, groupId, name, resourceBlockIdsBag);
127                    }
128            }
129    
130            /**
131             * Returns the permission checker bag for the guest user.
132             *
133             * @return the permission checker bag for the guest user
134             * @throws Exception if an exception occurred
135             */
136            public PermissionCheckerBag getGuestUserBag() throws Exception {
137                    Group guestGroup = GroupLocalServiceUtil.getGroup(
138                            getCompanyId(), GroupConstants.GUEST);
139    
140                    PermissionCheckerBag bag = PermissionCacheUtil.getBag(
141                            defaultUserId, guestGroup.getGroupId());
142    
143                    if (bag != null) {
144                            return bag;
145                    }
146    
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 bag
157                            // as this implies group membership which is incorrect in the case
158                            // of unauthenticated users.
159    
160                            bag = new PermissionCheckerBagImpl(defaultUserId, roles);
161                    }
162                    finally {
163                            if (bag == null) {
164                                    bag = new PermissionCheckerBagImpl(defaultUserId);
165                            }
166    
167                            PermissionCacheUtil.putBag(
168                                    defaultUserId, guestGroup.getGroupId(), bag);
169                    }
170    
171                    return bag;
172            }
173    
174            @Override
175            public List<Long> getOwnerResourceBlockIds(
176                    long companyId, long groupId, String name, String actionId) {
177    
178                    try {
179                            ResourceBlockIdsBag resourceBlockIdsBag =
180                                    getOwnerResourceBlockIdsBag(companyId, groupId, name);
181    
182                            return ResourceBlockLocalServiceUtil.getResourceBlockIds(
183                                    resourceBlockIdsBag, name, actionId);
184                    }
185                    catch (Exception e) {
186                    }
187    
188                    return Collections.emptyList();
189            }
190    
191            public ResourceBlockIdsBag getOwnerResourceBlockIdsBag(
192                    long companyId, long groupId, String name) {
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                                    Set<Group> userGroups = SetUtil.fromList(
355                                            GroupLocalServiceUtil.getUserGroups(userId, true));
356    
357                                    List<Organization> userOrgs = getUserOrgs(userId);
358    
359                                    Set<Group> userOrgGroups = SetUtil.fromList(
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                            Set<Role> roles = new HashSet<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                                    Set<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                                    Set<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(
449                                    userPermissionCheckerBag, ListUtil.fromCollection(roles));
450    
451                            return bag;
452                    }
453                    finally {
454                            if (bag == null) {
455                                    bag = new PermissionCheckerBagImpl(userId);
456                            }
457    
458                            PermissionCacheUtil.putBag(userId, groupId, bag);
459                    }
460            }
461    
462            @Override
463            public boolean hasOwnerPermission(
464                    long companyId, String name, String primKey, long ownerId,
465                    String actionId) {
466    
467                    if (ownerId != getUserId()) {
468                            return false;
469                    }
470    
471                    if (ownerId == defaultUserId) {
472                            if (actionId.equals(ActionKeys.VIEW)) {
473                                    return true;
474                            }
475                            else {
476                                    return false;
477                            }
478                    }
479    
480                    try {
481                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
482                                    PermissionedModel permissionedModel =
483                                            ResourceBlockLocalServiceUtil.getPermissionedModel(
484                                                    name, GetterUtil.getLong(primKey));
485    
486                                    long groupId = 0;
487    
488                                    if (permissionedModel instanceof GroupedModel) {
489                                            GroupedModel groupedModel = (GroupedModel)permissionedModel;
490    
491                                            groupId = groupedModel.getGroupId();
492                                    }
493    
494                                    ResourceBlockIdsBag resourceBlockIdsBag =
495                                            getOwnerResourceBlockIdsBag(companyId, groupId, name);
496    
497                                    return ResourceBlockLocalServiceUtil.hasPermission(
498                                            name, permissionedModel, actionId, resourceBlockIdsBag);
499                            }
500    
501                            return ResourcePermissionLocalServiceUtil.hasResourcePermission(
502                                    companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey,
503                                    getOwnerRoleId(), actionId);
504                    }
505                    catch (Exception e) {
506                            if (_log.isDebugEnabled()) {
507                                    _log.debug(e, e);
508                            }
509                    }
510    
511                    return false;
512            }
513    
514            @Override
515            public boolean hasPermission(
516                    long groupId, String name, String primKey, String actionId) {
517    
518                    StopWatch stopWatch = new StopWatch();
519    
520                    stopWatch.start();
521    
522                    Group group = null;
523    
524                    try {
525                            if (groupId > 0) {
526                                    group = GroupLocalServiceUtil.getGroup(groupId);
527    
528                                    // If the group is a personal site, check the "User Personal
529                                    // Site" group.
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 the group is a scope group for a layout, check the
539                                    // original group.
540    
541                                    if (group.isLayout() &&
542                                            !ResourceBlockLocalServiceUtil.isSupported(name)) {
543    
544                                            Layout layout = LayoutLocalServiceUtil.getLayout(
545                                                    group.getClassPK());
546    
547                                            groupId = layout.getGroupId();
548    
549                                            group = GroupLocalServiceUtil.getGroup(groupId);
550                                    }
551    
552                                    // If the group is a staging group, check the live group.
553    
554                                    if (group.isStagingGroup()) {
555                                            if (primKey.equals(String.valueOf(groupId))) {
556                                                    primKey = String.valueOf(group.getLiveGroupId());
557                                            }
558    
559                                            groupId = group.getLiveGroupId();
560                                            group = group.getLiveGroup();
561                                    }
562                            }
563                    }
564                    catch (Exception e) {
565                            _log.error(e, e);
566                    }
567    
568                    Boolean value = PermissionCacheUtil.getPermission(
569                            user.getUserId(), signedIn, groupId, name, primKey, actionId);
570    
571                    if (value != null) {
572                            return value.booleanValue();
573                    }
574    
575                    try {
576                            value = Boolean.valueOf(
577                                    hasPermissionImpl(groupId, name, primKey, actionId));
578    
579                            if (_log.isDebugEnabled()) {
580                                    _log.debug(
581                                            "Checking permission for " + groupId + " " + name +
582                                                    " " + primKey + " " + actionId + " takes " +
583                                                            stopWatch.getTime() + " ms");
584                            }
585                    }
586                    finally {
587                            if (value == null) {
588                                    value = Boolean.FALSE;
589                            }
590    
591                            PermissionCacheUtil.putPermission(
592                                    user.getUserId(), signedIn, groupId, name, primKey, actionId,
593                                    value);
594                    }
595    
596                    return value.booleanValue();
597            }
598    
599            @Override
600            public boolean hasUserPermission(
601                    long groupId, String name, String primKey, String actionId,
602                    boolean checkAdmin) {
603    
604                    try {
605                            return hasUserPermissionImpl(
606                                    groupId, name, primKey, actionId, checkAdmin);
607                    }
608                    catch (Exception e) {
609                            _log.error(e, e);
610    
611                            return false;
612                    }
613            }
614    
615            @Override
616            public boolean isCompanyAdmin() {
617                    try {
618                            return isCompanyAdminImpl();
619                    }
620                    catch (Exception e) {
621                            _log.error(e, e);
622    
623                            return false;
624                    }
625            }
626    
627            @Override
628            public boolean isCompanyAdmin(long companyId) {
629                    try {
630                            return isCompanyAdminImpl(companyId);
631                    }
632                    catch (Exception e) {
633                            _log.error(e, e);
634    
635                            return false;
636                    }
637            }
638    
639            @Override
640            public boolean isContentReviewer(long companyId, long groupId) {
641                    try {
642                            return isContentReviewerImpl(companyId, groupId);
643                    }
644                    catch (Exception e) {
645                            _log.error(e, e);
646                    }
647    
648                    return false;
649            }
650    
651            @Override
652            public boolean isGroupAdmin(long groupId) {
653                    try {
654                            return isGroupAdminImpl(groupId);
655                    }
656                    catch (Exception e) {
657                            _log.error(e, e);
658    
659                            return false;
660                    }
661            }
662    
663            @Override
664            public boolean isGroupMember(long groupId) {
665                    try {
666                            return isGroupMemberImpl(groupId);
667                    }
668                    catch (Exception e) {
669                            _log.error(e, e);
670    
671                            return false;
672                    }
673            }
674    
675            @Override
676            public boolean isGroupOwner(long groupId) {
677                    try {
678                            return isGroupOwnerImpl(groupId);
679                    }
680                    catch (Exception e) {
681                            _log.error(e, e);
682    
683                            return false;
684                    }
685            }
686    
687            @Override
688            public boolean isOrganizationAdmin(long organizationId) {
689                    try {
690                            return isOrganizationAdminImpl(organizationId);
691                    }
692                    catch (Exception e) {
693                            _log.error(e, e);
694    
695                            return false;
696                    }
697            }
698    
699            @Override
700            public boolean isOrganizationOwner(long organizationId) {
701                    try {
702                            return isOrganizationOwnerImpl(organizationId);
703                    }
704                    catch (Exception e) {
705                            _log.error(e, e);
706    
707                            return false;
708                    }
709            }
710    
711            protected void addTeamRoles(long userId, Group group, Set<Role> roles)
712                    throws Exception {
713    
714                    List<Team> userTeams = TeamLocalServiceUtil.getUserTeams(
715                            userId, group.getGroupId());
716    
717                    for (Team team : userTeams) {
718                            Role role = RoleLocalServiceUtil.getTeamRole(
719                                    team.getCompanyId(), team.getTeamId());
720    
721                            roles.add(role);
722                    }
723    
724                    LinkedHashMap<String, Object> teamParams =
725                            new LinkedHashMap<String, Object>();
726    
727                    teamParams.put("usersUserGroups", userId);
728    
729                    List<Team> userGroupTeams = TeamLocalServiceUtil.search(
730                            group.getGroupId(), null, null, teamParams, QueryUtil.ALL_POS,
731                            QueryUtil.ALL_POS, null);
732    
733                    for (Team team : userGroupTeams) {
734                            Role role = RoleLocalServiceUtil.getTeamRole(
735                                    team.getCompanyId(), team.getTeamId());
736    
737                            roles.add(role);
738                    }
739            }
740    
741            protected boolean doCheckPermission(
742                            long companyId, long groupId, String name, String primKey,
743                            String actionId, StopWatch stopWatch)
744                    throws Exception {
745    
746                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
747    
748                    if (ResourceBlockLocalServiceUtil.isSupported(name)) {
749                            ResourceBlockIdsBag resourceBlockIdsBag = getResourceBlockIdsBag(
750                                    companyId, groupId, getUserId(), name);
751    
752                            boolean value = ResourceBlockLocalServiceUtil.hasPermission(
753                                    name, GetterUtil.getLong(primKey), actionId,
754                                    resourceBlockIdsBag);
755    
756                            logHasUserPermission(
757                                    groupId, name, primKey, actionId, stopWatch, 2);
758    
759                            return value;
760                    }
761    
762                    List<Resource> resources = getResources(
763                            companyId, groupId, name, primKey, actionId);
764    
765                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
766    
767                    // Check if user has access to perform the action on the given resource
768                    // scopes. The resources are scoped to check first for an individual
769                    // class, then for the group that the class may belong to, and then for
770                    // the company that the class belongs to.
771    
772                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
773    
774                    boolean value = ResourceLocalServiceUtil.hasUserPermissions(
775                            user.getUserId(), groupId, resources, actionId, bag.getRoleIds());
776    
777                    logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 4);
778    
779                    return value;
780            }
781    
782            /**
783             * Returns representations of the resource at each scope level.
784             *
785             * <p>
786             * For example, if the class name and primary key of a blog entry were
787             * passed to this method, it would return a resource for the blog entry
788             * itself (individual scope), a resource representing all blog entries
789             * within its group (group scope), a resource standing for all blog entries
790             * within a group the user has a suitable role in (group-template scope),
791             * and a resource signifying all blog entries within the company (company
792             * scope).
793             * </p>
794             *
795             * @param  companyId the primary key of the company
796             * @param  groupId the primary key of the group containing the resource
797             * @param  name the resource's name, which can be either a class name or a
798             *         portlet ID
799             * @param  primKey the primary key of the resource
800             * @param  actionId unused
801             * @return representations of the resource at each scope level
802             * @throws Exception if an exception occurred
803             */
804            protected List<Resource> getResources(
805                            long companyId, long groupId, String name, String primKey,
806                            String actionId)
807                    throws Exception {
808    
809                    // Individual
810    
811                    List<Resource> resources = new ArrayList<Resource>(4);
812    
813                    Resource individualResource = ResourceLocalServiceUtil.getResource(
814                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
815    
816                    resources.add(individualResource);
817    
818                    // Group
819    
820                    if (groupId > 0) {
821                            Resource groupResource = ResourceLocalServiceUtil.getResource(
822                                    companyId, name, ResourceConstants.SCOPE_GROUP,
823                                    String.valueOf(groupId));
824    
825                            resources.add(groupResource);
826                    }
827    
828                    // Group template
829    
830                    if (signedIn && (groupId > 0)) {
831                            Resource groupTemplateResource =
832                                    ResourceLocalServiceUtil.getResource(
833                                            companyId, name, ResourceConstants.SCOPE_GROUP_TEMPLATE,
834                                            String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
835    
836                            resources.add(groupTemplateResource);
837                    }
838    
839                    // Company
840    
841                    Resource companyResource = ResourceLocalServiceUtil.getResource(
842                            companyId, name, ResourceConstants.SCOPE_COMPANY,
843                            String.valueOf(companyId));
844    
845                    resources.add(companyResource);
846    
847                    return resources;
848            }
849    
850            /**
851             * Returns all of the organizations that the user is a member of, including
852             * their parent organizations.
853             *
854             * @param  userId the primary key of the user
855             * @return all of the organizations that the user is a member of, including
856             *         their parent organizations
857             * @throws Exception if a user with the primary key could not be found
858             */
859            protected List<Organization> getUserOrgs(long userId) throws Exception {
860                    List<Organization> userOrgs =
861                            OrganizationLocalServiceUtil.getUserOrganizations(userId);
862    
863                    if (userOrgs.isEmpty()) {
864                            return userOrgs;
865                    }
866    
867                    Set<Organization> organizations = new LinkedHashSet<Organization>();
868    
869                    for (Organization organization : userOrgs) {
870                            if (!organizations.contains(organization)) {
871                                    organizations.add(organization);
872    
873                                    List<Organization> ancestorOrganizations =
874                                            OrganizationLocalServiceUtil.getParentOrganizations(
875                                                    organization.getOrganizationId());
876    
877                                    organizations.addAll(ancestorOrganizations);
878                            }
879                    }
880    
881                    return new ArrayList<Organization>(organizations);
882            }
883    
884            protected boolean hasGuestPermission(
885                            long groupId, String name, String primKey, String actionId)
886                    throws Exception {
887    
888                    ResourceActionsUtil.checkAction(name, actionId);
889    
890                    if (name.indexOf(CharPool.PERIOD) != -1) {
891    
892                            // Check unsupported model actions
893    
894                            List<String> actions =
895                                    ResourceActionsUtil.getModelResourceGuestUnsupportedActions(
896                                            name);
897    
898                            if (actions.contains(actionId)) {
899                                    return false;
900                            }
901                    }
902                    else {
903    
904                            // Check unsupported portlet actions
905    
906                            List<String> actions =
907                                    ResourceActionsUtil.getPortletResourceGuestUnsupportedActions(
908                                            name);
909    
910                            if (actions.contains(actionId)) {
911                                    return false;
912                            }
913                    }
914    
915                    long companyId = user.getCompanyId();
916    
917                    List<Resource> resources = getResources(
918                            companyId, groupId, name, primKey, actionId);
919    
920                    PermissionCheckerBag bag = getGuestUserBag();
921    
922                    try {
923                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
924                                    ResourceBlockIdsBag resourceBlockIdsBag =
925                                            getGuestResourceBlockIdsBag(companyId, groupId, name);
926    
927                                    return ResourceBlockLocalServiceUtil.hasPermission(
928                                            name, GetterUtil.getLong(primKey), actionId,
929                                            resourceBlockIdsBag);
930                            }
931    
932                            return ResourceLocalServiceUtil.hasUserPermissions(
933                                    defaultUserId, groupId, resources, actionId, bag.getRoleIds());
934                    }
935                    catch (Exception e) {
936                            _log.error(e, e);
937    
938                            return false;
939                    }
940            }
941    
942            protected boolean hasPermissionImpl(
943                    long groupId, String name, String primKey, String actionId) {
944    
945                    try {
946                            if (!signedIn) {
947                                    return hasGuestPermission(groupId, name, primKey, actionId);
948                            }
949    
950                            if (ResourceBlockLocalServiceUtil.isSupported(name)) {
951    
952                                    // It is not necessary to check guest permissions separately, as
953                                    // the user's resource block IDs bag will already have the guest
954                                    // permissions in it if checkGuest is true.
955    
956                                    return hasUserPermission(
957                                            groupId, name, primKey, actionId, true);
958                            }
959    
960                            boolean value = false;
961    
962                            if (checkGuest) {
963                                    value = hasGuestPermission(groupId, name, primKey, actionId);
964                            }
965    
966                            if (!value) {
967                                    value = hasUserPermission(
968                                            groupId, name, primKey, actionId, true);
969                            }
970    
971                            return value;
972                    }
973                    catch (Exception e) {
974                            _log.error(e, e);
975    
976                            return false;
977                    }
978            }
979    
980            protected boolean hasUserPermissionImpl(
981                            long groupId, String name, String primKey, String actionId,
982                            boolean checkAdmin)
983                    throws Exception {
984    
985                    StopWatch stopWatch = new StopWatch();
986    
987                    stopWatch.start();
988    
989                    long companyId = user.getCompanyId();
990    
991                    if (groupId > 0) {
992                            Group group = GroupLocalServiceUtil.getGroup(groupId);
993    
994                            companyId = group.getCompanyId();
995                    }
996    
997                    boolean hasLayoutManagerPermission = true;
998    
999                    // Check if the layout manager has permission to do this action for the
1000                    // current portlet
1001    
1002                    if (Validator.isNotNull(name) && Validator.isNotNull(primKey) &&
1003                            primKey.contains(PortletConstants.LAYOUT_SEPARATOR)) {
1004    
1005                            hasLayoutManagerPermission =
1006                                    PortletPermissionUtil.hasLayoutManagerPermission(
1007                                            name, actionId);
1008                    }
1009    
1010                    if (checkAdmin) {
1011                            if (isCompanyAdminImpl(companyId)) {
1012                                    return true;
1013                            }
1014    
1015                            if (name.equals(Organization.class.getName())) {
1016                                    long organizationId = GetterUtil.getInteger(primKey);
1017    
1018                                    if (isOrganizationAdminImpl(organizationId)) {
1019                                            return true;
1020                                    }
1021                            }
1022                            else if (isGroupAdminImpl(groupId) && hasLayoutManagerPermission) {
1023                                    return true;
1024                            }
1025                    }
1026    
1027                    return doCheckPermission(
1028                            companyId, groupId, name, primKey, actionId, stopWatch);
1029            }
1030    
1031            protected boolean isCompanyAdminImpl() throws Exception {
1032                    return isCompanyAdminImpl(user.getCompanyId());
1033            }
1034    
1035            protected boolean isCompanyAdminImpl(long companyId) throws Exception {
1036                    if (!signedIn) {
1037                            return false;
1038                    }
1039    
1040                    if (isOmniadmin()) {
1041                            return true;
1042                    }
1043    
1044                    Boolean value = companyAdmins.get(companyId);
1045    
1046                    if (value == null) {
1047                            boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
1048                                    user.getUserId(), companyId, RoleConstants.ADMINISTRATOR, true);
1049    
1050                            value = Boolean.valueOf(hasAdminRole);
1051    
1052                            companyAdmins.put(companyId, value);
1053                    }
1054    
1055                    return value.booleanValue();
1056            }
1057    
1058            protected boolean isContentReviewerImpl(long companyId, long groupId)
1059                    throws Exception {
1060    
1061                    if (!signedIn) {
1062                            return false;
1063                    }
1064    
1065                    if (isOmniadmin()) {
1066                            return true;
1067                    }
1068    
1069                    if (isCompanyAdmin(companyId)) {
1070                            return true;
1071                    }
1072    
1073                    if (groupId <= 0) {
1074                            return false;
1075                    }
1076    
1077                    if (isGroupAdmin(groupId)) {
1078                            return true;
1079                    }
1080    
1081                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1082    
1083                    if (bag == null) {
1084                            _log.error("Bag should never be null");
1085                    }
1086    
1087                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1088    
1089                    if (bag.isContentReviewer(this, group)) {
1090                            return true;
1091                    }
1092                    else {
1093                            return false;
1094                    }
1095            }
1096    
1097            protected boolean isGroupAdminImpl(long groupId) throws Exception {
1098                    if (!signedIn) {
1099                            return false;
1100                    }
1101    
1102                    if (isOmniadmin()) {
1103                            return true;
1104                    }
1105    
1106                    if (groupId <= 0) {
1107                            return false;
1108                    }
1109    
1110                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1111    
1112                    if (isCompanyAdmin(group.getCompanyId())) {
1113                            return true;
1114                    }
1115    
1116                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1117    
1118                    if (bag == null) {
1119                            _log.error("Bag should never be null");
1120                    }
1121    
1122                    if (bag.isGroupAdmin(this, group)) {
1123                            return true;
1124                    }
1125    
1126                    StopWatch stopWatch = new StopWatch();
1127    
1128                    stopWatch.start();
1129    
1130                    if (group.isOrganization()) {
1131                            Organization organization =
1132                                    OrganizationLocalServiceUtil.getOrganization(
1133                                            group.getOrganizationId());
1134    
1135                            while (!organization.isRoot()) {
1136                                    Organization parentOrganization =
1137                                            organization.getParentOrganization();
1138    
1139                                    Group parentGroup = parentOrganization.getGroup();
1140    
1141                                    if (doCheckPermission(
1142                                                    parentGroup.getCompanyId(), parentGroup.getGroupId(),
1143                                                    Organization.class.getName(),
1144                                                    String.valueOf(parentOrganization.getOrganizationId()),
1145                                                    ActionKeys.MANAGE_SUBORGANIZATIONS, stopWatch)) {
1146    
1147                                            return true;
1148                                    }
1149    
1150                                    organization = parentOrganization;
1151                            }
1152                    }
1153    
1154                    if (group.isSite()) {
1155                            while (!group.isRoot()) {
1156                                    Group parentGroup = group.getParentGroup();
1157    
1158                                    if (doCheckPermission(
1159                                                    parentGroup.getCompanyId(), parentGroup.getGroupId(),
1160                                                    Group.class.getName(),
1161                                                    String.valueOf(parentGroup.getGroupId()),
1162                                                    ActionKeys.MANAGE_SUBGROUPS, stopWatch)) {
1163    
1164                                            return true;
1165                                    }
1166    
1167                                    group = parentGroup;
1168                            }
1169                    }
1170    
1171                    return false;
1172            }
1173    
1174            protected boolean isGroupMemberImpl(long groupId) throws Exception {
1175                    if (!signedIn) {
1176                            return false;
1177                    }
1178    
1179                    if (groupId <= 0) {
1180                            return false;
1181                    }
1182    
1183                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1184    
1185                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1186    
1187                    if (bag == null) {
1188                            _log.error("Bag should never be null");
1189                    }
1190    
1191                    if (bag.isGroupMember(this, group)) {
1192                            return true;
1193                    }
1194                    else {
1195                            return false;
1196                    }
1197            }
1198    
1199            protected boolean isGroupOwnerImpl(long groupId) throws Exception {
1200                    if (!signedIn) {
1201                            return false;
1202                    }
1203    
1204                    if (isOmniadmin()) {
1205                            return true;
1206                    }
1207    
1208                    if (groupId <= 0) {
1209                            return false;
1210                    }
1211    
1212                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1213    
1214                    if (isCompanyAdmin(group.getCompanyId())) {
1215                            return true;
1216                    }
1217    
1218                    PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
1219    
1220                    if (bag == null) {
1221                            _log.error("Bag should never be null");
1222                    }
1223    
1224                    if (bag.isGroupOwner(this, group)) {
1225                            return true;
1226                    }
1227                    else {
1228                            return false;
1229                    }
1230            }
1231    
1232            protected boolean isOrganizationAdminImpl(long organizationId)
1233                    throws Exception {
1234    
1235                    if (!signedIn) {
1236                            return false;
1237                    }
1238    
1239                    if (isOmniadmin()) {
1240                            return true;
1241                    }
1242    
1243                    if (organizationId <= 0) {
1244                            return false;
1245                    }
1246    
1247                    Organization organization =
1248                            OrganizationLocalServiceUtil.fetchOrganization(organizationId);
1249    
1250                    if (organization == null) {
1251                            return false;
1252                    }
1253    
1254                    if (isCompanyAdmin(organization.getCompanyId())) {
1255                            return true;
1256                    }
1257    
1258                    PermissionCheckerBag bag = getUserBag(
1259                            user.getUserId(), organization.getGroupId());
1260    
1261                    if (bag == null) {
1262                            _log.error("Bag should never be null");
1263                    }
1264    
1265                    if (bag.isOrganizationAdmin(this, organization)) {
1266                            return true;
1267                    }
1268                    else {
1269                            return false;
1270                    }
1271            }
1272    
1273            protected boolean isOrganizationOwnerImpl(long organizationId)
1274                    throws Exception {
1275    
1276                    if (!signedIn) {
1277                            return false;
1278                    }
1279    
1280                    if (isOmniadmin()) {
1281                            return true;
1282                    }
1283    
1284                    if (organizationId <= 0) {
1285                            return false;
1286                    }
1287    
1288                    Organization organization =
1289                            OrganizationLocalServiceUtil.fetchOrganization(organizationId);
1290    
1291                    if (organization == null) {
1292                            return false;
1293                    }
1294    
1295                    if (isCompanyAdmin(organization.getCompanyId())) {
1296                            return true;
1297                    }
1298    
1299                    PermissionCheckerBag bag = getUserBag(
1300                            user.getUserId(), organization.getGroupId());
1301    
1302                    if (bag == null) {
1303                            _log.error("Bag should never be null");
1304                    }
1305    
1306                    if (bag.isOrganizationOwner(this, organization)) {
1307                            return true;
1308                    }
1309                    else {
1310                            return false;
1311                    }
1312            }
1313    
1314            protected void logHasUserPermission(
1315                    long groupId, String name, String primKey, String actionId,
1316                    StopWatch stopWatch, int block) {
1317    
1318                    if (!_log.isDebugEnabled()) {
1319                            return;
1320                    }
1321    
1322                    _log.debug(
1323                            "Checking user permission block " + block + " for " + groupId +
1324                                    " " + name + " " + primKey + " " + actionId + " takes " +
1325                                            stopWatch.getTime() + " ms");
1326            }
1327    
1328            /**
1329             * @deprecated As of 6.1.0
1330             */
1331            @Deprecated
1332            protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
1333    
1334            protected Map<Long, Boolean> companyAdmins = new HashMap<Long, Boolean>();
1335    
1336            private static final Log _log = LogFactoryUtil.getLog(
1337                    AdvancedPermissionChecker.class);
1338    
1339    }