diff --git a/README.md b/README.md index a3d3d9f..f3dee59 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ mvn clean install | `-p, --policy` | The path of the policy file or policy text | y | Please wrap it with `""` and separate each line with `\|` | | `-e, --enforce` | Check permissions | n | Please wrap it with `""` | | `-ex, --enforceEx` | Check permissions and get which policy it is | n | Please wrap it with `""` | +| `-AF, --addFuntion` | Add custom funtion | n | Please wrap it with `""` and separate each line with `\|` | | `-ap, --addPolicy` | Add a policy rule to the policy file | n | Please wrap it with `""` | | `-rp, --removePolicy` | Remove a policy rule from the policy file | n | Please wrap it with `""` | @@ -32,32 +33,32 @@ mvn clean install - Check whether Alice has read permission on data1 ```shell - java -jar target/casbin-java-cli.jar -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -e "alice, data1, read" + ./casbin enforce -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" "alice" "data1" "read" ``` - > Allow + > {"allow":true,"explain":null} ```shell - java -jar target/casbin-java-cli.jar -m "[request_definition]|r = sub, obj, act|[policy_definition]|p = sub, obj, act|[role_definition]|g = _, _|[policy_effect]|e = some(where (p.eft == allow))|[matchers]|m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act" -p "p, alice, data1, read|p, bob, data2, write|p, data2_admin, data2, read|p, data2_admin, data2, write|g, alice, data2_admin" -e "alice, data1, read" + ./casbin enforce -m "[request_definition]|r = sub, obj, act|[policy_definition]|p = sub, obj, act|[role_definition]|g = _, _|[policy_effect]|e = some(where (p.eft == allow))|[matchers]|m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act" -p "p, alice, data1, read|p, bob, data2, write|p, data2_admin, data2, read|p, data2_admin, data2, write|g, alice, data2_admin" "alice" "data1" "read" ``` - > Allow + > {"allow":true,"explain":null} - Check whether Alice has write permission for data2. If so, display the effective policy. ```shell - java -jar target/casbin-java-cli.jar -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -ex "alice, data2, write" + ./casbin enforceEx -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" "alice" "data2" "write" ``` - > true Reason: [alice, data2, write] + > {"allow":true,"explain":["data2_admin","data2","write"]} - Add a policy to the policy file ```shell - java -jar target/casbin-java-cli.jar -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -ap "alice, data2, write" + ./casbin addPolicy -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" "alice" "data2" "write" ``` - > Add Success + > {"allow":true,"explain":null} - Delete a policy from the policy file ```shell - java -jar target/casbin-java-cli.jar -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -rp "alice,data1,read" + ./casbin removePolicy -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" "alice" "data2" "write" ``` - > Remove Success + > {"allow":true,"explain":null} diff --git a/casbin b/casbin new file mode 100755 index 0000000..00c2157 --- /dev/null +++ b/casbin @@ -0,0 +1,2 @@ +#!/bin/sh +java -jar target/casbin-java-cli.jar "$@" \ No newline at end of file diff --git a/casbin.cmd b/casbin.cmd new file mode 100644 index 0000000..70124d9 --- /dev/null +++ b/casbin.cmd @@ -0,0 +1,5 @@ +@echo off +setlocal +set JAR_PATH=target\casbin-java-cli.jar +java -jar "%JAR_PATH%" %* +endlocal \ No newline at end of file diff --git a/examples/abac_rule_with_domains_policy.csv b/examples/abac_rule_with_domains_policy.csv index 095bebf..beb1ef8 100644 --- a/examples/abac_rule_with_domains_policy.csv +++ b/examples/abac_rule_with_domains_policy.csv @@ -3,4 +3,4 @@ p, r.domain == 'domain1', admin, domain1, data1, write p, r.domain == 'domain2', admin, domain2, data2, read p, r.domain == 'domain2', admin, domain2, data2, write g, alice, admin, domain1 -g, bob, admin, domain2 +g, bob, admin, domain2 \ No newline at end of file diff --git a/examples/basic_model.conf b/examples/basic_model.conf new file mode 100644 index 0000000..dc6da81 --- /dev/null +++ b/examples/basic_model.conf @@ -0,0 +1,11 @@ +[request_definition] +r = sub, obj, act + +[policy_definition] +p = sub, obj, act + +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = r.sub == p.sub && r.obj == p.obj && r.act == p.act \ No newline at end of file diff --git a/examples/basic_policy.csv b/examples/basic_policy.csv new file mode 100644 index 0000000..57aaa97 --- /dev/null +++ b/examples/basic_policy.csv @@ -0,0 +1,2 @@ +p, alice, data1, read +p, bob, data2, write \ No newline at end of file diff --git a/examples/keymatch_policy.csv b/examples/keymatch_policy.csv new file mode 100644 index 0000000..39c5966 --- /dev/null +++ b/examples/keymatch_policy.csv @@ -0,0 +1,5 @@ +p, alice, /alice_data/*, GET +p, alice, /alice_data/resource1, POST +p, bob, /alice_data/resource2, GET +p, bob, /bob_data/*, POST +p, cathy, /cathy_data, (GET)|(POST) \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0dad7f2..c1c7c7f 100644 --- a/pom.xml +++ b/pom.xml @@ -8,12 +8,6 @@ jar - - - - - - UTF-8 diff --git a/src/main/java/org/casbin/Client.java b/src/main/java/org/casbin/Client.java index d91d53e..54773a6 100644 --- a/src/main/java/org/casbin/Client.java +++ b/src/main/java/org/casbin/Client.java @@ -1,89 +1,80 @@ package org.casbin; + import org.apache.commons.cli.*; -import org.casbin.jcasbin.exception.CasbinEffectorException; -import org.casbin.jcasbin.main.EnforceResult; +import org.casbin.generate.DynamicClassGenerator; +import org.casbin.jcasbin.util.function.CustomFunction; +import org.casbin.util.Util; +import java.util.*; -public class Client { - private static void configureOptions(Options options) { - Option[] cliOptions = { - addOption("m", "model", true, "the path of the model file"), - addOption("p", "policy", true, "the path of the policy file"), - addOption("e", "enforce", true, "enforce"), - addOption("ex", "enforceEx", true, "enforceEx"), - addOption("ap", "addPolicy", true, "Add a policy rule to the storage"), - addOption("rp", "removePolicy", true, "Remove a policy rule from the storage") - }; - for (Option option : cliOptions) { - options.addOption(option); - } - } - private static Option addOption(String shortOpt, String longOpt, boolean hasArg, String description) { - return new Option(shortOpt, longOpt, hasArg, description); - } - public static Object run(String[] args) throws ParseException { - Options options = new Options(); - configureOptions(options); +public class Client { - CommandLineParser parser = new DefaultParser(); - CommandLine cmd = parser.parse(options, args); + public static String run(String... args) { + String result = ""; - String model = cmd.getOptionValue("model"); - String policy = cmd.getOptionValue("policy"); - NewEnforcer enforcer = null; try { - enforcer = new NewEnforcer(model, policy); - } catch (NullPointerException | CasbinEffectorException | UnsupportedOperationException e) { - System.out.println("unsupported effect:" + e.getMessage()); - System.exit(0); - } catch (Exception e) { - System.out.println(e.getMessage()); - System.exit(0); - } + if(args == null || args.length == 0) { + printUsageMessageAndExit(""); + } - try { - if(cmd.hasOption("enforce")) { - String enforceArgs = cmd.getOptionValue("enforce").replace(" ",""); - boolean result = enforcer.enforce(enforceArgs.split(",")); - System.out.println(result ? "Allow" : "Ban"); - return result; - } else if (cmd.hasOption("enforceEx")) { - String enforceArgs = cmd.getOptionValue("enforceEx").replace(" ",""); - EnforceResult enforceResult = enforcer.enforceEx(enforceArgs.split(",")); - boolean allow = enforceResult.isAllow(); - if(allow) { - System.out.printf("%s Reason: %s", allow, enforceResult.getExplain()); - } else { - System.out.println(allow); - } - return allow; - }else if (cmd.hasOption("addPolicy")){ - String policyArgs = cmd.getOptionValue("addPolicy").replace(" ",""); - boolean result = enforcer.addPolicy(policyArgs.split(",")); - System.out.println(result ? "Add Success" : "Add Failed"); - enforcer.savePolicy(); - return result; - }else if (cmd.hasOption("removePolicy")){ - String policyArgs = cmd.getOptionValue("removePolicy").replace(" ",""); - boolean result = enforcer.removePolicy(policyArgs.split(",")); - System.out.println(result ? "Remove Success" : "Remove Failed"); - enforcer.savePolicy(); - return result; - }else { - System.out.println("Command Error"); - return null; + String commandName = args[0]; + + CommandLine cmd = getCmd(Arrays.copyOfRange(args, 1, args.length)); + String model = cmd.getOptionValue("model"); + String policy = cmd.getOptionValue("policy"); + NewEnforcer enforcer = new NewEnforcer(model, policy); + + + if(cmd.hasOption("AF")) { + String codes = cmd.getOptionValue("AF"); + String methodName = Util.getMethodName(codes); + CustomFunction customFunction = DynamicClassGenerator.generateClass(methodName, codes); + enforcer.addFunction(methodName, customFunction); } + CommandExecutor commandExecutor = new CommandExecutor(enforcer, commandName, cmd.getArgs()); + Object o = commandExecutor.outputResult(); + System.out.println(o); + return o.toString(); + } catch (Exception e) { - System.out.println("unsupported effect:" + e.getMessage()); - System.exit(0); + e.printStackTrace(); + System.exit(1); } - return null; + return result; + } + + + private static void printUsageMessageAndExit(String commandName) throws Exception { + if (commandName.isEmpty()) { + System.out.println("Error: " + commandName + " not recognised"); + } +// new HelpCommand().run(); + System.exit(1); } public static void main(String[] args) throws ParseException { - Client cli = new Client(); - Object run = run(args); + run(args); + } + + private static CommandLine getCmd(String[] args) throws ParseException { + Options options = new Options(); + + Option option = new Option("AF", "AddFunction", true, "add function"); + option.setArgs(1); + option.setRequired(false); + options.addOption(option); + + option = new Option("m", "model", true, "the path of the model file or model text"); + option.hasArg(); + options.addOption(option); + + option = new Option("p", "policy", true, "the path of the policy file or policy text"); + option.hasArg(); + options.addOption(option); + + CommandLineParser parser = new DefaultParser(); + return parser.parse(options, args); } } diff --git a/src/main/java/org/casbin/CommandExecutor.java b/src/main/java/org/casbin/CommandExecutor.java new file mode 100644 index 0000000..fa5bd81 --- /dev/null +++ b/src/main/java/org/casbin/CommandExecutor.java @@ -0,0 +1,94 @@ +package org.casbin; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.casbin.jcasbin.main.EnforceResult; +import org.casbin.jcasbin.main.Enforcer; +import org.casbin.resp.ResponseBody; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.*; + +public class CommandExecutor { + + private NewEnforcer enforcer; + + private String inputMethodName; + + private String[] inputVal; + + public CommandExecutor(NewEnforcer enforcer, String inputMethodName, String[] inputVal) { + this.enforcer = enforcer; + this.inputMethodName = inputMethodName; + this.inputVal = inputVal; + } + + public String outputResult() throws InvocationTargetException, IllegalAccessException, JsonProcessingException { + Class clazz = enforcer.getClass(); + Method[] methods = clazz.getMethods(); + + ResponseBody responseBody = new ResponseBody(null, null); + for (Method method : methods) { + String methodName = method.getName(); + if(methodName.equals(inputMethodName)) { + Type[] genericParameterTypes = method.getGenericParameterTypes(); + Object[] convertedParams = new Object[genericParameterTypes.length]; + Class returnType = method.getReturnType(); + + if(genericParameterTypes.length == 3 && genericParameterTypes[0] == String.class && genericParameterTypes[1].getTypeName().equals("java.util.List") && genericParameterTypes[2].getTypeName().equals("java.util.List")) { + convertedParams[0] = inputVal[0]; + convertedParams[1] = Arrays.asList(inputVal[1].split(",")); + convertedParams[2] = Arrays.asList(inputVal[2].split(",")); + } else if(genericParameterTypes.length == 2 && genericParameterTypes[0].getTypeName().equals("java.util.List") && genericParameterTypes[1].getTypeName().equals("java.util.List")) { + convertedParams[0] = Arrays.asList(inputVal[0].split(",")); + convertedParams[1] = Arrays.asList(inputVal[1].split(",")); + } else { + for (int i = 0; i < genericParameterTypes.length; i++) { + if(genericParameterTypes[i] == int.class) { + convertedParams[i] = Integer.valueOf(inputVal[i]); + } else if(genericParameterTypes[i] == String.class) { + convertedParams[i] = inputVal[i]; + } else if(genericParameterTypes[i] == Object[].class || genericParameterTypes[i] == String[].class) { + convertedParams[i] = Arrays.copyOfRange(inputVal, i, inputVal.length); + } else if (genericParameterTypes[i] == String[][].class) { + String[] arr = Arrays.copyOfRange(inputVal, i, inputVal.length); + String[][] res = new String[arr.length][]; + for (int i1 = 0; i1 < res.length; i1++) { + res[i1] = arr[i1].split(","); + } + convertedParams[i] = res; + } else if (genericParameterTypes[i].getTypeName().equals("java.util.List")) { + String[] arr = Arrays.copyOfRange(inputVal, i, inputVal.length); + convertedParams[i] = Arrays.asList(arr); + } else if (genericParameterTypes[i].getTypeName().equals("java.util.List>")) { + List> res = new ArrayList<>(); + String[] arr = Arrays.copyOfRange(inputVal, i, inputVal.length); + for (String s : arr) { + List ans = new ArrayList<>(); + Collections.addAll(ans, s.split(",")); + res.add(ans); + } + convertedParams[i] = res; + } + } + } + + Object invoke = method.invoke(enforcer, convertedParams); + if(returnType == boolean.class) { + responseBody.setAllow((Boolean) invoke); + } else if (returnType == List.class) { + responseBody.setExplain((ArrayList) invoke); + } else if (returnType == EnforceResult.class) { + responseBody.setAllow(((EnforceResult) invoke).isAllow()); + responseBody.setExplain((ArrayList) ((EnforceResult) invoke).getExplain()); + } + enforcer.savePolicy(); + break; + } + } + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(responseBody); + } +} diff --git a/src/main/java/org/casbin/NewEnforcer.java b/src/main/java/org/casbin/NewEnforcer.java index ebb94e9..31736f1 100644 --- a/src/main/java/org/casbin/NewEnforcer.java +++ b/src/main/java/org/casbin/NewEnforcer.java @@ -1,6 +1,7 @@ package org.casbin; import org.casbin.jcasbin.main.Enforcer; +import org.casbin.jcasbin.util.function.CustomFunction; import java.io.BufferedWriter; import java.io.File; diff --git a/src/main/java/org/casbin/generate/CustomClassLoader.java b/src/main/java/org/casbin/generate/CustomClassLoader.java new file mode 100644 index 0000000..f21f21d --- /dev/null +++ b/src/main/java/org/casbin/generate/CustomClassLoader.java @@ -0,0 +1,7 @@ +package org.casbin.generate; + +public class CustomClassLoader extends ClassLoader { + public Class defineClass(String name, byte[] b) { + return super.defineClass(name, b, 0, b.length); + } +} diff --git a/src/main/java/org/casbin/generate/DynamicClassGenerator.java b/src/main/java/org/casbin/generate/DynamicClassGenerator.java new file mode 100644 index 0000000..8f18670 --- /dev/null +++ b/src/main/java/org/casbin/generate/DynamicClassGenerator.java @@ -0,0 +1,126 @@ +package org.casbin.generate; + + +import org.casbin.jcasbin.util.function.CustomFunction; + +import javax.tools.*; +import java.io.*; +import java.net.URI; +import java.util.*; + + +import static org.casbin.util.Util.*; + +public class DynamicClassGenerator { + + public static CustomFunction generateClass(String methodName, String methodCodes) { + String className = "CustomFunc"; + int argsNum = getArgsNum(methodCodes); + StringBuilder sb = new StringBuilder(); + + String codeSnippetOne = "import com.googlecode.aviator.runtime.type.AviatorBoolean;\n" + + "import com.googlecode.aviator.runtime.type.AviatorObject;\n" + + "import org.casbin.jcasbin.util.function.CustomFunction;\n" + + "import java.util.Map;\n" + + "import java.util.regex.Pattern;" + + "\n" + + " public class " + className + " extends CustomFunction {\n" + + " @Override\n" + + " public AviatorObject call(Map env, "; + + sb.append(codeSnippetOne); + for (int i = 0; i < argsNum; i++) { + if(i == argsNum - 1) { + sb.append("AviatorObject arg").append(i + 1); + } else { + sb.append("AviatorObject arg").append(i + 1).append(","); + } + } + sb.append(") {"); + + for (int i = 0; i < argsNum; i++) { + sb.append("String obj").append(i + 1).append("=getStringValue(arg").append(i + 1).append(", env);\n"); + } + + StringBuilder args = new StringBuilder(); + for (int i = 0; i < argsNum; i++) { + if(i == argsNum - 1) { + args.append("obj").append(i + 1); + } else { + args.append("obj").append(i + 1).append(","); + } + + } + sb.append("return AviatorBoolean.valueOf(").append(methodName).append("(").append(args).append("));}\n"); + sb.append("@Override\n" + "public String getName() {\n" + " return \"").append(methodName).append("\";\n").append("}\n"); + + sb.append("public static final String getStringValue(final AviatorObject arg,\n" + + " final Map env) {\n" + + " String result = null;\n" + + " final Object value = arg.getValue(env);\n" + + " if (value instanceof Character) {\n" + + " result = value.toString();\n" + + " } else {\n" + + " result = (String) value;\n" + + " }\n" + + " return result;\n" + + " }\n"); + + sb.append(methodCodes); + sb.append("}"); + try { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + + InMemoryJavaFileManager customFileManager = new InMemoryJavaFileManager(fileManager); + + JavaFileObject sourceFile = new JavaSourceFromString(className, sb.toString()); + Iterable compilationUnits = Collections.singletonList(sourceFile); + + JavaCompiler.CompilationTask task = compiler.getTask(null, customFileManager, diagnostics, null, null, compilationUnits); + boolean success = task.call(); + if(success) { + byte[] classBytes = customFileManager.getClassBytes(className); + if(classBytes != null) { + CustomClassLoader loader = new CustomClassLoader(); + Class loadedClass = loader.defineClass(className, classBytes); + CustomFunction customFunction = (CustomFunction) loadedClass.getDeclaredConstructor().newInstance(); + return customFunction; + } + } + return null; + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + static class InMemoryJavaFileManager extends ForwardingJavaFileManager { + private final Map classBytesMap = new HashMap<>(); + + InMemoryJavaFileManager(StandardJavaFileManager fileManager) { + super(fileManager); + } + + @Override + public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + classBytesMap.put(className, outputStream); + return new SimpleJavaFileObject(URI.create("string:///" + className.replace('.', '/') + kind.extension), kind) { + @Override + public OutputStream openOutputStream() { + return outputStream; + } + }; + } + + public byte[] getClassBytes(String className) { + ByteArrayOutputStream outputStream = classBytesMap.get(className); + return outputStream != null ? outputStream.toByteArray() : null; + } + } +} + + diff --git a/src/main/java/org/casbin/generate/JavaSourceFromString.java b/src/main/java/org/casbin/generate/JavaSourceFromString.java new file mode 100644 index 0000000..cc5b327 --- /dev/null +++ b/src/main/java/org/casbin/generate/JavaSourceFromString.java @@ -0,0 +1,18 @@ +package org.casbin.generate; + +import javax.tools.SimpleJavaFileObject; +import java.net.URI; + +public class JavaSourceFromString extends SimpleJavaFileObject { + private final String code; + + JavaSourceFromString(String name, String code) { + super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); + this.code = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return code; + } +} \ No newline at end of file diff --git a/src/main/java/org/casbin/resp/ResponseBody.java b/src/main/java/org/casbin/resp/ResponseBody.java new file mode 100644 index 0000000..a9c3a8e --- /dev/null +++ b/src/main/java/org/casbin/resp/ResponseBody.java @@ -0,0 +1,43 @@ +package org.casbin.resp; + +import java.util.ArrayList; + +public class ResponseBody { + + private Boolean allow; + + private ArrayList explain; + + public ResponseBody() { + + } + + public ResponseBody(Boolean allow, ArrayList explain) { + this.allow = allow; + this.explain = explain; + } + + public Boolean getAllow() { + return allow; + } + + public void setAllow(Boolean allow) { + this.allow = allow; + } + + public ArrayList getExplain() { + return explain; + } + + public void setExplain(ArrayList explain) { + this.explain = explain; + } + + @Override + public String toString() { + return "ResponseBody{" + + "allow=" + allow + + ", explain=" + explain + + '}'; + } +} diff --git a/src/main/java/org/casbin/util/Util.java b/src/main/java/org/casbin/util/Util.java new file mode 100644 index 0000000..56f0ce4 --- /dev/null +++ b/src/main/java/org/casbin/util/Util.java @@ -0,0 +1,29 @@ +package org.casbin.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Util { + + public static String getMethodName(String methodCodes) { + String regex = "\\b(\\w+)\\s*\\("; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(methodCodes); + return matcher.find() ? matcher.group(1) : null; + } + + public static int getArgsNum(String methodCodes) { + String regex = "\\(([^)]*)\\)"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(methodCodes); + if (matcher.find()) { + String args = matcher.group(1); + String[] argList = args.split(","); + return argList.length; + } + return 0; + } +} diff --git a/src/test/java/org/casbin/ClientTest.java b/src/test/java/org/casbin/ClientTest.java index f275b66..4557a30 100644 --- a/src/test/java/org/casbin/ClientTest.java +++ b/src/test/java/org/casbin/ClientTest.java @@ -1,58 +1,44 @@ package org.casbin; import org.apache.commons.cli.ParseException; -import org.casbin.jcasbin.main.Enforcer; import org.junit.Test; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; public class ClientTest { @Test public void testRBAC() throws ParseException { - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","alice,data1,read"}), true); - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","alice,data1,write"}), false); - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","alice,data2,read"}), true); - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","alice,data2,write"}), true); - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","bob,data1,read"}), false); - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","bob,data1,write"}), false); - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","bob,data2,read"}), false); - assertEquals(Client.run(new String[]{"-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv","-e","bob,data2,write"}), true); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data1", "write"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data2", "read"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data2", "write"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "bob", "data1", "read"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "bob", "data1", "write"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "bob", "data2", "read"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "bob", "data2", "write"}), "{\"allow\":true,\"explain\":null}"); } @Test public void testABAC() throws ParseException { - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","alice,domain1,data1,read"}), true); - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","alice,domain1,data1,write"}), true); - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","alice,domain2,data1,read"}), false); - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","alice,domain2,data1,write"}), false); - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","bob,domain1,data2,read"}), false); - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","bob,domain1,data2,write"}), false); - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","bob,domain2,data2,read"}), true); - assertEquals(Client.run(new String[]{"-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","bob,domain2,data2,read"}), true); - } + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "alice", "domain1", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "alice","domain1", "data1", "write"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "alice", "domain2", "data1", "read"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "alice", "domain2", "data1", "write"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "bob", "domain1", "data2", "read"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "bob", "domain1", "data2", "write"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "bob", "domain2", "data2", "read"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "bob", "domain2", "data2", "read"}), "{\"allow\":true,\"explain\":null}"); - @Test - public void testAddPolicy() throws ParseException { - String modelPath = "examples/rbac_model.conf"; - String policyPath = "examples/rbac_policy.csv"; - Enforcer enforcer = new Enforcer(modelPath, policyPath); - String policy = "aliceTest,data,read"; - assertEquals(Client.run(new String[]{"-m",modelPath,"-p",policyPath,"-ap",policy}), true); - enforcer.removePolicy(policy.split(",")); - enforcer.savePolicy(); } @Test - public void testRemovePolicy() throws ParseException { - String modelPath = "examples/rbac_model.conf"; - String policyPath = "examples/rbac_policy.csv"; - Enforcer enforcer = new Enforcer(modelPath, policyPath); - String policy = "alice,data1,read"; - assertEquals(Client.run(new String[]{"-m",modelPath,"-p",policyPath,"-rp",policy}), true); - enforcer.addPolicy(policy.split(",")); - enforcer.savePolicy(); + public void testAddAndRemovePolicy() throws ParseException { + assertEquals(Client.run(new String[]{"addPolicy","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "alice", "domain1", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"removePolicy","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv", "alice", "domain1", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addPolicy","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data2", "write"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"removePolicy","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data2", "write"}), "{\"allow\":true,\"explain\":null}"); } @Test @@ -76,8 +62,177 @@ public void testParseString() { "p, data2_admin, data2, read\n" + "p, data2_admin, data2, write\n" + "g, alice, data2_admin"; - NewEnforcer enforce = new NewEnforcer(model, policy); - assertTrue(enforce.enforce("alice", "data1", "read")); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", policy, "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + } + + @Test + public void testCustomFunction() throws ParseException { + String methodName = "keyMatchTest"; + String model = "[request_definition]\n" + + "r = sub, obj, act\n" + + "\n" + + "[policy_definition]\n" + + "p = sub, obj, act\n" + + "\n" + + "[policy_effect]\n" + + "e = some(where (p.eft == allow))\n" + + "\n" + + "[matchers]\n" + + "m = r.sub == p.sub && "+methodName+"(r.obj, p.obj) && regexMatch(r.act, p.act)\n"; + String func = "public static boolean "+methodName+"(String key1, String key2) {\n" + + " int i = key2.indexOf('*');\n" + + " if (i == -1) {\n" + + " return key1.equals(key2);\n" + + " }\n" + + "\n" + + " if (key1.length() > i) {\n" + + " return key1.substring(0, i).equals(key2.substring(0, i));\n" + + " }\n" + + " return key1.equals(key2.substring(0, i));\n" + + " }"; + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/alice_data/resource1", "GET"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/alice_data/resource1", "POST"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/alice_data/resource2", "GET"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/alice_data/resource2", "POST"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/bob_data/resource1", "GET"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/bob_data/resource1", "POST"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/bob_data/resource2", "GET"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "alice", "/bob_data/resource2", "POST"}), "{\"allow\":false,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/alice_data/resource1", "GET"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/alice_data/resource1", "POST"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/alice_data/resource2", "GET"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/alice_data/resource2", "POST"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/bob_data/resource1", "GET"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/bob_data/resource1", "POST"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/bob_data/resource2", "GET"}), "{\"allow\":false,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "bob", "/bob_data/resource2", "POST"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "cathy", "/cathy_data", "GET"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "cathy", "/cathy_data", "POST"}), "{\"allow\":true,\"explain\":null}"); + assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "cathy", "/cathy_data", "DELETE"}), "{\"allow\":false,\"explain\":null}"); + + } + + @Test + public void testEnforce() { + assertEquals(Client.run(new String[]{"enforce", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + } + + @Test + public void testManagementApi() { + assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + + String matcher = "m = r.sub == 'root' || r.sub == p.sub && r.obj == p.obj && r.act == p.act"; + assertEquals(Client.run(new String[]{"enforceWithMatcher","-m","examples/basic_model.conf", "-p", "examples/basic_policy.csv", matcher, "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"enforceEx", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice", "data1", "read"}), "{\"allow\":true,\"explain\":[\"alice\",\"data1\",\"read\"]}"); + + assertEquals(Client.run(new String[]{"enforceExWithMatcher", "-m", "examples/basic_model.conf", "-p", "examples/basic_policy.csv", matcher, "alice", "data1", "read"}), "{\"allow\":true,\"explain\":[\"alice\",\"data1\",\"read\"]}"); + + assertEquals(Client.run(new String[]{"batchEnforce", "-m", "examples/basic_model.conf", "-p", "examples/basic_policy.csv", "alice,data1,read", "bob,data2,write", "jack,data3,read"}), "{\"allow\":null,\"explain\":[true,true,false]}"); + + assertEquals(Client.run(new String[]{"getAllSubjects", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice", "data1", "read"}), "{\"allow\":null,\"explain\":[\"alice\",\"bob\",\"data2_admin\"]}"); + + assertEquals(Client.run(new String[]{"getAllObjects", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice", "data1", "read"}), "{\"allow\":null,\"explain\":[\"data1\",\"data2\"]}"); + + assertEquals(Client.run(new String[]{"getAllNamedSubjects", "-m", "examples/abac_rule_with_domains_model.conf", "-p", "examples/abac_rule_with_domains_policy.csv", "p"}), "{\"allow\":null,\"explain\":[\"r.domain == 'domain1'\",\"r.domain == 'domain2'\"]}"); + + assertEquals(Client.run(new String[]{"getAllNamedObjects", "-m", "examples/abac_rule_with_domains_model.conf", "-p", "examples/abac_rule_with_domains_policy.csv", "p"}), "{\"allow\":null,\"explain\":[\"admin\"]}"); + + assertEquals(Client.run(new String[]{"getAllActions", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv"}), "{\"allow\":null,\"explain\":[\"read\",\"write\"]}"); + + assertEquals(Client.run(new String[]{"getAllNamedActions", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p"}), "{\"allow\":null,\"explain\":[\"read\",\"write\"]}"); + + assertEquals(Client.run(new String[]{"getAllRoles", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv"}), "{\"allow\":null,\"explain\":[\"data2_admin\"]}"); + + assertEquals(Client.run(new String[]{"getAllNamedRoles", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g"}), "{\"allow\":null,\"explain\":[\"data2_admin\"]}"); + + assertEquals(Client.run(new String[]{"getPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv"}), "{\"allow\":null,\"explain\":[[\"alice\",\"data1\",\"read\"],[\"bob\",\"data2\",\"write\"],[\"data2_admin\",\"data2\",\"read\"],[\"data2_admin\",\"data2\",\"write\"]]}"); + + assertEquals(Client.run(new String[]{"getFilteredPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "0", "alice"}), "{\"allow\":null,\"explain\":[[\"alice\",\"data1\",\"read\"]]}"); + + assertEquals(Client.run(new String[]{"getNamedPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p"}), "{\"allow\":null,\"explain\":[[\"alice\",\"data1\",\"read\"],[\"bob\",\"data2\",\"write\"],[\"data2_admin\",\"data2\",\"read\"],[\"data2_admin\",\"data2\",\"write\"]]}"); + + assertEquals(Client.run(new String[]{"getFilteredNamedPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p", "0", "bob"}), "{\"allow\":null,\"explain\":[[\"bob\",\"data2\",\"write\"]]}"); + + assertEquals(Client.run(new String[]{"getGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv"}), "{\"allow\":null,\"explain\":[[\"alice\",\"data2_admin\"]]}"); + + assertEquals(Client.run(new String[]{"getFilteredGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "0", "alice"}), "{\"allow\":null,\"explain\":[[\"alice\",\"data2_admin\"]]}"); + + assertEquals(Client.run(new String[]{"getNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g"}), "{\"allow\":null,\"explain\":[[\"alice\",\"data2_admin\"]]}"); + + assertEquals(Client.run(new String[]{"getFilteredNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "0", "alice"}), "{\"allow\":null,\"explain\":[[\"alice\",\"data2_admin\"]]}"); + + assertEquals(Client.run(new String[]{"hasPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"hasNamedPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p", "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "eve", "data3", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removePolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "eve", "data3", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "jack,data4,read","katy,data4,write"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removePolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "jack,data4,read","katy,data4,write"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addNamedPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p", "eve", "data3", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeNamedPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p", "eve", "data3", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addNamedPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p", "jack,data4,read","katy,data4,write"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"hasGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice", "data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"hasNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "alice", "data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "group1", "data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"updateGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "group1,data2_admin","group2,data3_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "group2", "data3_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addGroupingPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "ham,data4_admin","jack,data5_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeGroupingPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "ham,data4_admin","jack,data5_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "group2", "data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "group2", "data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addNamedGroupingPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "ham,data4_admin","jack,data5_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeNamedGroupingPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "ham,data4_admin","jack,data5_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeFilteredGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "0", "alice"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "alice", "data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeFilteredNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "0", "alice"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "alice", "data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"updatePolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice,data1,read","alice,data1,write"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"updatePolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "alice,data1,write","alice,data1,read"}), "{\"allow\":true,\"explain\":null}"); + + + assertEquals(Client.run(new String[]{"updateNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "alice,data2_admin","admin,data4_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"updateNamedGroupingPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "g", "admin,data4_admin","alice,data2_admin"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeNamedPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p", "jack,data4,read","katy,data4,write"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeFilteredPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "0", "alice", "data1", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removeFilteredNamedPolicy", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv", "p", "0", "bob"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removePolicy","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "data2_admin", "data2", "read"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"removePolicy","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "data2_admin", "data2", "write"}), "{\"allow\":true,\"explain\":null}"); + + assertEquals(Client.run(new String[]{"addPolicies", "-m", "examples/rbac_model.conf", "-p", "examples/rbac_policy.csv","alice,data1,read","bob,data2,write","data2_admin,data2,read","data2_admin,data2,write"}), "{\"allow\":true,\"explain\":null}"); + } }