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         if (userId > 0) {
312             permissionQuery.addTerm(Field.USER_ID, userId);
313         }
314 
315         for (Role role : roles) {
316             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
317                 return query;
318             }
319 
320             long roleId = role.getRoleId();
321 
322             if (hasPermission(roleId, companyResourceId) ||
323                 hasPermission(roleId, groupResourceId)) {
324 
325                 return query;
326             }
327 
328             permissionQuery.addTerm(Field.ROLE_ID, role.getRoleId());
329         }
330 
331         for (Group group : groups) {
332             addRequiredMemberRole(group, permissionQuery);
333         }
334 
335         for (UserGroupRole userGroupRole : userGroupRoles) {
336             permissionQuery.addTerm(
337                 Field.GROUP_ROLE_ID,
338                 userGroupRole.getGroupId() + StringPool.DASH +
339                     userGroupRole.getRoleId());
340         }
341 
342         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
343 
344         fullQuery.add(query, BooleanClauseOccur.MUST);
345         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
346 
347         return fullQuery;
348     }
349 
350     protected Query doGetPermissionQuery_6(
351             long companyId, long groupId, long userId, String className,
352             Query query)
353         throws Exception {
354 
355         PermissionCheckerBag bag = getUserBag(userId);
356 
357         if (bag == null) {
358             return query;
359         }
360 
361         List<Group> groups = new ArrayList<Group>();
362         List<Role> roles = bag.getRoles();
363         List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
364 
365         if (groupId == 0) {
366             groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
367             groups.addAll(bag.getGroups());
368 
369             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
370                 userId);
371         }
372         else {
373             if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
374                 Group group = GroupLocalServiceUtil.getGroup(groupId);
375 
376                 groups.add(group);
377             }
378 
379             userGroupRoles.addAll(
380                 UserGroupRoleLocalServiceUtil.getUserGroupRoles(
381                     userId, groupId));
382             userGroupRoles.addAll(
383                 UserGroupRoleLocalServiceUtil.
384                     getUserGroupRolesByUserUserGroupAndGroup(userId, groupId));
385         }
386 
387         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
388 
389         if (defaultUserId != userId) {
390             roles.add(
391                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
392         }
393 
394         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
395 
396         if (userId > 0) {
397             permissionQuery.addTerm(Field.USER_ID, userId);
398         }
399 
400         for (Role role : roles) {
401             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
402                 return query;
403             }
404 
405             long roleId = role.getRoleId();
406 
407             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
408                     companyId, className, ResourceConstants.SCOPE_COMPANY,
409                     String.valueOf(companyId), roleId, ActionKeys.VIEW) ||
410                 ResourcePermissionLocalServiceUtil.hasResourcePermission(
411                     companyId, className, ResourceConstants.SCOPE_GROUP,
412                     String.valueOf(groupId), roleId, ActionKeys.VIEW)) {
413 
414                 return query;
415             }
416 
417             permissionQuery.addTerm(Field.ROLE_ID, roleId);
418         }
419 
420         for (Group group : groups) {
421             addRequiredMemberRole(group, permissionQuery);
422         }
423 
424         for (UserGroupRole userGroupRole : userGroupRoles) {
425             permissionQuery.addTerm(
426                 Field.GROUP_ROLE_ID,
427                 userGroupRole.getGroupId() + StringPool.DASH +
428                     userGroupRole.getRoleId());
429         }
430 
431         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
432 
433         fullQuery.add(query, BooleanClauseOccur.MUST);
434         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
435 
436         return fullQuery;
437     }
438 
439     protected void doUpdatePermissionFields_5(long resourceId)
440         throws Exception {
441 
442         Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
443 
444         Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
445 
446         if (indexer != null) {
447             indexer.reindex(
448                 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
449         }
450     }
451 
452     protected void doUpdatePermissionFields_6(
453             String resourceName, String resourceClassPK)
454         throws Exception {
455 
456         Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
457 
458         if (indexer != null) {
459             indexer.reindex(resourceName, GetterUtil.getLong(resourceClassPK));
460         }
461     }
462 
463     protected PermissionCheckerBag getUserBag(long userId) throws Exception {
464         User user = UserLocalServiceUtil.getUser(userId);
465 
466         PermissionChecker permissionChecker =
467             PermissionCheckerFactoryUtil.create(user, true);
468 
469         if (permissionChecker instanceof AdvancedPermissionChecker) {
470             AdvancedPermissionChecker advancedPermissionChecker =
471                 (AdvancedPermissionChecker)permissionChecker;
472 
473             return advancedPermissionChecker.getUserBag(userId, 0);
474         }
475         else {
476             return null;
477         }
478     }
479 
480     protected boolean hasPermission(long roleId, long resourceId)
481         throws SystemException {
482 
483         if (resourceId == 0) {
484             return false;
485         }
486 
487         List<Permission> permissions =
488             PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
489 
490         List<String> actions = ResourceActionsUtil.getActions(permissions);
491 
492         if (actions.contains(ActionKeys.VIEW)) {
493             return true;
494         }
495         else {
496             return false;
497         }
498     }
499 
500     private static Log _log = LogFactoryUtil.getLog(
501         SearchPermissionCheckerImpl.class);
502 
503 }