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,
183 classPK);
184
185 Group group = null;
186
187 if (groupId > 0) {
188 group = GroupLocalServiceUtil.getGroup(groupId);
189 }
190
191 List<Role> roles = ResourceActionsUtil.getRoles(
192 companyId, group, className, null);
193
194 List<Long> roleIds = new ArrayList<Long>();
195 List<String> groupRoleIds = new ArrayList<String>();
196
197 for (Role role : roles) {
198 long roleId = role.getRoleId();
199
200 if (hasPermission(roleId, resource.getResourceId())) {
201 if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
202 (role.getType() == RoleConstants.TYPE_SITE)) {
203
204 groupRoleIds.add(groupId + StringPool.DASH + roleId);
205 }
206 else {
207 roleIds.add(roleId);
208 }
209 }
210 }
211
212 document.addKeyword(
213 Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
214 document.addKeyword(
215 Field.GROUP_ROLE_ID,
216 groupRoleIds.toArray(new String[groupRoleIds.size()]));
217 }
218
219 protected void doAddPermissionFields_6(
220 long companyId, long groupId, String className, String classPK,
221 Document doc)
222 throws Exception {
223
224 Group group = null;
225
226 if (groupId > 0) {
227 group = GroupLocalServiceUtil.getGroup(groupId);
228 }
229
230 List<Role> roles = ResourceActionsUtil.getRoles(
231 companyId, group, className, null);
232
233 long[] roleIdsArray = new long[roles.size()];
234
235 for (int i = 0; i < roleIdsArray.length; i++) {
236 Role role = roles.get(i);
237
238 roleIdsArray[i] = role.getRoleId();
239 }
240
241 boolean[] hasResourcePermissions =
242 ResourcePermissionLocalServiceUtil.hasResourcePermissions(
243 companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
244 classPK, roleIdsArray, ActionKeys.VIEW);
245
246 List<Long> roleIds = new ArrayList<Long>();
247 List<String> groupRoleIds = new ArrayList<String>();
248
249 for (int i = 0; i < hasResourcePermissions.length; i++) {
250 if (!hasResourcePermissions[i]) {
251 continue;
252 }
253
254 Role role = roles.get(i);
255
256 if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
257 (role.getType() == RoleConstants.TYPE_SITE)) {
258
259 groupRoleIds.add(groupId + StringPool.DASH + role.getRoleId());
260 }
261 else {
262 roleIds.add(role.getRoleId());
263 }
264 }
265
266 doc.addKeyword(
267 Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
268 doc.addKeyword(
269 Field.GROUP_ROLE_ID,
270 groupRoleIds.toArray(new String[groupRoleIds.size()]));
271 }
272
273 protected Query doGetPermissionQuery(
274 long companyId, long[] groupIds, long userId, String className,
275 Query query, SearchContext searchContext)
276 throws Exception {
277
278 if ((PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 5) &&
279 (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM != 6)) {
280
281 return query;
282 }
283
284 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
285
286 if (!indexer.isFilterSearch()) {
287 return query;
288 }
289
290 PermissionChecker permissionChecker =
291 PermissionThreadLocal.getPermissionChecker();
292
293 AdvancedPermissionChecker advancedPermissionChecker = null;
294
295 if ((permissionChecker != null) &&
296 (permissionChecker instanceof AdvancedPermissionChecker)) {
297
298 advancedPermissionChecker =
299 (AdvancedPermissionChecker)permissionChecker;
300 }
301
302 if (advancedPermissionChecker == null) {
303 return query;
304 }
305
306 PermissionCheckerBag permissionCheckerBag = getPermissionCheckerBag(
307 advancedPermissionChecker, userId);
308
309 if (permissionCheckerBag == null) {
310 return query;
311 }
312
313 List<Group> groups = new UniqueList<Group>();
314 List<Role> roles = new UniqueList<Role>();
315 List<UserGroupRole> userGroupRoles = new UniqueList<UserGroupRole>();
316 Map<Long, List<Role>> groupIdsToRoles = new HashMap<Long, List<Role>>();
317
318 roles.addAll(permissionCheckerBag.getRoles());
319
320 if ((groupIds == null) || (groupIds.length == 0)) {
321 groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
322 groups.addAll(permissionCheckerBag.getGroups());
323
324 userGroupRoles =
325 UserGroupRoleLocalServiceUtil.getUserGroupRoles(userId);
326 }
327 else {
328 groups.addAll(permissionCheckerBag.getGroups());
329
330 for (long groupId : groupIds) {
331 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
332 Group group = GroupLocalServiceUtil.getGroup(groupId);
333
334 groups.add(group);
335 }
336
337 userGroupRoles.addAll(
338 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
339 userId, groupId));
340 userGroupRoles.addAll(
341 UserGroupRoleLocalServiceUtil.
342 getUserGroupRolesByUserUserGroupAndGroup(
343 userId, groupId));
344 }
345 }
346
347 if (advancedPermissionChecker.isSignedIn()) {
348 roles.add(
349 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
350 }
351
352 for (Group group : groups) {
353 PermissionCheckerBag userBag = advancedPermissionChecker.getUserBag(
354 userId, group.getGroupId());
355
356 List<Role> groupRoles = userBag.getRoles();
357
358 groupIdsToRoles.put(group.getGroupId(), groupRoles);
359
360 roles.addAll(groupRoles);
361 }
362
363 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
364 return doGetPermissionQuery_5(
365 companyId, groupIds, userId, className, query, searchContext,
366 advancedPermissionChecker, groups, roles, userGroupRoles,
367 groupIdsToRoles);
368 }
369 else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
370 return doGetPermissionQuery_6(
371 companyId, groupIds, userId, className, query, searchContext,
372 advancedPermissionChecker, groups, roles, userGroupRoles,
373 groupIdsToRoles);
374 }
375
376 return query;
377 }
378
379 protected Query doGetPermissionQuery_5(
380 long companyId, long[] groupIds, long userId, String className,
381 Query query, SearchContext searchContext,
382 AdvancedPermissionChecker advancedPermissionChecker,
383 List<Group> groups, List<Role> roles,
384 List<UserGroupRole> userGroupRoles,
385 Map<Long, List<Role>> groupIdsToRoles)
386 throws Exception {
387
388 long companyResourceId = 0;
389
390 try {
391 Resource companyResource = ResourceLocalServiceUtil.getResource(
392 companyId, className, ResourceConstants.SCOPE_COMPANY,
393 String.valueOf(companyId));
394
395 companyResourceId = companyResource.getResourceId();
396 }
397 catch (NoSuchResourceException nsre) {
398 }
399
400 long groupTemplateResourceId = 0;
401
402 try {
403 Resource groupTemplateResource =
404 ResourceLocalServiceUtil.getResource(
405 companyId, className,
406 ResourceConstants.SCOPE_GROUP_TEMPLATE,
407 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID));
408
409 groupTemplateResourceId = groupTemplateResource.getResourceId();
410 }
411 catch (NoSuchResourceException nsre) {
412 }
413
414 BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create(
415 searchContext);
416
417 if (userId > 0) {
418 permissionQuery.addTerm(Field.USER_ID, userId);
419 }
420
421 BooleanQuery groupsQuery = BooleanQueryFactoryUtil.create(
422 searchContext);
423 BooleanQuery rolesQuery = BooleanQueryFactoryUtil.create(searchContext);
424
425 for (Role role : roles) {
426 String roleName = role.getName();
427
428 if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
429 return query;
430 }
431
432 if (hasPermission(role.getRoleId(), companyResourceId)) {
433 return query;
434 }
435
436 if (hasPermission(role.getRoleId(), groupTemplateResourceId)) {
437 return query;
438 }
439
440 for (Group group : groups) {
441 try {
442 Resource groupResource =
443 ResourceLocalServiceUtil.getResource(
444 companyId, className, ResourceConstants.SCOPE_GROUP,
445 String.valueOf(group.getGroupId()));
446
447 if (hasPermission(
448 role.getRoleId(), groupResource.getResourceId())) {
449
450 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
451 }
452 }
453 catch (NoSuchResourceException nsre) {
454 }
455
456 if ((role.getType() != RoleConstants.TYPE_REGULAR) &&
457 hasPermission(role.getRoleId(), groupTemplateResourceId)) {
458
459 List<Role> groupRoles = groupIdsToRoles.get(
460 group.getGroupId());
461
462 if (groupRoles.contains(role)) {
463 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
464 }
465 }
466 }
467
468 rolesQuery.addTerm(Field.ROLE_ID, role.getRoleId());
469 }
470
471 for (Group group : groups) {
472 addRequiredMemberRole(group, rolesQuery);
473 }
474
475 for (UserGroupRole userGroupRole : userGroupRoles) {
476 rolesQuery.addTerm(
477 Field.GROUP_ROLE_ID,
478 userGroupRole.getGroupId() + StringPool.DASH +
479 userGroupRole.getRoleId());
480 }
481
482 if (groupsQuery.hasClauses()) {
483 permissionQuery.add(groupsQuery, BooleanClauseOccur.SHOULD);
484 }
485
486 if (rolesQuery.hasClauses()) {
487 permissionQuery.add(rolesQuery, BooleanClauseOccur.SHOULD);
488 }
489
490 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
491
492 fullQuery.add(query, BooleanClauseOccur.MUST);
493 fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
494
495 return fullQuery;
496 }
497
498 protected Query doGetPermissionQuery_6(
499 long companyId, long[] groupIds, long userId, String className,
500 Query query, SearchContext searchContext,
501 AdvancedPermissionChecker advancedPermissionChecker,
502 List<Group> groups, List<Role> roles,
503 List<UserGroupRole> userGroupRoles,
504 Map<Long, List<Role>> groupIdsToRoles)
505 throws Exception {
506
507 BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create(
508 searchContext);
509
510 if (userId > 0) {
511 permissionQuery.addTerm(Field.USER_ID, userId);
512 }
513
514 BooleanQuery groupsQuery = BooleanQueryFactoryUtil.create(
515 searchContext);
516 BooleanQuery rolesQuery = BooleanQueryFactoryUtil.create(searchContext);
517
518 for (Role role : roles) {
519 String roleName = role.getName();
520
521 if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
522 return query;
523 }
524
525 if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
526 companyId, className, ResourceConstants.SCOPE_COMPANY,
527 String.valueOf(companyId), role.getRoleId(),
528 ActionKeys.VIEW)) {
529
530 return query;
531 }
532
533 if ((role.getType() == RoleConstants.TYPE_REGULAR) &&
534 ResourcePermissionLocalServiceUtil.hasResourcePermission(
535 companyId, className,
536 ResourceConstants.SCOPE_GROUP_TEMPLATE,
537 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
538 role.getRoleId(), ActionKeys.VIEW)) {
539
540 return query;
541 }
542
543 for (Group group : groups) {
544 if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
545 companyId, className, ResourceConstants.SCOPE_GROUP,
546 String.valueOf(group.getGroupId()), role.getRoleId(),
547 ActionKeys.VIEW)) {
548
549 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
550 }
551
552 if ((role.getType() != RoleConstants.TYPE_REGULAR) &&
553 ResourcePermissionLocalServiceUtil.hasResourcePermission(
554 companyId, className,
555 ResourceConstants.SCOPE_GROUP_TEMPLATE,
556 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
557 role.getRoleId(), ActionKeys.VIEW)) {
558
559 List<Role> groupRoles = groupIdsToRoles.get(
560 group.getGroupId());
561
562 if (groupRoles.contains(role)) {
563 groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
564 }
565 }
566 }
567
568 rolesQuery.addTerm(Field.ROLE_ID, role.getRoleId());
569 }
570
571 for (Group group : groups) {
572 addRequiredMemberRole(group, rolesQuery);
573 }
574
575 for (UserGroupRole userGroupRole : userGroupRoles) {
576 rolesQuery.addTerm(
577 Field.GROUP_ROLE_ID,
578 userGroupRole.getGroupId() + StringPool.DASH +
579 userGroupRole.getRoleId());
580 }
581
582 if (groupsQuery.hasClauses()) {
583 permissionQuery.add(groupsQuery, BooleanClauseOccur.SHOULD);
584 }
585
586 if (rolesQuery.hasClauses()) {
587 permissionQuery.add(rolesQuery, BooleanClauseOccur.SHOULD);
588 }
589
590 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
591
592 fullQuery.add(query, BooleanClauseOccur.MUST);
593 fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
594
595 return fullQuery;
596 }
597
598 protected void doUpdatePermissionFields_5(long resourceId)
599 throws Exception {
600
601 Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
602
603 Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
604
605 if (indexer != null) {
606 indexer.reindex(
607 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
608 }
609 }
610
611 protected void doUpdatePermissionFields_6(
612 String resourceName, String resourceClassPK)
613 throws Exception {
614
615 Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
616
617 if (indexer != null) {
618 indexer.reindex(resourceName, GetterUtil.getLong(resourceClassPK));
619 }
620 }
621
622 protected PermissionCheckerBag getPermissionCheckerBag(
623 AdvancedPermissionChecker advancedPermissionChecker, long userId)
624 throws Exception {
625
626 if (!advancedPermissionChecker.isSignedIn()) {
627 return advancedPermissionChecker.getGuestUserBag();
628 }
629 else {
630 return advancedPermissionChecker.getUserBag(userId, 0);
631 }
632 }
633
634 protected boolean hasPermission(long roleId, long resourceId)
635 throws SystemException {
636
637 if (resourceId == 0) {
638 return false;
639 }
640
641 List<Permission> permissions =
642 PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
643
644 List<String> actions = ResourceActionsUtil.getActions(permissions);
645
646 if (actions.contains(ActionKeys.VIEW)) {
647 return true;
648 }
649 else {
650 return false;
651 }
652 }
653
654 private static Log _log = LogFactoryUtil.getLog(
655 SearchPermissionCheckerImpl.class);
656
657 }