Repository: incubator-blur Updated Branches: refs/heads/master 81129a0ce -> a587dc158
Adding formal acl read and discover types to blur. Still need to integrate SecureIndexSearcher to the BlurIndex and a table switch to enable. Project: http://git-wip-us.apache.org/repos/asf/incubator-blur/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-blur/commit/a587dc15 Tree: http://git-wip-us.apache.org/repos/asf/incubator-blur/tree/a587dc15 Diff: http://git-wip-us.apache.org/repos/asf/incubator-blur/diff/a587dc15 Branch: refs/heads/master Commit: a587dc158536bd73771c0af433a6e1d336d30ac5 Parents: 81129a0 Author: Aaron McCurry <[email protected]> Authored: Tue Jan 13 10:06:22 2015 -0500 Committer: Aaron McCurry <[email protected]> Committed: Tue Jan 13 10:06:22 2015 -0500 ---------------------------------------------------------------------- blur-query/pom.xml | 35 ++-- .../apache/blur/analysis/BaseFieldManager.java | 4 + .../type/AclDiscoverFieldTypeDefinition.java | 146 ++++++++++++++ .../type/AclReadFieldTypeDefinition.java | 146 ++++++++++++++ .../type/StringFieldTypeDefinition.java | 5 +- .../AclDiscoverFieldTypeDefinitionTest.java | 200 +++++++++++++++++++ .../type/AclReadFieldTypeDefinitionTest.java | 185 +++++++++++++++++ .../lucene-document-security-0.1.0-tests.jar | Bin 0 -> 18023 bytes .../0.1.0/lucene-document-security-0.1.0.jar | Bin 0 -> 80656 bytes .../0.1.0/lucene-document-security-0.1.0.pom | 117 +++++++++++ 10 files changed, 817 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/blur-query/pom.xml ---------------------------------------------------------------------- diff --git a/blur-query/pom.xml b/blur-query/pom.xml index 3f208f1..8be6d32 100644 --- a/blur-query/pom.xml +++ b/blur-query/pom.xml @@ -1,22 +1,14 @@ <?xml version="1.0" encoding="UTF-8" ?> -<!-- -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. ---> +<!-- 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. --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -24,7 +16,7 @@ under the License. <groupId>org.apache.blur</groupId> <artifactId>blur</artifactId> <version>0.2.4-incubating-SNAPSHOT</version> - <relativePath>../pom.xml</relativePath> + <relativePath>../pom.xml</relativePath> </parent> <groupId>org.apache.blur</groupId> <artifactId>blur-query</artifactId> @@ -71,6 +63,11 @@ under the License. <version>${lucene.version}</version> </dependency> <dependency> + <groupId>com.github.amccurry</groupId> + <artifactId>lucene-document-security</artifactId> + <version>0.1.0</version> + </dependency> + <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>${commons-cli.version}</version> http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/blur-query/src/main/java/org/apache/blur/analysis/BaseFieldManager.java ---------------------------------------------------------------------- diff --git a/blur-query/src/main/java/org/apache/blur/analysis/BaseFieldManager.java b/blur-query/src/main/java/org/apache/blur/analysis/BaseFieldManager.java index bc4c486..1bf8a24 100644 --- a/blur-query/src/main/java/org/apache/blur/analysis/BaseFieldManager.java +++ b/blur-query/src/main/java/org/apache/blur/analysis/BaseFieldManager.java @@ -28,6 +28,8 @@ import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.apache.blur.analysis.type.AclDiscoverFieldTypeDefinition; +import org.apache.blur.analysis.type.AclReadFieldTypeDefinition; import org.apache.blur.analysis.type.DateFieldTypeDefinition; import org.apache.blur.analysis.type.DoubleFieldTypeDefinition; import org.apache.blur.analysis.type.FieldLessFieldTypeDefinition; @@ -115,6 +117,8 @@ public abstract class BaseFieldManager extends FieldManager { registerType(SpatialPointVectorStrategyFieldTypeDefinition.class); registerType(SpatialTermQueryPrefixTreeStrategyFieldTypeDefinition.class); registerType(SpatialRecursivePrefixTreeStrategyFieldTypeDefinition.class); + registerType(AclReadFieldTypeDefinition.class); + registerType(AclDiscoverFieldTypeDefinition.class); _fieldLessField = fieldLessField; _strict = strict; _defaultMissingFieldLessIndexing = defaultMissingFieldLessIndexing; http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/blur-query/src/main/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinition.java ---------------------------------------------------------------------- diff --git a/blur-query/src/main/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinition.java b/blur-query/src/main/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinition.java new file mode 100644 index 0000000..d5a13e5 --- /dev/null +++ b/blur-query/src/main/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinition.java @@ -0,0 +1,146 @@ +/** + * 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 org.apache.blur.analysis.type; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import lucene.security.document.DocumentVisiblityField; + +import org.apache.blur.analysis.FieldTypeDefinition; +import org.apache.blur.thrift.generated.Column; +import org.apache.hadoop.conf.Configuration; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.core.KeywordAnalyzer; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.SortedDocValuesField; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.StoredField; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.SortField.Type; +import org.apache.lucene.util.BytesRef; + +public class AclDiscoverFieldTypeDefinition extends FieldTypeDefinition { + + private static final String INTERNAL_FIELDNAME = "_discover_"; + private static final KeywordAnalyzer KEYWORD_ANALYZER = new KeywordAnalyzer(); + private static final String ACL_DISCOVER = "acl-discover"; + private static final Collection<String> ALT_FIELD_NAMES; + + static { + ALT_FIELD_NAMES = new HashSet<String>(); + ALT_FIELD_NAMES.add(INTERNAL_FIELDNAME); + } + + @Override + public String getName() { + return ACL_DISCOVER; + } + + @Override + public void configure(String fieldNameForThisInstance, Map<String, String> properties, Configuration configuration) { + + } + + @Override + public Collection<String> getAlternateFieldNames() { + return ALT_FIELD_NAMES; + } + + @Override + public Iterable<? extends Field> getFieldsForColumn(String family, Column column) { + String fieldName = getFieldName(); + String value = column.getValue(); + List<Field> fields = new ArrayList<Field>(); + fields.add(new DocumentVisiblityField(INTERNAL_FIELDNAME, value, Store.NO)); + fields.add(new StoredField(fieldName, value)); + if (isSortEnable()) { + fields.add(new SortedDocValuesField(fieldName, new BytesRef(value))); + } + return fields; + } + + @Override + public Iterable<? extends Field> getFieldsForSubColumn(String family, Column column, String subName) { + String fieldName = getFieldName(); + String value = column.getValue(); + List<Field> fields = new ArrayList<Field>(); + fields.add(new DocumentVisiblityField(INTERNAL_FIELDNAME, value, Store.NO)); + if (isSortEnable()) { + fields.add(new SortedDocValuesField(fieldName, new BytesRef(value))); + } + return fields; + } + + @Override + public Analyzer getAnalyzerForIndex(String fieldName) { + // shouldn't be used ever + return KEYWORD_ANALYZER; + } + + @Override + public Analyzer getAnalyzerForQuery(String fieldName) { + return KEYWORD_ANALYZER; + } + + @Override + public boolean checkSupportForFuzzyQuery() { + return true; + } + + @Override + public boolean checkSupportForWildcardQuery() { + return true; + } + + @Override + public boolean checkSupportForPrefixQuery() { + return true; + } + + @Override + public boolean checkSupportForRegexQuery() { + return true; + } + + @Override + public boolean isNumeric() { + return false; + } + + @Override + public boolean checkSupportForCustomQuery() { + return false; + } + + @Override + public boolean checkSupportForSorting() { + return true; + } + + @Override + public SortField getSortField(boolean reverse) { + if (reverse) { + return new SortField(getFieldName(), Type.STRING, reverse); + } + return new SortField(getFieldName(), Type.STRING); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/blur-query/src/main/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinition.java ---------------------------------------------------------------------- diff --git a/blur-query/src/main/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinition.java b/blur-query/src/main/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinition.java new file mode 100644 index 0000000..52e37b2 --- /dev/null +++ b/blur-query/src/main/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinition.java @@ -0,0 +1,146 @@ +/** + * 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 org.apache.blur.analysis.type; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import lucene.security.document.DocumentVisiblityField; + +import org.apache.blur.analysis.FieldTypeDefinition; +import org.apache.blur.thrift.generated.Column; +import org.apache.hadoop.conf.Configuration; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.core.KeywordAnalyzer; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.SortedDocValuesField; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.StoredField; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.SortField.Type; +import org.apache.lucene.util.BytesRef; + +public class AclReadFieldTypeDefinition extends FieldTypeDefinition { + + private static final String INTERNAL_FIELDNAME = "_read_"; + private static final KeywordAnalyzer KEYWORD_ANALYZER = new KeywordAnalyzer(); + private static final String ACL_READ = "acl-read"; + private static final Collection<String> ALT_FIELD_NAMES; + + static { + ALT_FIELD_NAMES = new HashSet<String>(); + ALT_FIELD_NAMES.add(INTERNAL_FIELDNAME); + } + + @Override + public String getName() { + return ACL_READ; + } + + @Override + public void configure(String fieldNameForThisInstance, Map<String, String> properties, Configuration configuration) { + + } + + @Override + public Collection<String> getAlternateFieldNames() { + return ALT_FIELD_NAMES; + } + + @Override + public Iterable<? extends Field> getFieldsForColumn(String family, Column column) { + String fieldName = getFieldName(); + String value = column.getValue(); + List<Field> fields = new ArrayList<Field>(); + fields.add(new DocumentVisiblityField(INTERNAL_FIELDNAME, value, Store.NO)); + fields.add(new StoredField(fieldName, value)); + if (isSortEnable()) { + fields.add(new SortedDocValuesField(fieldName, new BytesRef(value))); + } + return fields; + } + + @Override + public Iterable<? extends Field> getFieldsForSubColumn(String family, Column column, String subName) { + String fieldName = getFieldName(); + String value = column.getValue(); + List<Field> fields = new ArrayList<Field>(); + fields.add(new DocumentVisiblityField(INTERNAL_FIELDNAME, value, Store.NO)); + if (isSortEnable()) { + fields.add(new SortedDocValuesField(fieldName, new BytesRef(value))); + } + return fields; + } + + @Override + public Analyzer getAnalyzerForIndex(String fieldName) { + // shouldn't be used ever + return KEYWORD_ANALYZER; + } + + @Override + public Analyzer getAnalyzerForQuery(String fieldName) { + return KEYWORD_ANALYZER; + } + + @Override + public boolean checkSupportForFuzzyQuery() { + return true; + } + + @Override + public boolean checkSupportForWildcardQuery() { + return true; + } + + @Override + public boolean checkSupportForPrefixQuery() { + return true; + } + + @Override + public boolean checkSupportForRegexQuery() { + return true; + } + + @Override + public boolean isNumeric() { + return false; + } + + @Override + public boolean checkSupportForCustomQuery() { + return false; + } + + @Override + public boolean checkSupportForSorting() { + return true; + } + + @Override + public SortField getSortField(boolean reverse) { + if (reverse) { + return new SortField(getFieldName(), Type.STRING, reverse); + } + return new SortField(getFieldName(), Type.STRING); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/blur-query/src/main/java/org/apache/blur/analysis/type/StringFieldTypeDefinition.java ---------------------------------------------------------------------- diff --git a/blur-query/src/main/java/org/apache/blur/analysis/type/StringFieldTypeDefinition.java b/blur-query/src/main/java/org/apache/blur/analysis/type/StringFieldTypeDefinition.java index e938311..aff3f8c 100644 --- a/blur-query/src/main/java/org/apache/blur/analysis/type/StringFieldTypeDefinition.java +++ b/blur-query/src/main/java/org/apache/blur/analysis/type/StringFieldTypeDefinition.java @@ -34,6 +34,7 @@ import org.apache.lucene.util.BytesRef; public class StringFieldTypeDefinition extends FieldTypeDefinition { + private static final KeywordAnalyzer KEYWORD_ANALYZER = new KeywordAnalyzer(); public static final String NAME = "string"; @Override @@ -75,12 +76,12 @@ public class StringFieldTypeDefinition extends FieldTypeDefinition { @Override public Analyzer getAnalyzerForIndex(String fieldName) { // shouldn't be used ever - return new KeywordAnalyzer(); + return KEYWORD_ANALYZER; } @Override public Analyzer getAnalyzerForQuery(String fieldName) { - return new KeywordAnalyzer(); + return KEYWORD_ANALYZER; } @Override http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/blur-query/src/test/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinitionTest.java ---------------------------------------------------------------------- diff --git a/blur-query/src/test/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinitionTest.java b/blur-query/src/test/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinitionTest.java new file mode 100644 index 0000000..70cc79b --- /dev/null +++ b/blur-query/src/test/java/org/apache/blur/analysis/type/AclDiscoverFieldTypeDefinitionTest.java @@ -0,0 +1,200 @@ +/** + * 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 org.apache.blur.analysis.type; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import lucene.security.index.AccessControlFactory; +import lucene.security.index.FilterAccessControlFactory; +import lucene.security.search.SecureIndexSearcher; + +import org.apache.blur.analysis.BaseFieldManager; +import org.apache.blur.analysis.FieldTypeDefinition; +import org.apache.blur.analysis.NoStopWordStandardAnalyzer; +import org.apache.blur.lucene.search.SuperParser; +import org.apache.blur.thrift.generated.Column; +import org.apache.blur.thrift.generated.Record; +import org.apache.blur.thrift.generated.ScoreType; +import org.apache.blur.utils.BlurConstants; +import org.apache.hadoop.conf.Configuration; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.StringField; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryparser.classic.ParseException; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.junit.Before; +import org.junit.Test; + +public class AclDiscoverFieldTypeDefinitionTest { + + private static final String FAM = "fam"; + + private Directory _dir = new RAMDirectory(); + private AccessControlFactory _accessControlFactory = new FilterAccessControlFactory(); + + private BaseFieldManager _fieldManager; + + @Before + public void setup() throws IOException { + _fieldManager = getFieldManager(new NoStopWordStandardAnalyzer()); + setupFieldManager(_fieldManager); + + List<List<Field>> docs = new ArrayList<List<Field>>(); + { + Record record = new Record(); + record.setFamily(FAM); + record.setRecordId("1234"); + record.addToColumns(new Column("string", "value")); + record.addToColumns(new Column("discover", "a&b")); + List<Field> fields = _fieldManager.getFields("1234", record); + fields.add(new StringField(BlurConstants.PRIME_DOC, BlurConstants.PRIME_DOC_VALUE, Store.NO)); + docs.add(fields); + } + { + Record record = new Record(); + record.setFamily(FAM); + record.setRecordId("5678"); + record.addToColumns(new Column("string", "value")); + record.addToColumns(new Column("discover", "a&c")); + docs.add(_fieldManager.getFields("1234", record)); + } + + IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_43, _fieldManager.getAnalyzerForIndex()); + IndexWriter writer = new IndexWriter(_dir, conf); + writer.addDocuments(docs); + writer.close(); + } + + @Test + public void test1RowQuery() throws IOException, ParseException { + test(0, true, null); + } + + @Test + public void test1RecordQuery() throws IOException, ParseException { + test(0, false, null); + } + + @Test + public void test2RowQuery() throws IOException, ParseException { + test(1, true, Arrays.asList("a", "b")); + } + + @Test + public void test2RecordQuery() throws IOException, ParseException { + test(1, false, Arrays.asList("a", "b")); + } + + @Test + public void test3RowQuery() throws IOException, ParseException { + test(1, true, Arrays.asList("a", "b", "c")); + } + + @Test + public void test3RecordQuery() throws IOException, ParseException { + test(2, false, Arrays.asList("a", "b", "c")); + } + + @Test + public void test4RowQuery() throws IOException, ParseException { + test(0, true, Arrays.asList("a")); + } + + @Test + public void test4RecordQuery() throws IOException, ParseException { + test(0, false, Arrays.asList("a")); + } + + private AccessControlFactory getAccessControlFactory() { + return _accessControlFactory; + } + + private void setupFieldManager(BaseFieldManager fieldManager) throws IOException { + fieldManager.addColumnDefinition(FAM, "string", null, false, "string", false, null); + fieldManager.addColumnDefinition(FAM, "discover", null, false, "acl-discover", false, null); + } + + protected BaseFieldManager getFieldManager(Analyzer a) throws IOException { + BaseFieldManager fieldManager = new BaseFieldManager(BlurConstants.SUPER, a, new Configuration()) { + @Override + protected boolean tryToStore(FieldTypeDefinition fieldTypeDefinition, String fieldName) { + return true; + } + + @Override + protected void tryToLoad(String fieldName) { + + } + + @Override + protected List<String> getFieldNamesToLoad() throws IOException { + return new ArrayList<String>(); + } + }; + return fieldManager; + } + + private void test(int expected, boolean rowQuery, Collection<String> discoverAuthorizations) throws IOException, + ParseException { + DirectoryReader reader = DirectoryReader.open(_dir); + SuperParser parser = new SuperParser(Version.LUCENE_43, _fieldManager, rowQuery, null, ScoreType.SUPER, new Term( + BlurConstants.PRIME_DOC, BlurConstants.PRIME_DOC_VALUE)); + + Query query = parser.parse("fam.string:value"); + + Collection<String> readAuthorizations = null; + Set<String> discoverableFields = new HashSet<String>(); + discoverableFields.add("rowid"); + discoverableFields.add("recordid"); + discoverableFields.add("family"); + IndexSearcher searcher = new SecureIndexSearcher(reader, getAccessControlFactory(), readAuthorizations, + discoverAuthorizations, discoverableFields); + + TopDocs topDocs = searcher.search(query, 10); + assertEquals(expected, topDocs.totalHits); + for (int i = 0; i < expected; i++) { + int doc = topDocs.scoreDocs[i].doc; + Document document = searcher.doc(doc); + List<IndexableField> fields = document.getFields(); + for (IndexableField field : fields) { + assertTrue(discoverableFields.contains(field.name())); + } + } + reader.close(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/blur-query/src/test/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinitionTest.java ---------------------------------------------------------------------- diff --git a/blur-query/src/test/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinitionTest.java b/blur-query/src/test/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinitionTest.java new file mode 100644 index 0000000..4bf42ae --- /dev/null +++ b/blur-query/src/test/java/org/apache/blur/analysis/type/AclReadFieldTypeDefinitionTest.java @@ -0,0 +1,185 @@ +/** + * 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 org.apache.blur.analysis.type; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import lucene.security.index.AccessControlFactory; +import lucene.security.index.FilterAccessControlFactory; +import lucene.security.search.SecureIndexSearcher; + +import org.apache.blur.analysis.BaseFieldManager; +import org.apache.blur.analysis.FieldTypeDefinition; +import org.apache.blur.analysis.NoStopWordStandardAnalyzer; +import org.apache.blur.lucene.search.SuperParser; +import org.apache.blur.thrift.generated.Column; +import org.apache.blur.thrift.generated.Record; +import org.apache.blur.thrift.generated.ScoreType; +import org.apache.blur.utils.BlurConstants; +import org.apache.hadoop.conf.Configuration; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryparser.classic.ParseException; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.junit.Before; +import org.junit.Test; + +public class AclReadFieldTypeDefinitionTest { + + private static final String FAM = "fam"; + + private Directory _dir = new RAMDirectory(); + private AccessControlFactory _accessControlFactory = new FilterAccessControlFactory(); + + private BaseFieldManager _fieldManager; + + @Before + public void setup() throws IOException { + _fieldManager = getFieldManager(new NoStopWordStandardAnalyzer()); + setupFieldManager(_fieldManager); + + List<List<Field>> docs = new ArrayList<List<Field>>(); + { + Record record = new Record(); + record.setFamily(FAM); + record.setRecordId("1234"); + record.addToColumns(new Column("string", "value")); + record.addToColumns(new Column("read", "a&b")); + List<Field> fields = _fieldManager.getFields("1234", record); + fields.add(new StringField(BlurConstants.PRIME_DOC, BlurConstants.PRIME_DOC_VALUE, Store.NO)); + docs.add(fields); + } + { + Record record = new Record(); + record.setFamily(FAM); + record.setRecordId("5678"); + record.addToColumns(new Column("string", "value")); + record.addToColumns(new Column("read", "a&c")); + docs.add(_fieldManager.getFields("1234", record)); + } + + IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_43, _fieldManager.getAnalyzerForIndex()); + IndexWriter writer = new IndexWriter(_dir, conf); + writer.addDocuments(docs); + writer.close(); + } + + @Test + public void test1RowQuery() throws IOException, ParseException { + test(0, true, null); + } + + @Test + public void test1RecordQuery() throws IOException, ParseException { + test(0, false, null); + } + + @Test + public void test2RowQuery() throws IOException, ParseException { + test(1, true, Arrays.asList("a", "b")); + } + + @Test + public void test2RecordQuery() throws IOException, ParseException { + test(1, false, Arrays.asList("a", "b")); + } + + @Test + public void test3RowQuery() throws IOException, ParseException { + test(1, true, Arrays.asList("a", "b", "c")); + } + + @Test + public void test3RecordQuery() throws IOException, ParseException { + test(2, false, Arrays.asList("a", "b", "c")); + } + + @Test + public void test4RowQuery() throws IOException, ParseException { + test(0, true, Arrays.asList("a")); + } + + @Test + public void test4RecordQuery() throws IOException, ParseException { + test(0, false, Arrays.asList("a")); + } + + private AccessControlFactory getAccessControlFactory() { + return _accessControlFactory; + } + + private void setupFieldManager(BaseFieldManager fieldManager) throws IOException { + fieldManager.addColumnDefinition(FAM, "string", null, false, "string", false, null); + fieldManager.addColumnDefinition(FAM, "read", null, false, "acl-read", false, null); + } + + protected BaseFieldManager getFieldManager(Analyzer a) throws IOException { + BaseFieldManager fieldManager = new BaseFieldManager(BlurConstants.SUPER, a, new Configuration()) { + @Override + protected boolean tryToStore(FieldTypeDefinition fieldTypeDefinition, String fieldName) { + return true; + } + + @Override + protected void tryToLoad(String fieldName) { + + } + + @Override + protected List<String> getFieldNamesToLoad() throws IOException { + return new ArrayList<String>(); + } + }; + return fieldManager; + } + + private void test(int expected, boolean rowQuery, Collection<String> readAuthorizations) throws IOException, + ParseException { + DirectoryReader reader = DirectoryReader.open(_dir); + SuperParser parser = new SuperParser(Version.LUCENE_43, _fieldManager, rowQuery, null, ScoreType.SUPER, new Term( + BlurConstants.PRIME_DOC, BlurConstants.PRIME_DOC_VALUE)); + + Query query = parser.parse("fam.string:value"); + + Collection<String> discoverAuthorizations = null; + Set<String> discoverableFields = null; + IndexSearcher searcher = new SecureIndexSearcher(reader, getAccessControlFactory(), readAuthorizations, + discoverAuthorizations, discoverableFields); + + TopDocs topDocs = searcher.search(query, 10); + assertEquals(expected, topDocs.totalHits); + reader.close(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0-tests.jar ---------------------------------------------------------------------- diff --git a/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0-tests.jar b/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0-tests.jar new file mode 100644 index 0000000..81d57e0 Binary files /dev/null and b/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0-tests.jar differ http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.jar ---------------------------------------------------------------------- diff --git a/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.jar b/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.jar new file mode 100644 index 0000000..0315c44 Binary files /dev/null and b/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.jar differ http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/a587dc15/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.pom ---------------------------------------------------------------------- diff --git a/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.pom b/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.pom new file mode 100644 index 0000000..fc6bd6f --- /dev/null +++ b/lib/com/github/amccurry/lucene-document-security/0.1.0/lucene-document-security-0.1.0.pom @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- +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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>com.github.amccurry</groupId> + <artifactId>lucene-document-security</artifactId> + <version>0.1.0</version> + <packaging>jar</packaging> + <name>Lucene Document Security</name> + <description>Provides an API for Document level security in Lucene.</description> + + <dependencies> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-core</artifactId> + <version>4.3.0</version> + </dependency> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-analyzers-common</artifactId> + <version>4.3.0</version> + </dependency> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-queryparser</artifactId> + <version>4.3.0</version> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1.3</version> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>14.0</version> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.9</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.9</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.googlecode.concurrentlinkedhashmap</groupId> + <artifactId>concurrentlinkedhashmap-lru</artifactId> + <version>1.3.2</version> + </dependency> + </dependencies> + + <repositories> + <repository> + <id>libdir</id> + <url>file://${basedir}/../lib</url> + </repository> + </repositories> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <argLine>-XX:+UseConcMarkSweepGC -Xmx1g -Xms1g</argLine> + <forkCount>2</forkCount> + <forkMode>always</forkMode> + <reuseForks>false</reuseForks> + <systemPropertyVariables> + <blur.tmp.dir>${project.build.directory}/target/tmp</blur.tmp.dir> + </systemPropertyVariables> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.6</source> + <target>1.6</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project>
