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