lucene.security.search.SecureIndexSearcher.java Source code

Java tutorial

Introduction

Here is the source code for lucene.security.search.SecureIndexSearcher.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package lucene.security.search;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;

import lucene.security.index.AccessControlFactory;
import lucene.security.index.AccessControlReader;
import lucene.security.index.SecureAtomicReader;
import lucene.security.index.SecureDirectoryReader;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.StoredFieldVisitor;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;

public class SecureIndexSearcher extends IndexSearcher {

    private final IndexReader _secureIndexReader;
    private final Map<Object, AtomicReaderContext> _leaveMap;
    private final AccessControlFactory _accessControlFactory;
    private final Collection<String> _readAuthorizations;
    private final Collection<String> _discoverAuthorizations;
    private final Set<String> _discoverableFields;
    private AccessControlReader _accessControlReader;

    public SecureIndexSearcher(IndexReader r, AccessControlFactory accessControlFactory,
            Collection<String> readAuthorizations, Collection<String> discoverAuthorizations,
            Set<String> discoverableFields) throws IOException {
        this(r, null, accessControlFactory, readAuthorizations, discoverAuthorizations, discoverableFields);
    }

    public SecureIndexSearcher(IndexReader r, ExecutorService executor, AccessControlFactory accessControlFactory,
            Collection<String> readAuthorizations, Collection<String> discoverAuthorizations,
            Set<String> discoverableFields) throws IOException {
        this(r.getContext(), executor, accessControlFactory, readAuthorizations, discoverAuthorizations,
                discoverableFields);
    }

    public SecureIndexSearcher(IndexReaderContext context, AccessControlFactory accessControlFactory,
            Collection<String> readAuthorizations, Collection<String> discoverAuthorizations,
            Set<String> discoverableFields) throws IOException {
        this(context, null, accessControlFactory, readAuthorizations, discoverAuthorizations, discoverableFields);
    }

    public SecureIndexSearcher(IndexReaderContext context, ExecutorService executor,
            AccessControlFactory accessControlFactory, Collection<String> readAuthorizations,
            Collection<String> discoverAuthorizations, Set<String> discoverableFields) throws IOException {
        super(context, executor);
        _accessControlFactory = accessControlFactory;
        _readAuthorizations = readAuthorizations;
        _discoverAuthorizations = discoverAuthorizations;
        _discoverableFields = discoverableFields;
        _accessControlReader = _accessControlFactory.getReader(readAuthorizations, discoverAuthorizations,
                discoverableFields);
        _secureIndexReader = getSecureIndexReader(context);
        List<AtomicReaderContext> leaves = _secureIndexReader.leaves();
        _leaveMap = new HashMap<Object, AtomicReaderContext>();
        for (AtomicReaderContext atomicReaderContext : leaves) {
            AtomicReader atomicReader = atomicReaderContext.reader();
            SecureAtomicReader secureAtomicReader = (SecureAtomicReader) atomicReader;
            AtomicReader originalReader = secureAtomicReader.getOriginalReader();
            Object coreCacheKey = originalReader.getCoreCacheKey();
            _leaveMap.put(coreCacheKey, atomicReaderContext);
        }
    }

    protected AtomicReader getSecureAtomicReader(AtomicReader atomicReader) throws IOException {
        return SecureAtomicReader.create(_accessControlFactory, atomicReader, _readAuthorizations,
                _discoverAuthorizations, _discoverableFields);
    }

    protected IndexReader getSecureIndexReader(IndexReaderContext context) throws IOException {
        IndexReader indexReader = context.reader();
        if (indexReader instanceof DirectoryReader) {
            return SecureDirectoryReader.create(_accessControlFactory, (DirectoryReader) indexReader,
                    _readAuthorizations, _discoverAuthorizations, _discoverableFields);
        } else if (indexReader instanceof AtomicReader) {
            return SecureAtomicReader.create(_accessControlFactory, (AtomicReader) indexReader, _readAuthorizations,
                    _discoverAuthorizations, _discoverableFields);
        }
        throw new IOException("IndexReader type [" + indexReader.getClass() + "] not supported.");
    }

    @Override
    public IndexReader getIndexReader() {
        return _secureIndexReader;
    }

    protected Filter getSecureFilter() throws IOException {
        return _accessControlReader.getQueryFilter();
    }

    protected Collector getSecureCollector(final Collector collector) {
        return new Collector() {

            @Override
            public void setScorer(Scorer scorer) throws IOException {
                collector.setScorer(scorer);
            }

            @Override
            public void setNextReader(AtomicReaderContext context) throws IOException {
                Object key = context.reader().getCoreCacheKey();
                AtomicReaderContext atomicReaderContext = _leaveMap.get(key);
                collector.setNextReader(atomicReaderContext);
            }

            @Override
            public void collect(int doc) throws IOException {
                collector.collect(doc);
            }

            @Override
            public boolean acceptsDocsOutOfOrder() {
                return collector.acceptsDocsOutOfOrder();
            }
        };
    }

    @Override
    public Weight createNormalizedWeight(Query query) throws IOException {
        return super.createNormalizedWeight(wrapFilter(query, getSecureFilter()));
    }

    @Override
    protected void search(List<AtomicReaderContext> leaves, Weight weight, Collector collector) throws IOException {
        super.search(leaves, weight, getSecureCollector(collector));
    }

    public Document doc(int docID) throws IOException {
        return _secureIndexReader.document(docID);
    }

    public void doc(int docID, StoredFieldVisitor fieldVisitor) throws IOException {
        _secureIndexReader.document(docID, fieldVisitor);
    }

    public Document doc(int docID, Set<String> fieldsToLoad) throws IOException {
        return _secureIndexReader.document(docID, fieldsToLoad);
    }

}