mirror of https://github.com/apache/lucene.git
SOLR-9049: RuleBasedAuthorizationPlugin supports regex in param values eg: "command" : "REGEX:(i?)create"
This commit is contained in:
parent
2fe824fd6e
commit
cf16f5d13d
|
@ -122,6 +122,8 @@ New Features
|
|||
* SOLR-5750: Add /admin/collections?action=BACKUP and RESTORE assuming access to a shared file system.
|
||||
(Varun Thacker, David Smiley)
|
||||
|
||||
* SOLR-9049: RuleBasedAuthorizationPlugin supports regex in param values eg: "command" : "REGEX:(i?)create" (noble)
|
||||
|
||||
Bug Fixes
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -3,15 +3,23 @@ package org.apache.solr.security;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.params.CommonParams;
|
||||
import org.apache.solr.common.util.Pair;
|
||||
|
||||
import static java.util.Collections.singleton;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.apache.solr.common.params.CommonParams.NAME;
|
||||
|
||||
/*
|
||||
|
@ -35,7 +43,7 @@ import static org.apache.solr.common.params.CommonParams.NAME;
|
|||
class Permission {
|
||||
String name;
|
||||
Set<String> path, role, collections, method;
|
||||
Map<String, Object> params;
|
||||
Map<String, Function<String[], Boolean>> params;
|
||||
PermissionNameProvider.Name wellknownName;
|
||||
|
||||
private Permission() {
|
||||
|
@ -63,7 +71,37 @@ class Permission {
|
|||
p.path = readSetSmart(name, m, "path");
|
||||
p.collections = readSetSmart(name, m, "collection");
|
||||
p.method = readSetSmart(name, m, "method");
|
||||
p.params = (Map<String, Object>) m.get("params");
|
||||
Map<String, Object> paramRules = (Map<String, Object>) m.get("params");
|
||||
if (paramRules != null) {
|
||||
p.params = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, Object> e : paramRules.entrySet()) {
|
||||
if (e.getValue() == null) {
|
||||
p.params.put(e.getKey(), (String[] val) -> val == null);
|
||||
} else {
|
||||
List<String> patternStrs = e.getValue() instanceof List ?
|
||||
(List) e.getValue() :
|
||||
singletonList(e.getValue().toString());
|
||||
List patterns = patternStrs.stream()
|
||||
.map(it -> it.startsWith("REGEX:") ?
|
||||
Pattern.compile(String.valueOf(it.substring("REGEX:".length())))
|
||||
: it)
|
||||
.collect(Collectors.toList());
|
||||
p.params.put(e.getKey(), val -> {
|
||||
if (val == null) return false;
|
||||
for (Object pattern : patterns) {
|
||||
for (String s : val) {
|
||||
if (pattern instanceof String) {
|
||||
if (pattern.equals(s)) return true;
|
||||
} else if (pattern instanceof Pattern) {
|
||||
if (((Pattern) pattern).matcher(s).find()) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,12 +26,14 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.solr.util.CommandOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyIterator;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static java.util.function.Function.identity;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
@ -129,12 +131,9 @@ public class RuleBasedAuthorizationPlugin implements AuthorizationPlugin, Config
|
|||
continue;
|
||||
}
|
||||
if (permission.params != null) {
|
||||
for (Map.Entry<String, Object> e : permission.params.entrySet()) {
|
||||
String paramVal = context.getParams().get(e.getKey());
|
||||
Object val = e.getValue();
|
||||
if (val instanceof List) {
|
||||
if (!((List) val).contains(paramVal)) continue loopPermissions;
|
||||
} else if (!Objects.equals(val, paramVal)) continue loopPermissions;
|
||||
for (Map.Entry<String, Function<String[], Boolean>> e : permission.params.entrySet()) {
|
||||
String[] paramVal = context.getParams().getParams(e.getKey());
|
||||
if(!e.getValue().apply(paramVal)) continue loopPermissions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.solr.security;
|
|||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.security.Principal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
|
@ -31,6 +32,7 @@ import org.apache.solr.SolrTestCaseJ4;
|
|||
import org.apache.solr.common.params.MapSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
import org.apache.solr.common.util.Utils;
|
||||
import org.apache.solr.handler.DumpRequestHandler;
|
||||
import org.apache.solr.handler.ReplicationHandler;
|
||||
import org.apache.solr.handler.SchemaHandler;
|
||||
import org.apache.solr.handler.UpdateRequestHandler;
|
||||
|
@ -251,6 +253,58 @@ public class TestRuleBasedAuthorizationPlugin extends SolrTestCaseJ4 {
|
|||
"params", new MapSolrParams(singletonMap("action", "CREATE")))
|
||||
,STATUS_OK );
|
||||
|
||||
rules = (Map) Utils.fromJSONString(permissions);
|
||||
List permissions = (List) rules.get("permissions");
|
||||
permissions.remove(permissions.size() -1);//remove the 'all' permission
|
||||
permissions.add(makeMap("name", "test-params", "role", "admin", "path", "/x", "params",
|
||||
makeMap("key", Arrays.asList("REGEX:(?i)val1", "VAL2"))));
|
||||
this.permissions = Utils.toJSONString(rules);
|
||||
|
||||
checkRules(makeMap("resource", "/x",
|
||||
"userPrincipal", null,
|
||||
"requestType", RequestType.UNKNOWN,
|
||||
"collectionRequests", "go",
|
||||
"handler", new DumpRequestHandler(),
|
||||
"params", new MapSolrParams(singletonMap("key", "VAL1")))
|
||||
, PROMPT_FOR_CREDENTIALS);
|
||||
|
||||
checkRules(makeMap("resource", "/x",
|
||||
"userPrincipal", null,
|
||||
"requestType", RequestType.UNKNOWN,
|
||||
"collectionRequests", "go",
|
||||
"handler", new DumpRequestHandler(),
|
||||
"params", new MapSolrParams(singletonMap("key", "Val1")))
|
||||
, PROMPT_FOR_CREDENTIALS);
|
||||
|
||||
checkRules(makeMap("resource", "/x",
|
||||
"userPrincipal", null,
|
||||
"requestType", RequestType.UNKNOWN,
|
||||
"collectionRequests", "go",
|
||||
"handler", new DumpRequestHandler(),
|
||||
"params", new MapSolrParams(singletonMap("key", "Val1")))
|
||||
, PROMPT_FOR_CREDENTIALS);
|
||||
checkRules(makeMap("resource", "/x",
|
||||
"userPrincipal", "joe",
|
||||
"requestType", RequestType.UNKNOWN,
|
||||
"collectionRequests", "go",
|
||||
"handler", new DumpRequestHandler(),
|
||||
"params", new MapSolrParams(singletonMap("key", "Val1")))
|
||||
, FORBIDDEN);
|
||||
|
||||
checkRules(makeMap("resource", "/x",
|
||||
"userPrincipal", "joe",
|
||||
"requestType", RequestType.UNKNOWN,
|
||||
"collectionRequests", "go",
|
||||
"handler", new DumpRequestHandler(),
|
||||
"params", new MapSolrParams(singletonMap("key", "Val2")))
|
||||
, STATUS_OK);
|
||||
checkRules(makeMap("resource", "/x",
|
||||
"userPrincipal", "joe",
|
||||
"requestType", RequestType.UNKNOWN,
|
||||
"collectionRequests", "go",
|
||||
"handler", new DumpRequestHandler(),
|
||||
"params", new MapSolrParams(singletonMap("key", "VAL2")))
|
||||
, FORBIDDEN);
|
||||
}
|
||||
|
||||
public void testEditRules() throws IOException {
|
||||
|
|
Loading…
Reference in New Issue