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