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