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