001    /**
002     * Copyright (c) 2000-present 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.kernel.search;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.security.permission.ActionKeys;
020    import com.liferay.portal.kernel.security.permission.PermissionChecker;
021    import com.liferay.portal.kernel.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.Time;
024    import com.liferay.portal.kernel.workflow.WorkflowConstants;
025    
026    import java.util.ArrayList;
027    import java.util.List;
028    
029    /**
030     * @author Tina Tian
031     */
032    public class DefaultSearchResultPermissionFilter
033            extends BaseSearchResultPermissionFilter {
034    
035            public DefaultSearchResultPermissionFilter(
036                    BaseIndexer<?> baseIndexer, PermissionChecker permissionChecker) {
037    
038                    _baseIndexer = baseIndexer;
039                    _permissionChecker = permissionChecker;
040            }
041    
042            @Override
043            protected void filterHits(Hits hits, SearchContext searchContext) {
044                    List<Document> docs = new ArrayList<>();
045                    int excludeDocsSize = 0;
046                    List<Float> scores = new ArrayList<>();
047    
048                    boolean companyAdmin = _permissionChecker.isCompanyAdmin(
049                            _permissionChecker.getCompanyId());
050                    int status = GetterUtil.getInteger(
051                            searchContext.getAttribute(Field.STATUS),
052                            WorkflowConstants.STATUS_APPROVED);
053    
054                    Document[] documents = hits.getDocs();
055    
056                    for (int i = 0; i < documents.length; i++) {
057                            if (_isIncludeDocument(
058                                            documents[i], _permissionChecker.getCompanyId(),
059                                            companyAdmin, status)) {
060    
061                                    docs.add(documents[i]);
062                                    scores.add(hits.score(i));
063                            }
064                            else {
065                                    excludeDocsSize++;
066                            }
067                    }
068    
069                    hits.setDocs(docs.toArray(new Document[docs.size()]));
070                    hits.setScores(ArrayUtil.toFloatArray(scores));
071                    hits.setSearchTime(
072                            (float)(System.currentTimeMillis() - hits.getStart()) /
073                                    Time.SECOND);
074                    hits.setLength(hits.getLength() - excludeDocsSize);
075            }
076    
077            @Override
078            protected Hits getHits(SearchContext searchContext) throws SearchException {
079                    return _baseIndexer.doSearch(searchContext);
080            }
081    
082            @Override
083            protected boolean isGroupAdmin(SearchContext searchContext) {
084                    long[] groupIds = searchContext.getGroupIds();
085    
086                    if (groupIds == null) {
087                            return false;
088                    }
089    
090                    for (long groupId : groupIds) {
091                            if (!_permissionChecker.isGroupAdmin(groupId)) {
092                                    return false;
093                            }
094                    }
095    
096                    return true;
097            }
098    
099            private boolean _isIncludeDocument(
100                    Document document, long companyId, boolean companyAdmin, int status) {
101    
102                    long entryCompanyId = GetterUtil.getLong(
103                            document.get(Field.COMPANY_ID));
104    
105                    if (entryCompanyId != companyId) {
106                            return false;
107                    }
108    
109                    if (companyAdmin) {
110                            return true;
111                    }
112    
113                    String entryClassName = document.get(Field.ENTRY_CLASS_NAME);
114    
115                    Indexer<?> indexer = IndexerRegistryUtil.getIndexer(entryClassName);
116    
117                    if (indexer == null) {
118                            return true;
119                    }
120    
121                    if (!indexer.isFilterSearch()) {
122                            return true;
123                    }
124    
125                    long entryClassPK = GetterUtil.getLong(
126                            document.get(Field.ENTRY_CLASS_PK));
127    
128                    try {
129                            if (indexer.hasPermission(
130                                            _permissionChecker, entryClassName, entryClassPK,
131                                            ActionKeys.VIEW) &&
132                                    indexer.isVisibleRelatedEntry(entryClassPK, status)) {
133    
134                                    return true;
135                            }
136                    }
137                    catch (Exception e) {
138                            if (_log.isDebugEnabled()) {
139                                    _log.debug(e, e);
140                            }
141                    }
142    
143                    return false;
144            }
145    
146            private static final Log _log = LogFactoryUtil.getLog(
147                    DefaultSearchResultPermissionFilter.class);
148    
149            private final BaseIndexer<?> _baseIndexer;
150            private final PermissionChecker _permissionChecker;
151    
152    }