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