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 PermissionCheckerBag bag = getBag(groupId);
173
174 if (signedIn && (bag == null)) {
175 try {
176
177 Group group = null;
178
179
182 if (groupId > 0) {
183 group = GroupLocalServiceUtil.getGroup(groupId);
184
185 if (group.isStagingGroup()) {
186 groupId = group.getLiveGroupId();
187 group = group.getLiveGroup();
188 }
189 }
190
191
197 List userGroups = new ArrayList();
198
200 if (groupId > 0) {
201 if (GroupLocalServiceUtil.hasUserGroup(
202 user.getUserId(), groupId)) {
203
204 userGroups.add(group);
205 }
206 }
207
208 List userOrgs = getUserOrgs(user.getUserId());
209
210 List userOrgGroups =
211 GroupLocalServiceUtil.getOrganizationsGroups(userOrgs);
212
213 List userUserGroups =
214 UserGroupLocalServiceUtil.getUserUserGroups(
215 user.getUserId());
216
217 List userUserGroupGroups =
218 GroupLocalServiceUtil.getUserGroupsGroups(userUserGroups);
219
220 List groups = new ArrayList(
221 userGroups.size() + userOrgGroups.size() +
222 userUserGroupGroups.size());
223
224 groups.addAll(userGroups);
225 groups.addAll(userOrgGroups);
226 groups.addAll(userUserGroupGroups);
227
228 List roles = null;
229
230 if ((USER_CHECK_ALGORITHM == 3) ||
231 (USER_CHECK_ALGORITHM == 4)) {
232
233 roles = RoleLocalServiceUtil.getUserRelatedRoles(
234 user.getUserId(), groups);
235
236 List userGroupRoles =
237 RoleLocalServiceUtil.getUserGroupRoles(
238 user.getUserId(), groupId);
239
240 roles.addAll(userGroupRoles);
241 }
242 else {
243 roles = new ArrayList();
244 }
245
246 if (_log.isDebugEnabled()) {
247 _log.debug(
248 "Creating bag for " + groupId + " " + name + " " +
249 primKey + " " + actionId + " takes " +
250 stopWatch.getTime() + " ms");
251 }
252
253 bag = new PermissionCheckerBagImpl(
254 user.getUserId(), userGroups, userOrgs, userOrgGroups,
255 userUserGroupGroups, groups, roles);
256
257 putBag(groupId, bag);
258 }
259 catch (Exception e) {
260 _log.error(e, e);
261 }
262 }
263
264 Boolean value = PermissionCacheUtil.hasPermission(
265 user.getUserId(), groupId, name, primKey, actionId);
266
267 if (value == null) {
268 value = Boolean.valueOf(
269 hasPermissionImpl(groupId, name, primKey, actionId));
270
271 PermissionCacheUtil.putPermission(
272 user.getUserId(), groupId, name, primKey, actionId, value);
273
274 if (_log.isDebugEnabled()) {
275 _log.debug(
276 "Checking permission for " + groupId + " " + name + " " +
277 primKey + " " + actionId + " takes " +
278 stopWatch.getTime() + " ms");
279 }
280 }
281
282 return value.booleanValue();
283 }
284
285 public boolean hasUserPermission(
286 long groupId, String name, String primKey, String actionId,
287 boolean checkAdmin) {
288
289 try {
290 return hasUserPermissionImpl(
291 groupId, name, primKey, actionId, checkAdmin);
292 }
293 catch (Exception e) {
294 _log.error(e, e);
295
296 return false;
297 }
298 }
299
300 public boolean isOmniadmin() {
301 if (omniadmin == null) {
302 omniadmin = Boolean.valueOf(OmniadminUtil.isOmniadmin(getUserId()));
303 }
304
305 return omniadmin.booleanValue();
306 }
307
308 public boolean isCompanyAdmin(long companyId) {
309 try {
310 return isCompanyAdminImpl(companyId);
311 }
312 catch (Exception e) {
313 _log.error(e, e);
314
315 return false;
316 }
317 }
318
319 public boolean isCommunityAdmin(long groupId) {
320 try {
321 return isCommunityAdminImpl(groupId);
322 }
323 catch (Exception e) {
324 _log.error(e, e);
325
326 return false;
327 }
328 }
329
330 public boolean isCommunityOwner(long groupId) {
331 try {
332 return isCommunityOwnerImpl(groupId);
333 }
334 catch (Exception e) {
335 _log.error(e, e);
336
337 return false;
338 }
339 }
340
341 protected PermissionCheckerBag getBag(long groupId) {
342 return (PermissionCheckerBag)bags.get(new Long(groupId));
343 }
344
345 protected long[] getResourceIds(
346 long companyId, long groupId, String name, String primKey,
347 String actionId)
348 throws Exception {
349
350
352 long[] resourceIds = new long[4];
353
354 try {
355 Resource resource = ResourceLocalServiceUtil.getResource(
356 companyId, name, ResourceImpl.SCOPE_INDIVIDUAL, primKey);
357
358 resourceIds[0] = resource.getResourceId();
359 }
360 catch (NoSuchResourceException nsre) {
361 if (_log.isWarnEnabled()) {
362 _log.warn(
363 "Resource " + companyId + " " + name + " " +
364 ResourceImpl.SCOPE_INDIVIDUAL + " " + primKey +
365 " does not exist");
366 }
367 }
368
369
371 try {
372 if (groupId > 0) {
373 Resource resource = ResourceLocalServiceUtil.getResource(
374 companyId, name, ResourceImpl.SCOPE_GROUP,
375 String.valueOf(groupId));
376
377 resourceIds[1] = resource.getResourceId();
378 }
379 }
380 catch (NoSuchResourceException nsre) {
381 if (_log.isWarnEnabled()) {
382 _log.warn(
383 "Resource " + companyId + " " + name + " " +
384 ResourceImpl.SCOPE_GROUP + " " + groupId +
385 " does not exist");
386 }
387 }
388
389
391 try {
392 if (groupId > 0) {
393 Resource resource = ResourceLocalServiceUtil.getResource(
394 companyId, name, ResourceImpl.SCOPE_GROUP_TEMPLATE,
395 String.valueOf(GroupImpl.DEFAULT_PARENT_GROUP_ID));
396
397 resourceIds[2] = resource.getResourceId();
398 }
399 }
400 catch (NoSuchResourceException nsre) {
401 if (_log.isWarnEnabled()) {
402 _log.warn(
403 "Resource " + companyId + " " + name + " " +
404 ResourceImpl.SCOPE_GROUP_TEMPLATE + " " +
405 GroupImpl.DEFAULT_PARENT_GROUP_ID +
406 " does not exist");
407 }
408 }
409
410
412 try {
413 Resource resource = ResourceLocalServiceUtil.getResource(
414 companyId, name, ResourceImpl.SCOPE_COMPANY,
415 String.valueOf(companyId));
416
417 resourceIds[3] = resource.getResourceId();
418 }
419 catch (NoSuchResourceException nsre) {
420 if (_log.isWarnEnabled()) {
421 _log.warn(
422 "Resource " + companyId + " " + name + " " +
423 ResourceImpl.SCOPE_COMPANY + " " + companyId +
424 " does not exist");
425 }
426 }
427
428 return resourceIds;
429 }
430
431 protected List getUserOrgs(long userId) throws Exception {
432 List userOrgs = OrganizationLocalServiceUtil.getUserOrganizations(
433 userId);
434
435 if (userOrgs.size() == 0) {
436 return userOrgs;
437 }
438
439 List organizations = new UniqueList();
440
441 Iterator itr = userOrgs.iterator();
442
443 while (itr.hasNext()){
444 Organization organization = (Organization)itr.next();
445
446 if (!organizations.contains(organization)) {
447 organizations.add(organization);
448
449 List ancestorOrganizations = OrganizationLocalServiceUtil.
450 getParentOrganizations(organization.getOrganizationId());
451
452 organizations.addAll(ancestorOrganizations);
453 }
454 }
455
456 return organizations;
457 }
458
459 protected boolean hasGuestPermission(
460 String name, String primKey, String actionId)
461 throws Exception {
462
463 if (name.indexOf(StringPool.PERIOD) != -1) {
464
465
467 List actions = ResourceActionsUtil.
468 getModelResourceGuestUnsupportedActions(name);
469
470 if (actions.contains(actionId)) {
471 return false;
472 }
473 }
474 else {
475
476
478 List actions = ResourceActionsUtil.
479 getPortletResourceGuestUnsupportedActions(name);
480
481 if (actions.contains(actionId)) {
482 return false;
483 }
484 }
485
486 long companyId = user.getCompanyId();
487
488 long[] resourceIds = getResourceIds(
489 companyId, 0, name, primKey, actionId);
490
491 PermissionCheckerBag bag = getBag(GUEST_GROUP_BAG_ID);
492
493 if (bag == null) {
494 Group guestGroup = GroupLocalServiceUtil.getGroup(
495 companyId, GroupImpl.GUEST);
496
497 List roles = RoleLocalServiceUtil.getGroupRoles(
498 guestGroup.getGroupId());
499
500 bag = new PermissionCheckerBagImpl(
501 defaultUserId, new ArrayList(), new ArrayList(),
502 new ArrayList(), new ArrayList(), new ArrayList(), roles);
503
504 putBag(GUEST_GROUP_BAG_ID, bag);
505 }
506
507 try {
508 return PermissionLocalServiceUtil.hasUserPermissions(
509 defaultUserId, 0, actionId, resourceIds, bag);
510 }
511 catch (Exception e) {
512 return false;
513 }
514 }
515
516 protected boolean hasPermissionImpl(
517 long groupId, String name, String primKey, String actionId) {
518
519 try {
520 if (!signedIn) {
521 return hasGuestPermission(name, primKey, actionId);
522 }
523 else {
524 boolean value = false;
525
526 if (checkGuest) {
527 value = hasGuestPermission(name, primKey, actionId);
528 }
529
530 if (!value) {
531 value = hasUserPermission(
532 groupId, name, primKey, actionId, true);
533 }
534
535 return value;
536 }
537 }
538 catch (Exception e) {
539 _log.error(e, e);
540
541 return false;
542 }
543 }
544
545 public boolean hasUserPermissionImpl(
546 long groupId, String name, String primKey, String actionId,
547 boolean checkAdmin)
548 throws Exception {
549
550 StopWatch stopWatch = null;
551
552 if (_log.isDebugEnabled()) {
553 stopWatch = new StopWatch();
554
555 stopWatch.start();
556 }
557
558 long companyId = user.getCompanyId();
559
560 boolean hasLayoutManagerPermission = true;
561
562 if ((Validator.isNotNull(name)) && (Validator.isNotNull(primKey)) &&
563 (primKey.indexOf(PortletImpl.LAYOUT_SEPARATOR) != -1)) {
564
565 hasLayoutManagerPermission =
566 PortletPermissionUtil.hasLayoutManagerPermission(
567 name, actionId);
568 }
569
570 if (checkAdmin &&
571 (isCompanyAdminImpl(companyId) ||
572 (isCommunityAdminImpl(groupId) &&
573 hasLayoutManagerPermission))) {
574
575 return true;
576 }
577
578 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
579
580 long[] resourceIds = getResourceIds(
581 companyId, groupId, name, primKey, actionId);
582
583 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 2);
584
585
590 PermissionCheckerBag bag = getBag(groupId);
591
592 boolean value = PermissionLocalServiceUtil.hasUserPermissions(
593 user.getUserId(), groupId, actionId, resourceIds, bag);
594
595 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
596
597 return value;
598 }
599
600 protected boolean isCompanyAdminImpl(long companyId) throws Exception {
601 if (isOmniadmin()) {
602 return true;
603 }
604
605 String key = String.valueOf(companyId);
606
607 Boolean value = (Boolean)companyAdmins.get(key);
608
609 if (value == null) {
610 boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
611 user.getUserId(), companyId, RoleImpl.ADMINISTRATOR, true);
612
613 value = Boolean.valueOf(hasAdminRole);
614
615 companyAdmins.put(key, value);
616 }
617
618 return value.booleanValue();
619 }
620
621 protected boolean isCommunityAdminImpl(long groupId) throws Exception {
622 if (isOmniadmin()) {
623 return true;
624 }
625
626 if (groupId <= 0) {
627 return false;
628 }
629
630 Group group = GroupLocalServiceUtil.getGroup(groupId);
631
632 if (isCompanyAdmin(group.getCompanyId())) {
633 return true;
634 }
635
636 PermissionCheckerBag bag = getBag(groupId);
637
638 if (bag == null) {
639 _log.error("Bag should never be null");
640 }
641
642 if (bag.isCommunityAdmin(this, group)) {
643 return true;
644 }
645 else {
646 return false;
647 }
648 }
649
650 protected boolean isCommunityOwnerImpl(long groupId) throws Exception {
651 if (isOmniadmin()) {
652 return true;
653 }
654
655 if (groupId <= 0) {
656 return false;
657 }
658
659 Group group = GroupLocalServiceUtil.getGroup(groupId);
660
661 if (isCompanyAdmin(group.getCompanyId())) {
662 return true;
663 }
664
665 PermissionCheckerBag bag = getBag(groupId);
666
667 if (bag == null) {
668 _log.error("Bag should never be null");
669 }
670
671 if (bag.isCommunityOwner(this, group)) {
672 return true;
673 }
674 else {
675 return false;
676 }
677 }
678
679 protected void logHasUserPermission(
680 long groupId, String name, String primKey, String actionId,
681 StopWatch stopWatch, int block) {
682
683 if (!_log.isDebugEnabled()) {
684 return;
685 }
686
687 _log.debug(
688 "Checking user permission block " + block + " for " + groupId +
689 " " + name + " " + primKey + " " + actionId + " takes " +
690 stopWatch.getTime() + " ms");
691 }
692
693 protected void putBag(long groupId, PermissionCheckerBag bag) {
694 bags.put(new Long(groupId), bag);
695 }
696
697 protected static final int GUEST_GROUP_BAG_ID = -101;
698
699 protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
700
701 protected User user;
702 protected long defaultUserId;
703 protected boolean signedIn;
704 protected boolean checkGuest;
705 protected Boolean omniadmin;
706 protected Map companyAdmins = new HashMap();
707 protected Map bags = CollectionFactory.getHashMap();
708
709 private static Log _log = LogFactory.getLog(PermissionCheckerImpl.class);
710
711 }