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