1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.search;
16  
17  import com.liferay.portal.NoSuchResourceException;
18  import com.liferay.portal.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 groupId, long userId, String className,
102         Query query) {
103 
104         try {
105             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
106                 return doGetPermissionQuery_5(
107                     companyId, groupId, userId, className, query);
108             }
109             else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
110                 return doGetPermissionQuery_6(
111                     companyId, groupId, userId, className, query);
112             }
113         }
114         catch (Exception e) {
115             _log.error(e, e);
116         }
117 
118         return null;
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 groupId, 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 (groupId == 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             if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
275                 Group group = GroupLocalServiceUtil.getGroup(groupId);
276 
277                 groups.add(group);
278             }
279 
280             userGroupRoles.addAll(
281                 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
282                     userId, groupId));
283             userGroupRoles.addAll(
284                 UserGroupRoleLocalServiceUtil.
285                     getUserGroupRolesByUserUserGroupAndGroup(userId, groupId));
286         }
287 
288         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
289 
290         if (defaultUserId != userId) {
291             roles.add(
292                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
293         }
294 
295         long companyResourceId = 0;
296 
297         try {
298             Resource companyResource = ResourceLocalServiceUtil.getResource(
299                 companyId, className, ResourceConstants.SCOPE_COMPANY,
300                 String.valueOf(companyId));
301 
302             companyResourceId = companyResource.getResourceId();
303         }
304         catch (NoSuchResourceException nsre) {
305         }
306 
307         long groupResourceId = 0;
308 
309         try {
310             Resource groupResource = ResourceLocalServiceUtil.getResource(
311                 companyId, className, ResourceConstants.SCOPE_GROUP,
312                 String.valueOf(groupId));
313 
314             groupResourceId = groupResource.getResourceId();
315         }
316         catch (NoSuchResourceException nsre) {
317         }
318 
319         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
320 
321         if (userId > 0) {
322             permissionQuery.addTerm(Field.USER_ID, userId);
323         }
324 
325         for (Role role : roles) {
326             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
327                 return query;
328             }
329 
330             long roleId = role.getRoleId();
331 
332             if (hasPermission(roleId, companyResourceId) ||
333                 hasPermission(roleId, groupResourceId)) {
334 
335                 return query;
336             }
337 
338             permissionQuery.addTerm(Field.ROLE_ID, role.getRoleId());
339         }
340 
341         for (Group group : groups) {
342             addRequiredMemberRole(group, permissionQuery);
343         }
344 
345         for (UserGroupRole userGroupRole : userGroupRoles) {
346             permissionQuery.addTerm(
347                 Field.GROUP_ROLE_ID,
348                 userGroupRole.getGroupId() + StringPool.DASH +
349                     userGroupRole.getRoleId());
350         }
351 
352         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
353 
354         fullQuery.add(query, BooleanClauseOccur.MUST);
355         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
356 
357         return fullQuery;
358     }
359 
360     protected Query doGetPermissionQuery_6(
361             long companyId, long groupId, long userId, String className,
362             Query query)
363         throws Exception {
364 
365         PermissionCheckerBag bag = getUserBag(userId);
366 
367         if (bag == null) {
368             return query;
369         }
370 
371         List<Group> groups = new ArrayList<Group>();
372         List<Role> roles = bag.getRoles();
373         List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
374 
375         if (groupId == 0) {
376             groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
377             groups.addAll(bag.getGroups());
378 
379             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
380                 userId);
381         }
382         else {
383             if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
384                 Group group = GroupLocalServiceUtil.getGroup(groupId);
385 
386                 groups.add(group);
387             }
388 
389             userGroupRoles.addAll(
390                 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
391                     userId, groupId));
392             userGroupRoles.addAll(
393                 UserGroupRoleLocalServiceUtil.
394                     getUserGroupRolesByUserUserGroupAndGroup(userId, groupId));
395         }
396 
397         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
398 
399         if (defaultUserId != userId) {
400             roles.add(
401                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
402         }
403 
404         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
405 
406         if (userId > 0) {
407             permissionQuery.addTerm(Field.USER_ID, userId);
408         }
409 
410         for (Role role : roles) {
411             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
412                 return query;
413             }
414 
415             long roleId = role.getRoleId();
416 
417             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
418                     companyId, className, ResourceConstants.SCOPE_COMPANY,
419                     String.valueOf(companyId), roleId, ActionKeys.VIEW) ||
420                 ResourcePermissionLocalServiceUtil.hasResourcePermission(
421                     companyId, className, ResourceConstants.SCOPE_GROUP,
422                     String.valueOf(groupId), roleId, ActionKeys.VIEW)) {
423 
424                 return query;
425             }
426 
427             permissionQuery.addTerm(Field.ROLE_ID, roleId);
428         }
429 
430         for (Group group : groups) {
431             addRequiredMemberRole(group, permissionQuery);
432         }
433 
434         for (UserGroupRole userGroupRole : userGroupRoles) {
435             permissionQuery.addTerm(
436                 Field.GROUP_ROLE_ID,
437                 userGroupRole.getGroupId() + StringPool.DASH +
438                     userGroupRole.getRoleId());
439         }
440 
441         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
442 
443         fullQuery.add(query, BooleanClauseOccur.MUST);
444         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
445 
446         return fullQuery;
447     }
448 
449     protected void doUpdatePermissionFields_5(long resourceId)
450         throws Exception {
451 
452         Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
453 
454         Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
455 
456         if (indexer != null) {
457             indexer.reIndex(
458                 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
459         }
460     }
461 
462     protected void doUpdatePermissionFields_6(
463             String resourceName, String resourceClassPK)
464         throws Exception {
465 
466         Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
467 
468         if (indexer != null) {
469             indexer.reIndex(resourceName, GetterUtil.getLong(resourceClassPK));
470         }
471     }
472 
473     protected PermissionCheckerBag getUserBag(long userId) throws Exception {
474         User user = UserLocalServiceUtil.getUser(userId);
475 
476         PermissionChecker permissionChecker =
477             PermissionCheckerFactoryUtil.create(user, true);
478 
479         if (permissionChecker instanceof AdvancedPermissionChecker) {
480             AdvancedPermissionChecker advancedPermissionChecker =
481                 (AdvancedPermissionChecker)permissionChecker;
482 
483             return advancedPermissionChecker.getUserBag(userId, 0);
484         }
485         else {
486             return null;
487         }
488     }
489 
490     protected boolean hasPermission(long roleId, long resourceId)
491         throws SystemException {
492 
493         if (resourceId == 0) {
494             return false;
495         }
496 
497         List<Permission> permissions =
498             PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
499 
500         List<String> actions = ResourceActionsUtil.getActions(permissions);
501 
502         if (actions.contains(ActionKeys.VIEW)) {
503             return true;
504         }
505         else {
506             return false;
507         }
508     }
509 
510     private static Log _log = LogFactoryUtil.getLog(
511         SearchPermissionCheckerImpl.class);
512 
513 }