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 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 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 = GroupLocalServiceUtil.getGroup(groupId);
179 
180         List<Role> roles = ResourceActionsUtil.getRoles(group, className);
181 
182         List<Long> roleIds = new ArrayList<Long>();
183         List<String> groupRoleIds = new ArrayList<String>();
184 
185         for (Role role : roles) {
186             long roleId = role.getRoleId();
187 
188             if (hasPermission(roleId, resource.getResourceId())) {
189                 if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
190                     (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
191 
192                     groupRoleIds.add(groupId + StringPool.DASH + roleId);
193                 }
194                 else {
195                     roleIds.add(roleId);
196                 }
197             }
198         }
199 
200         doc.addKeyword(
201             Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
202         doc.addKeyword(
203             Field.GROUP_ROLE_ID,
204             groupRoleIds.toArray(new String[groupRoleIds.size()]));
205     }
206 
207     protected void doAddPermissionFields_6(
208             long companyId, long groupId, String className, String classPK,
209             Document doc)
210         throws Exception {
211 
212         Group group = GroupLocalServiceUtil.getGroup(groupId);
213 
214         List<Role> roles = ResourceActionsUtil.getRoles(group, className);
215 
216         List<Long> roleIds = new ArrayList<Long>();
217         List<String> groupRoleIds = new ArrayList<String>();
218 
219         for (Role role : roles) {
220             long roleId = role.getRoleId();
221 
222             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
223                     companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
224                     classPK, roleId, ActionKeys.VIEW)) {
225 
226                 if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
227                     (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
228 
229                     groupRoleIds.add(groupId + StringPool.DASH + roleId);
230                 }
231                 else {
232                     roleIds.add(roleId);
233                 }
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_5(
245             long companyId, long groupId, long userId, String className,
246             Query query)
247         throws Exception {
248 
249         PermissionCheckerBag bag = getUserBag(userId);
250 
251         List<Group> groups = new ArrayList<Group>();
252         List<Role> roles = bag.getRoles();
253         List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
254 
255         if (groupId == 0) {
256             groups.addAll(
257                 GroupLocalServiceUtil.getUserGroups(userId, true));
258             groups.addAll(bag.getGroups());
259 
260             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
261                 userId);
262         }
263         else {
264             if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
265                 Group group = GroupLocalServiceUtil.getGroup(groupId);
266 
267                 groups.add(group);
268             }
269 
270             userGroupRoles.addAll(
271                 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
272                     userId, groupId));
273             userGroupRoles.addAll(
274                 UserGroupRoleLocalServiceUtil.
275                     getUserGroupRolesByUserUserGroupAndGroup(userId, groupId));
276         }
277 
278         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
279 
280         if (defaultUserId != userId) {
281             roles.add(
282                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
283         }
284 
285         long companyResourceId = 0;
286 
287         try {
288             Resource companyResource = ResourceLocalServiceUtil.getResource(
289                 companyId, className, ResourceConstants.SCOPE_COMPANY,
290                 String.valueOf(companyId));
291 
292             companyResourceId = companyResource.getResourceId();
293         }
294         catch (NoSuchResourceException nsre) {
295         }
296 
297         long groupResourceId = 0;
298 
299         try {
300             Resource groupResource = ResourceLocalServiceUtil.getResource(
301                 companyId, className, ResourceConstants.SCOPE_GROUP,
302                 String.valueOf(groupId));
303 
304             groupResourceId = groupResource.getResourceId();
305         }
306         catch (NoSuchResourceException nsre) {
307         }
308 
309         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
310 
311         for (Role role : roles) {
312             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
313                 return query;
314             }
315 
316             long roleId = role.getRoleId();
317 
318             if (hasPermission(roleId, companyResourceId) ||
319                 hasPermission(roleId, groupResourceId)) {
320 
321                 return query;
322             }
323 
324             permissionQuery.addTerm(Field.ROLE_ID, role.getRoleId());
325         }
326 
327         for (Group group : groups) {
328             addRequiredMemberRole(group, permissionQuery);
329         }
330 
331         for (UserGroupRole userGroupRole : userGroupRoles) {
332             permissionQuery.addTerm(
333                 Field.GROUP_ROLE_ID,
334                 userGroupRole.getGroupId() + StringPool.DASH +
335                     userGroupRole.getRoleId());
336         }
337 
338         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
339 
340         fullQuery.add(query, BooleanClauseOccur.MUST);
341         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
342 
343         return fullQuery;
344     }
345 
346     protected PermissionCheckerBag getUserBag(long userId) throws Exception {
347         User user = UserLocalServiceUtil.getUser(userId);
348 
349         PermissionChecker permissionChecker =
350             PermissionCheckerFactoryUtil.create(user, true);
351 
352         if (permissionChecker instanceof AdvancedPermissionChecker) {
353             AdvancedPermissionChecker advancedPermissionChecker =
354                 (AdvancedPermissionChecker)permissionChecker;
355 
356             return advancedPermissionChecker.getUserBag(userId, 0);
357         }
358         else {
359             return null;
360         }
361     }
362 
363     protected Query doGetPermissionQuery_6(
364             long companyId, long groupId, long userId, String className,
365             Query query)
366         throws Exception {
367 
368         PermissionCheckerBag bag = getUserBag(userId);
369 
370         if (bag == null) {
371             return query;
372         }
373 
374         List<Group> groups = new ArrayList<Group>();
375         List<Role> roles = bag.getRoles();
376         List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
377 
378         if (groupId == 0) {
379             groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
380             groups.addAll(bag.getGroups());
381 
382             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
383                 userId);
384         }
385         else {
386             if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
387                 Group group = GroupLocalServiceUtil.getGroup(groupId);
388 
389                 groups.add(group);
390             }
391 
392             userGroupRoles.addAll(
393                 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
394                     userId, groupId));
395             userGroupRoles.addAll(
396                 UserGroupRoleLocalServiceUtil.
397                     getUserGroupRolesByUserUserGroupAndGroup(userId, groupId));
398         }
399 
400         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
401 
402         if (defaultUserId != userId) {
403             roles.add(
404                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
405         }
406 
407         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
408 
409         for (Role role : roles) {
410             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
411                 return query;
412             }
413 
414             long roleId = role.getRoleId();
415 
416             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
417                     companyId, className, ResourceConstants.SCOPE_COMPANY,
418                     String.valueOf(companyId), roleId, ActionKeys.VIEW) ||
419                 ResourcePermissionLocalServiceUtil.hasResourcePermission(
420                     companyId, className, ResourceConstants.SCOPE_GROUP,
421                     String.valueOf(groupId), roleId, ActionKeys.VIEW)) {
422 
423                 return query;
424             }
425 
426             permissionQuery.addTerm(Field.ROLE_ID, roleId);
427         }
428 
429         for (Group group : groups) {
430             addRequiredMemberRole(group, permissionQuery);
431         }
432 
433         for (UserGroupRole userGroupRole : userGroupRoles) {
434             permissionQuery.addTerm(
435                 Field.GROUP_ROLE_ID,
436                 userGroupRole.getGroupId() + StringPool.DASH +
437                     userGroupRole.getRoleId());
438         }
439 
440         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
441 
442         fullQuery.add(query, BooleanClauseOccur.MUST);
443         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
444 
445         return fullQuery;
446     }
447 
448     protected void doUpdatePermissionFields_5(long resourceId)
449         throws Exception {
450 
451         Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
452 
453         Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
454 
455         if (indexer != null) {
456             indexer.reindex(
457                 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
458         }
459     }
460 
461     protected void doUpdatePermissionFields_6(
462             String resourceName, String resourceClassPK)
463         throws Exception {
464 
465         Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
466 
467         if (indexer != null) {
468             indexer.reindex(resourceName, GetterUtil.getLong(resourceClassPK));
469         }
470     }
471 
472     protected boolean hasPermission(long roleId, long resourceId)
473         throws SystemException {
474 
475         if (resourceId == 0) {
476             return false;
477         }
478 
479         List<Permission> permissions =
480             PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
481 
482         List<String> actions = ResourceActionsUtil.getActions(permissions);
483 
484         if (actions.contains(ActionKeys.VIEW)) {
485             return true;
486         }
487         else {
488             return false;
489         }
490     }
491 
492     private static Log _log = LogFactoryUtil.getLog(
493         SearchPermissionCheckerImpl.class);
494 
495 }