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