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