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