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