mirror of https://github.com/apache/lucene.git
SOLR-7838: An authorizationPlugin interface where the access control rules are stored/managed in ZooKeeper
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1694553 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
db2ccb1d41
commit
d841e40a7e
|
@ -0,0 +1,449 @@
|
|||
package org.apache.solr.security;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.params.CollectionParams;
|
||||
import org.apache.solr.common.util.Utils;
|
||||
import org.apache.solr.util.CommandOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.apache.solr.handler.admin.SecurityConfHandler.getMapValue;
|
||||
import static org.apache.solr.common.params.CommonParams.NAME;
|
||||
import static org.apache.solr.common.util.Utils.getDeepCopy;
|
||||
|
||||
|
||||
public class RuleBasedAuthorizationPlugin implements AuthorizationPlugin, ConfigEditablePlugin {
|
||||
static final Logger log = LoggerFactory.getLogger(RuleBasedAuthorizationPlugin.class);
|
||||
|
||||
private final Map<String, Set<String>> usersVsRoles = new HashMap<>();
|
||||
private final Map<String, WildCardSupportMap> mapping = new HashMap<>();
|
||||
private final List<Permission> permissions = new ArrayList<>();
|
||||
|
||||
|
||||
private static class WildCardSupportMap extends HashMap<String, List<Permission>> {
|
||||
final Set<String> wildcardPrefixes = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public List<Permission> put(String key, List<Permission> value) {
|
||||
if (key != null && key.endsWith("/*")) {
|
||||
key = key.substring(0, key.length() - 2);
|
||||
wildcardPrefixes.add(key);
|
||||
}
|
||||
return super.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Permission> get(Object key) {
|
||||
List<Permission> result = super.get(key);
|
||||
if (key == null || result != null) return result;
|
||||
if (!wildcardPrefixes.isEmpty()) {
|
||||
for (String s : wildcardPrefixes) {
|
||||
if (key.toString().startsWith(s)) {
|
||||
List<Permission> l = super.get(s);
|
||||
if (l != null) {
|
||||
result = result == null ? new ArrayList<>() : new ArrayList<>(result);
|
||||
result.addAll(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationResponse authorize(AuthorizationContext context) {
|
||||
List<AuthorizationContext.CollectionRequest> collectionRequests = context.getCollectionRequests();
|
||||
if (collectionRequests != null) {
|
||||
for (AuthorizationContext.CollectionRequest collreq : collectionRequests) {
|
||||
//check permissions for each collection
|
||||
MatchStatus flag = checkCollPerm(mapping.get(collreq.collectionName), context);
|
||||
if (flag != MatchStatus.NO_PERMISSIONS_FOUND) return flag.rsp;
|
||||
}
|
||||
}
|
||||
//check global permissions.
|
||||
MatchStatus flag = checkCollPerm(mapping.get(null), context);
|
||||
return flag.rsp;
|
||||
}
|
||||
|
||||
private MatchStatus checkCollPerm(Map<String, List<Permission>> pathVsPerms,
|
||||
AuthorizationContext context) {
|
||||
if (pathVsPerms == null) return MatchStatus.NO_PERMISSIONS_FOUND;
|
||||
|
||||
String path = context.getResource();
|
||||
MatchStatus flag = checkPathPerm(pathVsPerms.get(path), context);
|
||||
if (flag != MatchStatus.NO_PERMISSIONS_FOUND) return flag;
|
||||
return checkPathPerm(pathVsPerms.get(null), context);
|
||||
}
|
||||
|
||||
private MatchStatus checkPathPerm(List<Permission> permissions, AuthorizationContext context) {
|
||||
if (permissions == null || permissions.isEmpty()) return MatchStatus.NO_PERMISSIONS_FOUND;
|
||||
Principal principal = context.getUserPrincipal();
|
||||
loopPermissions:
|
||||
for (int i = 0; i < permissions.size(); i++) {
|
||||
Permission permission = permissions.get(i);
|
||||
if (permission.method != null && !permission.method.contains(context.getHttpMethod())) {
|
||||
//this permissions HTTP method does not match this rule. try other rules
|
||||
continue;
|
||||
}
|
||||
if(permission.predicate != null){
|
||||
if(!permission.predicate.test(context)) 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (permission.role == null) {
|
||||
//no role is assigned permission.That means everybody is allowed to access
|
||||
return MatchStatus.PERMITTED;
|
||||
}
|
||||
if (principal == null) {
|
||||
//this resource needs a principal but the request has come without
|
||||
//any credential.
|
||||
return MatchStatus.USER_REQUIRED;
|
||||
}
|
||||
|
||||
for (String role : permission.role) {
|
||||
Set<String> userRoles = usersVsRoles.get(principal.getName());
|
||||
if (userRoles != null && userRoles.contains(role)) return MatchStatus.PERMITTED;
|
||||
}
|
||||
return MatchStatus.FORBIDDEN;
|
||||
}
|
||||
return MatchStatus.NO_PERMISSIONS_FOUND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Map<String, Object> initInfo) {
|
||||
mapping.put(null, new WildCardSupportMap());
|
||||
Map<String, Object> map = getMapValue(initInfo, "user-role");
|
||||
for (Object o : map.entrySet()) {
|
||||
Map.Entry e = (Map.Entry) o;
|
||||
String roleName = (String) e.getKey();
|
||||
usersVsRoles.put(roleName, readValueAsSet(map, roleName));
|
||||
}
|
||||
map = getMapValue(initInfo, "permissions");
|
||||
for (Object o : map.entrySet()) {
|
||||
Map.Entry e = (Map.Entry) o;
|
||||
Permission p;
|
||||
try {
|
||||
p = Permission.load((String) e.getKey(), (Map) e.getValue());
|
||||
} catch (Exception exp) {
|
||||
log.error("Invalid permission ", exp);
|
||||
continue;
|
||||
}
|
||||
permissions.add(p);
|
||||
add2Mapping(p);
|
||||
}
|
||||
}
|
||||
|
||||
private void add2Mapping(Permission permission) {
|
||||
//this is to do optimized lookup of permissions for a given collection/path
|
||||
for (String c : permission.collections) {
|
||||
WildCardSupportMap m = mapping.get(c);
|
||||
if (m == null) mapping.put(c, m = new WildCardSupportMap());
|
||||
for (String path : permission.path) {
|
||||
List<Permission> perms = m.get(path);
|
||||
if (perms == null) m.put(path, perms = new ArrayList<>());
|
||||
perms.add(permission);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* read a key value as a set. if the value is a single string ,
|
||||
* return a singleton set
|
||||
*
|
||||
* @param m the map from which to lookup
|
||||
* @param key the key with which to do lookup
|
||||
*/
|
||||
static Set<String> readValueAsSet(Map m, String key) {
|
||||
Set<String> result = new HashSet<>();
|
||||
Object val = m.get(key);
|
||||
if (val == null) return null;
|
||||
if (val instanceof Collection) {
|
||||
Collection list = (Collection) val;
|
||||
for (Object o : list) result.add(String.valueOf(o));
|
||||
} else if (val instanceof String) {
|
||||
result.add((String) val);
|
||||
} else {
|
||||
throw new RuntimeException("Bad value for : " + key);
|
||||
}
|
||||
return result.isEmpty() ? null : Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException { }
|
||||
|
||||
static class Permission {
|
||||
String name;
|
||||
Set<String> path, role, collections, method;
|
||||
Map<String, Object> params;
|
||||
Predicate<AuthorizationContext> predicate;
|
||||
|
||||
private Permission() {
|
||||
}
|
||||
|
||||
static Permission load(String name, Map m) {
|
||||
Permission p = new Permission();
|
||||
if (!m.containsKey("role")) throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "role not specified");
|
||||
p.role = readValueAsSet(m, "role");
|
||||
if (well_known_permissions.containsKey(name)) {
|
||||
HashSet<String> disAllowed = new HashSet<>(knownKeys);
|
||||
disAllowed.remove("role");
|
||||
for (String s : disAllowed) {
|
||||
if (m.containsKey(s))
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, s + " is not a valid key for the permission : " + name);
|
||||
}
|
||||
p.predicate = (Predicate<AuthorizationContext>) ((Map) well_known_permissions.get(name)).get(Predicate.class.getName());
|
||||
m = well_known_permissions.get(name);
|
||||
}
|
||||
p.name = name;
|
||||
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");
|
||||
return p;
|
||||
}
|
||||
|
||||
static final Set<String> knownKeys = ImmutableSet.of("collection", "role", "params", "path", "method");
|
||||
}
|
||||
|
||||
enum MatchStatus {
|
||||
USER_REQUIRED(AuthorizationResponse.PROMPT),
|
||||
NO_PERMISSIONS_FOUND(AuthorizationResponse.OK),
|
||||
PERMITTED(AuthorizationResponse.OK),
|
||||
FORBIDDEN(AuthorizationResponse.FORBIDDEN);
|
||||
|
||||
final AuthorizationResponse rsp;
|
||||
|
||||
MatchStatus(AuthorizationResponse rsp) {
|
||||
this.rsp = rsp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This checks for the defaults available other rules for the keys
|
||||
*/
|
||||
private static Set<String> readSetSmart(String permissionName, Map m, String key) {
|
||||
Set<String> set = readValueAsSet(m, key);
|
||||
if (set == null && well_known_permissions.containsKey(permissionName)) {
|
||||
set = readValueAsSet((Map) well_known_permissions.get(permissionName), key);
|
||||
}
|
||||
if ("method".equals(key)) {
|
||||
if (set != null) {
|
||||
for (String s : set) if (!HTTP_METHODS.contains(s)) return null;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
return set == null ? Collections.singleton(null) : set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> edit(Map<String, Object> latestConf, List<CommandOperation> commands) {
|
||||
for (CommandOperation op : commands) {
|
||||
OPERATION operation = null;
|
||||
for (OPERATION o : OPERATION.values()) {
|
||||
if (o.name.equals(op.name)) {
|
||||
operation = o;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (operation == null) {
|
||||
op.unknownOperation();
|
||||
return null;
|
||||
}
|
||||
latestConf = operation.edit(latestConf, op);
|
||||
if (latestConf == null) return null;
|
||||
|
||||
}
|
||||
return latestConf;
|
||||
}
|
||||
|
||||
enum OPERATION {
|
||||
SET_USER_ROLE("set-user-role") {
|
||||
@Override
|
||||
public Map<String, Object> edit(Map<String, Object> latestConf, CommandOperation op) {
|
||||
Map<String, Object> roleMap = getMapValue(latestConf, "user-role");
|
||||
Map<String, Object> map = op.getDataMap();
|
||||
if (op.hasError()) return null;
|
||||
for (Map.Entry<String, Object> e : map.entrySet()) {
|
||||
if (e.getValue() == null) {
|
||||
roleMap.remove(e.getKey());
|
||||
continue;
|
||||
}
|
||||
if (e.getValue() instanceof String || e.getValue() instanceof List) {
|
||||
roleMap.put(e.getKey(), e.getValue());
|
||||
} else {
|
||||
op.addError("Unexpected value ");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return latestConf;
|
||||
}
|
||||
},
|
||||
SET_PERMISSION("set-permission") {
|
||||
@Override
|
||||
public Map<String, Object> edit(Map<String, Object> latestConf, CommandOperation op) {
|
||||
String name = op.getStr(NAME);
|
||||
Map<String, Object> dataMap = op.getDataMap();
|
||||
if (op.hasError()) return null;
|
||||
dataMap = getDeepCopy(dataMap, 3);
|
||||
dataMap.remove(NAME);
|
||||
String before = (String) dataMap.remove("before");
|
||||
for (String key : dataMap.keySet()) {
|
||||
if (!Permission.knownKeys.contains(key)) op.addError("Unknown key, " + key);
|
||||
}
|
||||
try {
|
||||
Permission.load(name, dataMap);
|
||||
} catch (Exception e) {
|
||||
op.addError(e.getMessage());
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> permissions = getMapValue(latestConf, "permissions");
|
||||
if (before == null) {
|
||||
permissions.put(name, dataMap);
|
||||
} else {
|
||||
Map<String, Object> permissionsCopy = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, Object> e : permissions.entrySet()) {
|
||||
if (e.getKey().equals(before)) permissionsCopy.put(name, dataMap);
|
||||
permissionsCopy.put(e.getKey(), e.getValue());
|
||||
}
|
||||
if (!permissionsCopy.containsKey(name)) {
|
||||
op.addError("Invalid 'before' :" + before);
|
||||
return null;
|
||||
}
|
||||
latestConf.put("permissions", permissionsCopy);
|
||||
}
|
||||
|
||||
return latestConf;
|
||||
}
|
||||
},
|
||||
DELETE_PERMISSION("delete-permission") {
|
||||
@Override
|
||||
public Map<String, Object> edit(Map<String, Object> latestConf, CommandOperation op) {
|
||||
List<String> names = op.getStrs("");
|
||||
if (names == null || names.isEmpty()) {
|
||||
op.addError("Invalid command");
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> p = getMapValue(latestConf, "permissions");
|
||||
for (String s : names) {
|
||||
if (p.remove(s) == null) {
|
||||
op.addError("Unknown permission : " + s);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return latestConf;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract Map<String, Object> edit(Map<String, Object> latestConf, CommandOperation op);
|
||||
|
||||
public final String name;
|
||||
|
||||
OPERATION(String s) {
|
||||
this.name = s;
|
||||
}
|
||||
|
||||
public static OPERATION get(String name) {
|
||||
for (OPERATION o : values()) if (o.name.equals(name)) return o;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Set<String> HTTP_METHODS = ImmutableSet.of("GET", "POST", "DELETE", "PUT", "HEAD");
|
||||
|
||||
private static final Map<String, Map<String,Object>> well_known_permissions = (Map) Utils.fromJSONString(
|
||||
" { " +
|
||||
" security-edit :{" +
|
||||
" path:['/admin/authentication','/admin/authorization']," +
|
||||
" method:POST }," +
|
||||
" security-read :{" +
|
||||
" path:['/admin/authentication','/admin/authorization']," +
|
||||
" method:GET }," +
|
||||
" schema-edit :{" +
|
||||
" method:POST," +
|
||||
" path:'/schema/*'}," +
|
||||
" collection-admin-edit :{" +
|
||||
" path:'/admin/collections'}," +
|
||||
" collection-admin-read :{" +
|
||||
" path:'/admin/collections'}," +
|
||||
" schema-read :{" +
|
||||
" method:GET," +
|
||||
" path:'/schema/*'}," +
|
||||
" config-read :{" +
|
||||
" method:GET," +
|
||||
" path:'/config/*'}," +
|
||||
" update :{" +
|
||||
" path:'/update/*'}," +
|
||||
" read :{" +
|
||||
" path:['/update/*', '/get']}," +
|
||||
" config-edit:{" +
|
||||
" method:POST," +
|
||||
" path:'/config/*'}}");
|
||||
|
||||
static {
|
||||
((Map) well_known_permissions.get("collection-admin-edit")).put(Predicate.class.getName(), getPredicate(true));
|
||||
((Map) well_known_permissions.get("collection-admin-read")).put(Predicate.class.getName(), getPredicate(false));
|
||||
}
|
||||
|
||||
private static Predicate<AuthorizationContext> getPredicate(final boolean isEdit) {
|
||||
return new Predicate<AuthorizationContext>() {
|
||||
@Override
|
||||
public boolean test(AuthorizationContext context) {
|
||||
String action = context.getParams().get("action");
|
||||
if (action == null) return false;
|
||||
CollectionParams.CollectionAction collectionAction = CollectionParams.CollectionAction.get(action);
|
||||
if (collectionAction == null) return false;
|
||||
return isEdit ? collectionAction.isWrite : !collectionAction.isWrite;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Utils.toJSONString(well_known_permissions));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
package org.apache.solr.security;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.auth.BasicUserPrincipal;
|
||||
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;
|
||||
|
||||
public class TestRuleBasedAuthorizationPlugin extends SolrTestCaseJ4 {
|
||||
|
||||
public void testBasicPermissions() {
|
||||
int STATUS_OK = 200;
|
||||
int FORBIDDEN = 403;
|
||||
int PROMPT_FOR_CREDENTIALS = 401;
|
||||
|
||||
String jsonRules= "{" +
|
||||
" user-role : {" +
|
||||
" steve: [dev,user]," +
|
||||
" tim: [dev,admin]," +
|
||||
" joe: [user]," +
|
||||
" noble:[dev,user]" +
|
||||
" }," +
|
||||
" permissions : {" +
|
||||
" schema-edit :{" +
|
||||
" role:admin" +
|
||||
" }," +
|
||||
" collection-admin-read :{" +
|
||||
" role:null" +
|
||||
" }," +
|
||||
" collection-admin-edit :{" +
|
||||
" role:admin" +
|
||||
" }," +
|
||||
" 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",
|
||||
"collectionRequests", Collections.singletonList(new AuthorizationContext.CollectionRequest("mycoll")),
|
||||
"userPrincipal", new BasicUserPrincipal("tim"));
|
||||
AuthorizationContext context = new MockAuthorizationContext(values);
|
||||
|
||||
AuthorizationResponse authResp = plugin.authorize(context);
|
||||
assertEquals(STATUS_OK, 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("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("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 final Map<String,Object> values;
|
||||
|
||||
private MockAuthorizationContext(Map<String, Object> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SolrParams getParams() {
|
||||
return (SolrParams) values.get("params");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
return (Principal) values.get("userPrincipal");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHttpHeader(String header) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration getHeaderNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteAddr() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteHost() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CollectionRequest> getCollectionRequests() {
|
||||
return (List<CollectionRequest>) values.get("collectionRequests");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestType getRequestType() {
|
||||
return (RequestType) values.get("requestType");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHttpMethod() {
|
||||
return (String) values.get("httpMethod");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResource() {
|
||||
return (String) values.get("resource");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue