You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2015/07/01 02:16:38 UTC
svn commit: r1688537 - in /lucene/dev/trunk/lucene: ./
core/src/java/org/apache/lucene/store/ core/src/test/org/apache/lucene/index/
test-framework/src/java/org/apache/lucene/util/
test-framework/src/test/org/apache/lucene/util/ tools/junit4/
Author: uschindler
Date: Wed Jul 1 00:16:37 2015
New Revision: 1688537
URL: http://svn.apache.org/r1688537
Log:
LUCENE-6542: FSDirectory's ctor now works with security policies or file systems that restrict write access
Added:
lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestReadOnlyIndex.java (with props)
lucene/dev/trunk/lucene/test-framework/src/test/org/apache/lucene/util/TestRunWithRestrictedPermissions.java (with props)
Modified:
lucene/dev/trunk/lucene/CHANGES.txt
lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java
lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
lucene/dev/trunk/lucene/tools/junit4/tests.policy
Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1688537&r1=1688536&r2=1688537&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Wed Jul 1 00:16:37 2015
@@ -232,6 +232,9 @@ Changes in Runtime Behavior
API, however the returned bits may be called on different documents compared
to before. (Adrien Grand)
+* LUCENE-6542: FSDirectory's ctor now works with security policies or file systems
+ that restrict write access. (Trejkaz, hossman, Uwe Schindler)
+
Optimizations
* LUCENE-6548: Some optimizations for BlockTree's intersect with very
@@ -264,6 +267,11 @@ Test Framework
* LUCENE-6637: Fix FSTTester to not violate file permissions on
-Dtests.verbose=true. (Mesbah M. Alam, Uwe Schindler)
+* LUCENE-6542: LuceneTestCase now has runWithRestrictedPermissions() to run
+ an action with reduced permissions. This can be used to simulate special
+ environments (e.g., read-only dirs). If tests are running without a security
+ manager, an assume cancels test execution automatically. (Uwe Schindler)
+
Changes in Backwards Compatibility Policy
* LUCENE-6553: The iterator returned by the LeafReader.postings method now
Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java?rev=1688537&r1=1688536&r2=1688537&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/store/FSDirectory.java Wed Jul 1 00:16:37 2015
@@ -125,7 +125,10 @@ public abstract class FSDirectory extend
*/
protected FSDirectory(Path path, LockFactory lockFactory) throws IOException {
super(lockFactory);
- Files.createDirectories(path); // create directory, if it doesn't exist
+ // If only read access is permitted, createDirectories fails even if the directory already exists.
+ if (!Files.isDirectory(path)) {
+ Files.createDirectories(path); // create directory, if it doesn't exist
+ }
directory = path.toRealPath();
}
Added: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestReadOnlyIndex.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestReadOnlyIndex.java?rev=1688537&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestReadOnlyIndex.java (added)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestReadOnlyIndex.java Wed Jul 1 00:16:37 2015
@@ -0,0 +1,98 @@
+package org.apache.lucene.index;
+
+/*
+ * 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.
+ */
+
+import java.io.FilePermission;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.PropertyPermission;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.PhraseQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.BeforeClass;
+
+public class TestReadOnlyIndex extends LuceneTestCase {
+
+ private static final String longTerm = "longtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongtermlongterm";
+ private static final String text = "This is the text to be indexed. " + longTerm;
+
+ private static Path indexPath;
+
+ @BeforeClass
+ public static void buildIndex() throws Exception {
+ indexPath = Files.createTempDirectory("readonlyindex");
+
+ // borrows from TestDemo, but not important to keep in sync with demo
+ Analyzer analyzer = new MockAnalyzer(random());
+ Directory directory = newFSDirectory(indexPath);
+ RandomIndexWriter iwriter = new RandomIndexWriter(random(), directory, analyzer);
+ Document doc = new Document();
+ doc.add(newTextField("fieldname", text, Field.Store.YES));
+ iwriter.addDocument(doc);
+ iwriter.close();
+ directory.close();
+ analyzer.close();
+ }
+
+ public void testReadOnlyIndex() throws Exception {
+ runWithRestrictedPermissions(this::doTestReadOnlyIndex,
+ // add some basic permissions (because we are limited already - so we grant all important ones):
+ new RuntimePermission("*"),
+ new PropertyPermission("*", "read"),
+ // only allow read to the given index dir, nothing else:
+ new FilePermission(indexPath.toString(), "read"),
+ new FilePermission(indexPath.resolve("-").toString(), "read")
+ );
+ }
+
+ private Void doTestReadOnlyIndex() throws Exception {
+ Directory dir = FSDirectory.open(indexPath);
+ IndexReader ireader = DirectoryReader.open(dir);
+ IndexSearcher isearcher = newSearcher(ireader);
+
+ // borrows from TestDemo, but not important to keep in sync with demo
+
+ assertEquals(1, isearcher.search(new TermQuery(new Term("fieldname", longTerm)), 1).totalHits);
+ Query query = new TermQuery(new Term("fieldname", "text"));
+ TopDocs hits = isearcher.search(query, 1);
+ assertEquals(1, hits.totalHits);
+ // Iterate through the results:
+ for (int i = 0; i < hits.scoreDocs.length; i++) {
+ StoredDocument hitDoc = isearcher.doc(hits.scoreDocs[i].doc);
+ assertEquals(text, hitDoc.get("fieldname"));
+ }
+
+ // Test simple phrase query
+ PhraseQuery phraseQuery = new PhraseQuery("fieldname", "to", "be");
+ assertEquals(1, isearcher.search(phraseQuery, 1).totalHits);
+
+ ireader.close();
+ return null; // void
+ }
+
+}
Modified: lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java?rev=1688537&r1=1688536&r2=1688537&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java (original)
+++ lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java Wed Jul 1 00:16:37 2015
@@ -34,6 +34,14 @@ import java.lang.reflect.Method;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
@@ -101,6 +109,7 @@ import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
+
import com.carrotsearch.randomizedtesting.JUnit4MethodProvider;
import com.carrotsearch.randomizedtesting.LifecycleScope;
import com.carrotsearch.randomizedtesting.MixWithSuiteName;
@@ -2604,6 +2613,25 @@ public abstract class LuceneTestCase ext
public static Path createTempFile() throws IOException {
return createTempFile("tempFile", ".tmp");
}
+
+ /**
+ * Runs a code part with restricted permissions (be sure to add all required permissions,
+ * because it would start with empty permissions). You cannot grant more permissions than
+ * our policy file allows, but you may restrict writing to several dirs...
+ * <p><em>Note:</em> This assumes a {@link SecurityManager} enabled, otherwise it
+ * stops test execution.
+ */
+ public static <T> T runWithRestrictedPermissions(PrivilegedExceptionAction<T> action, Permission... permissions) throws Exception {
+ assumeTrue("runWithRestrictedPermissions requires a SecurityManager enabled", System.getSecurityManager() != null);
+ final PermissionCollection perms = new Permissions();
+ Arrays.stream(permissions).forEach(perms::add);
+ final AccessControlContext ctx = new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ try {
+ return AccessController.doPrivileged(action, ctx);
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
+ }
/** True if assertions (-ea) are enabled (at least for this class). */
public static final boolean assertsAreEnabled;
Added: lucene/dev/trunk/lucene/test-framework/src/test/org/apache/lucene/util/TestRunWithRestrictedPermissions.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/test-framework/src/test/org/apache/lucene/util/TestRunWithRestrictedPermissions.java?rev=1688537&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/test-framework/src/test/org/apache/lucene/util/TestRunWithRestrictedPermissions.java (added)
+++ lucene/dev/trunk/lucene/test-framework/src/test/org/apache/lucene/util/TestRunWithRestrictedPermissions.java Wed Jul 1 00:16:37 2015
@@ -0,0 +1,69 @@
+package org.apache.lucene.util;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.AllPermission;
+
+public class TestRunWithRestrictedPermissions extends LuceneTestCase {
+
+ public void testDefaultsPass() throws Exception {
+ runWithRestrictedPermissions(this::doSomeForbiddenStuff, new AllPermission());
+ }
+
+ public void testNormallyAllowedStuff() throws Exception {
+ try {
+ runWithRestrictedPermissions(this::doSomeForbiddenStuff);
+ fail("this should not pass!");
+ } catch (SecurityException se) {
+ // pass
+ }
+ }
+
+ public void testCompletelyForbidden1() throws Exception {
+ try {
+ runWithRestrictedPermissions(this::doSomeCompletelyForbiddenStuff);
+ fail("this should not pass!");
+ } catch (SecurityException se) {
+ // pass
+ }
+ }
+
+ public void testCompletelyForbidden2() throws Exception {
+ try {
+ runWithRestrictedPermissions(this::doSomeCompletelyForbiddenStuff, new AllPermission());
+ fail("this should not pass (not even with AllPermission)");
+ } catch (SecurityException se) {
+ // pass
+ }
+ }
+
+ private Void doSomeForbiddenStuff() throws IOException {
+ createTempDir("cannot_create_temp_folder");
+ return null; // Void
+ }
+
+ // something like this should not never pass!!
+ private Void doSomeCompletelyForbiddenStuff() throws IOException {
+ Files.createFile(Paths.get("denied"));
+ return null; // Void
+ }
+
+}
Modified: lucene/dev/trunk/lucene/tools/junit4/tests.policy
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/tools/junit4/tests.policy?rev=1688537&r1=1688536&r2=1688537&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/tools/junit4/tests.policy (original)
+++ lucene/dev/trunk/lucene/tools/junit4/tests.policy Wed Jul 1 00:16:37 2015
@@ -110,4 +110,7 @@ grant {
// SSL related properties for jetty
permission java.security.SecurityPermission "getProperty.ssl.KeyManagerFactory.algorithm";
permission java.security.SecurityPermission "getProperty.ssl.TrustManagerFactory.algorithm";
+
+ // allows LuceneTestCase#runWithRestrictedPermissions to execute with lower (or no) permission
+ permission java.security.SecurityPermission "createAccessControlContext";
};