You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by va...@apache.org on 2014/04/29 23:24:16 UTC

[3/3] git commit: SENTRY-187: Use invariants rather than default for specification of update index level authorization (Gregory Chanan via Vamsee Yarlagadda)

SENTRY-187: Use invariants rather than default for specification of update index level authorization (Gregory Chanan via Vamsee Yarlagadda)


Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/1d6f38c0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/1d6f38c0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/1d6f38c0

Branch: refs/heads/master
Commit: 1d6f38c081e862d9c2d59638aaf22a3bb27858e5
Parents: b4c39a1
Author: Vamsee <va...@cloudera.com>
Authored: Tue Apr 29 14:20:30 2014 -0700
Committer: Vamsee <va...@cloudera.com>
Committed: Tue Apr 29 14:20:30 2014 -0700

----------------------------------------------------------------------
 .../e2e/solr/AbstractSolrSentryTestBase.java    | 80 ++++++++++++++++++++
 .../tests/e2e/solr/TestDocLevelOperations.java  | 56 +-------------
 .../tests/e2e/solr/TestUpdateOperations.java    | 26 +++++++
 .../collection1/conf/solrconfig-doclevel.xml    |  6 +-
 .../solr/collection1/conf/solrconfig.xml        | 14 +++-
 .../solr/sentry/test-authz-provider.ini         |  2 +-
 6 files changed, 128 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1d6f38c0/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestBase.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestBase.java b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestBase.java
index e90891d..b5b7678 100644
--- a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestBase.java
+++ b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/AbstractSolrSentryTestBase.java
@@ -16,16 +16,34 @@
  */
 package org.apache.sentry.tests.e2e.solr;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.Map;
 import java.util.Random;
+import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
 import com.google.common.io.Files;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.util.EntityUtils;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -701,6 +719,68 @@ public class AbstractSolrSentryTestBase {
     return css;
   }
 
+  /**
+   * Make a raw http request
+   */
+  protected String makeHttpRequest(CloudSolrServer server, String httpMethod,
+      String path, byte [] content, String contentType) throws Exception {
+    HttpClient httpClient = server.getLbServer().getHttpClient();
+    Set<String> liveNodes =
+      server.getZkStateReader().getClusterState().getLiveNodes();
+    assertTrue("Expected at least one live node", !liveNodes.isEmpty());
+    String firstServer = liveNodes.toArray(new String[0])[0].replace("_solr", "/solr");
+    URI uri = new URI("http://" + firstServer + path);
+    HttpRequestBase method = null;
+    if ("GET".equals(httpMethod)) {
+      method = new HttpGet(uri);
+    } else if ("HEAD".equals(httpMethod)) {
+      method = new HttpHead(uri);
+    } else if ("POST".equals(httpMethod)) {
+      method = new HttpPost(uri);
+    } else if ("PUT".equals(httpMethod)) {
+      method = new HttpPut(uri);
+    } else {
+      throw new IOException("Unsupported method: " + method);
+    }
+
+    if (method instanceof HttpEntityEnclosingRequestBase) {
+      HttpEntityEnclosingRequestBase entityEnclosing =
+        (HttpEntityEnclosingRequestBase)method;
+      ByteArrayEntity entityRequest = new ByteArrayEntity(content);
+      entityRequest.setContentType(contentType);
+      entityEnclosing.setEntity(entityRequest);
+    }
+
+    HttpEntity httpEntity = null;
+    boolean success = false;
+    String retValue = "";
+    try {
+      final HttpResponse response = httpClient.execute(method);
+      int httpStatus = response.getStatusLine().getStatusCode();
+      httpEntity = response.getEntity();
+
+      if (httpEntity != null) {
+        InputStream is = httpEntity.getContent();
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        try {
+          IOUtils.copyLarge(is, os);
+          os.flush();
+        } finally {
+          IOUtils.closeQuietly(os);
+          IOUtils.closeQuietly(is);
+        }
+        retValue = os.toString();
+      }
+      success = true;
+    } finally {
+      if (!success) {
+        EntityUtils.consumeQuietly(httpEntity);
+         method.abort();
+      }
+    }
+    return retValue;
+  }
+
   protected static void waitForRecoveriesToFinish(String collection,
                                                   CloudSolrServer solrServer,
                                                   boolean verbose) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1d6f38c0/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
index eccc576..2c0914e 100644
--- a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
+++ b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestDocLevelOperations.java
@@ -24,14 +24,6 @@ import org.junit.Before;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import org.apache.commons.io.IOUtils;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.util.EntityUtils;
-
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.impl.CloudSolrServer;
 import org.apache.solr.client.solrj.response.QueryResponse;
