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