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