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