001
014
015 package com.liferay.portal.search;
016
017 import com.liferay.portal.NoSuchResourceException;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.search.BooleanClauseOccur;
021 import com.liferay.portal.kernel.search.Document;
022 import com.liferay.portal.kernel.search.Field;
023 import com.liferay.portal.kernel.search.Indexer;
024 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
025 import com.liferay.portal.kernel.search.SearchContext;
026 import com.liferay.portal.kernel.search.SearchPermissionChecker;
027 import com.liferay.portal.kernel.search.filter.BooleanFilter;
028 import com.liferay.portal.kernel.search.filter.TermsFilter;
029 import com.liferay.portal.kernel.util.ArrayUtil;
030 import com.liferay.portal.kernel.util.GetterUtil;
031 import com.liferay.portal.kernel.util.ListUtil;
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.ResourceConstants;
037 import com.liferay.portal.model.Role;
038 import com.liferay.portal.model.RoleConstants;
039 import com.liferay.portal.model.UserGroupRole;
040 import com.liferay.portal.security.permission.ActionKeys;
041 import com.liferay.portal.security.permission.AdvancedPermissionChecker;
042 import com.liferay.portal.security.permission.PermissionChecker;
043 import com.liferay.portal.security.permission.PermissionCheckerBag;
044 import com.liferay.portal.security.permission.PermissionThreadLocal;
045 import com.liferay.portal.security.permission.ResourceActionsUtil;
046 import com.liferay.portal.security.permission.ResourceBlockIdsBag;
047 import com.liferay.portal.service.GroupLocalServiceUtil;
048 import com.liferay.portal.service.ResourceBlockLocalServiceUtil;
049 import com.liferay.portal.service.ResourceBlockPermissionLocalServiceUtil;
050 import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
051 import com.liferay.portal.service.RoleLocalServiceUtil;
052 import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
053 import com.liferay.portal.util.PortalUtil;
054
055 import java.util.ArrayList;
056 import java.util.HashMap;
057 import java.util.LinkedHashSet;
058 import java.util.List;
059 import java.util.Map;
060 import java.util.Set;
061
062
068 public class SearchPermissionCheckerImpl implements SearchPermissionChecker {
069
070 @Override
071 public void addPermissionFields(long companyId, Document document) {
072 try {
073 long groupId = GetterUtil.getLong(document.get(Field.GROUP_ID));
074
075 String className = document.get(Field.ENTRY_CLASS_NAME);
076
077 boolean relatedEntry = GetterUtil.getBoolean(
078 document.get(Field.RELATED_ENTRY));
079
080 if (relatedEntry) {
081 long classNameId = GetterUtil.getLong(
082 document.get(Field.CLASS_NAME_ID));
083
084 className = PortalUtil.getClassName(classNameId);
085 }
086
087 if (Validator.isNull(className)) {
088 return;
089 }
090
091 String classPK = document.get(Field.ROOT_ENTRY_CLASS_PK);
092
093 if (Validator.isNull(classPK)) {
094 classPK = document.get(Field.ENTRY_CLASS_PK);
095 }
096
097 if (relatedEntry) {
098 classPK = document.get(Field.CLASS_PK);
099 }
100
101 if (Validator.isNull(classPK)) {
102 return;
103 }
104
105 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
106
107 if (!indexer.isPermissionAware()) {
108 return;
109 }
110
111 doAddPermissionFields_6(
112 companyId, groupId, className, classPK, document);
113 }
114 catch (NoSuchResourceException nsre) {
115 if (_log.isDebugEnabled()) {
116 _log.debug(nsre, nsre);
117 }
118 }
119 catch (Exception e) {
120 _log.error(e, e);
121 }
122 }
123
124 @Override
125 public BooleanFilter getPermissionBooleanFilter(
126 long companyId, long[] groupIds, long userId, String className,
127 BooleanFilter booleanFilter, SearchContext searchContext) {
128
129 try {
130 booleanFilter = doGetPermissionBooleanFilter(
131 companyId, groupIds, userId, className, booleanFilter,
132 searchContext);
133 }
134 catch (Exception e) {
135 _log.error(e, e);
136 }
137
138 return booleanFilter;
139 }
140
141 @Override
142 public void updatePermissionFields(
143 String resourceName, String resourceClassPK) {
144
145 try {
146 doUpdatePermissionFields(resourceName, resourceClassPK);
147 }
148 catch (Exception e) {
149 _log.error(e, e);
150 }
151 }
152
153 protected void addRequiredMemberRole(
154 Group group, TermsFilter groupRolesTermsFilter)
155 throws Exception {
156
157 if (group.isOrganization()) {
158 Role organizationUserRole = RoleLocalServiceUtil.getRole(
159 group.getCompanyId(), RoleConstants.ORGANIZATION_USER);
160
161 groupRolesTermsFilter.addValue(
162 group.getGroupId() + StringPool.DASH +
163 organizationUserRole.getRoleId());
164 }
165
166 if (group.isSite()) {
167 Role siteMemberRole = RoleLocalServiceUtil.getRole(
168 group.getCompanyId(), RoleConstants.SITE_MEMBER);
169
170 groupRolesTermsFilter.addValue(
171 group.getGroupId() + StringPool.DASH +
172 siteMemberRole.getRoleId());
173 }
174 }
175
176 protected void doAddPermissionFields_6(
177 long companyId, long groupId, String className, String classPK,
178 Document doc)
179 throws Exception {
180
181 Group group = null;
182
183 if (groupId > 0) {
184 group = GroupLocalServiceUtil.getGroup(groupId);
185 }
186
187 List<Role> roles = ListUtil.copy(
188 ResourceActionsUtil.getRoles(companyId, group, className, null));
189
190 if (groupId > 0) {
191 List<Role> teamRoles = RoleLocalServiceUtil.getTeamRoles(groupId);
192
193 roles.addAll(teamRoles);
194 }
195
196 long[] roleIdsArray = new long[roles.size()];
197
198 for (int i = 0; i < roleIdsArray.length; i++) {
199 Role role = roles.get(i);
200
201 roleIdsArray[i] = role.getRoleId();
202 }
203
204 boolean[] hasResourcePermissions = null;
205
206 if (ResourceBlockLocalServiceUtil.isSupported(className)) {
207 ResourceBlockIdsBag resourceBlockIdsBag =
208 ResourceBlockLocalServiceUtil.getResourceBlockIdsBag(
209 companyId, groupId, className, roleIdsArray);
210
211 long actionId = ResourceBlockLocalServiceUtil.getActionId(
212 className, ActionKeys.VIEW);
213
214 List<Long> resourceBlockIds =
215 resourceBlockIdsBag.getResourceBlockIds(actionId);
216
217 hasResourcePermissions = new boolean[roleIdsArray.length];
218
219 for (long resourceBlockId : resourceBlockIds) {
220 for (int i = 0; i < roleIdsArray.length; i++) {
221 int count =
222 ResourceBlockPermissionLocalServiceUtil.
223 getResourceBlockPermissionsCount(
224 resourceBlockId, roleIdsArray[i]);
225
226 hasResourcePermissions[i] = (count > 0);
227 }
228 }
229 }
230 else {
231 hasResourcePermissions =
232 ResourcePermissionLocalServiceUtil.hasResourcePermissions(
233 companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
234 classPK, roleIdsArray, ActionKeys.VIEW);
235 }
236
237 List<Long> roleIds = new ArrayList<>();
238 List<String> groupRoleIds = new ArrayList<>();
239
240 for (int i = 0; i < hasResourcePermissions.length; i++) {
241 if (!hasResourcePermissions[i]) {
242 continue;
243 }
244
245 Role role = roles.get(i);
246
247 if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) ||
248 (role.getType() == RoleConstants.TYPE_SITE)) {
249
250 groupRoleIds.add(groupId + StringPool.DASH + role.getRoleId());
251 }
252 else {
253 roleIds.add(role.getRoleId());
254 }
255 }
256
257 doc.addKeyword(
258 Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
259 doc.addKeyword(
260 Field.GROUP_ROLE_ID,
261 groupRoleIds.toArray(new String[groupRoleIds.size()]));
262 }
263
264 protected BooleanFilter doGetPermissionBooleanFilter(
265 long companyId, long[] groupIds, long userId, String className,
266 BooleanFilter booleanFilter, SearchContext searchContext)
267 throws Exception {
268
269 Indexer indexer = IndexerRegistryUtil.getIndexer(className);
270
271 if (!indexer.isPermissionAware()) {
272 return booleanFilter;
273 }
274
275 PermissionChecker permissionChecker =
276 PermissionThreadLocal.getPermissionChecker();
277
278 AdvancedPermissionChecker advancedPermissionChecker = null;
279
280 if ((permissionChecker != null) &&
281 (permissionChecker instanceof AdvancedPermissionChecker)) {
282
283 advancedPermissionChecker =
284 (AdvancedPermissionChecker)permissionChecker;
285 }
286
287 if (advancedPermissionChecker == null) {
288 return booleanFilter;
289 }
290
291 PermissionCheckerBag permissionCheckerBag = getPermissionCheckerBag(
292 advancedPermissionChecker, userId);
293
294 if (permissionCheckerBag == null) {
295 return booleanFilter;
296 }
297
298 Set<Group> groups = new LinkedHashSet<>();
299 Set<Role> roles = new LinkedHashSet<>();
300 Set<UserGroupRole> userGroupRoles = new LinkedHashSet<>();
301 Map<Long, List<Role>> groupIdsToRoles = new HashMap<>();
302
303 populate(
304 companyId, groupIds, userId, advancedPermissionChecker,
305 permissionCheckerBag, groups, roles, userGroupRoles,
306 groupIdsToRoles);
307
308 return doGetPermissionFilter_6(
309 companyId, groupIds, userId, className, booleanFilter, groups,
310 roles, userGroupRoles, groupIdsToRoles);
311 }
312
313 protected BooleanFilter doGetPermissionFilter_6(
314 long companyId, long[] groupIds, long userId, String className,
315 BooleanFilter booleanFilter, Set<Group> groups, Set<Role> roles,
316 Set<UserGroupRole> userGroupRoles,
317 Map<Long, List<Role>> groupIdsToRoles)
318 throws Exception {
319
320 BooleanFilter permissionBooleanFilter = new BooleanFilter();
321
322 if (userId > 0) {
323 permissionBooleanFilter.addTerm(Field.USER_ID, userId);
324 }
325
326 TermsFilter groupsTermsFilter = new TermsFilter(Field.GROUP_ID);
327 TermsFilter groupRolesTermsFilter = new TermsFilter(
328 Field.GROUP_ROLE_ID);
329 TermsFilter rolesTermsFilter = new TermsFilter(Field.ROLE_ID);
330
331 for (Role role : roles) {
332 String roleName = role.getName();
333
334 if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
335 return booleanFilter;
336 }
337
338 if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
339 companyId, className, ResourceConstants.SCOPE_COMPANY,
340 String.valueOf(companyId), role.getRoleId(),
341 ActionKeys.VIEW)) {
342
343 return booleanFilter;
344 }
345
346 if ((role.getType() == RoleConstants.TYPE_REGULAR) &&
347 ResourcePermissionLocalServiceUtil.hasResourcePermission(
348 companyId, className,
349 ResourceConstants.SCOPE_GROUP_TEMPLATE,
350 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
351 role.getRoleId(), ActionKeys.VIEW)) {
352
353 return booleanFilter;
354 }
355
356 for (Group group : groups) {
357 if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
358 companyId, className, ResourceConstants.SCOPE_GROUP,
359 String.valueOf(group.getGroupId()), role.getRoleId(),
360 ActionKeys.VIEW)) {
361
362 groupsTermsFilter.addValue(
363 String.valueOf(group.getGroupId()));
364 }
365
366 if ((role.getType() != RoleConstants.TYPE_REGULAR) &&
367 ResourcePermissionLocalServiceUtil.hasResourcePermission(
368 companyId, className,
369 ResourceConstants.SCOPE_GROUP_TEMPLATE,
370 String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
371 role.getRoleId(), ActionKeys.VIEW)) {
372
373 List<Role> groupRoles = groupIdsToRoles.get(
374 group.getGroupId());
375
376 if (groupRoles.contains(role)) {
377 groupsTermsFilter.addValue(
378 String.valueOf(group.getGroupId()));
379 }
380 }
381
382 if (group.isSite() &&
383 !roleName.equals(RoleConstants.SITE_MEMBER) &&
384 (role.getType() == RoleConstants.TYPE_SITE)) {
385
386 groupRolesTermsFilter.addValue(
387 group.getGroupId() + StringPool.DASH +
388 role.getRoleId());
389 }
390 }
391
392 if (ArrayUtil.isNotEmpty(groupIds)) {
393 for (long groupId : groupIds) {
394 if (ResourcePermissionLocalServiceUtil.
395 hasResourcePermission(
396 companyId, className,
397 ResourceConstants.SCOPE_GROUP,
398 String.valueOf(groupId), role.getRoleId(),
399 ActionKeys.VIEW)) {
400
401 groupsTermsFilter.addValue(String.valueOf(groupId));
402 }
403 }
404 }
405
406 rolesTermsFilter.addValue(String.valueOf(role.getRoleId()));
407 }
408
409 for (Group group : groups) {
410 addRequiredMemberRole(group, groupRolesTermsFilter);
411 }
412
413 for (UserGroupRole userGroupRole : userGroupRoles) {
414 groupRolesTermsFilter.addValue(
415 userGroupRole.getGroupId() + StringPool.DASH +
416 userGroupRole.getRoleId());
417 }
418
419 if (!groupsTermsFilter.isEmpty()) {
420 permissionBooleanFilter.add(groupsTermsFilter);
421 }
422
423 if (!groupRolesTermsFilter.isEmpty()) {
424 permissionBooleanFilter.add(groupRolesTermsFilter);
425 }
426
427 if (!rolesTermsFilter.isEmpty()) {
428 permissionBooleanFilter.add(rolesTermsFilter);
429 }
430
431 if (!permissionBooleanFilter.hasClauses()) {
432 return booleanFilter;
433 }
434
435 BooleanFilter fullBooleanFilter = new BooleanFilter();
436
437 if ((booleanFilter != null) && booleanFilter.hasClauses()) {
438 fullBooleanFilter.add(booleanFilter, BooleanClauseOccur.MUST);
439 }
440
441 fullBooleanFilter.add(permissionBooleanFilter, BooleanClauseOccur.MUST);
442
443 return fullBooleanFilter;
444 }
445
446 protected void doUpdatePermissionFields(
447 String resourceName, String resourceClassPK)
448 throws Exception {
449
450 Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
451
452 if (indexer != null) {
453 indexer.reindex(resourceName, GetterUtil.getLong(resourceClassPK));
454 }
455 }
456
457 protected PermissionCheckerBag getPermissionCheckerBag(
458 AdvancedPermissionChecker advancedPermissionChecker, long userId)
459 throws Exception {
460
461 if (!advancedPermissionChecker.isSignedIn()) {
462 return advancedPermissionChecker.getGuestUserBag();
463 }
464 else {
465 return advancedPermissionChecker.getUserBag(userId, 0);
466 }
467 }
468
469 protected void populate(
470 long companyId, long[] groupIds, long userId,
471 AdvancedPermissionChecker advancedPermissionChecker,
472 PermissionCheckerBag permissionCheckerBag, Set<Group> groups,
473 Set<Role> roles, Set<UserGroupRole> userGroupRoles,
474 Map<Long, List<Role>> groupIdsToRoles)
475 throws Exception {
476
477 roles.addAll(permissionCheckerBag.getRoles());
478
479 if (ArrayUtil.isEmpty(groupIds)) {
480 groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
481 groups.addAll(permissionCheckerBag.getGroups());
482
483 userGroupRoles.addAll(
484 UserGroupRoleLocalServiceUtil.getUserGroupRoles(userId));
485 }
486 else {
487 for (long groupId : groupIds) {
488 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
489 Group group = GroupLocalServiceUtil.getGroup(groupId);
490
491 groups.add(group);
492 }
493
494 userGroupRoles.addAll(
495 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
496 userId, groupId));
497 userGroupRoles.addAll(
498 UserGroupRoleLocalServiceUtil.
499 getUserGroupRolesByUserUserGroupAndGroup(
500 userId, groupId));
501 }
502 }
503
504 if (advancedPermissionChecker.isSignedIn()) {
505 roles.add(
506 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
507 }
508
509 for (Group group : groups) {
510 PermissionCheckerBag userBag = advancedPermissionChecker.getUserBag(
511 userId, group.getGroupId());
512
513 List<Role> groupRoles = ListUtil.fromCollection(userBag.getRoles());
514
515 groupIdsToRoles.put(group.getGroupId(), groupRoles);
516
517 roles.addAll(groupRoles);
518 }
519 }
520
521 private static final Log _log = LogFactoryUtil.getLog(
522 SearchPermissionCheckerImpl.class);
523
524 }