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