You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2016/06/16 12:09:13 UTC

[43/50] [abbrv] lucene-solr:apiv2: SOLR-8048: bin/solr script should support basic auth credentials provided in solr.in.sh

SOLR-8048: bin/solr script should support basic auth credentials provided in solr.in.sh


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/97e696dd
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/97e696dd
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/97e696dd

Branch: refs/heads/apiv2
Commit: 97e696dd506aa01142c8456452c6f66451dd5430
Parents: b9ded92
Author: Noble Paul <no...@apache.org>
Authored: Tue Jun 14 19:37:45 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Jun 14 19:37:45 2016 +0530

----------------------------------------------------------------------
 solr/CHANGES.txt                                |  4 +-
 .../src/java/org/apache/solr/util/SolrCLI.java  | 25 +++++-
 .../solr/security/BasicAuthIntegrationTest.java | 85 +++++++++++---------
 3 files changed, 70 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/97e696dd/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 2146539..bd7f19c 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -57,7 +57,9 @@ Detailed Change List
 New Features
 ----------------------
 
-* SOLR-9187: Support dates and booleans in /export handler, support boolean DocValues fields
+* SOLR-9187: Support dates and booleans in /export handler, support boolean DocValues fields (Erick Erickson)
+
+* SOLR-8048: bin/solr script should support basic auth credentials provided in solr.in.sh (noble)
 
 
 Bug Fixes

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/97e696dd/solr/core/src/java/org/apache/solr/util/SolrCLI.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
index 9bc986b..02f8d5a 100644
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -16,8 +16,6 @@
  */
 package org.apache.solr.util;
 
-import static org.apache.solr.common.params.CommonParams.NAME;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -56,6 +54,7 @@ import org.apache.commons.cli.Option;
 import org.apache.commons.cli.OptionBuilder;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.exec.DefaultExecuteResultHandler;
 import org.apache.commons.exec.DefaultExecutor;
 import org.apache.commons.exec.Executor;
@@ -74,6 +73,7 @@ import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.utils.URIBuilder;
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.message.BasicHeader;
 import org.apache.http.util.EntityUtils;
 import org.apache.lucene.util.Version;
 import org.apache.solr.client.solrj.SolrClient;
@@ -88,7 +88,6 @@ import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ClusterState;
-import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.cloud.ZkCoreNodeProps;
@@ -97,6 +96,7 @@ import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.ContentStreamBase;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.StrUtils;
 import org.noggit.CharArr;
 import org.noggit.JSONParser;
 import org.noggit.JSONWriter;
