001
014
015 package com.liferay.portal.search;
016
017 import com.liferay.portal.NoSuchResourceException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.search.BooleanClauseOccur;
022 import com.liferay.portal.kernel.search.BooleanQuery;
023 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
024 import com.liferay.portal.kernel.search.Document;
025 import com.liferay.portal.kernel.search.Field;
026 import com.liferay.portal.kernel.search.Indexer;
027 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028 import com.liferay.portal.kernel.search.Query;
029 import com.liferay.portal.kernel.search.SearchContext;
030 import com.liferay.portal.kernel.search.SearchPermissionChecker;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.StringPool;
033 import com.liferay.portal.kernel.util.UniqueList;
034 import com.liferay.portal.kernel.util.Validator;
035 import com.liferay.portal.model.Group;
036 import com.liferay.portal.model.GroupConstants;
037 import com.liferay.portal.model.Permission;
038 import com.liferay.portal.model.Resource;
039 import com.liferay.portal.model.ResourceConstants;
040 import com.liferay.portal.model.Role;
041 import com.liferay.portal.model.RoleConstants;
042 import com.liferay.portal.model.Team;
043 import com.liferay.portal.model.UserGroupRole;
044 import com.liferay.portal.security.permission.ActionKeys;
045 import com.liferay.portal.security.permission.AdvancedPermissionChecker;
046 import com.liferay.portal.security.permission.PermissionChecker;
047 import com.liferay.portal.security.permission.PermissionCheckerBag;
048 import com.liferay.portal.security.permission.PermissionThreadLocal;
049 import com.liferay.portal.security.permission.ResourceActionsUtil;
050 import com.liferay.portal.security.permission.ResourceBlockIdsBag;
051 import com.liferay.portal.service.GroupLocalServiceUtil;
052 import com.liferay.portal.service.PermissionLocalServiceUtil;
053 import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
054 import com.liferay.portal.service.ResourceBlockPermissionLocalServiceUtil;
055 import com.liferay.portal.service.ResourceLocalServiceUtil;
056 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
057 import com.liferay.portal.service.RoleLocalServiceUtil;
058 import com.liferay.portal.service.TeamLocalServiceUtil;
059 import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
060 import com.liferay.portal.util.PropsValues;
061
062 import java.util.ArrayList;
063 import java.util.HashMap;
064 import java.util.List;
065 import java.util.Map;
066
067
073 public class SearchPermissionCheckerImpl implements SearchPermissionChecker {
074
075 @Override
076 public void addPermissionFields(long companyId, Document document) {
077 try {
078 long groupId = GetterUtil.getLong(document.get(Field.GROUP_ID));
079
080 String className = document.get(Field.ENTRY_CLASS_NAME);
081
082 if (Validator.isNull(className)) {
083 return;
084 }
085
086 String classPK = document.get(Field.ROOT_ENTRY_CLASS_PK);
087
088 if (Validator.isNull(classPK)) {
089 classPK = document.get(Field.ENTRY_CLASS_PK);
090 }
091
092 if (Validator.isNull(classPK)) {
093 return;
094 }
095
096 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
097
098 if (!indexer.isPermissionAware()) {
099 return;
100 }
101
102 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
103 doAddPermissionFields_5(
104 companyId, groupId, className, classPK, document);
105 }
106 else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
107 doAddPermissionFields_6(
108 companyId, groupId, className, classPK, document);
109 }
110 }
111 catch (NoSuchResourceException nsre) {
112 }
113 catch (Exception e) {
114 _log.error(e, e);
115 }
116 }
117
118 @Override
119 public Query getPermissionQuery(
120 long companyId, long[] groupIds, long userId, String className,
121 Query query, SearchContext searchContext) {
122
123 try {
124 query = doGetPermissionQuery(
125 companyId, groupIds, userId, className, query, searchContext);
126 }
127 catch (Exception e) {
128 _log.error(e, e);
129 }
130
131 return query;
132 }
133
134 @Override
135 public void updatePermissionFields(long resourceId) {
136 try {
137 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
138 doUpdatePermissionFields_5(resourceId);
139 }
140 }
141 catch (Exception e) {
142 _log.error(e, e);
143 }
144 }
145
146 @Override
147 public void updatePermissionFields(
148 String resourceName, String resourceClassPK) {
149
150 try {
151 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
152 doUpdatePermissionFields_6(resourceName, resourceClassPK);
153 }
154 }
155 catch (Exception e) {
156 _log.error(e, e);
157 }
158 }
159
160 protected void addRequiredMemberRole(
161 Group group, BooleanQuery permissionQuery)
162 throws Exception {
163
164 if (group.isOrganization()) {
165 Role organizationUserRole = RoleLocalServiceUtil.getRole(
166 group.getCompanyId(), RoleConstants.ORGANIZATION_USER);
167
168 permissionQuery.addTerm(
169 Field.GROUP_ROLE_ID,
170 group.getGroupId() + StringPool.DASH +
171 organizationUserRole.getRoleId());
172 }
173
174 if (group.isSite()) {
175 Role siteMemberRole = RoleLocalServiceUtil.getRole(
176 group.getCompanyId(), RoleConstants.SITE_MEMBER);
177
178 permissionQuery.addTerm(
179 Field.GROUP_ROLE_ID,
180 group.getGroupId() + StringPool.DASH +
181 siteMemberRole.getRoleId());
182 }
183 }
184
185 protected void doAddPermissionFields_5(
186 long companyId, long groupId, String className, String classPK,
187 Document document)
188 throws Exception {
189
190 Resource resource = ResourceLocalServiceUtil.getResource(
191 companyId, className, ResourceConstants.SCOPE_INDIVIDUAL, classPK);
192
193 Group group = null;
194
195 if (groupId > 0) {
196 group = GroupLocalServiceUtil.getGroup(groupId);
197 }
198
199 List<Role> roles = ResourceActionsUtil.getRoles(
200 companyId, group, className, null);
201
202 List<Long> roleIds = new ArrayList<Long>();
203 List<String> groupRoleIds = new ArrayList<String>();
204
205 for (Role role : roles) {
206 long roleId = role.getRoleId();
207
208 if (hasPermission(roleId, resource.getResourceId())) {
209 if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
210 (role.getType() == RoleConstants.TYPE_SITE)) {
211
212 groupRoleIds.add(groupId + StringPool.DASH + roleId);
213 }
214 else {
215 roleIds.add(roleId);
216 }
217 }
218 }
219
220 document.addKeyword(
221 Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
222 document.addKeyword(
223 Field.GROUP_ROLE_ID,
224 groupRoleIds.toArray(new String[groupRoleIds.size()]));
225 }
226
227 protected void doAddPermissionFields_6(
228 long companyId, long groupId, String className, String classPK,
229 Document doc)
230 throws Exception {
231
232 Group group = null;
233
234 if (groupId > 0) {
235 group = GroupLocalServiceUtil.getGroup(groupId);
236 }
237
238 List<Role> roles = ResourceActionsUtil.getRoles(
239 companyId, group, className, null);
240
241 if (groupId > 0) {
242 List<Team> teams = TeamLocalServiceUtil.getGroupTeams(groupId);
243
244 for (Team team : teams) {
245 Role role = RoleLocalServiceUtil.getTeamRole(
246 team.getCompanyId(), team.getTeamId());
247
248 roles.add(role);
249 }
250 }
251
252 long[] roleIdsArray = new long[roles.size()];
253
254 for (int i = 0; i < roleIdsArray.length; i++) {
255 Role role = roles.get(i);
256
257 roleIdsArray[i] = role.getRoleId();
258 }
259
260 boolean[] hasResourcePermissions = null;
261
262 if (ResourceBlockLocalServiceUtil.isSupported(className)) {
263 ResourceBlockIdsBag resourceBlockIdsBag =
264 ResourceBlockLocalServiceUtil.getResourceBlockIdsBag(
265 companyId, groupId, className, roleIdsArray);
266
267 long actionId = ResourceBlockLocalServiceUtil.getActionId(
268 className, ActionKeys.VIEW);
269
270 List<Long> resourceBlockIds =
271 resourceBlockIdsBag.getResourceBlockIds(actionId);
272
273 hasResourcePermissions = new boolean[roleIdsArray.length];
274
275 for (long resourceBlockId : resourceBlockIds) {
276 for (int i = 0; i < roleIdsArray.length; i++) {
277 int count =
278 ResourceBlockPermissionLocalServiceUtil.
279 getResourceBlockPermissionsCount(
280 resourceBlockId, roleIdsArray[i]);
281
282 hasResourcePermissions[i] = (count > 0);
283 }
284 }
285 }
286 else {
287 hasResourcePermissions =
288 ResourcePermissionLocalServiceUtil.hasResourcePermissions(
289 companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
290 classPK, roleIdsArray, ActionKeys.VIEW);
291 }
292
293 List<Long> roleIds = new ArrayList<Long>();
294 List<String> groupRoleIds = new ArrayList<String>();
295
296 for (int i = 0; i < hasResourcePermissions.length; i++) {
297 if (!hasResourcePermissions[i]) {
298 continue;
299 }
300
301 Role role = roles.get(i);
302
303 if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
304 (role.getType() == RoleConstants.TYPE_SITE)) {
305
306 groupRoleIds.add(groupId + StringPool.DASH + role.getRoleId());
307 }
308 else {
309 roleIds.add(role.getRoleId());
310 }
311 }
312
313 doc.addKeyword(
314 Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
315 doc.addKeyword(
316 Field.GROUP_ROLE_ID,
317 groupRoleIds.toArray(new String[groupRoleIds.size()]));
318 }
319
320 protected Query doGetPermissionQuery(
321 long companyId, long[] groupIds, long userId, String className,
322 Query query, SearchContext searchContext)
323 throws Exception {
324
325 if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 5) &&
326 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 6)) {
327
328 return query;
329 }
330
331 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
332
333 if (!indexer.isPermissionAware()) {
334 return query;
335 }
336
337 PermissionChecker permissionChecker =
338 PermissionThreadLocal.getPermissionChecker();
339
340 AdvancedPermissionChecker advancedPermissionChecker = null;
341
342 if ((permissionChecker != null) &&
343 (permissionChecker instanceof AdvancedPermissionChecker)) {
344
345 advancedPermissionChecker =
346 (AdvancedPermissionChecker)permissionChecker;
347 }
348
349 if (advancedPermissionChecker == null) {
350 return query;
351 }
352
353 PermissionCheckerBag permissionCheckerBag = getPermissionCheckerBag(
354 advancedPermissionChecker, userId);
355
356 if (permissionCheckerBag == null) {
357 return query;
358 }
359
360 List<Group> groups = new UniqueList<Group>();
361 List<Role> roles = new UniqueList<Role>();
362 List<UserGroupRole> userGroupRoles = new UniqueList<UserGroupRole>();
363 Map<Long, List<Role>> groupIdsToRoles = new HashMap<Long, List<Role>>();
364
365 roles.addAll(permissionCheckerBag.getRoles());
366
367 if ((groupIds == null) || (groupIds.length == 0)) {
368 groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
369 groups.addAll(permissionCheckerBag.getGroups());
370
371 userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
372 userId);
373 }
374 else {
375 groups.addAll(permissionCheckerBag.getGroups());
376
377 for (long groupId : groupIds) {
378 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
379 Group group = GroupLocalServiceUtil.getGroup(groupId);
380
381 groups.add(group);
382 }
383
384 userGroupRoles.addAll(
385 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
386 userId, groupId));
387 userGroupRoles.addAll(
388 UserGroupRoleLocalServiceUtil.
389 getUserGroupRolesByUserUserGroupAndGroup(
390 userId, groupId));
391 }
392 }
393
394 if (advancedPermissionChecker.isSignedIn()) {
395 roles.add(
396 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
397 }
398
399 for (Group group : groups) {
400 PermissionCheckerBag userBag = advancedPermissionChecker.getUserBag(
401 userId, group.getGroupId());
402
403 List<Role> groupRoles = userBag.getRoles();
404
405 groupIdsToRoles.put(group.getGroupId(), groupRoles);
406
407 roles.addAll(groupRoles);
408 }
409
410 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
411 return doGetPermissionQuery_5(
412 companyId, groupIds, userId, className, query, searchContext,
413 advancedPermissionChecker, groups, roles, userGroupRoles,
414 groupIdsToRoles);
415 }
416 else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
417 return doGetPermissionQuery_6(
418 companyId, groupIds, userId, className, query, searchContext,
419 advancedPermissionChecker, groups, roles, userGroupRoles,
420 groupIdsToRoles);
421 }
422
423 return query;
424 }
425
426 protected Query doGetPermissionQuery_5(
427 long companyId, long[] groupIds, long userId, String className,
428 Query query, SearchContext searchContext,
429 AdvancedPermissionChecker advancedPermissionChecker,
430 List<Group> groups, List<Role> roles,
431 List<UserGroupRole> userGroupRoles,
432 Map<Long, List<Role>> groupIdsToRoles)
433 throws Exception {
434
435 long companyResourceId = 0;
436
437 try {
438 Resource companyResource = ResourceLocalServiceUtil.getResource(
439 companyId, className, ResourceConstants.SCOPE_COMPANY,
440 String.valueOf(companyId));
441
442 companyResourceId = companyResource.getResourceId();
443 }
444 catch (NoSuchResourceException nsre) {
445 }
446
447 long groupTemplateResourceId = 0;
448
449 try {
450 Resource groupTemplateResource =
451 ResourceLocalServiceUtil.getResource(
452 companyId, className,
453 ResourceConstants.SCOPE_GROUP_TEMPLATE,
454 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
455
456 groupTemplateResourceId = groupTemplateResource.getResourceId();
457 }
458 catch (NoSuchResourceException nsre) {
459 }
460
461 BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create(
462 searchContext);
463
464 if (userId > 0) {
465 permissionQuery.addTerm(Field.USER_ID, userId);
466 }
467
468 BooleanQuery groupsQuery = BooleanQueryFactoryUtil.create(
469 searchContext);
470 BooleanQuery rolesQuery = BooleanQueryFactoryUtil.create(searchContext);
471
472 for (Role role : roles) {
473 String roleName = role.getName();
474
475 if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
476 return query;
477 }
478
479 if (hasPermission(role.getRoleId(), companyResourceId)) {
480 return query;
481 }
482
483 if (hasPermission(role.getRoleId(), groupTemplateResourceId)) {
484 return query;
485 }
486
487 for (Group group : groups) {
488 try {
489 Resource groupResource =
490 ResourceLocalServiceUtil.getResource(
491 companyId, className, ResourceConstants.SCOPE_GROUP,
492 String.valueOf(group.getGroupId()));
493
494 if (hasPermission(
495 role.getRoleId(), groupResource.getResourceId())) {
496
497 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
498 }
499 }
500 catch (NoSuchResourceException nsre) {
501 }
502
503 if ((role.getType() != RoleConstants.TYPE_REGULAR) &&
504 hasPermission(role.getRoleId(), groupTemplateResourceId)) {
505
506 List<Role> groupRoles = groupIdsToRoles.get(
507 group.getGroupId());
508
509 if (groupRoles.contains(role)) {
510 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
511 }
512 }
513 }
514
515 rolesQuery.addTerm(Field.ROLE_ID, role.getRoleId());
516 }
517
518 for (Group group : groups) {
519 addRequiredMemberRole(group, rolesQuery);
520 }
521
522 for (UserGroupRole userGroupRole : userGroupRoles) {
523 rolesQuery.addTerm(
524 Field.GROUP_ROLE_ID,
525 userGroupRole.getGroupId() + StringPool.DASH +
526 userGroupRole.getRoleId());
527 }
528
529 if (groupsQuery.hasClauses()) {
530 permissionQuery.add(groupsQuery, BooleanClauseOccur.SHOULD);
531 }
532
533 if (rolesQuery.hasClauses()) {
534 permissionQuery.add(rolesQuery, BooleanClauseOccur.SHOULD);
535 }
536
537 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
538
539 fullQuery.add(query, BooleanClauseOccur.MUST);
540 fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
541
542 return fullQuery;
543 }
544
545 protected Query doGetPermissionQuery_6(
546 long companyId, long[] groupIds, long userId, String className,
547 Query query, SearchContext searchContext,
548 AdvancedPermissionChecker advancedPermissionChecker,
549 List<Group> groups, List<Role> roles,
550 List<UserGroupRole> userGroupRoles,
551 Map<Long, List<Role>> groupIdsToRoles)
552 throws Exception {
553
554 BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create(
555 searchContext);
556
557 if (userId > 0) {
558 permissionQuery.addTerm(Field.USER_ID, userId);
559 }
560
561 BooleanQuery groupsQuery = BooleanQueryFactoryUtil.create(
562 searchContext);
563 BooleanQuery rolesQuery = BooleanQueryFactoryUtil.create(searchContext);
564
565 for (Role role : roles) {
566 String roleName = role.getName();
567
568 if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
569 return query;
570 }
571
572 if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
573 companyId, className, ResourceConstants.SCOPE_COMPANY,
574 String.valueOf(companyId), role.getRoleId(),
575 ActionKeys.VIEW)) {
576
577 return query;
578 }
579
580 if ((role.getType() == RoleConstants.TYPE_REGULAR) &&
581 ResourcePermissionLocalServiceUtil.hasResourcePermission(
582 companyId, className,
583 ResourceConstants.SCOPE_GROUP_TEMPLATE,
584 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
585 role.getRoleId(), ActionKeys.VIEW)) {
586
587 return query;
588 }
589
590 for (Group group : groups) {
591 if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
592 companyId, className, ResourceConstants.SCOPE_GROUP,
593 String.valueOf(group.getGroupId()), role.getRoleId(),
594 ActionKeys.VIEW)) {
595
596 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
597 }
598
599 if ((role.getType() != RoleConstants.TYPE_REGULAR) &&
600 ResourcePermissionLocalServiceUtil.hasResourcePermission(
601 companyId, className,
602 ResourceConstants.SCOPE_GROUP_TEMPLATE,
603 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
604 role.getRoleId(), ActionKeys.VIEW)) {
605
606 List<Role> groupRoles = groupIdsToRoles.get(
607 group.getGroupId());
608
609 if (groupRoles.contains(role)) {
610 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
611 }
612 }
613
614 if (group.isSite() &&
615 !role.getName().equals(RoleConstants.SITE_MEMBER) &&
616 (role.getType() == RoleConstants.TYPE_SITE)) {
617
618 rolesQuery.addTerm(
619 Field.GROUP_ROLE_ID,
620 group.getGroupId() + StringPool.DASH +
621 role.getRoleId());
622 }
623 }
624
625 rolesQuery.addTerm(Field.ROLE_ID, role.getRoleId());
626 }
627
628 for (Group group : groups) {
629 addRequiredMemberRole(group, rolesQuery);
630 }
631
632 for (UserGroupRole userGroupRole : userGroupRoles) {
633 rolesQuery.addTerm(
634 Field.GROUP_ROLE_ID,
635 userGroupRole.getGroupId() + StringPool.DASH +
636 userGroupRole.getRoleId());
637 }
638
639 if (groupsQuery.hasClauses()) {
640 permissionQuery.add(groupsQuery, BooleanClauseOccur.SHOULD);
641 }
642
643 if (rolesQuery.hasClauses()) {
644 permissionQuery.add(rolesQuery, BooleanClauseOccur.SHOULD);
645 }
646
647 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
648
649 fullQuery.add(query, BooleanClauseOccur.MUST);
650 fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
651
652 return fullQuery;
653 }
654
655 protected void doUpdatePermissionFields_5(long resourceId)
656 throws Exception {
657
658 Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
659
660 Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
661
662 if (indexer != null) {
663 indexer.reindex(
664 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
665 }
666 }
667
668 protected void doUpdatePermissionFields_6(
669 String resourceName, String resourceClassPK)
670 throws Exception {
671
672 Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
673
674 if (indexer != null) {
675 indexer.reindex(resourceName, GetterUtil.getLong(resourceClassPK));
676 }
677 }
678
679 protected PermissionCheckerBag getPermissionCheckerBag(
680 AdvancedPermissionChecker advancedPermissionChecker, long userId)
681 throws Exception {
682
683 if (!advancedPermissionChecker.isSignedIn()) {
684 return advancedPermissionChecker.getGuestUserBag();
685 }
686 else {
687 return advancedPermissionChecker.getUserBag(userId, 0);
688 }
689 }
690
691 protected boolean hasPermission(long roleId, long resourceId)
692 throws SystemException {
693
694 if (resourceId == 0) {
695 return false;
696 }
697
698 List<Permission> permissions =
699 PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
700
701 List<String> actions = ResourceActionsUtil.getActions(permissions);
702
703 if (actions.contains(ActionKeys.VIEW)) {
704 return true;
705 }
706 else {
707 return false;
708 }
709 }
710
711 private static Log _log = LogFactoryUtil.getLog(
712 SearchPermissionCheckerImpl.class);
713
714 }