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