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