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