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