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