@@ -40,12 +32,8 @@ import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrInputDocument;
 
 import java.io.File;
-import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
-import java.net.URI;
 import java.net.URLEncoder;
 import java.util.ArrayList;
-import java.util.Set;
 
 import org.junit.Test;
 
@@ -81,44 +69,6 @@ public class TestDocLevelOperations extends AbstractSolrSentryTestBase {
     setupCollection(name);
   }
 
-  private String doHttpGet(CloudSolrServer server, String path) throws Exception {
-    HttpClient httpClient = server.getLbServer().getHttpClient();
-    Set<String> liveNodes =
-      server.getZkStateReader().getClusterState().getLiveNodes();
-    assertTrue("Expected at least one live node", !liveNodes.isEmpty());
-    String firstServer = liveNodes.toArray(new String[0])[0].replace("_solr", "/solr");
-    URI uri = new URI("http://" + firstServer + path);
-    HttpGet get = new HttpGet(uri);
-    HttpEntity httpEntity = null;
-    boolean success = false;
-    String retValue = "";
-    try {
-      final HttpResponse response = httpClient.execute(get);
-      int httpStatus = response.getStatusLine().getStatusCode();
-      httpEntity = response.getEntity();
-
-      if (httpEntity != null) {
-        InputStream is = httpEntity.getContent();
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        try {
-          IOUtils.copyLarge(is, os);
-          os.flush();
-        } finally {
-          IOUtils.closeQuietly(os);
-          IOUtils.closeQuietly(is);
-        }
-        retValue = os.toString();
-      }
-      success = true;
-    } finally {
-      if (!success) {
-        EntityUtils.consumeQuietly(httpEntity);
-        get.abort();
-      }
-    }
-    return retValue;
-  }
-
   /**
    * Test that queries from different users only return the documents they have access to.
    */
