1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.StringPool;
41  import com.liferay.portal.kernel.util.Validator;
42  import com.liferay.portal.model.Group;
43  import com.liferay.portal.model.Permission;
44  import com.liferay.portal.model.Resource;
45  import com.liferay.portal.model.ResourceConstants;
46  import com.liferay.portal.model.Role;
47  import com.liferay.portal.model.RoleConstants;
48  import com.liferay.portal.model.UserGroupRole;
49  import com.liferay.portal.security.permission.ActionKeys;
50  import com.liferay.portal.security.permission.ResourceActionsUtil;
51  import com.liferay.portal.service.GroupLocalServiceUtil;
52  import com.liferay.portal.service.PermissionLocalServiceUtil;
53  import com.liferay.portal.service.ResourceLocalServiceUtil;
54  import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
55  import com.liferay.portal.service.RoleLocalServiceUtil;
56  import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
57  import com.liferay.portal.service.UserLocalServiceUtil;
58  import com.liferay.portal.util.PropsValues;
59  
60  import java.util.ArrayList;
61  import java.util.List;
62  
63  /**
64   * <a href="SearchPermissionCheckerImpl.java.html"><b><i>View Source</i></b></a>
65   *
66   * @author Allen Chiang
67   * @author Bruno Farache
68   * @author Raymond Augé
69   */
70  public class SearchPermissionCheckerImpl implements SearchPermissionChecker {
71  
72      public void addPermissionFields(long companyId, Document doc) {
73          try {
74              long groupId = GetterUtil.getLong(doc.get(Field.GROUP_ID));
75              String className = doc.get(Field.ENTRY_CLASS_NAME);
76  
77              String classPK = doc.get(Field.ROOT_ENTRY_CLASS_PK);
78  
79              if (Validator.isNull(classPK)) {
80                  classPK = doc.get(Field.ENTRY_CLASS_PK);
81              }
82  
83              if (Validator.isNotNull(className) &&
84                  Validator.isNotNull(classPK)) {
85  
86                  if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
87                      doAddPermissionFields_5(
88                          companyId, groupId, className, classPK, doc);
89                  }
90                  else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
91                      doAddPermissionFields_6(
92                          companyId, groupId, className, classPK, doc);
93                  }
94              }
95          }
96          catch (NoSuchResourceException nsre) {
97          }
98          catch (Exception e) {
99              _log.error(e, e);
100         }
101     }
102 
103     public Query getPermissionQuery(
104         long companyId, long groupId, long userId, String className,
105         Query query) {
106 
107         try {
108             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
109                 return doGetPermissionQuery_5(
110                     companyId, groupId, userId, className, query);
111             }
112             else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
113                 return doGetPermissionQuery_6(
114                     companyId, groupId, userId, className, query);
115             }
116         }
117         catch (Exception e) {
118             _log.error(e, e);
119         }
120 
121         return query;
122     }
123 
124     public void updatePermissionFields(long resourceId) {
125         try {
126             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
127                 doUpdatePermissionFields_5(resourceId);
128             }
129         }
130         catch (Exception e) {
131             _log.error(e, e);
132         }
133     }
134 
135     public void updatePermissionFields(
136         String resourceName, String resourceClassPK) {
137 
138         try {
139             if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
140                 doUpdatePermissionFields_6(resourceName, resourceClassPK);
141             }
142         }
143         catch (Exception e) {
144             _log.error(e, e);
145         }
146     }
147 
148     protected void doAddPermissionFields_5(
149             long companyId, long groupId, String className, String classPK,
150             Document doc)
151         throws Exception {
152 
153         Resource resource = ResourceLocalServiceUtil.getResource(
154             companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
155             classPK);
156 
157         Group group = GroupLocalServiceUtil.getGroup(groupId);
158 
159         List<Role> roles = ResourceActionsUtil.getRoles(group, className);
160 
161         List<Long> roleIds = new ArrayList<Long>();
162         List<String> groupRoleIds = new ArrayList<String>();
163 
164         for (Role role : roles) {
165             long roleId = role.getRoleId();
166 
167             if (hasPermission(roleId, resource.getResourceId())) {
168                 if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
169                     (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
170 
171                     groupRoleIds.add(groupId + StringPool.DASH + roleId);
172                 }
173                 else {
174                     roleIds.add(roleId);
175                 }
176             }
177         }
178 
179         doc.addKeyword(
180             Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
181         doc.addKeyword(
182             Field.GROUP_ROLE_ID,
183             groupRoleIds.toArray(new String[groupRoleIds.size()]));
184     }
185 
186     protected void doAddPermissionFields_6(
187             long companyId, long groupId, String className, String classPK,
188             Document doc)
189         throws Exception {
190 
191         Group group = GroupLocalServiceUtil.getGroup(groupId);
192 
193         List<Role> roles = ResourceActionsUtil.getRoles(group, className);
194 
195         List<Long> roleIds = new ArrayList<Long>();
196         List<String> groupRoleIds = new ArrayList<String>();
197 
198         for (Role role : roles) {
199             long roleId = role.getRoleId();
200 
201             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
202                     companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
203                     classPK, roleId, ActionKeys.VIEW)) {
204 
205                 if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
206                     (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
207 
208                     groupRoleIds.add(groupId + StringPool.DASH + roleId);
209                 }
210                 else {
211                     roleIds.add(roleId);
212                 }
213             }
214         }
215 
216         doc.addKeyword(
217             Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
218         doc.addKeyword(
219             Field.GROUP_ROLE_ID,
220             groupRoleIds.toArray(new String[groupRoleIds.size()]));
221     }
222 
223     protected Query doGetPermissionQuery_5(
224             long companyId, long groupId, long userId, String className,
225             Query query)
226         throws Exception {
227 
228         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
229 
230         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
231 
232         List<Role> roles = RoleLocalServiceUtil.getUserRoles(userId);
233 
234         roles = ListUtil.copy(roles);
235 
236         List<UserGroupRole> userGroupRoles = null;
237 
238         if (groupId == 0) {
239             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
240                 userId);
241         }
242         else {
243             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
244                 userId, groupId);
245 
246             userGroupRoles = ListUtil.copy(userGroupRoles);
247 
248             userGroupRoles.addAll(
249                 UserGroupRoleLocalServiceUtil.
250                     getUserGroupRolesByUserUserGroupAndGroup(userId, groupId));
251         }
252 
253         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
254 
255         if (defaultUserId != userId) {
256             roles.add(
257                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
258         }
259 
260         long companyResourceId = 0;
261 
262         try {
263             Resource companyResource = ResourceLocalServiceUtil.getResource(
264                 companyId, className, ResourceConstants.SCOPE_COMPANY,
265                 String.valueOf(companyId));
266 
267             companyResourceId = companyResource.getResourceId();
268         }
269         catch (NoSuchResourceException nsre) {
270         }
271 
272         long groupResourceId = 0;
273 
274         try {
275             Resource groupResource = ResourceLocalServiceUtil.getResource(
276                 companyId, className, ResourceConstants.SCOPE_GROUP,
277                 String.valueOf(groupId));
278 
279             groupResourceId = groupResource.getResourceId();
280         }
281         catch (NoSuchResourceException nsre) {
282         }
283 
284         for (Role role : roles) {
285             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
286                 return query;
287             }
288 
289             long roleId = role.getRoleId();
290 
291             if (hasPermission(roleId, companyResourceId) ||
292                 hasPermission(roleId, groupResourceId)) {
293 
294                 return query;
295             }
296 
297             permissionQuery.addTerm(Field.ROLE_ID, role.getRoleId());
298         }
299 
300         for (UserGroupRole userGroupRole : userGroupRoles) {
301             permissionQuery.addTerm(
302                 Field.GROUP_ROLE_ID,
303                 userGroupRole.getGroupId() + StringPool.DASH +
304                     userGroupRole.getRoleId());
305         }
306 
307         fullQuery.add(query, BooleanClauseOccur.MUST);
308         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
309 
310         return fullQuery;
311     }
312 
313     protected Query doGetPermissionQuery_6(
314             long companyId, long groupId, long userId, String className,
315             Query query)
316         throws Exception {
317 
318         BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
319 
320         BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
321 
322         List<Role> roles = RoleLocalServiceUtil.getUserRoles(userId);
323 
324         roles = ListUtil.copy(roles);
325 
326         List<UserGroupRole> userGroupRoles = null;
327 
328         if (groupId == 0) {
329             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
330                 userId);
331         }
332         else {
333             userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
334                 userId, groupId);
335 
336             userGroupRoles = ListUtil.copy(userGroupRoles);
337 
338             userGroupRoles.addAll(
339                 UserGroupRoleLocalServiceUtil.
340                     getUserGroupRolesByUserUserGroupAndGroup(userId, groupId));
341         }
342 
343         long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
344 
345         if (defaultUserId != userId) {
346             roles.add(
347                 RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
348         }
349 
350         for (Role role : roles) {
351             if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
352                 return query;
353             }
354 
355             long roleId = role.getRoleId();
356 
357             if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
358                     companyId, className, ResourceConstants.SCOPE_COMPANY,
359                     String.valueOf(companyId), roleId, ActionKeys.VIEW) ||
360                 ResourcePermissionLocalServiceUtil.hasResourcePermission(
361                     companyId, className, ResourceConstants.SCOPE_GROUP,
362                     String.valueOf(groupId), roleId, ActionKeys.VIEW)) {
363 
364                 return query;
365             }
366 
367             permissionQuery.addTerm(Field.ROLE_ID, roleId);
368         }
369 
370         for (UserGroupRole userGroupRole : userGroupRoles) {
371             permissionQuery.addTerm(
372                 Field.GROUP_ROLE_ID,
373                 userGroupRole.getGroupId() + StringPool.DASH +
374                     userGroupRole.getRoleId());
375         }
376 
377         fullQuery.add(query, BooleanClauseOccur.MUST);
378         fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
379 
380         return fullQuery;
381     }
382 
383     protected void doUpdatePermissionFields_5(long resourceId)
384         throws Exception {
385 
386         Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
387 
388         Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
389 
390         if (indexer != null) {
391             indexer.reIndex(
392                 resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
393         }
394     }
395 
396     protected void doUpdatePermissionFields_6(
397             String resourceName, String resourceClassPK)
398         throws Exception {
399 
400         Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
401 
402         if (indexer != null) {
403             indexer.reIndex(resourceName, GetterUtil.getLong(resourceClassPK));
404         }
405     }
406 
407     protected boolean hasPermission(long roleId, long resourceId)
408         throws SystemException {
409 
410         if (resourceId == 0) {
411             return false;
412         }
413 
414         List<Permission> permissions =
415             PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
416 
417         List<String> actions = ResourceActionsUtil.getActions(permissions);
418 
419         if (actions.contains(ActionKeys.VIEW)) {
420             return true;
421         }
422         else {
423             return false;
424         }
425     }
426 
427     private static Log _log =
428         LogFactoryUtil.getLog(SearchPermissionCheckerImpl.class);
429 
430 }