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