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