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