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
80 List<Group> userGroups = new ArrayList<Group>();
81
83 if (groupId > 0) {
84 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
85 Group group = GroupLocalServiceUtil.getGroup(groupId);
86
87 userGroups.add(group);
88 }
89 }
90
91 List<Organization> userOrgs = getUserOrgs(userId);
92
93 List<Group> userOrgGroups =
94 GroupLocalServiceUtil.getOrganizationsGroups(userOrgs);
95
96 List<UserGroup> userUserGroups =
97 UserGroupLocalServiceUtil.getUserUserGroups(userId);
98
99 List<Group> userUserGroupGroups =
100 GroupLocalServiceUtil.getUserGroupsGroups(userUserGroups);
101
102 List<Group> groups = new ArrayList<Group>(
103 userGroups.size() + userOrgGroups.size() +
104 userUserGroupGroups.size());
105
106 groups.addAll(userGroups);
107 groups.addAll(userOrgGroups);
108 groups.addAll(userUserGroupGroups);
109
110 List<Role> roles = new UniqueList<Role>();
111
112 if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 3) ||
113 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 4) ||
114 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) ||
115 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6)) {
116
117 if (groups.size() > 0) {
118 List<Role> userRelatedRoles=
119 RoleLocalServiceUtil.getUserRelatedRoles(
120 userId, groups);
121
122 roles.addAll(userRelatedRoles);
123 }
124 else {
125 roles.addAll(RoleLocalServiceUtil.getUserRoles(userId));
126 }
127
128 List<Role> userGroupRoles =
129 RoleLocalServiceUtil.getUserGroupRoles(userId, groupId);
130
131 roles.addAll(userGroupRoles);
132
133 List<Role> userGroupGroupRoles =
134 RoleLocalServiceUtil.getUserGroupGroupRoles(
135 userId, groupId);
136
137 roles.addAll(userGroupGroupRoles);
138
139 if (!userGroups.isEmpty()) {
140 Group group = userGroups.get(0);
141
142 addRequiredMemberRole(group, roles);
143 }
144 }
145 else {
146 roles = new ArrayList<Role>();
147 }
148
149 bag = new PermissionCheckerBagImpl(
150 userId, userGroups, userOrgs, userOrgGroups,
151 userUserGroupGroups, groups, roles);
152
153 return bag;
154 }
155 finally {
156 if (bag == null) {
157 bag = new PermissionCheckerBagImpl(
158 userId, new ArrayList<Group>(),
159 new ArrayList<Organization>(), new ArrayList<Group>(),
160 new ArrayList<Group>(), new ArrayList<Group>(),
161 new ArrayList<Role>());
162 }
163
164 PermissionCacheUtil.putBag(userId, groupId, bag);
165 }
166 }
167
168 public boolean hasOwnerPermission(
169 long companyId, String name, String primKey, long ownerId,
170 String actionId) {
171
172 if (ownerId != getUserId()) {
173 return false;
174 }
175
176 if (ownerId == defaultUserId) {
177 if (actionId == ActionKeys.VIEW) {
178 return true;
179 }
180 else {
181 return false;
182 }
183 }
184
185 try {
186 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
187 return ResourcePermissionLocalServiceUtil.hasResourcePermission(
188 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL,
189 primKey, getOwnerRoleId(), actionId);
190 }
191 else {
192 Resource resource = ResourceLocalServiceUtil.getResource(
193 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL,
194 primKey);
195
196 List<Permission> permissions =
197 PermissionLocalServiceUtil.getRolePermissions(
198 getOwnerRoleId(), resource.getResourceId());
199
200 int pos = Collections.binarySearch(
201 permissions, actionId, new PermissionActionIdComparator());
202
203 if (pos >= 0) {
204 return true;
205 }
206 }
207 }
208 catch (Exception e) {
209 if (_log.isDebugEnabled()) {
210 _log.debug(e, e);
211 }
212 }
213
214 return false;
215 }
216
217 public boolean hasPermission(
218 long groupId, String name, String primKey, String actionId) {
219
220 StopWatch stopWatch = null;
221
222 if (_log.isDebugEnabled()) {
223 stopWatch = new StopWatch();
224
225 stopWatch.start();
226 }
227
228 Group group = null;
229
230
234 try {
235 if (groupId > 0) {
236 group = GroupLocalServiceUtil.getGroup(groupId);
237
238 if (group.isStagingGroup()) {
239 if (primKey.equals(String.valueOf(groupId))) {
240 primKey = String.valueOf(group.getLiveGroupId());
241 }
242
243 groupId = group.getLiveGroupId();
244 group = group.getLiveGroup();
245 }
246 else if (group.isLayout()) {
247 Layout layout = LayoutLocalServiceUtil.getLayout(
248 group.getClassPK());
249
250 groupId = layout.getGroupId();
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 if (name.indexOf(StringPool.PERIOD) != -1) {
478
479
481 List<String> actions = ResourceActionsUtil.
482 getModelResourceGuestUnsupportedActions(name);
483
484 if (actions.contains(actionId)) {
485 return false;
486 }
487 }
488 else {
489
490
492 List<String> actions = ResourceActionsUtil.
493 getPortletResourceGuestUnsupportedActions(name);
494
495 if (actions.contains(actionId)) {
496 return false;
497 }
498 }
499
500 long companyId = user.getCompanyId();
501
502 List<Resource> resources = getResources(
503 companyId, groupId, name, primKey, actionId);
504
505 Group guestGroup = GroupLocalServiceUtil.getGroup(
506 companyId, GroupConstants.GUEST);
507
508 PermissionCheckerBag bag = PermissionCacheUtil.getBag(
509 defaultUserId, guestGroup.getGroupId());
510
511 if (bag == null) {
512 try {
513 List<Group> groups = new ArrayList<Group>();
514
515 groups.add(guestGroup);
516
517 List<Role> roles = RoleLocalServiceUtil.getUserRelatedRoles(
518 defaultUserId, groups);
519
520 bag = new PermissionCheckerBagImpl(
521 defaultUserId, new ArrayList<Group>(),
522 new ArrayList<Organization>(), new ArrayList<Group>(),
523 new ArrayList<Group>(), new ArrayList<Group>(), roles);
524 }
525 finally {
526 if (bag == null) {
527 bag = new PermissionCheckerBagImpl(
528 defaultUserId, new ArrayList<Group>(),
529 new ArrayList<Organization>(), new ArrayList<Group>(),
530 new ArrayList<Group>(), new ArrayList<Group>(),
531 new ArrayList<Role>());
532 }
533
534 PermissionCacheUtil.putBag(
535 defaultUserId, guestGroup.getGroupId(), bag);
536 }
537 }
538
539 try {
540 return PermissionLocalServiceUtil.hasUserPermissions(
541 defaultUserId, groupId, resources, actionId, bag);
542 }
543 catch (Exception e) {
544 _log.error(e, e);
545
546 return false;
547 }
548 }
549
550 protected boolean hasPermissionImpl(
551 long groupId, String name, String primKey, String actionId) {
552
553 try {
554 if (!signedIn) {
555 return hasGuestPermission(groupId, name, primKey, actionId);
556 }
557 else {
558 boolean value = false;
559
560 if (checkGuest) {
561 value = hasGuestPermission(
562 groupId, name, primKey, actionId);
563 }
564
565 if (!value) {
566 value = hasUserPermission(
567 groupId, name, primKey, actionId, true);
568 }
569
570 return value;
571 }
572 }
573 catch (Exception e) {
574 _log.error(e, e);
575
576 return false;
577 }
578 }
579
580 protected boolean hasUserPermissionImpl(
581 long groupId, String name, String primKey, String actionId,
582 boolean checkAdmin)
583 throws Exception {
584
585 StopWatch stopWatch = null;
586
587 if (_log.isDebugEnabled()) {
588 stopWatch = new StopWatch();
589
590 stopWatch.start();
591 }
592
593 long companyId = user.getCompanyId();
594
595 boolean hasLayoutManagerPermission = true;
596
597
600 if ((Validator.isNotNull(name)) && (Validator.isNotNull(primKey)) &&
601 (primKey.indexOf(PortletConstants.LAYOUT_SEPARATOR) != -1)) {
602
603 hasLayoutManagerPermission =
604 PortletPermissionUtil.hasLayoutManagerPermission(
605 name, actionId);
606 }
607
608 if (checkAdmin &&
609 (isCompanyAdminImpl(companyId) ||
610 (isCommunityAdminImpl(groupId) &&
611 hasLayoutManagerPermission))) {
612
613 return true;
614 }
615
616 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
617
618 List<Resource> resources = getResources(
619 companyId, groupId, name, primKey, actionId);
620
621 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 2);
622
623
628 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
629
630 boolean value = PermissionLocalServiceUtil.hasUserPermissions(
631 user.getUserId(), groupId, resources, actionId, bag);
632
633 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
634
635 return value;
636 }
637
638 protected boolean isCommunityAdminImpl(long groupId) throws Exception {
639 if (!signedIn) {
640 return false;
641 }
642
643 if (isOmniadmin()) {
644 return true;
645 }
646
647 if (groupId <= 0) {
648 return false;
649 }
650
651 Group group = GroupLocalServiceUtil.getGroup(groupId);
652
653 if (isCompanyAdmin(group.getCompanyId())) {
654 return true;
655 }
656
657 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
658
659 if (bag == null) {
660 _log.error("Bag should never be null");
661 }
662
663 if (bag.isCommunityAdmin(this, group)) {
664 return true;
665 }
666 else {
667 return false;
668 }
669 }
670
671 protected boolean isCommunityOwnerImpl(long groupId) throws Exception {
672 if (!signedIn) {
673 return false;
674 }
675
676 if (isOmniadmin()) {
677 return true;
678 }
679
680 if (groupId <= 0) {
681 return false;
682 }
683
684 Group group = GroupLocalServiceUtil.getGroup(groupId);
685
686 if (isCompanyAdmin(group.getCompanyId())) {
687 return true;
688 }
689
690 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
691
692 if (bag == null) {
693 _log.error("Bag should never be null");
694 }
695
696 if (bag.isCommunityOwner(this, group)) {
697 return true;
698 }
699 else {
700 return false;
701 }
702 }
703
704 protected boolean isCompanyAdminImpl() throws Exception {
705 return isCompanyAdminImpl(user.getCompanyId());
706 }
707
708 protected boolean isCompanyAdminImpl(long companyId) throws Exception {
709 if (!signedIn) {
710 return false;
711 }
712
713 if (isOmniadmin()) {
714 return true;
715 }
716
717 Boolean value = companyAdmins.get(companyId);
718
719 if (value == null) {
720 boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
721 user.getUserId(), companyId, RoleConstants.ADMINISTRATOR, true);
722
723 value = Boolean.valueOf(hasAdminRole);
724
725 companyAdmins.put(companyId, value);
726 }
727
728 return value.booleanValue();
729 }
730
731 protected void logHasUserPermission(
732 long groupId, String name, String primKey, String actionId,
733 StopWatch stopWatch, int block) {
734
735 if (!_log.isDebugEnabled()) {
736 return;
737 }
738
739 _log.debug(
740 "Checking user permission block " + block + " for " + groupId +
741 " " + name + " " + primKey + " " + actionId + " takes " +
742 stopWatch.getTime() + " ms");
743 }
744
745
748 protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
749
750 protected Map<Long, Boolean> companyAdmins = new HashMap<Long, Boolean>();
751
752 private static Log _log = LogFactoryUtil.getLog(
753 AdvancedPermissionChecker.class);
754
755 }