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/15 06:20:35 UTC
lucene-solr:branch_6x: SOLR-8048: bin/solr script should support
basic auth credentials provided in solr.in.sh
Repository: lucene-solr
Updated Branches:
refs/heads/branch_6x ba9221483 -> 62452f033
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/62452f03
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/62452f03
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/62452f03
Branch: refs/heads/branch_6x
Commit: 62452f033a3945d2812fa17ab07cfbe7248bb439
Parents: ba92214
Author: Noble Paul <no...@apache.org>
Authored: Wed Jun 15 11:50:23 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Wed Jun 15 11:50:23 2016 +0530
----------------------------------------------------------------------
solr/CHANGES.txt | 4 +-
.../src/java/org/apache/solr/util/SolrCLI.java | 20 ++++
.../solr/security/BasicAuthIntegrationTest.java | 115 +++++++++++--------
3 files changed, 89 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62452f03/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 570cee2..3f7c523 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -33,7 +33,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/62452f03/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 23186a7..eeae858 100644
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -54,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;
@@ -72,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;
@@ -94,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;
@@ -101,6 +104,7 @@ import org.noggit.ObjectBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.solr.common.params.CommonParams.NAME;
/**
@@ -138,6 +142,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
@@ -152,6 +157,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(UTF_8));
+ httpRequest.addHeader(new BasicHeader("Authorization", "Basic "+ new String(encodedBytes, UTF_8)));
+ });
+ }
+ }
+
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/62452f03/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 d24ef3e..89e4140 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;
@@ -36,6 +41,7 @@ import org.apache.http.util.EntityUtils;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.HttpClientUtil;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.GenericSolrRequest;
@@ -54,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;
@@ -79,7 +86,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
cloudSolrClient.setDefaultCollection(null);
NamedList<Object> rsp;
- HttpClient cl = cloudSolrClient.getLbClient().getHttpClient();
+ HttpClient cl = HttpClientUtil.createClient(null);
String baseUrl = getRandomReplica(zkStateReader.getClusterState().getCollection(defaultCollName), random()).getStr(BASE_URL_PROP);
verifySecurityStatus(cl, baseUrl + authcPrefix, "/errorMessages", null, 20);
zkClient.setData("/security.json", STD_CONF.replaceAll("'", "\"").getBytes(UTF_8), true);
@@ -95,6 +102,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
break;
}
}
+
assertTrue("No server found to restart , looking for : "+baseUrl , found);
String command = "{\n" +
@@ -119,6 +127,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
verifySecurityStatus(cl, baseUrl + authcPrefix, "authentication.enabled", "true", 20);
HttpResponse r = cl.execute(httpPost);
int statusCode = r.getStatusLine().getStatusCode();
+ Utils.consumeFully(r.getEntity());
assertEquals("proper_cred sent, but access denied", 200, statusCode);
baseUrl = getRandomReplica(zkStateReader.getClusterState().getCollection(defaultCollName), random()).getStr(BASE_URL_PROP);
@@ -127,55 +136,39 @@ 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());
+ 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());
+ "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);
-
+ 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();
reload.setCollectionName(defaultCollName);
- HttpSolrClient solrClient = getHttpSolrClient(baseUrl);
- try {
- rsp = solrClient.request(reload);
- fail("must have failed");
- } catch (HttpSolrClient.RemoteSolrException e) {
+ try (HttpSolrClient solrClient = getHttpSolrClient(baseUrl)) {
+ try {
+ rsp = solrClient.request(reload);
+ fail("must have failed");
+ } catch (HttpSolrClient.RemoteSolrException e) {
- }
- reload.setMethod(SolrRequest.METHOD.POST);
- try {
- rsp = solrClient.request(reload);
- fail("must have failed");
- } catch (HttpSolrClient.RemoteSolrException e) {
+ }
+ reload.setMethod(SolrRequest.METHOD.POST);
+ try {
+ rsp = solrClient.request(reload);
+ fail("must have failed");
+ } catch (HttpSolrClient.RemoteSolrException e) {
+ }
}
cloudSolrClient.request(new CollectionAdminRequest.Reload()
.setCollectionName(defaultCollName)
@@ -191,13 +184,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());
+ executeCommand(baseUrl + authzPrefix, cl,"{set-permission : { name : update , role : admin}}", "harry", "HarryIsUberCool");
SolrInputDocument doc = new SolrInputDocument();
doc.setField("id","4");
@@ -206,6 +193,40 @@ 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 {
@@ -214,9 +235,10 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
List<String> hierarchy = StrUtils.splitSmart(objPath, '/');
for (int i = 0; i < count; i++) {
HttpGet get = new HttpGet(url);
- s = EntityUtils.toString(cl.execute(get).getEntity());
+ HttpResponse rsp = cl.execute(get);
+ s = EntityUtils.toString(rsp.getEntity());
Map m = (Map) Utils.fromJSONString(s);
-
+ Utils.consumeFully(rsp.getEntity());
Object actual = Utils.getObjectByPath(m, true, hierarchy);
if (expected instanceof Predicate) {
Predicate predicate = (Predicate) expected;
@@ -253,12 +275,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