1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.search;
24  
25  import com.liferay.portal.NoSuchResourceException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.search.BooleanClauseOccur;
30  import com.liferay.portal.kernel.search.BooleanQuery;
31  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
32  import com.liferay.portal.kernel.search.Document;
33  import com.liferay.portal.kernel.search.Field;
34  import com.liferay.portal.kernel.search.Indexer;
35  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
36  import com.liferay.portal.kernel.search.Query;
37  import com.liferay.portal.kernel.search.SearchPermissionChecker;
38  import com.liferay.portal.kernel.util.GetterUtil;
39  import com.liferay.portal.kernel.util.ListUtil;
40  import com.liferay.portal.kernel.util.Validator;
41  import com.liferay.portal.model.Group;
42  import com.liferay.portal.model.Permission;
43  import com.liferay.portal.model.Resource;
44  import com.liferay.portal.model.ResourceConstants;
45  import com.liferay.portal.model.Role;
46  import com.liferay.portal.model.RoleConstants;
47  import com.liferay.portal.security.permission.ActionKeys;
48  import com.liferay.portal.security.permission.ResourceActionsUtil;
49  import com.liferay.portal.service.GroupLocalServiceUtil;
50  import com.liferay.portal.service.PermissionLocalServiceUtil;
51  import com.liferay.portal.service.ResourceLocalServiceUtil;
52  import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
53  import com.liferay.portal.service.RoleLocalServiceUtil;
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   *
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              String classPK = doc.get(Field.ENTRY_CLASS_PK);
74  
75              if (Validator.isNotNull(className) &&
76                  Validator.isNotNull(classPK)) {
77  
78                  if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
79                      doAddPermissionFields_5(
80                          companyId, groupId, className, classPK, doc);
81                  }
82                  else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
83                      doAddPermissionFields_6(
84                          companyId, groupId, className, classPK, doc);
85                  }
86              }
87          }
88          catch (NoSuchResourceException nsre) {
89          }
90          catch (Exception e) {
91              _log.error(e, e);
92          }
93      }
94  
95      public Query getPermissionQuery(
96          long companyId, long groupId, long userId, String className,
97          Query query) {
98  
99          try {
100             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
101                 return doGetPermissionQuery_5(
102                     companyId, groupId, userId, className, query);
103             }
104             else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
105                 return doGetPermissionQuery_6(
106                     companyId, groupId, userId, className, query);
107             }
108         }
109         catch (Exception e) {
110             _log.error(e, e);
111         }
112 
113         return query;
114     }
115 
116     public void updatePermissionFields(long resourceId) {
117         try {
118             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
119                 doUpdatePermissionFields_5(resourceId);
120             }
121         }
122         catch (Exception e) {
123             _log.error(e, e);
124         }
125     }
126 
127     public void updatePermissionFields(
128         String resourceName, String resourceClassPK) {
129 
130         try {
131             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
132                 doUpdatePermissionFields_6(resourceName, resourceClassPK);
133             }
134         }
135         catch (Exception e) {
136             _log.error(e, e);
137         }
138     }
139 
140     protected void doAddPermissionFields_5(
141             long companyId, long groupId, String className, String classPK,
142             Document doc)
143         throws Exception {
144 
145         Resource resource = ResourceLocalServiceUtil.getResource(
146             companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
147             classPK);
148 
149         Group group = GroupLocalServiceUtil.getGroup(groupId);
150 
151         List<Role> roles = ResourceActionsUtil.getRoles(group, className);
152 
153         List<Long> roleIds = new ArrayList<Long>();
154 
155         for (Role role : roles) {
156             long roleId = role.getRoleId();
157 
158             if (hasPermission(roleId, resource.getResourceId())) {
159                 roleIds.add(roleId);
160             }
161         }
162 
163         doc.addKeyword(
164             Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
165     }
166 
167     protected void doAddPermissionFields_6(
168             long companyId, long groupId, String className, String classPK,
169             Document doc)
170         throws Exception {
171 
172         Group group = GroupLocalServiceUtil.getGroup(groupId);
173 
174         List<Role> roles = ResourceActionsUtil.getRoles(group, className);
175 
176         List<Long> roleIds = new ArrayList<Long>();
177 
178         for (Role role : roles) {
179             long roleId = role.getRoleId();
180 
181             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
182                     companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
183                     classPK, roleId, ActionKeys.VIEW)) {
184 
185                 roleIds.add(roleId);
186             }
187         }
188 
189         doc.addKeyword(
190             Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
191     }
192 
193     protected Query doGetPermissionQuery_5(
194             long companyId, long groupId, long userId, String className,
195             Query query)
196         throws Exception {
197 
198         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
199 
200         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
201 
202         List<Role> roles = RoleLocalServiceUtil.getUserRoles(userId);
203 
204         roles = ListUtil.copy(roles);
205 
206         roles.addAll(RoleLocalServiceUtil.getUserGroupRoles(userId, groupId));
207 
208         long companyResourceId = 0;
209 
210         try {
211             Resource companyResource = ResourceLocalServiceUtil.getResource(
212                 companyId, className, ResourceConstants.SCOPE_COMPANY,
213                 String.valueOf(companyId));
214 
215             companyResourceId = companyResource.getResourceId();
216         }
217         catch (NoSuchResourceException nsre) {
218         }
219 
220         long groupResourceId = 0;
221 
222         try {
223             Resource groupResource = ResourceLocalServiceUtil.getResource(
224                 companyId, className, ResourceConstants.SCOPE_GROUP,
225                 String.valueOf(groupId));
226 
227             groupResourceId = groupResource.getResourceId();
228         }
229         catch (NoSuchResourceException nsre) {
230         }
231 
232         for (Role role : roles) {
233             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
234                 return query;
235             }
236 
237             long roleId = role.getRoleId();
238 
239             if (hasPermission(roleId, companyResourceId) ||
240                 hasPermission(roleId, groupResourceId)) {
241 
242                 return query;
243             }
244 
245             permissionQuery.addTerm(Field.ROLE_ID, role.getRoleId());
246         }
247 
248         fullQuery.add(query, BooleanClauseOccur.MUST);
249         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
250 
251         return fullQuery;
252     }
253 
254     protected Query doGetPermissionQuery_6(
255             long companyId, long groupId, long userId, String className,
256             Query query)
257         throws Exception {
258 
259         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
260 
261         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
262 
263         List<Role> roles = RoleLocalServiceUtil.getUserRoles(userId);
264 
265         roles = ListUtil.copy(roles);
266 
267         roles.addAll(RoleLocalServiceUtil.getUserGroupRoles(userId, groupId));
268 
269         for (Role role : roles) {
270             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
271                 return query;
272             }
273 
274             long roleId = role.getRoleId();
275 
276             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
277                     companyId, className, ResourceConstants.SCOPE_COMPANY,
278                     String.valueOf(companyId), roleId, ActionKeys.VIEW) ||
279                 ResourcePermissionLocalServiceUtil.hasResourcePermission(
280                     companyId, className, ResourceConstants.SCOPE_GROUP,
281                     String.valueOf(groupId), roleId, ActionKeys.VIEW)) {
282 
283                 return query;
284             }
285 
286             permissionQuery.addTerm(Field.ROLE_ID, roleId);
287         }
288 
289         fullQuery.add(query, BooleanClauseOccur.MUST);
290         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
291 
292         return fullQuery;
293     }
294 
295     protected void doUpdatePermissionFields_5(long resourceId)
296         throws Exception {
297 
298         Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
299 
300         Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
301 
302         if (indexer != null) {
303             indexer.reIndex(
304                 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
305         }
306     }
307 
308     protected void doUpdatePermissionFields_6(
309             String resourceName, String resourceClassPK)
310         throws Exception {
311 
312         Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
313 
314         if (indexer != null) {
315             indexer.reIndex(resourceName, GetterUtil.getLong(resourceClassPK));
316         }
317     }
318 
319     protected boolean hasPermission(long roleId, long resourceId)
320         throws SystemException {
321 
322         if (resourceId == 0) {
323             return false;
324         }
325 
326         List<Permission> permissions =
327             PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
328 
329         List<String> actions = ResourceActionsUtil.getActions(permissions);
330 
331         if (actions.contains(ActionKeys.VIEW)) {
332             return true;
333         }
334         else {
335             return false;
336         }
337     }
338 
339     private static Log _log =
340         LogFactoryUtil.getLog(SearchPermissionCheckerImpl.class);
341 
342 }