@@ -104,11 +104,12 @@ import org.noggit.ObjectBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.solr.common.params.CommonParams.NAME;
 /**
  * Command-line utility for working with Solr.
  */
 public class SolrCLI {
-   
+
   /**
    * Defines the interface to a Solr tool that can be run from this command-line app.
    */
@@ -139,6 +140,7 @@ public class SolrCLI {
 
       int toolExitStatus = 0;
       try {
+        setBasicAuth(cli);
         runImpl(cli);
       } catch (Exception exc) {
         // since this is a CLI, spare the user the stacktrace
@@ -153,6 +155,21 @@ public class SolrCLI {
       return toolExitStatus;
     }
 
+    private void setBasicAuth(CommandLine cli) throws Exception {
+      String basicauth = System.getProperty("basicauth", null);
+      if (basicauth != null) {
+        List<String> ss = StrUtils.splitSmart(basicauth, ':');
+        if (ss.size() != 2)
+          throw new Exception("Please provide 'basicauth' in the 'user:password' format");
+
+        HttpClientUtil.addRequestInterceptor((httpRequest, httpContext) -> {
+          String pair = ss.get(0) + ":" + ss.get(1);
+          byte[] encodedBytes = Base64.encodeBase64(pair.getBytes());
+          httpRequest.addHeader(new BasicHeader("Authorization", "Basic "+ new String(encodedBytes)));
+        });
+      }
+    }
+
     protected abstract void runImpl(CommandLine cli) throws Exception;
 
     // It's a little awkward putting this in ToolBase, but to re-use it in upconfig and create, _and_ have access

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/97e696dd/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
index 33565dd..00a43d7 100644
--- a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
@@ -16,7 +16,12 @@
  */
 package org.apache.solr.security;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
 import java.lang.invoke.MethodHandles;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -55,6 +60,7 @@ import org.apache.solr.common.util.ContentStreamBase;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.common.util.Utils;
+import org.apache.solr.util.SolrCLI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -129,39 +135,20 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
         "'set-user-role': {'harry':'admin'}\n" +
         "}";
 
-    httpPost = new HttpPost(baseUrl + authzPrefix);
-    setBasicAuthHeader(httpPost, "solr", "SolrRocks");
-    httpPost.setEntity(new ByteArrayEntity(command.getBytes(UTF_8)));
-    httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
-    r = cl.execute(httpPost);
-    assertEquals(200, r.getStatusLine().getStatusCode());
-    Utils.consumeFully(r.getEntity());
+    executeCommand(baseUrl + authzPrefix, cl,command, "solr", "SolrRocks");
 
     baseUrl = getRandomReplica(zkStateReader.getClusterState().getCollection(defaultCollName), random()).getStr(BASE_URL_PROP);
     verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/user-role/harry", NOT_NULL_PREDICATE, 20);
 
-
-    httpPost = new HttpPost(baseUrl + authzPrefix);
-    setBasicAuthHeader(httpPost, "harry", "HarryIsUberCool");
-    httpPost.setEntity(new ByteArrayEntity(Utils.toJSON(singletonMap("set-permission", Utils.makeMap
+    executeCommand(baseUrl + authzPrefix, cl, Utils.toJSONString(singletonMap("set-permission", Utils.makeMap
         ("collection", "x",
             "path", "/update/*",
-            "role", "dev")))));
-
-    httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
-    verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/user-role/harry", NOT_NULL_PREDICATE, 20);
-    r = cl.execute(httpPost);
-    assertEquals(200, r.getStatusLine().getStatusCode());
-    Utils.consumeFully(r.getEntity());
+            "role", "dev"))), "harry", "HarryIsUberCool" );
 
     verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/permissions[1]/collection", "x", 20);
 
-    httpPost = new HttpPost(baseUrl + authzPrefix);
-    setBasicAuthHeader(httpPost, "harry", "HarryIsUberCool");
-    httpPost.setEntity(new ByteArrayEntity(Utils.toJSON(singletonMap("set-permission", Utils.makeMap
-        ("name","collection-admin-edit", "role", "admin" )))));
-    r = cl.execute(httpPost);
-    Utils.consumeFully(r.getEntity());
+    executeCommand(baseUrl + authzPrefix, cl,Utils.toJSONString(singletonMap("set-permission", Utils.makeMap
+        ("name", "collection-admin-edit", "role", "admin"))), "harry", "HarryIsUberCool"  );
     verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/permissions[2]/name", "collection-admin-edit", 20);
 
     CollectionAdminRequest.Reload reload = new CollectionAdminRequest.Reload();
@@ -196,14 +183,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     }
 
     cloudSolrClient.setDefaultCollection(old);
-
-    httpPost = new HttpPost(baseUrl + authzPrefix);
-    setBasicAuthHeader(httpPost, "harry", "HarryIsUberCool");
-    httpPost.setEntity(new ByteArrayEntity("{set-permission : { name : update , role : admin}}".getBytes(UTF_8)));
-    httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
-    r = cl.execute(httpPost);
-    assertEquals(200,r.getStatusLine().getStatusCode());
-    Utils.consumeFully(r.getEntity());
+    executeCommand(baseUrl + authzPrefix, cl,"{set-permission : { name : update , role : admin}}", "harry", "HarryIsUberCool");
 
     SolrInputDocument doc = new SolrInputDocument();
     doc.setField("id","4");
@@ -212,10 +192,42 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     update.add(doc);
     update.setCommitWithin(100);
     cloudSolrClient.request(update);
-    
+
+
+    executeCommand(baseUrl + authzPrefix, cl, "{set-property : { blockUnknown: true}}", "harry", "HarryIsUberCool");
+    String[] toolArgs = new String[]{
+        "status", "-solr", baseUrl};
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    PrintStream stdoutSim = new PrintStream(baos, true, StandardCharsets.UTF_8.name());
+    SolrCLI.StatusTool tool = new SolrCLI.StatusTool(stdoutSim);
+    try {
+      System.setProperty("basicauth", "harry:HarryIsUberCool");
+      tool.runTool(SolrCLI.processCommandLineArgs(SolrCLI.joinCommonAndToolOptions(tool.getOptions()), toolArgs));
+      Map obj = (Map) Utils.fromJSON(new ByteArrayInputStream(baos.toByteArray()));
+      assertTrue(obj.containsKey("version"));
+      assertTrue(obj.containsKey("startTime"));
+      assertTrue(obj.containsKey("uptime"));
+      assertTrue(obj.containsKey("memory"));
+    } catch (Exception e) {
+      log.error("RunExampleTool failed due to: " + e +
+          "; stdout from tool prior to failure: " + baos.toString(StandardCharsets.UTF_8.name()));
+    }
+    executeCommand(baseUrl + authzPrefix, cl, "{set-property : { blockUnknown: false}}", "harry", "HarryIsUberCool");
     HttpClientUtil.close(cl);
   }
 
+  public static void executeCommand(String url, HttpClient cl, String payload, String user, String pwd) throws IOException {
+    HttpPost httpPost;
+    HttpResponse r;
+    httpPost = new HttpPost(url);
+    setBasicAuthHeader(httpPost, user, pwd);
+    httpPost.setEntity(new ByteArrayEntity(payload.getBytes(UTF_8)));
+    httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
+    r = cl.execute(httpPost);
+    assertEquals(200, r.getStatusLine().getStatusCode());
+    Utils.consumeFully(r.getEntity());
+  }
+
   public static void verifySecurityStatus(HttpClient cl, String url, String objPath, Object expected, int count) throws Exception {
     boolean success = false;
     String s = null;
@@ -262,12 +274,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     return l.isEmpty() ? null : l.get(0);
   }
 
-  static final Predicate NOT_NULL_PREDICATE = new Predicate() {
-    @Override
-    public boolean test(Object o) {
-      return o != null;
-    }
-  };
+  static final Predicate NOT_NULL_PREDICATE = o -> o != null;
 
   //the password is 'SolrRocks'
   //this could be generated everytime. But , then we will not know if there is any regression