001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.search;
016    
017    import com.liferay.portal.NoSuchResourceException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.search.BooleanClauseOccur;
022    import com.liferay.portal.kernel.search.BooleanQuery;
023    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
024    import com.liferay.portal.kernel.search.Document;
025    import com.liferay.portal.kernel.search.Field;
026    import com.liferay.portal.kernel.search.Indexer;
027    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028    import com.liferay.portal.kernel.search.Query;
029    import com.liferay.portal.kernel.search.SearchPermissionChecker;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.model.Group;
034    import com.liferay.portal.model.Permission;
035    import com.liferay.portal.model.Resource;
036    import com.liferay.portal.model.ResourceConstants;
037    import com.liferay.portal.model.Role;
038    import com.liferay.portal.model.RoleConstants;
039    import com.liferay.portal.model.User;
040    import com.liferay.portal.model.UserGroupRole;
041    import com.liferay.portal.security.permission.ActionKeys;
042    import com.liferay.portal.security.permission.AdvancedPermissionChecker;
043    import com.liferay.portal.security.permission.PermissionChecker;
044    import com.liferay.portal.security.permission.PermissionCheckerBag;
045    import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
046    import com.liferay.portal.security.permission.ResourceActionsUtil;
047    import com.liferay.portal.service.GroupLocalServiceUtil;
048    import com.liferay.portal.service.PermissionLocalServiceUtil;
049    import com.liferay.portal.service.ResourceLocalServiceUtil;
050    import com.liferay.portal.service.ResourcePermissionLocalServiceUtil;
051    import com.liferay.portal.service.RoleLocalServiceUtil;
052    import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
053    import com.liferay.portal.service.UserLocalServiceUtil;
054    import com.liferay.portal.util.PropsValues;
055    
056    import java.util.ArrayList;
057    import java.util.List;
058    
059    /**
060     * @author Allen Chiang
061     * @author Bruno Farache
062     * @author Raymond Augé
063     * @author Amos Fong
064     */
065    public class SearchPermissionCheckerImpl implements SearchPermissionChecker {
066    
067            public void addPermissionFields(long companyId, Document doc) {
068                    try {
069                            long groupId = GetterUtil.getLong(doc.get(Field.GROUP_ID));
070                            String className = doc.get(Field.ENTRY_CLASS_NAME);
071    
072                            String classPK = doc.get(Field.ROOT_ENTRY_CLASS_PK);
073    
074                            if (Validator.isNull(classPK)) {
075                                    classPK = doc.get(Field.ENTRY_CLASS_PK);
076                            }
077    
078                            if (Validator.isNotNull(className) &&
079                                    Validator.isNotNull(classPK)) {
080    
081                                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
082                                            doAddPermissionFields_5(
083                                                    companyId, groupId, className, classPK, doc);
084                                    }
085                                    else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
086                                            doAddPermissionFields_6(
087                                                    companyId, groupId, className, classPK, doc);
088                                    }
089                            }
090                    }
091                    catch (NoSuchResourceException nsre) {
092                    }
093                    catch (Exception e) {
094                            _log.error(e, e);
095                    }
096            }
097    
098            public Query getPermissionQuery(
099                    long companyId, long[] groupIds, long userId, String className,
100                    Query query) {
101    
102                    try {
103                            if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
104                                    return doGetPermissionQuery_5(
105                                            companyId, groupIds, userId, className, query);
106                            }
107                            else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
108                                    return doGetPermissionQuery_6(
109                                            companyId, groupIds, userId, className, query);
110                            }
111                    }
112                    catch (Exception e) {
113                            _log.error(e, e);
114                    }
115    
116                    return query;
117            }
118    
119            public void updatePermissionFields(long resourceId) {
120                    try {
121                            if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
122                                    doUpdatePermissionFields_5(resourceId);
123                            }
124                    }
125                    catch (Exception e) {
126                            _log.error(e, e);
127                    }
128            }
129    
130            public void updatePermissionFields(
131                    String resourceName, String resourceClassPK) {
132    
133                    try {
134                            if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
135                                    doUpdatePermissionFields_6(resourceName, resourceClassPK);
136                            }
137                    }
138                    catch (Exception e) {
139                            _log.error(e, e);
140                    }
141            }
142    
143            protected void addRequiredMemberRole(
144                            Group group, BooleanQuery permissionQuery)
145                    throws Exception {
146    
147                    if (group.isCommunity()) {
148                            Role communityMemberRole = RoleLocalServiceUtil.getRole(
149                                    group.getCompanyId(), RoleConstants.COMMUNITY_MEMBER);
150    
151                            permissionQuery.addTerm(
152                                    Field.GROUP_ROLE_ID,
153                                    group.getGroupId() + StringPool.DASH +
154                                            communityMemberRole.getRoleId());
155                    }
156                    else if (group.isOrganization()) {
157                            Role organizationMemberRole = RoleLocalServiceUtil.getRole(
158                                    group.getCompanyId(), RoleConstants.ORGANIZATION_MEMBER);
159    
160                            permissionQuery.addTerm(
161                                    Field.GROUP_ROLE_ID,
162                                    group.getGroupId() + StringPool.DASH +
163                                            organizationMemberRole.getRoleId());
164                    }
165            }
166    
167            protected void doAddPermissionFields_5(
168                            long companyId, long groupId, String className, String classPK,
169                            Document doc)
170                    throws Exception {
171    
172                    Resource resource = ResourceLocalServiceUtil.getResource(
173                            companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
174                            classPK);
175    
176                    Group group = null;
177    
178                    if (groupId > 0) {
179                            group = GroupLocalServiceUtil.getGroup(groupId);
180                    }
181    
182                    List<Role> roles = ResourceActionsUtil.getRoles(
183                            companyId, group, className);
184    
185                    List<Long> roleIds = new ArrayList<Long>();
186                    List<String> groupRoleIds = new ArrayList<String>();
187    
188                    for (Role role : roles) {
189                            long roleId = role.getRoleId();
190    
191                            if (hasPermission(roleId, resource.getResourceId())) {
192                                    if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
193                                            (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
194    
195                                            groupRoleIds.add(groupId + StringPool.DASH + roleId);
196                                    }
197                                    else {
198                                            roleIds.add(roleId);
199                                    }
200                            }
201                    }
202    
203                    doc.addKeyword(
204                            Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
205                    doc.addKeyword(
206                            Field.GROUP_ROLE_ID,
207                            groupRoleIds.toArray(new String[groupRoleIds.size()]));
208            }
209    
210            protected void doAddPermissionFields_6(
211                            long companyId, long groupId, String className, String classPK,
212                            Document doc)
213                    throws Exception {
214    
215                    Group group = null;
216    
217                    if (groupId > 0) {
218                            group = GroupLocalServiceUtil.getGroup(groupId);
219                    }
220    
221                    List<Role> roles = ResourceActionsUtil.getRoles(
222                            companyId, group, className);
223    
224                    List<Long> roleIds = new ArrayList<Long>();
225                    List<String> groupRoleIds = new ArrayList<String>();
226    
227                    for (Role role : roles) {
228                            long roleId = role.getRoleId();
229    
230                            if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
231                                            companyId, className, ResourceConstants.SCOPE_INDIVIDUAL,
232                                            classPK, roleId, ActionKeys.VIEW)) {
233    
234                                    if ((role.getType() == RoleConstants.TYPE_COMMUNITY) ||
235                                            (role.getType() == RoleConstants.TYPE_ORGANIZATION)) {
236    
237                                            groupRoleIds.add(groupId + StringPool.DASH + roleId);
238                                    }
239                                    else {
240                                            roleIds.add(roleId);
241                                    }
242                            }
243                    }
244    
245                    doc.addKeyword(
246                            Field.ROLE_ID, roleIds.toArray(new Long[roleIds.size()]));
247                    doc.addKeyword(
248                            Field.GROUP_ROLE_ID,
249                            groupRoleIds.toArray(new String[groupRoleIds.size()]));
250            }
251    
252            protected Query doGetPermissionQuery_5(
253                            long companyId, long[] groupIds, long userId, String className,
254                            Query query)
255                    throws Exception {
256    
257                    PermissionCheckerBag bag = getUserBag(userId);
258    
259                    List<Group> groups = new ArrayList<Group>();
260                    List<Role> roles = bag.getRoles();
261                    List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
262    
263                    if ((groupIds == null) || (groupIds.length == 0)) {
264                            groups.addAll(
265                                    GroupLocalServiceUtil.getUserGroups(userId, true));
266                            groups.addAll(bag.getGroups());
267    
268                            userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
269                                    userId);
270                    }
271                    else {
272                            for (long groupId : groupIds) {
273                                    if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
274                                            Group group = GroupLocalServiceUtil.getGroup(groupId);
275    
276                                            groups.add(group);
277                                    }
278    
279                                    userGroupRoles.addAll(
280                                            UserGroupRoleLocalServiceUtil.getUserGroupRoles(
281                                                    userId, groupId));
282                                    userGroupRoles.addAll(
283                                            UserGroupRoleLocalServiceUtil.
284                                                    getUserGroupRolesByUserUserGroupAndGroup(
285                                                            userId, groupId));
286                            }
287                    }
288    
289                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
290    
291                    if (defaultUserId != userId) {
292                            roles.add(
293                                    RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
294                    }
295    
296                    long companyResourceId = 0;
297    
298                    try {
299                            Resource companyResource = ResourceLocalServiceUtil.getResource(
300                                    companyId, className, ResourceConstants.SCOPE_COMPANY,
301                                    String.valueOf(companyId));
302    
303                            companyResourceId = companyResource.getResourceId();
304                    }
305                    catch (NoSuchResourceException nsre) {
306                    }
307    
308                    long[] groupResourceIds = new long[groups.size()];
309    
310                    try {
311                            for (int i = 0; i < groups.size() ; i++ ) {
312                                    Group group = groups.get(i);
313    
314                                    Resource groupResource = ResourceLocalServiceUtil.getResource(
315                                            companyId, className, ResourceConstants.SCOPE_GROUP,
316                                            String.valueOf(group.getGroupId()));
317    
318                                    groupResourceIds[i] = groupResource.getResourceId();
319                            }
320                    }
321                    catch (NoSuchResourceException nsre) {
322                    }
323    
324                    BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
325    
326                    if (userId > 0) {
327                            permissionQuery.addTerm(Field.USER_ID, userId);
328                    }
329    
330                    for (Role role : roles) {
331                            if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
332                                    return query;
333                            }
334    
335                            long roleId = role.getRoleId();
336    
337                            if (hasPermission(roleId, companyResourceId)) {
338                                    return query;
339                            }
340    
341                            for (long groupResourceId : groupResourceIds) {
342                                    if (hasPermission(roleId, groupResourceId)) {
343                                            return query;
344                                    }
345                            }
346    
347                            permissionQuery.addTerm(Field.ROLE_ID, role.getRoleId());
348                    }
349    
350                    for (Group group : groups) {
351                            addRequiredMemberRole(group, permissionQuery);
352                    }
353    
354                    for (UserGroupRole userGroupRole : userGroupRoles) {
355                            permissionQuery.addTerm(
356                                    Field.GROUP_ROLE_ID,
357                                    userGroupRole.getGroupId() + StringPool.DASH +
358                                            userGroupRole.getRoleId());
359                    }
360    
361                    BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
362    
363                    fullQuery.add(query, BooleanClauseOccur.MUST);
364                    fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
365    
366                    return fullQuery;
367            }
368    
369            protected Query doGetPermissionQuery_6(
370                            long companyId, long[] groupIds, long userId, String className,
371                            Query query)
372                    throws Exception {
373    
374                    PermissionCheckerBag bag = getUserBag(userId);
375    
376                    if (bag == null) {
377                            return query;
378                    }
379    
380                    List<Group> groups = new ArrayList<Group>();
381                    List<Role> roles = bag.getRoles();
382                    List<UserGroupRole> userGroupRoles = new ArrayList<UserGroupRole>();
383    
384                    if ((groupIds == null) || (groupIds.length == 0)) {
385                            groups.addAll(GroupLocalServiceUtil.getUserGroups(userId, true));
386                            groups.addAll(bag.getGroups());
387    
388                            userGroupRoles = UserGroupRoleLocalServiceUtil.getUserGroupRoles(
389                                    userId);
390                    }
391                    else {
392                            for (long groupId : groupIds) {
393                                    if (GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
394                                            Group group = GroupLocalServiceUtil.getGroup(groupId);
395    
396                                            groups.add(group);
397                                    }
398    
399                                    userGroupRoles.addAll(
400                                            UserGroupRoleLocalServiceUtil.getUserGroupRoles(
401                                                    userId, groupId));
402                                    userGroupRoles.addAll(
403                                            UserGroupRoleLocalServiceUtil.
404                                                    getUserGroupRolesByUserUserGroupAndGroup(
405                                                    userId, groupId));
406                            }
407                    }
408    
409                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
410    
411                    if (defaultUserId != userId) {
412                            roles.add(
413                                    RoleLocalServiceUtil.getRole(companyId, RoleConstants.GUEST));
414                    }
415    
416                    BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create();
417    
418                    if (userId > 0) {
419                            permissionQuery.addTerm(Field.USER_ID, userId);
420                    }
421    
422                    for (Role role : roles) {
423                            if (role.getName().equals(RoleConstants.ADMINISTRATOR)) {
424                                    return query;
425                            }
426    
427                            long roleId = role.getRoleId();
428    
429                            if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
430                                            companyId, className, ResourceConstants.SCOPE_COMPANY,
431                                            String.valueOf(companyId), roleId, ActionKeys.VIEW)) {
432    
433                                    return query;
434                            }
435    
436                            for (Group group : groups) {
437                                    if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
438                                                    companyId, className, ResourceConstants.SCOPE_GROUP,
439                                                    String.valueOf(group.getGroupId()), roleId,
440                                                    ActionKeys.VIEW)) {
441    
442                                            return query;
443                                    }
444                            }
445    
446                            permissionQuery.addTerm(Field.ROLE_ID, roleId);
447                    }
448    
449                    for (Group group : groups) {
450                            addRequiredMemberRole(group, permissionQuery);
451                    }
452    
453                    for (UserGroupRole userGroupRole : userGroupRoles) {
454                            permissionQuery.addTerm(
455                                    Field.GROUP_ROLE_ID,
456                                    userGroupRole.getGroupId() + StringPool.DASH +
457                                            userGroupRole.getRoleId());
458                    }
459    
460                    BooleanQuery fullQuery = BooleanQueryFactoryUtil.create();
461    
462                    fullQuery.add(query, BooleanClauseOccur.MUST);
463                    fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);
464    
465                    return fullQuery;
466            }
467    
468            protected void doUpdatePermissionFields_5(long resourceId)
469                    throws Exception {
470    
471                    Resource resource = ResourceLocalServiceUtil.getResource(resourceId);
472    
473                    Indexer indexer = IndexerRegistryUtil.getIndexer(resource.getName());
474    
475                    if (indexer != null) {
476                            indexer.reindex(
477                                    resource.getName(), GetterUtil.getLong(resource.getPrimKey()));
478                    }
479            }
480    
481            protected void doUpdatePermissionFields_6(
482                            String resourceName, String resourceClassPK)
483                    throws Exception {
484    
485                    Indexer indexer = IndexerRegistryUtil.getIndexer(resourceName);
486    
487                    if (indexer != null) {
488                            indexer.reindex(resourceName, GetterUtil.getLong(resourceClassPK));
489                    }
490            }
491    
492            protected PermissionCheckerBag getUserBag(long userId) throws Exception {
493                    User user = UserLocalServiceUtil.getUser(userId);
494    
495                    PermissionChecker permissionChecker =
496                            PermissionCheckerFactoryUtil.create(user, true);
497    
498                    if (permissionChecker instanceof AdvancedPermissionChecker) {
499                            AdvancedPermissionChecker advancedPermissionChecker =
500                                    (AdvancedPermissionChecker)permissionChecker;
501    
502                            return advancedPermissionChecker.getUserBag(userId, 0);
503                    }
504                    else {
505                            return null;
506                    }
507            }
508    
509            protected boolean hasPermission(long roleId, long resourceId)
510                    throws SystemException {
511    
512                    if (resourceId == 0) {
513                            return false;
514                    }
515    
516                    List<Permission> permissions =
517                            PermissionLocalServiceUtil.getRolePermissions(roleId, resourceId);
518    
519                    List<String> actions = ResourceActionsUtil.getActions(permissions);
520    
521                    if (actions.contains(ActionKeys.VIEW)) {
522                            return true;
523                    }
524                    else {
525                            return false;
526                    }
527            }
528    
529            private static Log _log = LogFactoryUtil.getLog(
530                    SearchPermissionCheckerImpl.class);
531    
532    }