@@ -190,20 +140,20 @@ public class TestDocLevelOperations extends AbstractSolrSentryTestBase {
       setAuthenticationUser("junit");
       String fq = URLEncoder.encode(" {!raw f=" + AUTH_FIELD + " v=docLevel}");
       String path = "/" + collectionName + "/select?q=*:*&fq="+fq;
-      String retValue = doHttpGet(server, path);
+      String retValue = makeHttpRequest(server, "GET", path, null, null);
       assertTrue(retValue.contains("numFound=\"" + NUM_DOCS / 2 + "\" "));
 
       // test that user can't inject an "OR" into the query
       final String syntaxErrorMsg = "org.apache.solr.search.SyntaxError: Cannot parse";
       fq = URLEncoder.encode(" {!raw f=" + AUTH_FIELD + " v=docLevel} OR ");
       path = "/" + collectionName + "/select?q=*:*&fq="+fq;
-      retValue = doHttpGet(server, path);
+      retValue = makeHttpRequest(server, "GET", path, null, null);
       assertTrue(retValue.contains(syntaxErrorMsg));
 
       // same test, prefix OR this time
       fq = URLEncoder.encode(" OR {!raw f=" + AUTH_FIELD + " v=docLevel}");
       path = "/" + collectionName + "/select?q=*:*&fq="+fq;
-      retValue = doHttpGet(server, path);
+      retValue = makeHttpRequest(server, "GET", path, null, null);
       assertTrue(retValue.contains(syntaxErrorMsg));
     } finally {
       server.shutdown();

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1d6f38c0/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestUpdateOperations.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestUpdateOperations.java b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestUpdateOperations.java
index 7163573..b439a91 100644
--- a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestUpdateOperations.java
+++ b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/TestUpdateOperations.java
@@ -21,6 +21,9 @@ import org.slf4j.LoggerFactory;
 
 import org.junit.Test;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.solr.client.solrj.impl.CloudSolrServer;
 
 import java.io.File;
 import java.io.PrintWriter;
@@ -85,4 +88,27 @@ public class TestUpdateOperations extends AbstractSolrSentryTestBase {
     assertEquals("Total test failures: " + testFailures.size() + " \n\n"
         + testFailures.toString() + "\n\n\n", 0, testFailures.size());
   }
+
+  @Test
+  public void testInvariantProcessor() throws Exception {
+    String collectionName = "testInvariantCollection";
+    // Upload configs to ZK
+    uploadConfigDirToZk(RESOURCES_DIR + File.separator + DEFAULT_COLLECTION
+        + File.separator + "conf");
+    setupCollection(collectionName);
+
+    // Send a update request and try to set the update.chain to skip the
+    // index-authorization checks
+    setAuthenticationUser("junit");
+    CloudSolrServer server = getCloudSolrServer(collectionName);
+    try {
+      String path = "/" + collectionName + "/update?update.chain=skipUpdateIndexAuthorization&commit=true";
+      String body = "<add><doc><field name=\"id\">testInvariantDoc</field></doc></add>";
+      String ret = makeHttpRequest(server, "POST", path, body.getBytes("UTF-8"), "text/xml");
+      assertTrue("Expected sentry exception", ret.contains("SentrySolrAuthorizationException: User junit"
+        + " does not have privileges for testInvariantCollection"));
+    } finally {
+      server.shutdown();
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1d6f38c0/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig-doclevel.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig-doclevel.xml b/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig-doclevel.xml
index 0ab2278..7c0d73f 100644
--- a/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig-doclevel.xml
+++ b/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig-doclevel.xml
@@ -1039,7 +1039,7 @@
          on each Update Request
       -->
     
-       <lst name="defaults">
+       <lst name="invariants">
          <str name="update.chain">updateIndexAuthorization</str>
        </lst>
        
@@ -1050,6 +1050,8 @@
   <requestHandler name="/update/json" class="solr.JsonUpdateRequestHandler">
         <lst name="defaults">
          <str name="stream.contentType">application/json</str>
+       </lst>
+       <lst name="invariants">
          <str name="update.chain">updateIndexAuthorization</str>
        </lst>
 
@@ -1057,6 +1059,8 @@
   <requestHandler name="/update/csv" class="solr.CSVRequestHandler">
         <lst name="defaults">
          <str name="stream.contentType">application/csv</str>
+       </lst>
+       <lst name="invariants">
          <str name="update.chain">updateIndexAuthorization</str>
        </lst>
 

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1d6f38c0/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig.xml b/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig.xml
index 4276cda..9e71f09 100644
--- a/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig.xml
+++ b/sentry-tests/sentry-tests-solr/src/test/resources/solr/collection1/conf/solrconfig.xml
@@ -1035,7 +1035,7 @@
          on each Update Request
       -->
     
-       <lst name="defaults">
+       <lst name="invariants">
          <str name="update.chain">updateIndexAuthorization</str>
        </lst>
        
@@ -1046,6 +1046,8 @@
   <requestHandler name="/update/json" class="solr.JsonUpdateRequestHandler">
         <lst name="defaults">
          <str name="stream.contentType">application/json</str>
+       </lst>
+       <lst name="invariants">
          <str name="update.chain">updateIndexAuthorization</str>
        </lst>
 
@@ -1053,6 +1055,8 @@
   <requestHandler name="/update/csv" class="solr.CSVRequestHandler">
         <lst name="defaults">
          <str name="stream.contentType">application/csv</str>
+       </lst>
+       <lst name="invariants">
          <str name="update.chain">updateIndexAuthorization</str>
        </lst>
 
@@ -1748,6 +1752,14 @@
       <processor class="solr.RunUpdateProcessorFactory" />
     </updateRequestProcessorChain> 
 
+    <!-- A request processor chain that skips index level authorization.  Check
+      that clients can't invoke this. -->
+    <updateRequestProcessorChain name="skipUpdateIndexAuthorization">
+      <processor class="solr.LogUpdateProcessorFactory" />
+      <processor class="solr.DistributedUpdateProcessorFactory" />
+      <processor class="solr.RunUpdateProcessorFactory" />
+    </updateRequestProcessorChain>
+
   <!-- Response Writers
 
        http://wiki.apache.org/solr/QueryResponseWriter

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/1d6f38c0/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini b/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
index 74176a1..a07fb2d 100644
--- a/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
+++ b/sentry-tests/sentry-tests-solr/src/test/resources/solr/sentry/test-authz-provider.ini
@@ -31,7 +31,7 @@ admin_all_group = admin_all_role
 [roles]
 junit_role = collection=admin, collection=collection1, collection=docLevelCollection, collection=allGroupsCollection
 docLevel_role = collection=docLevelCollection
-admin_role = collection=admin, collection=collection1, collection=sentryCollection, collection=sentryCollection_underlying1, collection=sentryCollection_underlying2, collection=docLevelCollection, collection=allGroupsCollection
+admin_role = collection=admin, collection=collection1, collection=sentryCollection, collection=sentryCollection_underlying1, collection=sentryCollection_underlying2, collection=docLevelCollection, collection=allGroupsCollection, collection=testInvariantCollection
 sentryCollection_query_role = collection=sentryCollection->action=query
 sentryCollection_update_role = collection=sentryCollection->action=update
 sentryCollection_query_update_role = collection=sentryCollection->action=query, collection=sentryCollection->action=update