1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.search;
16  
17  import com.liferay.portal.NoSuchResourceException;
18  import com.liferay.portal.kernel.exception.SystemException;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.search.BooleanClauseOccur;
22  import com.liferay.portal.kernel.search.BooleanQuery;
23  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
24  import com.liferay.portal.kernel.search.Document;
25  import com.liferay.portal.kernel.search.Field;
26  import com.liferay.portal.kernel.search.Indexer;
27  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
28  import com.liferay.portal.kernel.search.Query;
29  import com.liferay.portal.kernel.search.SearchPermissionChecker;
30  import com.liferay.portal.kernel.util.GetterUtil;
31  import com.liferay.portal.kernel.util.StringPool;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.model.Group;
34  import com.liferay.portal.model.Permission;
35  import com.liferay.portal.model.Resource;
36  import com.liferay.portal.model.ResourceConstants;
37  import com.liferay.portal.model.Role;
38  import com.liferay.portal.model.RoleConstants;
39  import com.liferay.portal.model.User;
40  import com.liferay.portal.model.UserGroupRole;
41  import com.liferay.portal.security.permission.ActionKeys;
42  import com.liferay.portal.security.permission.AdvancedPermissionChecker;
43  import com.liferay.portal.security.permission.PermissionChecker;
44  import com.liferay.portal.security.permission.PermissionCheckerBag;
45  import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
46  import com.liferay.portal.security.permission.ResourceActionsUtil;
47  import com.liferay.portal.service.GroupLocalServiceUtil;
48  import com.liferay.portal.service.PermissionLocalServiceUtil;
49  import com.liferay.portal.service.ResourceLocalServiceUtil;
50  import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
51  import com.liferay.portal.service.RoleLocalServiceUtil;
52  import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
53  import com.liferay.portal.service.UserLocalServiceUtil;
54  import com.liferay.portal.util.PropsValues;
55  
56  import java.util.ArrayList;
57  import java.util.List;
58  
59  /**
60   * <a href="SearchPermissionCheckerImpl.java.html"><b><i>View Source</i></b></a>
61   *
62   * @author Allen Chiang
63   * @author Bruno Farache
64   * @author Raymond Augé
65   * @author Amos Fong
66   */
67  public class SearchPermissionCheckerImpl implements SearchPermissionChecker {
68  
69      public void addPermissionFields(long companyId, Document doc) {
70          try {
71              long groupId = GetterUtil.getLong(doc.get(Field.GROUP_ID));
72              String className = doc.get(Field.ENTRY_CLASS_NAME);
73  
74              String classPK = doc.get(Field.ROOT_ENTRY_CLASS_PK);
75  
76              if (Validator.isNull(classPK)) {
77                  classPK = doc.get(Field.ENTRY_CLASS_PK);
78              }
79  
80              if (Validator.isNotNull(className) &&
81                  Validator.isNotNull(classPK)) {
82  
83                  if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
84                      doAddPermissionFields_5(
85                          companyId, groupId, className, classPK, doc);
86                  }
87                  else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
88                      doAddPermissionFields_6(
89                          companyId, groupId, className, classPK, doc);
90                  }
91              }
92          }
93          catch (NoSuchResourceException nsre) {
94          }
95          catch (Exception e) {
96              _log.error(e, e);
97          }
98      }
99  
100     public Query getPermissionQuery(
101         long companyId, long[] groupIds, long userId, String className,
102         Query query) {
103 
104         try {
105             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
106                 return doGetPermissionQuery_5(
107                     companyId, groupIds, userId, className, query);
108             }
109             else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
110                 return doGetPermissionQuery_6(
111                     companyId, groupIds, userId, className, query);
112             }
113         }
114         catch (Exception e) {
115             _log.error(e, e);
116         }
117 
118         return query;
119     }
120 
121     public void updatePermissionFields(long resourceId) {
122         try {
123             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
124                 doUpdatePermissionFields_5(resourceId);
125             }
126         }
127         catch (Exception e) {
128             _log.error(e, e);
129         }
130     }
131 
132     public void updatePermissionFields(
133         String resourceName, String resourceClassPK) {
134 
135         try {
136             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
137                 doUpdatePermissionFields_6(resourceName, resourceClassPK);
138             }
139         }
140         catch (Exception e) {
141             _log.error(e, e);
142         }
143     }
144 
145     protected void addRequiredMemberRole(
146             Group group, BooleanQuery permissionQuery)
147         throws Exception {
148 
149         if (group.isCommunity()) {
150             Role communityMemberRole = RoleLocalServiceUtil.getRole(
151                 group.getCompanyId(), RoleConstants.COMMUNITY_MEMBER);
152 
153             permissionQuery.addTerm(
154                 Field.GROUP_ROLE_ID,
155                 group.getGroupId() + StringPool.DASH +
156                     communityMemberRole.getRoleId());
157         }
158         else if (group.isOrganization()) {
159             Role organizationMemberRole = RoleLocalServiceUtil.getRole(
160                 group.getCompanyId(), RoleConstants.ORGANIZATION_MEMBER);
161 
162             permissionQuery.addTerm(
163                 Field.GROUP_ROLE_ID,
164                 group.getGroupId() + StringPool.DASH +
165                     organizationMemberRole.getRoleId());
166         }
167     }
168 
169     protected void doAddPermissionFields_5(
170             long companyId, long groupId, String className, String classPK,
171             Document doc)
172         throws Exception {
173 
174         Resource resource = ResourceLocalServiceUtil.getResource(
175             companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
176             classPK);
177 
178         Group group = null;
179 
180         if (groupId > 0) {
181             group = GroupLocalServiceUtil.getGroup(groupId);
182         }
183 
184         List<Role> roles = ResourceActionsUtil.getRoles(
185             companyId, group, className);
186 
187         List<Long> roleIds = new ArrayList<Long>();
188         List<String> groupRoleIds = new ArrayList<String>();
189 
190         for (Role role : roles) {
191             long roleId = role.getRoleId();
192 
193             if (hasPermission(roleId, resource.getResourceId())) {
194                 if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
195                     (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
196 
197                     groupRoleIds.add(groupId + StringPool.DASH + roleId);
198                 }
199                 else {
200                     roleIds.add(roleId);
201                 }
202             }
203         }
204 
205         doc.addKeyword(
206             Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
207         doc.addKeyword(
208             Field.GROUP_ROLE_ID,
209             groupRoleIds.toArray(new String[groupRoleIds.size()]));
210     }
211 
212     protected void doAddPermissionFields_6(
213             long companyId, long groupId, String className, String classPK,
214             Document doc)
215         throws Exception {
216 
217         Group group = null;
218 
219         if (groupId > 0) {
220             group = GroupLocalServiceUtil.getGroup(groupId);
221         }
222 
223         List<Role> roles = ResourceActionsUtil.getRoles(
224             companyId, group, className);
225 
226         List<Long> roleIds = new ArrayList<Long>();
227         List<String> groupRoleIds = new ArrayList<String>();
228 
229         for (Role role : roles) {
230             long roleId = role.getRoleId();
231 
232             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
233                     companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
234                     classPK, roleId, ActionKeys.VIEW)) {
235 
236                 if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
237                     (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
238 
239                     groupRoleIds.add(groupId + StringPool.DASH + roleId);
240                 }
241                 else {
242                     roleIds.add(roleId);
243                 }
244             }
245         }
246 
247         doc.addKeyword(
248             Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
249         doc.addKeyword(
250             Field.GROUP_ROLE_ID,
251             groupRoleIds.toArray(new String[groupRoleIds.size()]));
252     }
253 
254     protected Query doGetPermissionQuery_5(
255             long companyId, long[] groupIds, long userId, String className,
256             Query query)
257         throws Exception {
258 
259         PermissionCheckerBag bag = getUserBag(userId);
260 
261         List<Group> groups = new ArrayList<Group>();
262         List<Role> roles = bag.getRoles();
263         List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
264 
265         if ((groupIds == null) || (groupIds.length == 0)) {
266             groups.addAll(
267                 GroupLocalServiceUtil.getUserGroups(userId, true));
268             groups.addAll(bag.getGroups());
269 
270             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
271                 userId);
272         }
273         else {
274             for (long groupId : groupIds) {
275                 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
276                     Group group = GroupLocalServiceUtil.getGroup(groupId);
277 
278                     groups.add(group);
279                 }
280 
281                 userGroupRoles.addAll(
282                     UserGroupRoleLocalServiceUtil.getUserGroupRoles(
283                         userId, groupId));
284                 userGroupRoles.addAll(
285                     UserGroupRoleLocalServiceUtil.
286                         getUserGroupRolesByUserUserGroupAndGroup(
287                             userId, groupId));
288             }
289         }
290 
291         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
292 
293         if (defaultUserId != userId) {
294             roles.add(
295                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
296         }
297 
298         long companyResourceId = 0;
299 
300         try {
301             Resource companyResource = ResourceLocalServiceUtil.getResource(
302                 companyId, className, ResourceConstants.SCOPE_COMPANY,
303                 String.valueOf(companyId));
304 
305             companyResourceId = companyResource.getResourceId();
306         }
307         catch (NoSuchResourceException nsre) {
308         }
309 
310         long[] groupResourceIds = new long[groupIds.length];
311 
312         try {
313             for (int i = 0; i < groupIds.length ; i++ ) {
314                 Resource groupResource = ResourceLocalServiceUtil.getResource(
315                     companyId, className, ResourceConstants.SCOPE_GROUP,
316                     String.valueOf(groupIds[i]));
317 
318                 groupResourceIds[i] = groupResource.getResourceId();
319             }
320         }
321         catch (NoSuchResourceException nsre) {
322         }
323 
324         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
325 
326         if (userId > 0) {
327             permissionQuery.addTerm(Field.USER_ID, userId);
328         }
329 
330         for (Role role : roles) {
331             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
332                 return query;
333             }
334 
335             long roleId = role.getRoleId();
336 
337             if (hasPermission(roleId, companyResourceId)) {
338                 return query;
339             }
340 
341             for (long groupResourceId : groupResourceIds) {
342                 if (hasPermission(roleId, groupResourceId)) {
343                     return query;
344                 }
345             }
346 
347             permissionQuery.addTerm(Field.ROLE_ID, role.getRoleId());
348         }
349 
350         for (Group group : groups) {
351             addRequiredMemberRole(group, permissionQuery);
352         }
353 
354         for (UserGroupRole userGroupRole : userGroupRoles) {
355             permissionQuery.addTerm(
356                 Field.GROUP_ROLE_ID,
357                 userGroupRole.getGroupId() + StringPool.DASH +
358                     userGroupRole.getRoleId());
359         }
360 
361         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
362 
363         fullQuery.add(query, BooleanClauseOccur.MUST);
364         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
365 
366         return fullQuery;
367     }
368 
369     protected Query doGetPermissionQuery_6(
370             long companyId, long[] groupIds, long userId, String className,
371             Query query)
372         throws Exception {
373 
374         PermissionCheckerBag bag = getUserBag(userId);
375 
376         if (bag == null) {
377             return query;
378         }
379 
380         List<Group> groups = new ArrayList<Group>();
381         List<Role> roles = bag.getRoles();
382         List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
383 
384         if ((groupIds == null) || (groupIds.length == 0)) {
385             groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
386             groups.addAll(bag.getGroups());
387 
388             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
389                 userId);
390         }
391         else {
392             for (long groupId : groupIds) {
393                 if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
394                     Group group = GroupLocalServiceUtil.getGroup(groupId);
395 
396                     groups.add(group);
397                 }
398 
399                 userGroupRoles.addAll(
400                     UserGroupRoleLocalServiceUtil.getUserGroupRoles(
401                         userId, groupId));
402                 userGroupRoles.addAll(
403                     UserGroupRoleLocalServiceUtil.
404                         getUserGroupRolesByUserUserGroupAndGroup(
405                         userId, groupId));
406             }
407         }
408 
409         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
410 
411         if (defaultUserId != userId) {
412             roles.add(
413                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
414         }
415 
416         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
417 
418         if (userId > 0) {
419             permissionQuery.addTerm(Field.USER_ID, userId);
420         }
421 
422         for (Role role : roles) {
423             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
424                 return query;
425             }
426 
427             long roleId = role.getRoleId();
428 
429             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
430                     companyId, className, ResourceConstants.SCOPE_COMPANY,
431                     String.valueOf(companyId), roleId, ActionKeys.VIEW)) {
432 
433                 return query;
434             }
435 
436             for (Group group : groups) {
437                 if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
438                         companyId, className, ResourceConstants.SCOPE_GROUP,
439                         String.valueOf(group.getGroupId()), roleId,
440                         ActionKeys.VIEW)) {
441 
442                     return query;
443                 }
444             }
445 
446             permissionQuery.addTerm(Field.ROLE_ID, roleId);
447         }
448 
449         for (Group group : groups) {
450             addRequiredMemberRole(group, permissionQuery);
451         }
452 
453         for (UserGroupRole userGroupRole : userGroupRoles) {
454             permissionQuery.addTerm(
455                 Field.GROUP_ROLE_ID,
456                 userGroupRole.getGroupId() + StringPool.DASH +
457                     userGroupRole.getRoleId());
458         }
459 
460         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
461 
462         fullQuery.add(query, BooleanClauseOccur.MUST);
463         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
464 
465         return fullQuery;
466     }
467 
468     protected void doUpdatePermissionFields_5(long resourceId)
469         throws Exception {
470 
471         Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
472 
473         Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
474 
475         if (indexer != null) {
476             indexer.reindex(
477                 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
478         }
479     }
480 
481     protected void doUpdatePermissionFields_6(
482             String resourceName, String resourceClassPK)
483         throws Exception {
484 
485         Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
486 
487         if (indexer != null) {
488             indexer.reindex(resourceName, GetterUtil.getLong(resourceClassPK));
489         }
490     }
491 
492     protected PermissionCheckerBag getUserBag(long userId) throws Exception {
493         User user = UserLocalServiceUtil.getUser(userId);
494 
495         PermissionChecker permissionChecker =
496             PermissionCheckerFactoryUtil.create(user, true);
497 
498         if (permissionChecker instanceof AdvancedPermissionChecker) {
499             AdvancedPermissionChecker advancedPermissionChecker =
500                 (AdvancedPermissionChecker)permissionChecker;
501 
502             return advancedPermissionChecker.getUserBag(userId, 0);
503         }
504         else {
505             return null;
506         }
507     }
508 
509     protected boolean hasPermission(long roleId, long resourceId)
510         throws SystemException {
511 
512         if (resourceId == 0) {
513             return false;
514         }
515 
516         List<Permission> permissions =
517             PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
518 
519         List<String> actions = ResourceActionsUtil.getActions(permissions);
520 
521         if (actions.contains(ActionKeys.VIEW)) {
522             return true;
523         }
524         else {
525             return false;
526         }
527     }
528 
529     private static Log _log = LogFactoryUtil.getLog(
530         SearchPermissionCheckerImpl.class);
531 
532 }