SOLR-8410: Add all read paths to 'read' permission in RuleBasedAuthorizationPlugin

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1720223 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Noble Paul 2015-12-15 19:00:51 +00:00
parent fc09a4729f
commit a1951a4469
3 changed files with 131 additions and 89 deletions

View File

@ -318,6 +318,8 @@ Other Changes
* SOLR-8414: AbstractDistribZkTestBase.verifyReplicaStatus could throw NPE (Christine Poerschke) * SOLR-8414: AbstractDistribZkTestBase.verifyReplicaStatus could throw NPE (Christine Poerschke)
* SOLR-8410: Add all read paths to 'read' permission in RuleBasedAuthorizationPlugin (noble)
================== 5.4.0 ================== ================== 5.4.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release

View File

@ -464,17 +464,17 @@ public class RuleBasedAuthorizationPlugin implements AuthorizationPlugin, Config
" update :{" + " update :{" +
" path:'/update/*'}," + " path:'/update/*'}," +
" read :{" + " read :{" +
" path:['/select', '/get']}," + " path:['/select', '/get','/browse','/tvrh','/terms','/clustering','/elevate', '/export','/spell','/clustering']}," +
" config-edit:{" + " config-edit:{" +
" method:POST," + " method:POST," +
" path:'/config/*'}}"); " path:'/config/*'}}");
static { static {
((Map) well_known_permissions.get("collection-admin-edit")).put(Predicate.class.getName(), getPredicate(true)); ((Map) well_known_permissions.get("collection-admin-edit")).put(Predicate.class.getName(), getCollectionActionPredicate(true));
((Map) well_known_permissions.get("collection-admin-read")).put(Predicate.class.getName(), getPredicate(false)); ((Map) well_known_permissions.get("collection-admin-read")).put(Predicate.class.getName(), getCollectionActionPredicate(false));
} }
private static Predicate<AuthorizationContext> getPredicate(final boolean isEdit) { private static Predicate<AuthorizationContext> getCollectionActionPredicate(final boolean isEdit) {
return new Predicate<AuthorizationContext>() { return new Predicate<AuthorizationContext>() {
@Override @Override
public boolean test(AuthorizationContext context) { public boolean test(AuthorizationContext context) {

View File

@ -17,11 +17,10 @@ package org.apache.solr.security;
* limitations under the License. * limitations under the License.
*/ */
import java.nio.charset.StandardCharsets;
import java.security.Principal; import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -30,98 +29,137 @@ import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.Utils; import org.apache.solr.common.util.Utils;
import org.apache.solr.security.AuthorizationContext.CollectionRequest;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.apache.solr.common.util.Utils.makeMap;
public class TestRuleBasedAuthorizationPlugin extends SolrTestCaseJ4 { public class TestRuleBasedAuthorizationPlugin extends SolrTestCaseJ4 {
String permissions = "{" +
" user-role : {" +
" steve: [dev,user]," +
" tim: [dev,admin]," +
" joe: [user]," +
" noble:[dev,user]" +
" }," +
" permissions : [" +
" {name:'schema-edit'," +
" role:admin}," +
" {name:'collection-admin-read'," +
" role:null}," +
" {name:collection-admin-edit ," +
" role:admin}," +
" {name:mycoll_update," +
" collection:mycoll," +
" path:'/update/*'," +
" role:[dev,admin]" +
" },{name:read , role:dev }]}";
public void testBasicPermissions() { public void testBasicPermissions() {
int STATUS_OK = 200; int STATUS_OK = 200;
int FORBIDDEN = 403; int FORBIDDEN = 403;
int PROMPT_FOR_CREDENTIALS = 401; int PROMPT_FOR_CREDENTIALS = 401;
String jsonRules= "{" + checkRules(makeMap("resource", "/update/json/docs",
" user-role : {" +
" steve: [dev,user]," +
" tim: [dev,admin]," +
" joe: [user]," +
" noble:[dev,user]" +
" }," +
" permissions : [" +
" {name:'schema-edit'," +
" role:admin}," +
" {name:'collection-admin-read'," +
" role:null}," +
" {name:collection-admin-edit ," +
" role:admin}," +
" {name:mycoll_update," +
" collection:mycoll," +
" path:'/update/*'," +
" role:[dev,admin]" +
" }]}" ;
Map initConfig = (Map) Utils.fromJSON(jsonRules.getBytes(StandardCharsets.UTF_8));
RuleBasedAuthorizationPlugin plugin= new RuleBasedAuthorizationPlugin();
plugin.init(initConfig);
Map<String, Object> values = Utils.makeMap(
"resource", "/update/json/docs",
"httpMethod", "POST", "httpMethod", "POST",
"collectionRequests", Collections.singletonList(new AuthorizationContext.CollectionRequest("mycoll")), "userPrincipal", "tim",
"userPrincipal", new BasicUserPrincipal("tim")); "collectionRequests", singletonList(new CollectionRequest("mycoll")) )
, STATUS_OK);
checkRules(makeMap("resource", "/update/json/docs",
"httpMethod", "POST",
"collectionRequests", singletonList(new CollectionRequest("mycoll")) )
, PROMPT_FOR_CREDENTIALS);
checkRules(makeMap("resource", "/schema",
"userPrincipal", "somebody",
"collectionRequests", singletonList(new CollectionRequest("mycoll")),
"httpMethod", "POST")
, FORBIDDEN);
checkRules(makeMap("resource", "/schema",
"userPrincipal", "somebody",
"collectionRequests", singletonList(new CollectionRequest("mycoll")),
"httpMethod", "GET")
, STATUS_OK);
checkRules(makeMap("resource", "/schema/fields",
"userPrincipal", "somebody",
"collectionRequests", singletonList(new CollectionRequest("mycoll")),
"httpMethod", "GET")
, STATUS_OK);
checkRules(makeMap("resource", "/schema",
"userPrincipal", "somebody",
"collectionRequests", singletonList(new CollectionRequest("mycoll")),
"httpMethod", "POST" )
, FORBIDDEN);
checkRules(makeMap("resource", "/admin/collections",
"userPrincipal", "tim",
"requestType", AuthorizationContext.RequestType.ADMIN,
"collectionRequests", null,
"httpMethod", "GET",
"params", new MapSolrParams(singletonMap("action", "LIST")))
, STATUS_OK);
checkRules(makeMap("resource", "/admin/collections",
"userPrincipal", null,
"requestType", AuthorizationContext.RequestType.ADMIN,
"collectionRequests", null,
"httpMethod", "GET",
"params", new MapSolrParams(singletonMap("action", "LIST")))
, STATUS_OK);
checkRules(makeMap("resource", "/admin/collections",
"userPrincipal", null,
"requestType", AuthorizationContext.RequestType.ADMIN,
"collectionRequests", null,
"params", new MapSolrParams(singletonMap("action", "CREATE")))
, PROMPT_FOR_CREDENTIALS);
checkRules(makeMap("resource", "/admin/collections",
"userPrincipal", null,
"requestType", AuthorizationContext.RequestType.ADMIN,
"collectionRequests", null,
"params", new MapSolrParams(singletonMap("action", "RELOAD")))
, PROMPT_FOR_CREDENTIALS);
checkRules(makeMap("resource", "/admin/collections",
"userPrincipal", "somebody",
"requestType", AuthorizationContext.RequestType.ADMIN,
"collectionRequests", null,
"params", new MapSolrParams(singletonMap("action", "CREATE")))
, FORBIDDEN);
checkRules(makeMap("resource", "/admin/collections",
"userPrincipal", "tim",
"requestType", AuthorizationContext.RequestType.ADMIN,
"collectionRequests", null,
"params", new MapSolrParams(singletonMap("action", "CREATE")))
, STATUS_OK);
checkRules(makeMap("resource", "/select",
"httpMethod", "GET",
"collectionRequests", singletonList(new CollectionRequest("mycoll")),
"userPrincipal", "joe")
, FORBIDDEN);
}
private void checkRules(Map<String, Object> values, int expected) {
AuthorizationContext context = new MockAuthorizationContext(values); AuthorizationContext context = new MockAuthorizationContext(values);
RuleBasedAuthorizationPlugin plugin = new RuleBasedAuthorizationPlugin();
plugin.init((Map) Utils.fromJSONString(permissions));
AuthorizationResponse authResp = plugin.authorize(context); AuthorizationResponse authResp = plugin.authorize(context);
assertEquals(STATUS_OK, authResp.statusCode); assertEquals(expected, authResp.statusCode);
values.remove("userPrincipal");
authResp = plugin.authorize(context);
assertEquals(PROMPT_FOR_CREDENTIALS,authResp.statusCode);
values.put("userPrincipal", new BasicUserPrincipal("somebody"));
authResp = plugin.authorize(context);
assertEquals(FORBIDDEN,authResp.statusCode);
values.put("httpMethod","GET");
values.put("resource","/schema");
authResp = plugin.authorize(context);
assertEquals(STATUS_OK,authResp.statusCode);
values.put("resource","/schema/fields");
authResp = plugin.authorize(context);
assertEquals(STATUS_OK,authResp.statusCode);
values.put("resource","/schema");
values.put("httpMethod","POST");
authResp = plugin.authorize(context);
assertEquals(FORBIDDEN,authResp.statusCode);
values.put("resource","/admin/collections");
values.put("requestType", AuthorizationContext.RequestType.ADMIN);
values.put("params", new MapSolrParams(Collections.singletonMap("action", "LIST")));
values.put("httpMethod","GET");
authResp = plugin.authorize(context);
assertEquals(STATUS_OK,authResp.statusCode);
values.remove("userPrincipal");
authResp = plugin.authorize(context);
assertEquals(STATUS_OK,authResp.statusCode);
values.put("params", new MapSolrParams(Collections.singletonMap("action", "CREATE")));
authResp = plugin.authorize(context);
assertEquals(PROMPT_FOR_CREDENTIALS, authResp.statusCode);
values.put("params", new MapSolrParams(Collections.singletonMap("action", "RELOAD")));
authResp = plugin.authorize(context);
assertEquals(PROMPT_FOR_CREDENTIALS, authResp.statusCode);
values.put("userPrincipal", new BasicUserPrincipal("somebody"));
authResp = plugin.authorize(context);
assertEquals(FORBIDDEN,authResp.statusCode);
values.put("userPrincipal", new BasicUserPrincipal("tim"));
authResp = plugin.authorize(context);
assertEquals(STATUS_OK,authResp.statusCode);
} }
private static class MockAuthorizationContext extends AuthorizationContext { private static class MockAuthorizationContext extends AuthorizationContext {
@ -133,12 +171,14 @@ public class TestRuleBasedAuthorizationPlugin extends SolrTestCaseJ4 {
@Override @Override
public SolrParams getParams() { public SolrParams getParams() {
return (SolrParams) values.get("params"); SolrParams params = (SolrParams) values.get("params");
return params == null ? new MapSolrParams(new HashMap<String, String>()) : params;
} }
@Override @Override
public Principal getUserPrincipal() { public Principal getUserPrincipal() {
return (Principal) values.get("userPrincipal"); Object userPrincipal = values.get("userPrincipal");
return userPrincipal == null ? null : new BasicUserPrincipal(String.valueOf(userPrincipal));
} }
@Override @Override