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