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 Group guestGroup = GroupLocalServiceUtil.getGroup(
421 companyId, GroupImpl.GUEST);
422
423 PermissionCheckerBag bag = PermissionCacheUtil.getBag(
424 defaultUserId, guestGroup.getGroupId());
425
426 if (bag == null) {
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(
440 defaultUserId, guestGroup.getGroupId(), bag);
441 }
442
443 try {
444 return PermissionLocalServiceUtil.hasUserPermissions(
445 defaultUserId, 0, actionId, resourceIds, bag);
446 }
447 catch (Exception e) {
448 return false;
449 }
450 }
451
452 protected boolean hasPermissionImpl(
453 long groupId, String name, String primKey, String actionId) {
454
455 try {
456 if (!signedIn) {
457 return hasGuestPermission(name, primKey, actionId);
458 }
459 else {
460 boolean value = false;
461
462 if (checkGuest) {
463 value = hasGuestPermission(name, primKey, actionId);
464 }
465
466 if (!value) {
467 value = hasUserPermission(
468 groupId, name, primKey, actionId, true);
469 }
470
471 return value;
472 }
473 }
474 catch (Exception e) {
475 _log.error(e, e);
476
477 return false;
478 }
479 }
480
481 protected boolean hasUserPermissionImpl(
482 long groupId, String name, String primKey, String actionId,
483 boolean checkAdmin)
484 throws Exception {
485
486 StopWatch stopWatch = null;
487
488 if (_log.isDebugEnabled()) {
489 stopWatch = new StopWatch();
490
491 stopWatch.start();
492 }
493
494 long companyId = user.getCompanyId();
495
496 boolean hasLayoutManagerPermission = true;
497
498
501 if ((Validator.isNotNull(name)) && (Validator.isNotNull(primKey)) &&
502 (primKey.indexOf(PortletConstants.LAYOUT_SEPARATOR) != -1)) {
503
504 hasLayoutManagerPermission =
505 PortletPermissionUtil.hasLayoutManagerPermission(
506 name, actionId);
507 }
508
509 if (checkAdmin &&
510 (isCompanyAdminImpl(companyId) ||
511 (isCommunityAdminImpl(groupId) &&
512 hasLayoutManagerPermission))) {
513
514 return true;
515 }
516
517 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 1);
518
519 long[] resourceIds = getResourceIds(
520 companyId, groupId, name, primKey, actionId);
521
522 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 2);
523
524
529 PermissionCheckerBag bag = PermissionCacheUtil.getBag(
530 user.getUserId(), groupId);
531
532 boolean value = PermissionLocalServiceUtil.hasUserPermissions(
533 user.getUserId(), groupId, actionId, resourceIds, bag);
534
535 logHasUserPermission(groupId, name, primKey, actionId, stopWatch, 3);
536
537 return value;
538 }
539
540 protected boolean isCompanyAdminImpl(long companyId) throws Exception {
541 if (!signedIn) {
542 return false;
543 }
544
545 if (isOmniadmin()) {
546 return true;
547 }
548
549 Boolean value = companyAdmins.get(companyId);
550
551 if (value == null) {
552 boolean hasAdminRole = RoleLocalServiceUtil.hasUserRole(
553 user.getUserId(), companyId, RoleImpl.ADMINISTRATOR, true);
554
555 value = Boolean.valueOf(hasAdminRole);
556
557 companyAdmins.put(companyId, value);
558 }
559
560 return value.booleanValue();
561 }
562
563 protected boolean isCommunityAdminImpl(long groupId) throws Exception {
564 if (!signedIn) {
565 return false;
566 }
567
568 if (isOmniadmin()) {
569 return true;
570 }
571
572 if (groupId <= 0) {
573 return false;
574 }
575
576 Group group = GroupLocalServiceUtil.getGroup(groupId);
577
578 if (isCompanyAdmin(group.getCompanyId())) {
579 return true;
580 }
581
582 PermissionCheckerBag bag = PermissionCacheUtil.getBag(
583 user.getUserId(), groupId);
584
585 if (bag == null) {
586 _log.error("Bag should never be null");
587 }
588
589 if (bag.isCommunityAdmin(this, group)) {
590 return true;
591 }
592 else {
593 return false;
594 }
595 }
596
597 protected boolean isCommunityOwnerImpl(long groupId) throws Exception {
598 if (!signedIn) {
599 return false;
600 }
601
602 if (isOmniadmin()) {
603 return true;
604 }
605
606 if (groupId <= 0) {
607 return false;
608 }
609
610 Group group = GroupLocalServiceUtil.getGroup(groupId);
611
612 if (isCompanyAdmin(group.getCompanyId())) {
613 return true;
614 }
615
616 PermissionCheckerBag bag = PermissionCacheUtil.getBag(
617 user.getUserId(), groupId);
618
619 if (bag == null) {
620 _log.error("Bag should never be null");
621 }
622
623 if (bag.isCommunityOwner(this, group)) {
624 return true;
625 }
626 else {
627 return false;
628 }
629 }
630
631 protected void logHasUserPermission(
632 long groupId, String name, String primKey, String actionId,
633 StopWatch stopWatch, int block) {
634
635 if (!_log.isDebugEnabled()) {
636 return;
637 }
638
639 _log.debug(
640 "Checking user permission block " + block + " for " + groupId +
641 " " + name + " " + primKey + " " + actionId + " takes " +
642 stopWatch.getTime() + " ms");
643 }
644
645 protected static final String RESULTS_SEPARATOR = "_RESULTS_SEPARATOR_";
646
647 protected Map<Long, Boolean> companyAdmins = new HashMap<Long, Boolean>();
648
649 private static Log _log =
650 LogFactory.getLog(AdvancedPermissionChecker.class);
651
652 }