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