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