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
70 public class AdvancedPermissionChecker extends BasePermissionChecker {
71
72 public boolean hasOwnerPermission(
73 long companyId, String name, String primKey, long ownerId,
74 String actionId) {
75
76 if (ownerId != getUserId()) {
77 return false;
78 }
79
80 try {
81 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
82 return ResourcePermissionLocalServiceUtil.hasResourcePermission(
83 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL,
84 primKey, getOwnerRoleId(), actionId);
85 }
86 else {
87 Resource resource = ResourceLocalServiceUtil.getResource(
88 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL,
89 primKey);
90
91 List<Permission> permissions =
92 PermissionLocalServiceUtil.getRolePermissions(
93 getOwnerRoleId(), resource.getResourceId());
94
95 int pos = Collections.binarySearch(
96 permissions, actionId, new PermissionActionIdComparator());
97
98 if (pos >= 0) {
99 return true;
100 }
101 }
102 }
103 catch (Exception e) {
104 if (_log.isDebugEnabled()) {
105 _log.debug(e, e);
106 }
107 }
108
109 return false;
110 }
111
112 public boolean hasPermission(
113 long groupId, String name, String primKey, String actionId) {
114
115 StopWatch stopWatch = null;
116
117 if (_log.isDebugEnabled()) {
118 stopWatch = new StopWatch();
119
120 stopWatch.start();
121 }
122
123 Group group = null;
124
125
129 try {
130 if (groupId > 0) {
131 group = GroupLocalServiceUtil.getGroup(groupId);
132
133 if (group.isStagingGroup()) {
134 if (primKey.equals(String.valueOf(groupId))) {
135 primKey = String.valueOf(group.getLiveGroupId());
136 }
137
138 groupId = group.getLiveGroupId();
139 group = group.getLiveGroup();
140 }
141 else if (group.isLayout()) {
142 Layout layout = LayoutLocalServiceUtil.getLayout(
143 group.getClassPK());
144
145 groupId = layout.getGroupId();
146 }
147 }
148 }
149 catch (Exception e) {
150 _log.error(e, e);
151 }
152
153 Boolean value = PermissionCacheUtil.getPermission(
154 user.getUserId(), groupId, name, primKey, actionId);
155
156 if (value == null) {
157 try {
158 value = Boolean.valueOf(
159 hasPermissionImpl(groupId, name, primKey, actionId));
160
161 if (_log.isDebugEnabled()) {
162 _log.debug(
163 "Checking permission for " + groupId + " " + name +
164 " " + primKey + " " + actionId + " takes " +
165 stopWatch.getTime() + " ms");
166 }
167 }
168 finally {
169 if (value == null) {
170 value = Boolean.FALSE;
171 }
172
173 PermissionCacheUtil.putPermission(
174 user.getUserId(), groupId, name, primKey, actionId, value);
175 }
176 }
177
178 return value.booleanValue();
179 }
180
181 public boolean hasUserPermission(
182 long groupId, String name, String primKey, String actionId,
183 boolean checkAdmin) {
184
185 try {
186 return hasUserPermissionImpl(
187 groupId, name, primKey, actionId, checkAdmin);
188 }
189 catch (Exception e) {
190 _log.error(e, e);
191
192 return false;
193 }
194 }
195
196 public boolean isCommunityAdmin(long groupId) {
197 try {
198 return isCommunityAdminImpl(groupId);
199 }
200 catch (Exception e) {
201 _log.error(e, e);
202
203 return false;
204 }
205 }
206
207 public boolean isCommunityOwner(long groupId) {
208 try {
209 return isCommunityOwnerImpl(groupId);
210 }
211 catch (Exception e) {
212 _log.error(e, e);
213
214 return false;
215 }
216 }
217
218 public boolean isCompanyAdmin() {
219 try {
220 return isCompanyAdminImpl();
221 }
222 catch (Exception e) {
223 _log.error(e, e);
224
225 return false;
226 }
227 }
228
229 public boolean isCompanyAdmin(long companyId) {
230 try {
231 return isCompanyAdminImpl(companyId);
232 }
233 catch (Exception e) {
234 _log.error(e, e);
235
236 return false;
237 }
238 }
239
240 protected List<Resource> getResources(
241 long companyId, long groupId, String name, String primKey,
242 String actionId)
243 throws Exception {
244
245
247 List<Resource> resources = new ArrayList<Resource>(4);
248
249 try {
250 Resource resource = ResourceLocalServiceUtil.getResource(
251 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
252
253 resources.add(resource);
254 }
255 catch (NoSuchResourceException nsre) {
256 if (_log.isWarnEnabled()) {
257 _log.warn(
258 "Resource " + companyId + " " + name + " " +
259 ResourceConstants.SCOPE_INDIVIDUAL + " " + primKey +
260 " does not exist");
261 }
262 }
263
264
266 try {
267 if (groupId > 0) {
268 Resource resource = ResourceLocalServiceUtil.getResource(
269 companyId, name, ResourceConstants.SCOPE_GROUP,
270 String.valueOf(groupId));
271
272 resources.add(resource);
273 }
274 }
275 catch (NoSuchResourceException nsre) {
276 if (_log.isWarnEnabled()) {
277 _log.warn(
278 "Resource " + companyId + " " + name + " " +
279 ResourceConstants.SCOPE_GROUP + " " + groupId +
280 " does not exist");
281 }
282 }
283
284
286 try {
287 if (signedIn && (groupId > 0)) {
288 Resource resource = ResourceLocalServiceUtil.getResource(
289 companyId, name, ResourceConstants.SCOPE_GROUP_TEMPLATE,
290 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
291
292 resources.add(resource);
293 }
294 }
295 catch (NoSuchResourceException nsre) {
296 if (_log.isWarnEnabled()) {
297 _log.warn(
298 "Resource " + companyId + " " + name + " " +
299 ResourceConstants.SCOPE_GROUP_TEMPLATE + " " +
300 GroupConstants.DEFAULT_PARENT_GROUP_ID +
301 " does not exist");
302 }
303 }
304
305
307 try {
308 Resource resource = ResourceLocalServiceUtil.getResource(
309 companyId, name, ResourceConstants.SCOPE_COMPANY,
310 String.valueOf(companyId));
311
312 resources.add(resource);
313 }
314 catch (NoSuchResourceException nsre) {
315 if (_log.isWarnEnabled()) {
316 _log.warn(
317 "Resource " + companyId + " " + name + " " +
318 ResourceConstants.SCOPE_COMPANY + " " + companyId +
319 " does not exist");
320 }
321 }
322
323 return resources;
324 }
325
326 protected PermissionCheckerBag getUserBag(long userId, long groupId)
327 throws Exception {
328
329 PermissionCheckerBag bag = PermissionCacheUtil.getBag(userId, groupId);
330
331 if (bag != null) {
332 return bag;
333 }
334
335 try {
336
337
343 List<Group> userGroups = new ArrayList<Group>();
344
346 if (groupId > 0) {
347 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
348 Group group = GroupLocalServiceUtil.getGroup(groupId);
349
350 userGroups.add(group);
351 }
352 }
353
354 List<Organization> userOrgs = getUserOrgs(userId);
355
356 List<Group> userOrgGroups =
357 GroupLocalServiceUtil.getOrganizationsGroups(userOrgs);
358
359 List<UserGroup> userUserGroups =
360 UserGroupLocalServiceUtil.getUserUserGroups(userId);
361
362 List<Group> userUserGroupGroups =
363 GroupLocalServiceUtil.getUserGroupsGroups(userUserGroups);
364
365 List<Group> groups = new ArrayList<Group>(
366 userGroups.size() + userOrgGroups.size() +
367 userUserGroupGroups.size());
368
369 groups.addAll(userGroups);
370 groups.addAll(userOrgGroups);
371 groups.addAll(userUserGroupGroups);
372
373 List<Role> roles = new ArrayList<Role>(10);
374
375 if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 3) ||
376 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 4) ||
377 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) ||
378 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6)) {
379
380 if (groups.size() > 0) {
381 List<Role> userRelatedRoles=
382 RoleLocalServiceUtil.getUserRelatedRoles(
383 userId, groups);
384
385 roles.addAll(userRelatedRoles);
386 }
387 else {
388 roles.addAll(RoleLocalServiceUtil.getUserRoles(userId));
389 }
390
391 if (userGroups.size() > 0) {
392 Role role = RoleLocalServiceUtil.getRole(
393 user.getCompanyId(), RoleConstants.COMMUNITY_MEMBER);
394
395 roles.add(role);
396 }
397
398 if (userOrgs.size() > 0) {
399 Role role = RoleLocalServiceUtil.getRole(
400 user.getCompanyId(), RoleConstants.ORGANIZATION_MEMBER);
401
402 roles.add(role);
403 }
404
405 List<Role> userGroupRoles =
406 RoleLocalServiceUtil.getUserGroupRoles(userId, groupId);
407
408 roles.addAll(userGroupRoles);
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);
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 return false;
530 }
531 }
532
533 protected boolean hasPermissionImpl(
534 long groupId, String name, String primKey, String actionId) {
535
536 try {
537 if (!signedIn) {
538 return hasGuestPermission(groupId, name, primKey, actionId);
539 }
540 else {
541 boolean value = false;
542
543 if (checkGuest) {
544 value = hasGuestPermission(
545 groupId, name, primKey, actionId);
546 }
547
548 if (!value) {
549 value = hasUserPermission(
550 groupId, name, primKey, actionId, true);
551 }
552
553 return value;
554 }
555 }
556 catch (Exception e) {
557 _log.error(e, e);
558
559 return false;
560 }
561 }
562
563 protected boolean hasUserPermissionImpl(
564 long groupId, String name, String primKey, String actionId,
565 boolean checkAdmin)
566 throws Exception {
567
568 StopWatch stopWatch = null;
569
570 if (_log.isDebugEnabled()) {
571 stopWatch = new StopWatch();
572
573 stopWatch.start();
574 }
575
576 long companyId = user.getCompanyId();
577
578 boolean hasLayoutManagerPermission = true;
579
580
583 if ((Validator.isNotNull(name)) && (Validator.isNotNull(primKey)) &&
584 (primKey.indexOf(PortletConstants.LAYOUT_SEPARATOR) != -1)) {
585
586 hasLayoutManagerPermission =
587 PortletPermissionUtil.hasLayoutManagerPermission(
588 name, actionId);
589 }
590
591 if (checkAdmin &&
592 (isCompanyAdminImpl(companyId) ||
593 (isCommunityAdminImpl(groupId) &&
594 hasLayoutManagerPermission))) {
595
596 return true;
597 }
598
599 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
600
601 List<Resource> resources = getResources(
602 companyId, groupId, name, primKey, actionId);
603
604 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 2);
605
606
611 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
612
613 boolean value = PermissionLocalServiceUtil.hasUserPermissions(
614 user.getUserId(), groupId, resources, actionId, bag);
615
616 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
617
618 return value;
619 }
620
621 protected boolean isCompanyAdminImpl() throws Exception {
622 return isCompanyAdminImpl(user.getCompanyId());
623 }
624
625 protected boolean isCompanyAdminImpl(long companyId) throws Exception {
626 if (!signedIn) {
627 return false;
628 }
629
630 if (isOmniadmin()) {
631 return true;
632 }
633
634 Boolean value = companyAdmins.get(companyId);
635
636 if (value == null) {
637 boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
638 user.getUserId(), companyId, RoleConstants.ADMINISTRATOR, true);
639
640 value = Boolean.valueOf(hasAdminRole);
641
642 companyAdmins.put(companyId, value);
643 }
644
645 return value.booleanValue();
646 }
647
648 protected boolean isCommunityAdminImpl(long groupId) throws Exception {
649 if (!signedIn) {
650 return false;
651 }
652
653 if (isOmniadmin()) {
654 return true;
655 }
656
657 if (groupId <= 0) {
658 return false;
659 }
660
661 Group group = GroupLocalServiceUtil.getGroup(groupId);
662
663 if (isCompanyAdmin(group.getCompanyId())) {
664 return true;
665 }
666
667 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
668
669 if (bag == null) {
670 _log.error("Bag should never be null");
671 }
672
673 if (bag.isCommunityAdmin(this, group)) {
674 return true;
675 }
676 else {
677 return false;
678 }
679 }
680
681 protected boolean isCommunityOwnerImpl(long groupId) throws Exception {
682 if (!signedIn) {
683 return false;
684 }
685
686 if (isOmniadmin()) {
687 return true;
688 }
689
690 if (groupId <= 0) {
691 return false;
692 }
693
694 Group group = GroupLocalServiceUtil.getGroup(groupId);
695
696 if (isCompanyAdmin(group.getCompanyId())) {
697 return true;
698 }
699
700 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
701
702 if (bag == null) {
703 _log.error("Bag should never be null");
704 }
705
706 if (bag.isCommunityOwner(this, group)) {
707 return true;
708 }
709 else {
710 return false;
711 }
712 }
713
714 protected void logHasUserPermission(
715 long groupId, String name, String primKey, String actionId,
716 StopWatch stopWatch, int block) {
717
718 if (!_log.isDebugEnabled()) {
719 return;
720 }
721
722 _log.debug(
723 "Checking user permission block " + block + " for " + groupId +
724 " " + name + " " + primKey + " " + actionId + " takes " +
725 stopWatch.getTime() + " ms");
726 }
727
728 protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
729
730 protected Map<Long, Boolean> companyAdmins = new HashMap<Long, Boolean>();
731
732 private static Log _log =
733 LogFactoryUtil.getLog(AdvancedPermissionChecker.class);
734
735 }