1
14
15 package com.liferay.portal.security.permission;
16
17 import com.liferay.portal.NoSuchResourceException;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.util.ArrayUtil;
21 import com.liferay.portal.kernel.util.SetUtil;
22 import com.liferay.portal.kernel.util.StringPool;
23 import com.liferay.portal.kernel.util.Validator;
24 import com.liferay.portal.model.Group;
25 import com.liferay.portal.model.GroupConstants;
26 import com.liferay.portal.model.Layout;
27 import com.liferay.portal.model.Organization;
28 import com.liferay.portal.model.Permission;
29 import com.liferay.portal.model.PortletConstants;
30 import com.liferay.portal.model.Resource;
31 import com.liferay.portal.model.ResourceConstants;
32 import com.liferay.portal.model.Role;
33 import com.liferay.portal.model.RoleConstants;
34 import com.liferay.portal.model.Team;
35 import com.liferay.portal.model.UserGroup;
36 import com.liferay.portal.security.permission.comparator.PermissionActionIdComparator;
37 import com.liferay.portal.service.GroupLocalServiceUtil;
38 import com.liferay.portal.service.LayoutLocalServiceUtil;
39 import com.liferay.portal.service.OrganizationLocalServiceUtil;
40 import com.liferay.portal.service.PermissionLocalServiceUtil;
41 import com.liferay.portal.service.ResourceLocalServiceUtil;
42 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
43 import com.liferay.portal.service.RoleLocalServiceUtil;
44 import com.liferay.portal.service.TeamLocalServiceUtil;
45 import com.liferay.portal.service.UserGroupLocalServiceUtil;
46 import com.liferay.portal.service.permission.PortletPermissionUtil;
47 import com.liferay.portal.util.PropsValues;
48 import com.liferay.util.UniqueList;
49
50 import java.util.ArrayList;
51 import java.util.Collections;
52 import java.util.HashMap;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Set;
56
57 import org.apache.commons.lang.time.StopWatch;
58
59
66 public class AdvancedPermissionChecker extends BasePermissionChecker {
67
68 public long[] getRoleIds(long userId, long groupId) {
69 PermissionCheckerBag bag = null;
70
71 try {
72 bag = getUserBag(userId, groupId);
73 }
74 catch (Exception e) {
75 }
76
77 if (bag != null) {
78 if (checkGuest) {
79 Set<Long> roleIds = SetUtil.fromArray(bag.getRoleIds());
80
81 try {
82 PermissionCheckerBag guestBag = getGuestUserBag();
83
84 if (guestBag != null) {
85 for (long roleId : guestBag.getRoleIds()) {
86 roleIds.add(roleId);
87 }
88 }
89 }
90 catch (Exception e) {
91 }
92
93 return ArrayUtil.toArray(
94 roleIds.toArray(new Long[roleIds.size()]));
95 }
96 else {
97 return bag.getRoleIds();
98 }
99 }
100
101 return PermissionChecker.DEFAULT_ROLE_IDS;
102 }
103
104 public PermissionCheckerBag getGuestUserBag() throws Exception {
105 Group guestGroup = GroupLocalServiceUtil.getGroup(
106 getCompanyId(), GroupConstants.GUEST);
107
108 PermissionCheckerBag bag = PermissionCacheUtil.getBag(
109 defaultUserId, guestGroup.getGroupId());
110
111 if (bag == null) {
112 try {
113 List<Group> groups = new ArrayList<Group>();
114
115 groups.add(guestGroup);
116
117 List<Role> roles = RoleLocalServiceUtil.getUserRelatedRoles(
118 defaultUserId, groups);
119
120 bag = new PermissionCheckerBagImpl(
121 defaultUserId, new ArrayList<Group>(),
122 new ArrayList<Organization>(), new ArrayList<Group>(),
123 new ArrayList<Group>(), new ArrayList<Group>(), roles);
124 }
125 finally {
126 if (bag == null) {
127 bag = new PermissionCheckerBagImpl(
128 defaultUserId, new ArrayList<Group>(),
129 new ArrayList<Organization>(), new ArrayList<Group>(),
130 new ArrayList<Group>(), new ArrayList<Group>(),
131 new ArrayList<Role>());
132 }
133
134 PermissionCacheUtil.putBag(
135 defaultUserId, guestGroup.getGroupId(), bag);
136 }
137 }
138
139 return bag;
140 }
141
142 public PermissionCheckerBag getUserBag(long userId, long groupId)
143 throws Exception {
144
145 PermissionCheckerBag bag = PermissionCacheUtil.getBag(userId, groupId);
146
147 if (bag != null) {
148 return bag;
149 }
150
151 try {
152
153 Group group = null;
154
155 if (groupId > 0) {
156 group = GroupLocalServiceUtil.getGroup(groupId);
157 }
158
159
165 List<Group> userGroups = new ArrayList<Group>();
166
168 if ((group != null) && group.isCommunity() &&
169 GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
170
171 userGroups.add(group);
172 }
173
174 List<Organization> userOrgs = getUserOrgs(userId);
175
176 List<Group> userOrgGroups =
177 GroupLocalServiceUtil.getOrganizationsGroups(userOrgs);
178
179 List<UserGroup> userUserGroups =
180 UserGroupLocalServiceUtil.getUserUserGroups(userId);
181
182 List<Group> userUserGroupGroups =
183 GroupLocalServiceUtil.getUserGroupsGroups(userUserGroups);
184
185 List<Group> groups = new ArrayList<Group>(
186 userGroups.size() + userOrgGroups.size() +
187 userUserGroupGroups.size());
188
189 groups.addAll(userGroups);
190 groups.addAll(userOrgGroups);
191 groups.addAll(userUserGroupGroups);
192
193 List<Role> roles = new UniqueList<Role>();
194
195 if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 3) ||
196 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 4) ||
197 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) ||
198 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6)) {
199
200 if (groups.size() > 0) {
201 List<Role> userRelatedRoles=
202 RoleLocalServiceUtil.getUserRelatedRoles(
203 userId, groups);
204
205 roles.addAll(userRelatedRoles);
206 }
207 else {
208 roles.addAll(RoleLocalServiceUtil.getUserRoles(userId));
209 }
210
211 List<Role> userGroupRoles =
212 RoleLocalServiceUtil.getUserGroupRoles(userId, groupId);
213
214 roles.addAll(userGroupRoles);
215
216 List<Role> userGroupGroupRoles =
217 RoleLocalServiceUtil.getUserGroupGroupRoles(
218 userId, groupId);
219
220 roles.addAll(userGroupGroupRoles);
221
222 if ((group != null) &&
223 ((group.isCommunity() && userGroups.contains(group)) ||
224 (group.isOrganization() &&
225 userOrgGroups.contains(group)))) {
226
227 addRequiredMemberRole(group, roles);
228 addTeamRoles(userId, group, roles);
229 }
230 }
231 else {
232 roles = new ArrayList<Role>();
233 }
234
235 bag = new PermissionCheckerBagImpl(
236 userId, userGroups, userOrgs, userOrgGroups,
237 userUserGroupGroups, groups, roles);
238
239 return bag;
240 }
241 finally {
242 if (bag == null) {
243 bag = new PermissionCheckerBagImpl(
244 userId, new ArrayList<Group>(),
245 new ArrayList<Organization>(), new ArrayList<Group>(),
246 new ArrayList<Group>(), new ArrayList<Group>(),
247 new ArrayList<Role>());
248 }
249
250 PermissionCacheUtil.putBag(userId, groupId, bag);
251 }
252 }
253
254 public boolean hasOwnerPermission(
255 long companyId, String name, String primKey, long ownerId,
256 String actionId) {
257
258 if (ownerId != getUserId()) {
259 return false;
260 }
261
262 if (ownerId == defaultUserId) {
263 if (actionId == ActionKeys.VIEW) {
264 return true;
265 }
266 else {
267 return false;
268 }
269 }
270
271 try {
272 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
273 return ResourcePermissionLocalServiceUtil.hasResourcePermission(
274 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL,
275 primKey, getOwnerRoleId(), actionId);
276 }
277 else {
278 ResourceActionsUtil.checkAction(name, actionId);
279
280 Resource resource = ResourceLocalServiceUtil.getResource(
281 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL,
282 primKey);
283
284 List<Permission> permissions =
285 PermissionLocalServiceUtil.getRolePermissions(
286 getOwnerRoleId(), resource.getResourceId());
287
288 int pos = Collections.binarySearch(
289 permissions, actionId, new PermissionActionIdComparator());
290
291 if (pos >= 0) {
292 return true;
293 }
294 }
295 }
296 catch (Exception e) {
297 if (_log.isDebugEnabled()) {
298 _log.debug(e, e);
299 }
300 }
301
302 return false;
303 }
304
305 public boolean hasPermission(
306 long groupId, String name, String primKey, String actionId) {
307
308 StopWatch stopWatch = null;
309
310 if (_log.isDebugEnabled()) {
311 stopWatch = new StopWatch();
312
313 stopWatch.start();
314 }
315
316 Group group = null;
317
318
322 try {
323 if (groupId > 0) {
324 group = GroupLocalServiceUtil.getGroup(groupId);
325
326 if (group.isStagingGroup()) {
327 if (primKey.equals(String.valueOf(groupId))) {
328 primKey = String.valueOf(group.getLiveGroupId());
329 }
330
331 groupId = group.getLiveGroupId();
332 group = group.getLiveGroup();
333 }
334 else if (group.isLayout()) {
335 Layout layout = LayoutLocalServiceUtil.getLayout(
336 group.getClassPK());
337
338 groupId = layout.getGroupId();
339 }
340 }
341 }
342 catch (Exception e) {
343 _log.error(e, e);
344 }
345
346 Boolean value = PermissionCacheUtil.getPermission(
347 user.getUserId(), groupId, name, primKey, actionId);
348
349 if (value == null) {
350 try {
351 value = Boolean.valueOf(
352 hasPermissionImpl(groupId, name, primKey, actionId));
353
354 if (_log.isDebugEnabled()) {
355 _log.debug(
356 "Checking permission for " + groupId + " " + name +
357 " " + primKey + " " + actionId + " takes " +
358 stopWatch.getTime() + " ms");
359 }
360 }
361 finally {
362 if (value == null) {
363 value = Boolean.FALSE;
364 }
365
366 PermissionCacheUtil.putPermission(
367 user.getUserId(), groupId, name, primKey, actionId, value);
368 }
369 }
370
371 return value.booleanValue();
372 }
373
374 public boolean hasUserPermission(
375 long groupId, String name, String primKey, String actionId,
376 boolean checkAdmin) {
377
378 try {
379 return hasUserPermissionImpl(
380 groupId, name, primKey, actionId, checkAdmin);
381 }
382 catch (Exception e) {
383 _log.error(e, e);
384
385 return false;
386 }
387 }
388
389 public boolean isCommunityAdmin(long groupId) {
390 try {
391 return isCommunityAdminImpl(groupId);
392 }
393 catch (Exception e) {
394 _log.error(e, e);
395
396 return false;
397 }
398 }
399
400 public boolean isCommunityOwner(long groupId) {
401 try {
402 return isCommunityOwnerImpl(groupId);
403 }
404 catch (Exception e) {
405 _log.error(e, e);
406
407 return false;
408 }
409 }
410
411 public boolean isCompanyAdmin() {
412 try {
413 return isCompanyAdminImpl();
414 }
415 catch (Exception e) {
416 _log.error(e, e);
417
418 return false;
419 }
420 }
421
422 public boolean isCompanyAdmin(long companyId) {
423 try {
424 return isCompanyAdminImpl(companyId);
425 }
426 catch (Exception e) {
427 _log.error(e, e);
428
429 return false;
430 }
431 }
432
433 protected void addRequiredMemberRole(Group group, List<Role> roles)
434 throws Exception {
435
436 if (group.isCommunity()) {
437 Role communityMemberRole = RoleLocalServiceUtil.getRole(
438 group.getCompanyId(), RoleConstants.COMMUNITY_MEMBER);
439
440 roles.add(communityMemberRole);
441 }
442 else if (group.isOrganization()) {
443 Role organizationMemberRole = RoleLocalServiceUtil.getRole(
444 group.getCompanyId(), RoleConstants.ORGANIZATION_MEMBER);
445
446 roles.add(organizationMemberRole);
447 }
448 }
449
450 protected void addTeamRoles(long userId, Group group, List<Role> roles)
451 throws Exception {
452
453 if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) ||
454 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6)) {
455
456 List<Team> teams = TeamLocalServiceUtil.getUserTeams(
457 userId, group.getGroupId());
458
459 for (Team team : teams) {
460 Role role = RoleLocalServiceUtil.getTeamRole(
461 team.getCompanyId(), team.getTeamId());
462
463 roles.add(role);
464 }
465 }
466 }
467
468 protected List<Resource> getResources(
469 long companyId, long groupId, String name, String primKey,
470 String actionId)
471 throws Exception {
472
473
475 List<Resource> resources = new ArrayList<Resource>(4);
476
477 try {
478 Resource resource = ResourceLocalServiceUtil.getResource(
479 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
480
481 resources.add(resource);
482 }
483 catch (NoSuchResourceException nsre) {
484 if (_log.isWarnEnabled()) {
485 _log.warn(
486 "Resource " + companyId + " " + name + " " +
487 ResourceConstants.SCOPE_INDIVIDUAL + " " + primKey +
488 " does not exist");
489 }
490 }
491
492
494 try {
495 if (groupId > 0) {
496 Resource resource = ResourceLocalServiceUtil.getResource(
497 companyId, name, ResourceConstants.SCOPE_GROUP,
498 String.valueOf(groupId));
499
500 resources.add(resource);
501 }
502 }
503 catch (NoSuchResourceException nsre) {
504 if (_log.isWarnEnabled()) {
505 _log.warn(
506 "Resource " + companyId + " " + name + " " +
507 ResourceConstants.SCOPE_GROUP + " " + groupId +
508 " does not exist");
509 }
510 }
511
512
514 try {
515 if (signedIn && (groupId > 0)) {
516 Resource resource = ResourceLocalServiceUtil.getResource(
517 companyId, name, ResourceConstants.SCOPE_GROUP_TEMPLATE,
518 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
519
520 resources.add(resource);
521 }
522 }
523 catch (NoSuchResourceException nsre) {
524 if (_log.isWarnEnabled()) {
525 _log.warn(
526 "Resource " + companyId + " " + name + " " +
527 ResourceConstants.SCOPE_GROUP_TEMPLATE + " " +
528 GroupConstants.DEFAULT_PARENT_GROUP_ID +
529 " does not exist");
530 }
531 }
532
533
535 try {
536 Resource resource = ResourceLocalServiceUtil.getResource(
537 companyId, name, ResourceConstants.SCOPE_COMPANY,
538 String.valueOf(companyId));
539
540 resources.add(resource);
541 }
542 catch (NoSuchResourceException nsre) {
543 if (_log.isWarnEnabled()) {
544 _log.warn(
545 "Resource " + companyId + " " + name + " " +
546 ResourceConstants.SCOPE_COMPANY + " " + companyId +
547 " does not exist");
548 }
549 }
550
551 return resources;
552 }
553
554 protected List<Organization> getUserOrgs(long userId) throws Exception {
555 List<Organization> userOrgs =
556 OrganizationLocalServiceUtil.getUserOrganizations(userId, true);
557
558 if (userOrgs.size() == 0) {
559 return userOrgs;
560 }
561
562 List<Organization> organizations = new UniqueList<Organization>();
563
564 for (Organization organization : userOrgs) {
565 if (!organizations.contains(organization)) {
566 organizations.add(organization);
567
568 List<Organization> ancestorOrganizations =
569 OrganizationLocalServiceUtil.getParentOrganizations(
570 organization.getOrganizationId());
571
572 organizations.addAll(ancestorOrganizations);
573 }
574 }
575
576 return organizations;
577 }
578
579 protected boolean hasGuestPermission(
580 long groupId, String name, String primKey, String actionId)
581 throws Exception {
582
583 ResourceActionsUtil.checkAction(name, actionId);
584
585 if (name.indexOf(StringPool.PERIOD) != -1) {
586
587
589 List<String> actions = ResourceActionsUtil.
590 getModelResourceGuestUnsupportedActions(name);
591
592 if (actions.contains(actionId)) {
593 return false;
594 }
595 }
596 else {
597
598
600 List<String> actions = ResourceActionsUtil.
601 getPortletResourceGuestUnsupportedActions(name);
602
603 if (actions.contains(actionId)) {
604 return false;
605 }
606 }
607
608 long companyId = user.getCompanyId();
609
610 List<Resource> resources = getResources(
611 companyId, groupId, name, primKey, actionId);
612
613 PermissionCheckerBag bag = getGuestUserBag();
614
615 try {
616 return PermissionLocalServiceUtil.hasUserPermissions(
617 defaultUserId, groupId, resources, actionId, bag);
618 }
619 catch (Exception e) {
620 _log.error(e, e);
621
622 return false;
623 }
624 }
625
626 protected boolean hasPermissionImpl(
627 long groupId, String name, String primKey, String actionId) {
628
629 try {
630 if (!signedIn) {
631 return hasGuestPermission(groupId, name, primKey, actionId);
632 }
633 else {
634 boolean value = false;
635
636 if (checkGuest) {
637 value = hasGuestPermission(
638 groupId, name, primKey, actionId);
639 }
640
641 if (!value) {
642 value = hasUserPermission(
643 groupId, name, primKey, actionId, true);
644 }
645
646 return value;
647 }
648 }
649 catch (Exception e) {
650 _log.error(e, e);
651
652 return false;
653 }
654 }
655
656 protected boolean hasUserPermissionImpl(
657 long groupId, String name, String primKey, String actionId,
658 boolean checkAdmin)
659 throws Exception {
660
661 StopWatch stopWatch = null;
662
663 if (_log.isDebugEnabled()) {
664 stopWatch = new StopWatch();
665
666 stopWatch.start();
667 }
668
669 long companyId = user.getCompanyId();
670
671 boolean hasLayoutManagerPermission = true;
672
673
676 if ((Validator.isNotNull(name)) && (Validator.isNotNull(primKey)) &&
677 (primKey.indexOf(PortletConstants.LAYOUT_SEPARATOR) != -1)) {
678
679 hasLayoutManagerPermission =
680 PortletPermissionUtil.hasLayoutManagerPermission(
681 name, actionId);
682 }
683
684 if (checkAdmin &&
685 (isCompanyAdminImpl(companyId) ||
686 (isCommunityAdminImpl(groupId) &&
687 hasLayoutManagerPermission))) {
688
689 return true;
690 }
691
692 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
693
694 List<Resource> resources = getResources(
695 companyId, groupId, name, primKey, actionId);
696
697 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 2);
698
699
704 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
705
706 boolean value = PermissionLocalServiceUtil.hasUserPermissions(
707 user.getUserId(), groupId, resources, actionId, bag);
708
709 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
710
711 return value;
712 }
713
714 protected boolean isCommunityAdminImpl(long groupId) throws Exception {
715 if (!signedIn) {
716 return false;
717 }
718
719 if (isOmniadmin()) {
720 return true;
721 }
722
723 if (groupId <= 0) {
724 return false;
725 }
726
727 Group group = GroupLocalServiceUtil.getGroup(groupId);
728
729 if (isCompanyAdmin(group.getCompanyId())) {
730 return true;
731 }
732
733 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
734
735 if (bag == null) {
736 _log.error("Bag should never be null");
737 }
738
739 if (bag.isCommunityAdmin(this, group)) {
740 return true;
741 }
742 else {
743 return false;
744 }
745 }
746
747 protected boolean isCommunityOwnerImpl(long groupId) throws Exception {
748 if (!signedIn) {
749 return false;
750 }
751
752 if (isOmniadmin()) {
753 return true;
754 }
755
756 if (groupId <= 0) {
757 return false;
758 }
759
760 Group group = GroupLocalServiceUtil.getGroup(groupId);
761
762 if (isCompanyAdmin(group.getCompanyId())) {
763 return true;
764 }
765
766 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
767
768 if (bag == null) {
769 _log.error("Bag should never be null");
770 }
771
772 if (bag.isCommunityOwner(this, group)) {
773 return true;
774 }
775 else {
776 return false;
777 }
778 }
779
780 protected boolean isCompanyAdminImpl() throws Exception {
781 return isCompanyAdminImpl(user.getCompanyId());
782 }
783
784 protected boolean isCompanyAdminImpl(long companyId) throws Exception {
785 if (!signedIn) {
786 return false;
787 }
788
789 if (isOmniadmin()) {
790 return true;
791 }
792
793 Boolean value = companyAdmins.get(companyId);
794
795 if (value == null) {
796 boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
797 user.getUserId(), companyId, RoleConstants.ADMINISTRATOR, true);
798
799 value = Boolean.valueOf(hasAdminRole);
800
801 companyAdmins.put(companyId, value);
802 }
803
804 return value.booleanValue();
805 }
806
807 protected void logHasUserPermission(
808 long groupId, String name, String primKey, String actionId,
809 StopWatch stopWatch, int block) {
810
811 if (!_log.isDebugEnabled()) {
812 return;
813 }
814
815 _log.debug(
816 "Checking user permission block " + block + " for " + groupId +
817 " " + name + " " + primKey + " " + actionId + " takes " +
818 stopWatch.getTime() + " ms");
819 }
820
821
824 protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
825
826 protected Map<Long, Boolean> companyAdmins = new HashMap<Long, Boolean>();
827
828 private static Log _log = LogFactoryUtil.getLog(
829 AdvancedPermissionChecker.class);
830
831 }