1
22
23 package com.liferay.portal.security.permission;
24
25 import com.liferay.portal.NoSuchResourceException;
26 import com.liferay.portal.kernel.log.Log;
27 import com.liferay.portal.kernel.log.LogFactoryUtil;
28 import com.liferay.portal.kernel.util.StringPool;
29 import com.liferay.portal.kernel.util.Validator;
30 import com.liferay.portal.model.Group;
31 import com.liferay.portal.model.GroupConstants;
32 import com.liferay.portal.model.Organization;
33 import com.liferay.portal.model.Permission;
34 import com.liferay.portal.model.PortletConstants;
35 import com.liferay.portal.model.Resource;
36 import com.liferay.portal.model.ResourceConstants;
37 import com.liferay.portal.model.Role;
38 import com.liferay.portal.model.RoleConstants;
39 import com.liferay.portal.model.UserGroup;
40 import com.liferay.portal.security.permission.comparator.PermissionActionIdComparator;
41 import com.liferay.portal.service.GroupLocalServiceUtil;
42 import com.liferay.portal.service.OrganizationLocalServiceUtil;
43 import com.liferay.portal.service.PermissionLocalServiceUtil;
44 import com.liferay.portal.service.ResourceLocalServiceUtil;
45 import com.liferay.portal.service.RoleLocalServiceUtil;
46 import com.liferay.portal.service.UserGroupLocalServiceUtil;
47 import com.liferay.portal.service.permission.PortletPermissionUtil;
48 import com.liferay.portal.util.PropsValues;
49 import com.liferay.util.UniqueList;
50
51 import java.util.ArrayList;
52 import java.util.Collections;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56
57 import org.apache.commons.lang.time.StopWatch;
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 >= 0) {
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 protected long[] getResourceIds(
215 long companyId, long groupId, String name, String primKey,
216 String actionId)
217 throws Exception {
218
219
221 long[] resourceIds = new long[4];
222
223 try {
224 Resource resource = ResourceLocalServiceUtil.getResource(
225 companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
226
227 resourceIds[0] = resource.getResourceId();
228 }
229 catch (NoSuchResourceException nsre) {
230 if (_log.isWarnEnabled()) {
231 _log.warn(
232 "Resource " + companyId + " " + name + " " +
233 ResourceConstants.SCOPE_INDIVIDUAL + " " + primKey +
234 " does not exist");
235 }
236 }
237
238
240 try {
241 if (groupId > 0) {
242 Resource resource = ResourceLocalServiceUtil.getResource(
243 companyId, name, ResourceConstants.SCOPE_GROUP,
244 String.valueOf(groupId));
245
246 resourceIds[1] = resource.getResourceId();
247 }
248 }
249 catch (NoSuchResourceException nsre) {
250 if (_log.isWarnEnabled()) {
251 _log.warn(
252 "Resource " + companyId + " " + name + " " +
253 ResourceConstants.SCOPE_GROUP + " " + groupId +
254 " does not exist");
255 }
256 }
257
258
260 try {
261 if (signedIn && (groupId > 0)) {
262 Resource resource = ResourceLocalServiceUtil.getResource(
263 companyId, name, ResourceConstants.SCOPE_GROUP_TEMPLATE,
264 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
265
266 resourceIds[2] = resource.getResourceId();
267 }
268 }
269 catch (NoSuchResourceException nsre) {
270 if (_log.isWarnEnabled()) {
271 _log.warn(
272 "Resource " + companyId + " " + name + " " +
273 ResourceConstants.SCOPE_GROUP_TEMPLATE + " " +
274 GroupConstants.DEFAULT_PARENT_GROUP_ID +
275 " does not exist");
276 }
277 }
278
279
281 try {
282 Resource resource = ResourceLocalServiceUtil.getResource(
283 companyId, name, ResourceConstants.SCOPE_COMPANY,
284 String.valueOf(companyId));
285
286 resourceIds[3] = resource.getResourceId();
287 }
288 catch (NoSuchResourceException nsre) {
289 if (_log.isWarnEnabled()) {
290 _log.warn(
291 "Resource " + companyId + " " + name + " " +
292 ResourceConstants.SCOPE_COMPANY + " " + companyId +
293 " does not exist");
294 }
295 }
296
297 return resourceIds;
298 }
299
300 protected PermissionCheckerBag getUserBag(long userId, long groupId)
301 throws Exception {
302
303 PermissionCheckerBag bag = PermissionCacheUtil.getBag(userId, groupId);
304
305 if (bag != null) {
306 return bag;
307 }
308
309
315 List<Group> userGroups = new ArrayList<Group>();
316
318 if (groupId > 0) {
319 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
320 Group group = GroupLocalServiceUtil.getGroup(groupId);
321
322 userGroups.add(group);
323 }
324 }
325
326 List<Organization> userOrgs = getUserOrgs(userId);
327
328 List<Group> userOrgGroups =
329 GroupLocalServiceUtil.getOrganizationsGroups(userOrgs);
330
331 List<UserGroup> userUserGroups =
332 UserGroupLocalServiceUtil.getUserUserGroups(userId);
333
334 List<Group> userUserGroupGroups =
335 GroupLocalServiceUtil.getUserGroupsGroups(userUserGroups);
336
337 List<Group> groups = new ArrayList<Group>(
338 userGroups.size() + userOrgGroups.size() +
339 userUserGroupGroups.size());
340
341 groups.addAll(userGroups);
342 groups.addAll(userOrgGroups);
343 groups.addAll(userUserGroupGroups);
344
345 List<Role> roles = new ArrayList<Role>(10);
346
347 if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 3) ||
348 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 4) ||
349 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5)) {
350
351 if (groups.size() > 0) {
352 roles.addAll(
353 RoleLocalServiceUtil.getUserRelatedRoles(userId, groups));
354 }
355 else {
356 roles.addAll(RoleLocalServiceUtil.getUserRoles(userId));
357 }
358
359 if (userGroups.size() > 0) {
360 Role role = RoleLocalServiceUtil.getRole(
361 user.getCompanyId(), RoleConstants.COMMUNITY_MEMBER);
362
363 roles.add(role);
364 }
365
366 if (userOrgs.size() > 0) {
367 Role role = RoleLocalServiceUtil.getRole(
368 user.getCompanyId(), RoleConstants.ORGANIZATION_MEMBER);
369
370 roles.add(role);
371 }
372
373 List<Role> userGroupRoles = RoleLocalServiceUtil.getUserGroupRoles(
374 userId, groupId);
375
376 roles.addAll(userGroupRoles);
377 }
378 else {
379 roles = new ArrayList<Role>();
380 }
381
382 bag = new PermissionCheckerBagImpl(
383 userId, userGroups, userOrgs, userOrgGroups,
384 userUserGroupGroups, groups, roles);
385
386 PermissionCacheUtil.putBag(userId, groupId, bag);
387
388 return bag;
389 }
390
391 protected List<Organization> getUserOrgs(long userId) throws Exception {
392 List<Organization> userOrgs =
393 OrganizationLocalServiceUtil.getUserOrganizations(userId);
394
395 if (userOrgs.size() == 0) {
396 return userOrgs;
397 }
398
399 List<Organization> organizations = new UniqueList<Organization>();
400
401 for (Organization organization : userOrgs) {
402 if (!organizations.contains(organization)) {
403 organizations.add(organization);
404
405 List<Organization> ancestorOrganizations =
406 OrganizationLocalServiceUtil.getParentOrganizations(
407 organization.getOrganizationId());
408
409 organizations.addAll(ancestorOrganizations);
410 }
411 }
412
413 return organizations;
414 }
415
416 protected boolean hasGuestPermission(
417 long groupId, String name, String primKey, String actionId)
418 throws Exception {
419
420 if (name.indexOf(StringPool.PERIOD) != -1) {
421
422
424 List<String> actions = ResourceActionsUtil.
425 getModelResourceGuestUnsupportedActions(name);
426
427 if (actions.contains(actionId)) {
428 return false;
429 }
430 }
431 else {
432
433
435 List<String> actions = ResourceActionsUtil.
436 getPortletResourceGuestUnsupportedActions(name);
437
438 if (actions.contains(actionId)) {
439 return false;
440 }
441 }
442
443 long companyId = user.getCompanyId();
444
445 long[] resourceIds = getResourceIds(
446 companyId, groupId, name, primKey, actionId);
447
448 Group guestGroup = GroupLocalServiceUtil.getGroup(
449 companyId, GroupConstants.GUEST);
450
451 PermissionCheckerBag bag = PermissionCacheUtil.getBag(
452 defaultUserId, guestGroup.getGroupId());
453
454 if (bag == null) {
455 List<Group> groups = new ArrayList<Group>();
456
457 groups.add(guestGroup);
458
459 List<Role> roles = RoleLocalServiceUtil.getUserRelatedRoles(
460 defaultUserId, groups);
461
462 bag = new PermissionCheckerBagImpl(
463 defaultUserId, new ArrayList<Group>(),
464 new ArrayList<Organization>(), new ArrayList<Group>(),
465 new ArrayList<Group>(), new ArrayList<Group>(), roles);
466
467 PermissionCacheUtil.putBag(
468 defaultUserId, guestGroup.getGroupId(), bag);
469 }
470
471 try {
472 return PermissionLocalServiceUtil.hasUserPermissions(
473 defaultUserId, groupId, actionId, resourceIds, bag);
474 }
475 catch (Exception e) {
476 return false;
477 }
478 }
479
480 protected boolean hasPermissionImpl(
481 long groupId, String name, String primKey, String actionId) {
482
483 try {
484 if (!signedIn) {
485 return hasGuestPermission(groupId, name, primKey, actionId);
486 }
487 else {
488 boolean value = false;
489
490 if (checkGuest) {
491 value = hasGuestPermission(
492 groupId, name, primKey, actionId);
493 }
494
495 if (!value) {
496 value = hasUserPermission(
497 groupId, name, primKey, actionId, true);
498 }
499
500 return value;
501 }
502 }
503 catch (Exception e) {
504 _log.error(e, e);
505
506 return false;
507 }
508 }
509
510 protected boolean hasUserPermissionImpl(
511 long groupId, String name, String primKey, String actionId,
512 boolean checkAdmin)
513 throws Exception {
514
515 StopWatch stopWatch = null;
516
517 if (_log.isDebugEnabled()) {
518 stopWatch = new StopWatch();
519
520 stopWatch.start();
521 }
522
523 long companyId = user.getCompanyId();
524
525 boolean hasLayoutManagerPermission = true;
526
527
530 if ((Validator.isNotNull(name)) && (Validator.isNotNull(primKey)) &&
531 (primKey.indexOf(PortletConstants.LAYOUT_SEPARATOR) != -1)) {
532
533 hasLayoutManagerPermission =
534 PortletPermissionUtil.hasLayoutManagerPermission(
535 name, actionId);
536 }
537
538 if (checkAdmin &&
539 (isCompanyAdminImpl(companyId) ||
540 (isCommunityAdminImpl(groupId) &&
541 hasLayoutManagerPermission))) {
542
543 return true;
544 }
545
546 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
547
548 long[] resourceIds = getResourceIds(
549 companyId, groupId, name, primKey, actionId);
550
551 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 2);
552
553
558 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
559
560 boolean value = PermissionLocalServiceUtil.hasUserPermissions(
561 user.getUserId(), groupId, actionId, resourceIds, bag);
562
563 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
564
565 return value;
566 }
567
568 protected boolean isCompanyAdminImpl() throws Exception {
569 return isCompanyAdminImpl(user.getCompanyId());
570 }
571
572 protected boolean isCompanyAdminImpl(long companyId) throws Exception {
573 if (!signedIn) {
574 return false;
575 }
576
577 if (isOmniadmin()) {
578 return true;
579 }
580
581 Boolean value = companyAdmins.get(companyId);
582
583 if (value == null) {
584 boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
585 user.getUserId(), companyId, RoleConstants.ADMINISTRATOR, true);
586
587 value = Boolean.valueOf(hasAdminRole);
588
589 companyAdmins.put(companyId, value);
590 }
591
592 return value.booleanValue();
593 }
594
595 protected boolean isCommunityAdminImpl(long groupId) throws Exception {
596 if (!signedIn) {
597 return false;
598 }
599
600 if (isOmniadmin()) {
601 return true;
602 }
603
604 if (groupId <= 0) {
605 return false;
606 }
607
608 Group group = GroupLocalServiceUtil.getGroup(groupId);
609
610 if (isCompanyAdmin(group.getCompanyId())) {
611 return true;
612 }
613
614 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
615
616 if (bag == null) {
617 _log.error("Bag should never be null");
618 }
619
620 if (bag.isCommunityAdmin(this, group)) {
621 return true;
622 }
623 else {
624 return false;
625 }
626 }
627
628 protected boolean isCommunityOwnerImpl(long groupId) throws Exception {
629 if (!signedIn) {
630 return false;
631 }
632
633 if (isOmniadmin()) {
634 return true;
635 }
636
637 if (groupId <= 0) {
638 return false;
639 }
640
641 Group group = GroupLocalServiceUtil.getGroup(groupId);
642
643 if (isCompanyAdmin(group.getCompanyId())) {
644 return true;
645 }
646
647 PermissionCheckerBag bag = getUserBag(user.getUserId(), groupId);
648
649 if (bag == null) {
650 _log.error("Bag should never be null");
651 }
652
653 if (bag.isCommunityOwner(this, group)) {
654 return true;
655 }
656 else {
657 return false;
658 }
659 }
660
661 protected void logHasUserPermission(
662 long groupId, String name, String primKey, String actionId,
663 StopWatch stopWatch, int block) {
664
665 if (!_log.isDebugEnabled()) {
666 return;
667 }
668
669 _log.debug(
670 "Checking user permission block " + block + " for " + groupId +
671 " " + name + " " + primKey + " " + actionId + " takes " +
672 stopWatch.getTime() + " ms");
673 }
674
675 protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
676
677 protected Map<Long, Boolean> companyAdmins = new HashMap<Long, Boolean>();
678
679 private static Log _log =
680 LogFactoryUtil.getLog(AdvancedPermissionChecker.class);
681
682 }