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