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