From e8a08817e2bf027a8c9ce8b880c98f8aed692d07 Mon Sep 17 00:00:00 2001
From: Liao Xin <93535922+liewstar@users.noreply.github.com>
Date: Wed, 21 Aug 2024 22:05:10 +0800
Subject: [PATCH 1/3] feat: support custom function, Management API and RBAC
with Domains API (#10)
* feat: Support parsing string
* feat: simple check model
* feat: update README
* feat: support management api and rbac with domain api
* feat: update pom.xml
* feat: add tests for dynamically compiled code
* feat: remove unused models and policies
---
README.md | 1 +
examples/abac_rule_with_domains_policy.csv | 2 +-
examples/keymatch_policy.csv | 5 +
pom.xml | 6 -
src/main/java/org/casbin/Client.java | 167 +++++---
src/main/java/org/casbin/NewEnforcer.java | 1 +
.../org/casbin/command/AbstractCommand.java | 12 +
.../java/org/casbin/command/HelpCommand.java | 8 +
.../org/casbin/command/ManagementCommand.java | 387 ++++++++++++++++++
.../org/casbin/command/OperationHandle.java | 5 +
.../java/org/casbin/command/RBACCommand.java | 10 +
.../command/RBACWithConditionsCommand.java | 10 +
.../command/RBACWithDomainsCommand.java | 90 ++++
.../casbin/command/RoleManagerCommand.java | 10 +
.../casbin/generate/CustomClassLoader.java | 7 +
.../generate/DynamicClassGenerator.java | 126 ++++++
.../casbin/generate/JavaSourceFromString.java | 18 +
src/main/java/org/casbin/util/Util.java | 49 +++
src/test/java/org/casbin/ClientTest.java | 107 +++--
19 files changed, 908 insertions(+), 113 deletions(-)
create mode 100644 examples/keymatch_policy.csv
create mode 100644 src/main/java/org/casbin/command/AbstractCommand.java
create mode 100644 src/main/java/org/casbin/command/HelpCommand.java
create mode 100644 src/main/java/org/casbin/command/ManagementCommand.java
create mode 100644 src/main/java/org/casbin/command/OperationHandle.java
create mode 100644 src/main/java/org/casbin/command/RBACCommand.java
create mode 100644 src/main/java/org/casbin/command/RBACWithConditionsCommand.java
create mode 100644 src/main/java/org/casbin/command/RBACWithDomainsCommand.java
create mode 100644 src/main/java/org/casbin/command/RoleManagerCommand.java
create mode 100644 src/main/java/org/casbin/generate/CustomClassLoader.java
create mode 100644 src/main/java/org/casbin/generate/DynamicClassGenerator.java
create mode 100644 src/main/java/org/casbin/generate/JavaSourceFromString.java
create mode 100644 src/main/java/org/casbin/util/Util.java
diff --git a/README.md b/README.md
index a3d3d9f..4c482ec 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 `""` |
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/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..b7ff039 100644
--- a/src/main/java/org/casbin/Client.java
+++ b/src/main/java/org/casbin/Client.java
@@ -1,89 +1,120 @@
package org.casbin;
+
import org.apache.commons.cli.*;
-import org.casbin.jcasbin.exception.CasbinEffectorException;
-import org.casbin.jcasbin.main.EnforceResult;
+import org.casbin.command.*;
+import org.casbin.generate.DynamicClassGenerator;
+import org.casbin.jcasbin.util.function.CustomFunction;
+import org.casbin.util.Util;
+
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
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);
+ private static final String RBAC_COMMAND = "rbac";
+ private static final String RBAC_WITH_CONDITION_COMMAND = "rbac_with_condition";
+ private static final String RBAC_WITH_DOMAINS_COMMAND = "rbac_with_domains";
+ private static final String ROLEMANAGER_COMMAND = "role_manager";
+ private static final String MANAGEMENT_COMMAND = "management";
- CommandLineParser parser = new DefaultParser();
- CommandLine cmd = parser.parse(options, args);
+ private static final Map COMMANDS = new HashMap<>();
- 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);
- }
+ static {
+ COMMANDS.put(RBAC_COMMAND, new RBACCommand());
+ COMMANDS.put(RBAC_WITH_CONDITION_COMMAND, new RBACWithConditionsCommand());
+ COMMANDS.put(RBAC_WITH_DOMAINS_COMMAND, new RBACWithDomainsCommand());
+ COMMANDS.put(ROLEMANAGER_COMMAND, new RoleManagerCommand());
+ COMMANDS.put(MANAGEMENT_COMMAND, new ManagementCommand());
+ }
+
+ public static String run(String... args) {
+ String result = "";
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());
+ if(args == null || args.length == 0) {
+ printUsageMessageAndExit("");
+ }
+
+ Options options = new Options();
+ Option option = new Option("m", "model", true, "the path of the model file or model text");
+ options.addOption(option);
+ option = new Option("p", "policy", true, "the path of the policy file or policy text");
+ options.addOption(option);
+ option = new Option("af", "addFunction", true, "add custom function");
+ option.setRequired(false);
+ options.addOption(option);
+
+ boolean hasAddFuntion = false;
+ for (String arg : args) {
+ if(arg.equals("-af") || arg.equals("-addFunction")) {
+ hasAddFuntion = true;
+ break;
+ }
+ }
+
+ CommandLineParser parser = new DefaultParser();
+
+ CommandLine cmd = null;
+ if(hasAddFuntion) {
+ cmd = parser.parse(options, Arrays.stream(args).limit(7).toArray(String[]::new));
+ } else {
+ cmd = parser.parse(options, Arrays.stream(args).limit(5).toArray(String[]::new));
+ }
+
+ if(cmd.hasOption("model") && cmd.hasOption("policy")) {
+ String model = cmd.getOptionValue("model");
+ String policy = cmd.getOptionValue("policy");
+ NewEnforcer enforcer = new NewEnforcer(model, policy);
+
+ if (hasAddFuntion) {
+ String codes = cmd.getOptionValue("addFunction");
+ String methodName = Util.getMethodName(codes);
+ CustomFunction customFunction = DynamicClassGenerator.generateClass(methodName, codes);
+ enforcer.addFunction(methodName, customFunction);
+ }
+
+ String commandName = args[0];
+ AbstractCommand command = COMMANDS.get(commandName);
+
+
+
+ if(command != null) {
+ if(hasAddFuntion) {
+ result = command.run(enforcer, Arrays.copyOfRange(args, 7, args.length));
+ } else {
+ result = command.run(enforcer, Arrays.copyOfRange(args, 5, args.length));
+ }
+// System.exit(0);
} else {
- System.out.println(allow);
+ printUsageMessageAndExit(commandName);
}
- 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;
+
+ } else {
+ new HelpCommand().run();
+ System.exit(1);
}
} 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);
}
}
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/command/AbstractCommand.java b/src/main/java/org/casbin/command/AbstractCommand.java
new file mode 100644
index 0000000..e4d357a
--- /dev/null
+++ b/src/main/java/org/casbin/command/AbstractCommand.java
@@ -0,0 +1,12 @@
+package org.casbin.command;
+
+import org.casbin.NewEnforcer;
+
+public abstract class AbstractCommand {
+
+ protected AbstractCommand() {
+
+ }
+
+ public abstract String run(NewEnforcer enforcer, String... args) throws Exception;
+}
diff --git a/src/main/java/org/casbin/command/HelpCommand.java b/src/main/java/org/casbin/command/HelpCommand.java
new file mode 100644
index 0000000..f8ed0b1
--- /dev/null
+++ b/src/main/java/org/casbin/command/HelpCommand.java
@@ -0,0 +1,8 @@
+package org.casbin.command;
+
+public class HelpCommand {
+
+ public void run() {
+ System.out.println("Usage: java -jar casbin-java-cli.jar rbac|rbac_with_condition|rbac_with_domains|role_manager|management [options]");
+ }
+}
diff --git a/src/main/java/org/casbin/command/ManagementCommand.java b/src/main/java/org/casbin/command/ManagementCommand.java
new file mode 100644
index 0000000..9856fb5
--- /dev/null
+++ b/src/main/java/org/casbin/command/ManagementCommand.java
@@ -0,0 +1,387 @@
+package org.casbin.command;
+
+import org.apache.commons.cli.*;
+import org.casbin.NewEnforcer;
+
+import java.util.HashMap;
+
+import java.util.Map;
+
+import static org.casbin.util.Util.*;
+
+public class ManagementCommand extends AbstractCommand{
+
+ private static final String ENFORCE = "enforce";
+ private static final String ENFORCE_WITH_MATCHER = "enforceWithMatcher";
+ private static final String ENFORCE_EX = "enforceEx";
+ private static final String ENFORCE_EX_WITH_MATCHER = "enforceExWithMatcher";
+ private static final String BATCH_ENFORCE = "batchEnforce";
+ private static final String GET_ALL_SUBJECTS = "getAllSubjects";
+ private static final String GET_ALL_NAMED_SUBJECTS = "getAllNamedSubjects";
+ private static final String GET_ALL_OBJECTS = "getAllObjects";
+ private static final String GET_ALL_NAMED_OBJECTS = "getAllNamedObjects";
+ private static final String GET_ALL_ACTIONS = "getAllActions";
+ private static final String GET_ALL_NAMED_ACTIONS = "getAllNamedActions";
+ private static final String GET_ALL_ROLES = "getAllRoles";
+ private static final String GET_ALL_NAMED_ROLES = "getAllNamedRoles";
+ private static final String GET_POLICY = "getPolicy";
+ private static final String GET_FILTERED_POLICY = "getFilteredPolicy";
+ private static final String GET_NAMED_POLICY = "getNamedPolicy";
+ private static final String GET_FILTERED_NAMED_POLICY = "getFilteredNamedPolicy";
+ private static final String GET_GROUPING_POLICY = "getGroupingPolicy";
+ private static final String GET_FILTERED_GROUPING_POLICY = "getFilteredGroupingPolicy";
+ private static final String GET_NAMED_GROUPING_POLICY = "getNamedGroupingPolicy";
+ private static final String GET_FILTERED_NAMED_GROUPING_POLICY = "getFilteredNamedGroupingPolicy";
+ private static final String HAS_POLICY = "hasPolicy";
+ private static final String HAS_NAMED_POLICY = "hasNamedPolicy";
+ private static final String ADD_POLICY = "addPolicy";
+ private static final String ADD_POLICIES = "addPolicies";
+ private static final String ADD_NAMED_POLICY = "addNamedPolicy";
+ private static final String ADD_NAMED_POLICIES = "addNamedPolicies";
+ private static final String REMOVE_POLICY = "removePolicy";
+ private static final String REMOVE_POLICIES = "removePolicies";
+ private static final String REMOVE_FILTERED_POLICY = "removeFilteredPolicy";
+ private static final String REMOVE_NAMED_POLICY = "removeNamedPolicy";
+ private static final String REMOVE_NAMED_POLICIES = "removeNamedPolicies";
+ private static final String REMOVE_FILTERED_NAMED_POLICY = "removeFilteredNamedPolicy";
+ private static final String HAS_GROUPING_POLICY = "hasGroupingPolicy";
+ private static final String HAS_NAMED_GROUPING_POLICY = "hasNamedGroupingPolicy";
+ private static final String ADD_GROUPING_POLICY = "addGroupingPolicy";
+ private static final String ADD_GROUPING_POLICIES = "addGroupingPolicies";
+ private static final String ADD_NAMED_GROUPING_POLICY = "addNamedGroupingPolicy";
+ private static final String ADD_NAMED_GROUPING_POLICIES = "addNamedGroupingPolicies";
+ private static final String REMOVE_GROUPING_POLICY = "removeGroupingPolicy";
+ private static final String REMOVE_GROUPING_POLICIES = "removeGroupingPolicies";
+ private static final String REMOVE_FILTERED_GROUPING_POLICY = "removeFilteredGroupingPolicy";
+ private static final String REMOVE_NAMED_GROUPING_POLICY = "removeNamedGroupingPolicy";
+ private static final String REMOVE_FILTERED_NAMED_GROUPING_POLICY = "removeFilteredNamedGroupingPolicy";
+ private static final String UPDATE_POLICY = "updatePolicy";
+ private static final String LOAD_FILTERED_POLICY = "loadFilteredPolicy";
+ private static final String UPDATE_GROUPING_POLICY = "updateGroupingPolicy";
+ private static final String UPDATE_NAMED_GROUPING_POLICY = "updateNamedGroupingPolicy";
+
+ @Override
+ public String run(NewEnforcer enforcer, String... args) throws Exception {
+ Options options = getOptions();
+
+ CommandLineParser parser = new DefaultParser();
+ HelpFormatter formatter = new HelpFormatter();
+ Map handlers = getStringOperationHandleMap(enforcer);
+
+ try {
+ CommandLine cmd = parser.parse(options, args);
+
+ String option = cmd.hasOption(ENFORCE) ? ENFORCE :
+ cmd.hasOption(ENFORCE_WITH_MATCHER) ? ENFORCE_WITH_MATCHER :
+ cmd.hasOption(ENFORCE_EX) ? ENFORCE_EX :
+ cmd.hasOption(ENFORCE_EX_WITH_MATCHER) ? ENFORCE_EX_WITH_MATCHER :
+ cmd.hasOption(BATCH_ENFORCE) ? BATCH_ENFORCE :
+ cmd.hasOption(GET_ALL_SUBJECTS) ? GET_ALL_SUBJECTS :
+ cmd.hasOption(GET_ALL_NAMED_SUBJECTS) ? GET_ALL_NAMED_SUBJECTS :
+ cmd.hasOption(GET_ALL_OBJECTS) ? GET_ALL_OBJECTS :
+ cmd.hasOption(GET_ALL_NAMED_OBJECTS) ? GET_ALL_NAMED_OBJECTS :
+ cmd.hasOption(GET_ALL_ACTIONS) ? GET_ALL_ACTIONS :
+ cmd.hasOption(GET_ALL_NAMED_ACTIONS) ? GET_ALL_NAMED_ACTIONS :
+ cmd.hasOption(GET_ALL_ROLES) ? GET_ALL_ROLES :
+ cmd.hasOption(GET_ALL_NAMED_ROLES) ? GET_ALL_NAMED_ROLES :
+ cmd.hasOption(GET_POLICY) ? GET_POLICY :
+ cmd.hasOption(GET_FILTERED_POLICY) ? GET_FILTERED_POLICY :
+ cmd.hasOption(GET_NAMED_POLICY) ? GET_NAMED_POLICY :
+ cmd.hasOption(GET_FILTERED_NAMED_POLICY) ? GET_FILTERED_NAMED_POLICY :
+ cmd.hasOption(GET_GROUPING_POLICY) ? GET_GROUPING_POLICY :
+ cmd.hasOption(GET_FILTERED_GROUPING_POLICY) ? GET_FILTERED_GROUPING_POLICY :
+ cmd.hasOption(GET_NAMED_GROUPING_POLICY) ? GET_NAMED_GROUPING_POLICY :
+ cmd.hasOption(GET_FILTERED_NAMED_GROUPING_POLICY) ? GET_FILTERED_NAMED_GROUPING_POLICY :
+ cmd.hasOption(HAS_POLICY) ? HAS_POLICY :
+ cmd.hasOption(HAS_NAMED_POLICY) ? HAS_NAMED_POLICY :
+ cmd.hasOption(ADD_POLICY) ? ADD_POLICY :
+ cmd.hasOption(ADD_POLICIES) ? ADD_POLICIES :
+ cmd.hasOption(ADD_NAMED_POLICY) ? ADD_NAMED_POLICY :
+ cmd.hasOption(ADD_NAMED_POLICIES) ? ADD_NAMED_POLICIES :
+ cmd.hasOption(REMOVE_POLICY) ? REMOVE_POLICY :
+ cmd.hasOption(REMOVE_POLICIES) ? REMOVE_POLICIES :
+ cmd.hasOption(REMOVE_FILTERED_POLICY) ? REMOVE_FILTERED_POLICY :
+ cmd.hasOption(REMOVE_NAMED_POLICY) ? REMOVE_NAMED_POLICY :
+ cmd.hasOption(REMOVE_NAMED_POLICIES) ? REMOVE_NAMED_POLICIES :
+ cmd.hasOption(REMOVE_FILTERED_NAMED_POLICY) ? REMOVE_FILTERED_NAMED_POLICY :
+ cmd.hasOption(HAS_GROUPING_POLICY) ? HAS_GROUPING_POLICY :
+ cmd.hasOption(HAS_NAMED_GROUPING_POLICY) ? HAS_NAMED_GROUPING_POLICY :
+ cmd.hasOption(ADD_GROUPING_POLICY) ? ADD_GROUPING_POLICY :
+ cmd.hasOption(ADD_GROUPING_POLICIES) ? ADD_GROUPING_POLICIES :
+ cmd.hasOption(ADD_NAMED_GROUPING_POLICY) ? ADD_NAMED_GROUPING_POLICY :
+ cmd.hasOption(ADD_NAMED_GROUPING_POLICIES) ? ADD_NAMED_GROUPING_POLICIES :
+ cmd.hasOption(REMOVE_GROUPING_POLICY) ? REMOVE_GROUPING_POLICY :
+ cmd.hasOption(REMOVE_GROUPING_POLICIES) ? REMOVE_GROUPING_POLICIES :
+ cmd.hasOption(REMOVE_FILTERED_GROUPING_POLICY) ? REMOVE_FILTERED_GROUPING_POLICY :
+ cmd.hasOption(REMOVE_NAMED_GROUPING_POLICY) ? REMOVE_NAMED_GROUPING_POLICY :
+ cmd.hasOption(REMOVE_FILTERED_NAMED_GROUPING_POLICY) ? REMOVE_FILTERED_NAMED_GROUPING_POLICY :
+ cmd.hasOption(UPDATE_POLICY) ? UPDATE_POLICY :
+ cmd.hasOption(LOAD_FILTERED_POLICY) ? LOAD_FILTERED_POLICY :
+ cmd.hasOption(UPDATE_GROUPING_POLICY) ? UPDATE_GROUPING_POLICY :
+ cmd.hasOption(UPDATE_NAMED_GROUPING_POLICY) ? UPDATE_NAMED_GROUPING_POLICY : null;
+ OperationHandle handle = handlers.get(option);
+ String[] params = cmd.getOptionValues(option);
+ String res = handle.handle(params);
+ enforcer.savePolicy();
+ System.out.println(res);
+ return res;
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ formatter.printHelp("management", options);
+ }
+ return "";
+ }
+
+ private static Map getStringOperationHandleMap(NewEnforcer enforcer) {
+ Map handlers = new HashMap<>();
+
+ handlers.put(ENFORCE, params -> String.valueOf(enforcer.enforce(cutString(params[0]))));
+ handlers.put(ENFORCE_WITH_MATCHER, (params) -> String.valueOf(enforcer.enforceWithMatcher(params[0], cutString(params[1]))));
+ handlers.put(ENFORCE_EX, (params) -> String.valueOf(enforcer.enforceEx(cutString(params[0]))));
+ handlers.put(ENFORCE_EX_WITH_MATCHER, (params) -> String.valueOf(enforcer.enforceExWithMatcher(params[0], cutString(params[1]))));
+ handlers.put(BATCH_ENFORCE, (params) -> String.valueOf(enforcer.batchEnforce(parseNestedLists(params[0]))));
+ handlers.put(GET_ALL_SUBJECTS, (params) -> String.valueOf(enforcer.getAllSubjects()));
+ handlers.put(GET_ALL_NAMED_SUBJECTS, (params) -> String.valueOf(enforcer.getAllNamedSubjects(params[0])));
+ handlers.put(GET_ALL_OBJECTS, (params) -> String.valueOf(enforcer.getAllObjects()));
+ handlers.put(GET_ALL_NAMED_OBJECTS, (params) -> String.valueOf(enforcer.getAllNamedObjects(params[0])));
+ handlers.put(GET_ALL_ACTIONS, (params) -> String.valueOf(enforcer.getAllActions()));
+ handlers.put(GET_ALL_NAMED_ACTIONS, (params) -> String.valueOf(enforcer.getAllNamedActions(params[0])));
+ handlers.put(GET_ALL_ROLES, (params) -> String.valueOf(enforcer.getAllRoles()));
+ handlers.put(GET_ALL_NAMED_ROLES, (params) -> String.valueOf(enforcer.getAllNamedRoles(params[0])));
+ handlers.put(GET_POLICY, (params) -> String.valueOf(enforcer.getPolicy()));
+ handlers.put(GET_FILTERED_POLICY, (params) -> String.valueOf(enforcer.getFilteredPolicy(Integer.parseInt(params[0]), cutString(params[1]))));
+ handlers.put(GET_NAMED_POLICY, (params) -> String.valueOf(enforcer.getNamedPolicy(params[0])));
+ handlers.put(GET_FILTERED_NAMED_POLICY, (params) -> String.valueOf(enforcer.getFilteredNamedPolicy(params[0], Integer.parseInt(params[1]), cutString(params[2]))));
+ handlers.put(GET_GROUPING_POLICY, (params) -> String.valueOf(enforcer.getGroupingPolicy()));
+ handlers.put(GET_FILTERED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.getFilteredGroupingPolicy(Integer.parseInt(params[0]), cutString(params[1]))));
+ handlers.put(GET_NAMED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.getNamedGroupingPolicy(params[0])));
+ handlers.put(GET_FILTERED_NAMED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.getFilteredNamedGroupingPolicy(params[0], Integer.parseInt(params[1]), cutString(params[0]))));
+ handlers.put(HAS_POLICY, (params) -> String.valueOf(enforcer.hasPolicy(cutString(params[0]))));
+ handlers.put(HAS_NAMED_POLICY, (params) -> String.valueOf(enforcer.hasNamedPolicy(params[0], cutString(params[1]))));
+ handlers.put(ADD_POLICY, (params) -> String.valueOf(enforcer.addPolicy(cutString(params[0]))));
+ handlers.put(ADD_POLICIES, (params) -> String.valueOf(enforcer.addPolicies(parseNestedLists(params[0]))));
+ handlers.put(ADD_NAMED_POLICY, (params) -> String.valueOf(enforcer.addNamedPolicy(params[0], cutString(params[1]))));
+ handlers.put(ADD_NAMED_POLICIES, (params) -> String.valueOf(enforcer.addNamedPolicies(params[0], parseNestedLists(params[1]))));
+ handlers.put(REMOVE_POLICY, (params) -> String.valueOf(enforcer.removePolicy(cutString(params[0]))));
+ handlers.put(REMOVE_POLICIES, (params) -> String.valueOf(enforcer.removePolicies(parseNestedLists(params[0]))));
+ handlers.put(REMOVE_FILTERED_POLICY, (params) -> String.valueOf(enforcer.removeFilteredPolicy(Integer.parseInt(params[0]), cutString(params[1]))));
+ handlers.put(REMOVE_NAMED_POLICY, (params) -> String.valueOf(enforcer.removeNamedPolicy(params[0], cutString(params[1]))));
+ handlers.put(REMOVE_NAMED_POLICIES, (params) -> String.valueOf(enforcer.removeNamedPolicies(params[0], parseNestedLists(params[1]))));
+ handlers.put(REMOVE_FILTERED_NAMED_POLICY, (params) -> String.valueOf(enforcer.removeFilteredNamedPolicy(params[0], Integer.parseInt(params[1]), cutString(params[0]))));
+ handlers.put(HAS_GROUPING_POLICY, (params) -> String.valueOf(enforcer.hasGroupingPolicy(cutString(params[0]))));
+ handlers.put(HAS_NAMED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.hasNamedGroupingPolicy(params[0], cutString(params[1]))));
+ handlers.put(ADD_GROUPING_POLICY, (params) -> String.valueOf(enforcer.addGroupingPolicy(cutString(params[0]))));
+ handlers.put(ADD_GROUPING_POLICIES, (params) -> String.valueOf(enforcer.addGroupingPolicies(parseNestedLists(params[0]))));
+ handlers.put(ADD_NAMED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.addNamedGroupingPolicy(params[0], cutString(params[1]))));
+ handlers.put(ADD_NAMED_GROUPING_POLICIES, (params) -> String.valueOf(enforcer.addNamedGroupingPolicies(params[0], parseNestedLists(params[1]))));
+ handlers.put(REMOVE_GROUPING_POLICY, (params) -> String.valueOf(enforcer.removeGroupingPolicy(params[0])));
+ handlers.put(REMOVE_GROUPING_POLICIES, (params) -> String.valueOf(enforcer.removeGroupingPolicies(parseNestedLists(params[0]))));
+ handlers.put(REMOVE_FILTERED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.removeFilteredGroupingPolicy(Integer.parseInt(params[0]), cutString(params[1]))));
+ handlers.put(REMOVE_NAMED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.removeNamedGroupingPolicy(params[0], cutString(params[1]))));
+ handlers.put(REMOVE_FILTERED_NAMED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.removeFilteredNamedGroupingPolicy(params[0], Integer.parseInt(params[1]), cutString(params[0]))));
+ handlers.put(UPDATE_POLICY, (params) -> String.valueOf(enforcer.updatePolicy(parseOrdinary(params[0]), parseOrdinary(params[1]))));
+ //handlers.put(LOAD_FILTERED_POLICY, (params) -> String.valueOf(enforcer.loadFilteredPolicy()));
+ handlers.put(UPDATE_GROUPING_POLICY, (params) -> String.valueOf(enforcer.updateGroupingPolicy(parseOrdinary(params[0]), parseOrdinary(params[1]))));
+ handlers.put(UPDATE_NAMED_GROUPING_POLICY, (params) -> String.valueOf(enforcer.updateNamedGroupingPolicy(params[0], parseOrdinary(params[1]), parseOrdinary(params[2]))));
+
+ return handlers;
+ }
+
+
+ private static Options getOptions() {
+ Options options = new Options();
+
+ Option option = new Option("e", ENFORCE, false, "enforce access control");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("ewm", ENFORCE_WITH_MATCHER, false, "enforce access control with matcher");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("ex", ENFORCE_EX, false, "enforce access control exception");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("exwm", ENFORCE_EX_WITH_MATCHER, false, "enforce access control exception with matcher");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("be", BATCH_ENFORCE, false, "batch enforce access control");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("gas", GET_ALL_SUBJECTS, false, "get all subjects");
+ options.addOption(option);
+
+ option = new Option("gans", GET_ALL_NAMED_SUBJECTS, false, "get all named subjects");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("go", GET_ALL_OBJECTS, false, "get all objects");
+ options.addOption(option);
+
+ option = new Option("ganos", GET_ALL_NAMED_OBJECTS, false, "get all named objects");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("ga", GET_ALL_ACTIONS, false, "get all actions");
+ options.addOption(option);
+
+ option = new Option("ganas", GET_ALL_NAMED_ACTIONS, false, "get all named actions");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("grl", GET_ALL_ROLES, false, "get all roles");
+ options.addOption(option);
+
+ option = new Option("garnr", GET_ALL_NAMED_ROLES, false, "get all named roles");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("gp", GET_POLICY, false, "get policy");
+ options.addOption(option);
+
+ option = new Option("gfp", GET_FILTERED_POLICY, false, "get filtered policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("gnp", GET_NAMED_POLICY, false, "get named policy");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("gfnp", GET_FILTERED_NAMED_POLICY, false, "get filtered named policy");
+ option.setArgs(3);
+ options.addOption(option);
+
+ option = new Option("ggp", GET_GROUPING_POLICY, false, "get grouping policy");
+ options.addOption(option);
+
+ option = new Option("gfgp", GET_FILTERED_GROUPING_POLICY, false, "get filtered grouping policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("gnrp", GET_NAMED_GROUPING_POLICY, false, "get named grouping policy");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("gfngp", GET_FILTERED_NAMED_GROUPING_POLICY, false, "get filtered named grouping policy");
+ option.setArgs(3);
+ options.addOption(option);
+
+ option = new Option("hp", HAS_POLICY, false, "check if a policy exists");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("hnp", HAS_NAMED_POLICY, false, "check if a named policy exists");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("ap", ADD_POLICY, false, "add a policy");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("aps", ADD_POLICIES, false, "add multiple policies");
+ option.setArgs(0);
+ options.addOption(option);
+
+ option = new Option("anp", ADD_NAMED_POLICY, false, "add a named policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("ans", ADD_NAMED_POLICIES, false, "add multiple named policies");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("rp", REMOVE_POLICY, false, "remove a policy");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("rps", REMOVE_POLICIES, false, "remove multiple policies");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("rfp", REMOVE_FILTERED_POLICY, false, "remove a policy by filter");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("rnp", REMOVE_NAMED_POLICY, false, "remove a named policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("rnps", REMOVE_NAMED_POLICIES, false, "remove multiple named policies");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("rfnp", REMOVE_FILTERED_NAMED_POLICY, false, "remove a named policy by filter");
+ option.setArgs(3);
+ options.addOption(option);
+
+ option = new Option("hgp", HAS_GROUPING_POLICY, false, "check if a grouping policy exists");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("hnpgp", HAS_NAMED_GROUPING_POLICY, false, "check if a named grouping policy exists");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("agp", ADD_GROUPING_POLICY, false, "add a grouping policy");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("ags", ADD_GROUPING_POLICIES, false, "add multiple grouping policies");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("angp", ADD_NAMED_GROUPING_POLICY, false, "add a named grouping policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("angs", ADD_NAMED_GROUPING_POLICIES, false, "add multiple named grouping policies");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("agnex", REMOVE_GROUPING_POLICIES, false, "remove multiple grouping policies");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("rgp", REMOVE_GROUPING_POLICY, false, "remove a grouping policy");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("rgs", REMOVE_GROUPING_POLICIES, false, "remove multiple grouping policies");
+ option.setArgs(1);
+ options.addOption(option);
+
+ option = new Option("rgfp", REMOVE_FILTERED_GROUPING_POLICY, false, "remove a grouping policy by filter");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("rngp", REMOVE_NAMED_GROUPING_POLICY, false, "remove a named grouping policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("rnfngp", REMOVE_FILTERED_NAMED_GROUPING_POLICY, false, "remove a named grouping policy by filter");
+ option.setArgs(3);
+ options.addOption(option);
+
+ option = new Option("up", UPDATE_POLICY, false, "update a policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("lfp", LOAD_FILTERED_POLICY, false, "load a filtered policy");
+ options.addOption(option);
+
+ option = new Option("ugp", UPDATE_GROUPING_POLICY, false, "update a grouping policy");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("ungp", UPDATE_NAMED_GROUPING_POLICY, false, "update a named grouping policy");
+ option.setArgs(3);
+ options.addOption(option);
+
+ return options;
+ }
+
+
+}
diff --git a/src/main/java/org/casbin/command/OperationHandle.java b/src/main/java/org/casbin/command/OperationHandle.java
new file mode 100644
index 0000000..2f2ded0
--- /dev/null
+++ b/src/main/java/org/casbin/command/OperationHandle.java
@@ -0,0 +1,5 @@
+package org.casbin.command;
+
+public interface OperationHandle {
+ String handle(String[] params);
+}
diff --git a/src/main/java/org/casbin/command/RBACCommand.java b/src/main/java/org/casbin/command/RBACCommand.java
new file mode 100644
index 0000000..3a20c36
--- /dev/null
+++ b/src/main/java/org/casbin/command/RBACCommand.java
@@ -0,0 +1,10 @@
+package org.casbin.command;
+
+import org.casbin.NewEnforcer;
+
+public class RBACCommand extends AbstractCommand{
+ @Override
+ public String run(NewEnforcer enforcer, String... args) throws Exception {
+ return "";
+ }
+}
diff --git a/src/main/java/org/casbin/command/RBACWithConditionsCommand.java b/src/main/java/org/casbin/command/RBACWithConditionsCommand.java
new file mode 100644
index 0000000..e26f0f1
--- /dev/null
+++ b/src/main/java/org/casbin/command/RBACWithConditionsCommand.java
@@ -0,0 +1,10 @@
+package org.casbin.command;
+
+import org.casbin.NewEnforcer;
+
+public class RBACWithConditionsCommand extends AbstractCommand{
+ @Override
+ public String run(NewEnforcer enforcer, String... args) throws Exception {
+ return "";
+ }
+}
diff --git a/src/main/java/org/casbin/command/RBACWithDomainsCommand.java b/src/main/java/org/casbin/command/RBACWithDomainsCommand.java
new file mode 100644
index 0000000..9ba49b4
--- /dev/null
+++ b/src/main/java/org/casbin/command/RBACWithDomainsCommand.java
@@ -0,0 +1,90 @@
+package org.casbin.command;
+
+import org.apache.commons.cli.*;
+import org.casbin.NewEnforcer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class RBACWithDomainsCommand extends AbstractCommand{
+
+ private static final String GET_USERS_FOR_ROLE_IN_DOMAIN = "getUsersForRoleInDomain";
+ private static final String GET_ROLES_FOR_USER_IN_DOMAIN = "getRolesForUserInDomain";
+ private static final String GET_PERMISSIONS_FOR_USER_IN_DOMAIN = "getPermissionsForUserInDomain";
+ private static final String ADD_ROLE_FOR_USER_IN_DOMAIN = "addRoleForUserInDomain";
+ private static final String DELETE_ROLE_FOR_USER_IN_DOMAIN = "deleteRoleForUserInDomain";
+ private static final String DELETE_ROLES_FOR_USER_IN_DOMAIN = "deleteRolesForUserInDomain";
+
+ @Override
+ public String run(NewEnforcer enforcer, String... args) throws Exception {
+ Options options = getOptions();
+
+ CommandLineParser parser = new DefaultParser();
+ HelpFormatter formatter = new HelpFormatter();
+
+ Map handlers = getStringOperationHandleMap(enforcer);
+
+ try {
+ CommandLine cmd = parser.parse(options, args);
+
+ String option = cmd.hasOption(GET_USERS_FOR_ROLE_IN_DOMAIN) ? GET_USERS_FOR_ROLE_IN_DOMAIN :
+ cmd.hasOption(GET_ROLES_FOR_USER_IN_DOMAIN) ? GET_ROLES_FOR_USER_IN_DOMAIN :
+ cmd.hasOption(GET_PERMISSIONS_FOR_USER_IN_DOMAIN) ? GET_PERMISSIONS_FOR_USER_IN_DOMAIN :
+ cmd.hasOption(ADD_ROLE_FOR_USER_IN_DOMAIN) ? ADD_ROLE_FOR_USER_IN_DOMAIN :
+ cmd.hasOption(DELETE_ROLE_FOR_USER_IN_DOMAIN) ? DELETE_ROLE_FOR_USER_IN_DOMAIN : DELETE_ROLES_FOR_USER_IN_DOMAIN;
+
+ OperationHandle handle = handlers.get(option);
+ String[] params = cmd.getOptionValues(option);
+ String res = handle.handle(params);
+ enforcer.savePolicy();
+ System.out.println(res);
+ return res;
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ formatter.printHelp("rbac_with_domains", options);
+ }
+ return "";
+ }
+
+ private static Map getStringOperationHandleMap(NewEnforcer enforcer) {
+ Map handlers = new HashMap<>();
+ handlers.put(GET_USERS_FOR_ROLE_IN_DOMAIN, (params) -> String.valueOf(enforcer.getUsersForRoleInDomain(params[0], params[1])));
+ handlers.put(GET_ROLES_FOR_USER_IN_DOMAIN, (params) -> String.valueOf(enforcer.getRolesForUserInDomain(params[0], params[1])));
+ handlers.put(GET_PERMISSIONS_FOR_USER_IN_DOMAIN, (params) -> String.valueOf(enforcer.getPermissionsForUserInDomain(params[0], params[1])));
+ handlers.put(ADD_ROLE_FOR_USER_IN_DOMAIN, (params) -> String.valueOf(enforcer.addRoleForUserInDomain(params[0], params[1], params[2])));
+ handlers.put(DELETE_ROLE_FOR_USER_IN_DOMAIN, (params) -> String.valueOf(enforcer.deleteRoleForUserInDomain(params[0], params[1], params[2])));
+ handlers.put(DELETE_ROLES_FOR_USER_IN_DOMAIN, (params) -> String.valueOf(enforcer.deleteRolesForUser(params[0])));
+ return handlers;
+ }
+
+ private static Options getOptions() {
+ Options options = new Options();
+
+ Option option = new Option("gu", GET_USERS_FOR_ROLE_IN_DOMAIN, true, "retrieve the users that have a role within a domain");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("gr", GET_ROLES_FOR_USER_IN_DOMAIN, true, "retrieves the roles that a user has within a domain");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("gp", GET_PERMISSIONS_FOR_USER_IN_DOMAIN, true, "retrieves the permissions for a user or role within a domain");
+ option.setArgs(2);
+ options.addOption(option);
+
+ option = new Option("ar", ADD_ROLE_FOR_USER_IN_DOMAIN, true, "adds a role for a user within a domain. It returns false if the user already has the role (no changes made)");
+ option.setArgs(3);
+ options.addOption(option);
+
+ option = new Option("dr", DELETE_ROLE_FOR_USER_IN_DOMAIN, true, "removes a role for a user within a domain. It returns false if the user does not have the role (no changes made)");
+ option.setArgs(3);
+ options.addOption(option);
+
+ option = new Option("drs", DELETE_ROLES_FOR_USER_IN_DOMAIN, true, "removes all roles for a user within a domain. It returns false if the user does not have any roles (no changes made)");
+ option.setArgs(1);
+ options.addOption(option);
+
+ return options;
+ }
+}
diff --git a/src/main/java/org/casbin/command/RoleManagerCommand.java b/src/main/java/org/casbin/command/RoleManagerCommand.java
new file mode 100644
index 0000000..d039021
--- /dev/null
+++ b/src/main/java/org/casbin/command/RoleManagerCommand.java
@@ -0,0 +1,10 @@
+package org.casbin.command;
+
+import org.casbin.NewEnforcer;
+
+public class RoleManagerCommand extends AbstractCommand{
+ @Override
+ public String run(NewEnforcer enforcer, String... args) throws Exception {
+ return "";
+ }
+}
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 extends JavaFileObject> 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/util/Util.java b/src/main/java/org/casbin/util/Util.java
new file mode 100644
index 0000000..62fe032
--- /dev/null
+++ b/src/main/java/org/casbin/util/Util.java
@@ -0,0 +1,49 @@
+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 List> parseNestedLists(String input) {
+ String innerString = input.substring(1, input.length() - 1);
+ String[] items = innerString.split("\\],\\[");
+ List> result = new ArrayList<>();
+ for (String item : items) {
+ String cleanItem = item.replace("[", "").replace("]", "");
+ List subList = Arrays.asList(cleanItem.split(","));
+ result.add(subList);
+ }
+ return result;
+ }
+
+ public static List parseOrdinary(String input) {
+ String trimmedInput = input.substring(1, input.length() - 1);
+ return Arrays.asList(trimmedInput.split(","));
+ }
+
+ 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 String[] cutString(String str) {
+ return str.replace(" ","").split(",");
+ }
+
+ 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..bd60c50 100644
--- a/src/test/java/org/casbin/ClientTest.java
+++ b/src/test/java/org/casbin/ClientTest.java
@@ -1,58 +1,41 @@
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[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "alice,data1,read"}), "true");
+ assertEquals(Client.run(new String[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "alice,data1,write"}), "false");
+ assertEquals(Client.run(new String[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "alice,data2,read"}), "true");
+ assertEquals(Client.run(new String[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "alice,data2,write"}), "true");
+ assertEquals(Client.run(new String[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "bob,data1,read"}), "false");
+ assertEquals(Client.run(new String[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "bob,data1,write"}), "false");
+ assertEquals(Client.run(new String[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "bob,data2,read"}), "false");
+ assertEquals(Client.run(new String[]{"management","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "-e", "bob,data2,write"}), "true");
}
@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[]{"management","-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[]{"management","-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[]{"management","-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[]{"management","-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[]{"management","-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[]{"management","-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[]{"management","-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[]{"management","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-e","bob,domain2,data2,read"}), "true");
- @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[]{"management","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-ap","alice,domain1,data1,read"}), "true");
+ assertEquals(Client.run(new String[]{"management","-m","examples/abac_rule_with_domains_model.conf","-p","examples/abac_rule_with_domains_policy.csv","-rp","alice,domain1,data1,read"}), "true");
}
@Test
@@ -76,8 +59,56 @@ 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[]{"management","-m",model,"-p",policy,"-e","alice,data1,read"}), "true");
}
+ @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[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /alice_data/resource1, GET"}), "true");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /alice_data/resource1, POST"}), "true");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /alice_data/resource2, GET"}), "true");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /alice_data/resource2, POST"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /bob_data/resource1, GET"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /bob_data/resource1, POST"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /bob_data/resource2, GET"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "alice, /bob_data/resource2, POST"}), "false");
+
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /alice_data/resource1, GET"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /alice_data/resource1, POST"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /alice_data/resource2, GET"}), "true");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /alice_data/resource2, POST"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /bob_data/resource1, GET"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /bob_data/resource1, POST"}), "true");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /bob_data/resource2, GET"}), "false");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "bob, /bob_data/resource2, POST"}), "true");
+
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "cathy, /cathy_data, GET"}), "true");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "cathy, /cathy_data, POST"}), "true");
+ assertEquals(Client.run(new String[]{"management", "-m", model, "-p", "examples/keymatch_policy.csv", "-af", func, "-e", "cathy, /cathy_data, DELETE"}), "false");
+
+ }
+
}
From eee4fe93a964af70bf94f3566c9f04378e74496a Mon Sep 17 00:00:00 2001
From: Liao Xin <93535922+liewstar@users.noreply.github.com>
Date: Wed, 18 Sep 2024 23:36:38 +0800
Subject: [PATCH 2/3] feat: Use "casbin" command instead of "java -jar
target/casbin-java-cli.jar" command (#14)
* feat: Use "casbin" command instead of "java -jar target/casbin-java-cli.jar" command
* fix: remove .sh suffix
---
README.md | 10 +++++-----
casbin | 2 ++
casbin.cmd | 5 +++++
3 files changed, 12 insertions(+), 5 deletions(-)
create mode 100755 casbin
create mode 100644 casbin.cmd
diff --git a/README.md b/README.md
index 4c482ec..9921991 100644
--- a/README.md
+++ b/README.md
@@ -33,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 -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -e "alice, data1, read"
```
> Allow
```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 -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"
```
> Allow
- 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 -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -ex "alice, data2, write"
```
> true Reason: [alice, 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 -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -ap "alice, data2, write"
```
> Add Success
- 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 -m "examples/rbac_model.conf" -p "examples/rbac_policy.csv" -rp "alice,data1,read"
```
> Remove Success
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
From 49b01e16a5cdedb280f276af4035b78b6b440fc9 Mon Sep 17 00:00:00 2001
From: Liao Xin <93535922+liewstar@users.noreply.github.com>
Date: Sun, 22 Sep 2024 22:28:20 +0800
Subject: [PATCH 3/3] fix: add enforce command (#15)
---
README.md | 8 ++++----
src/main/java/org/casbin/Client.java | 2 ++
.../java/org/casbin/command/EnforceCommand.java | 15 +++++++++++++++
src/test/java/org/casbin/ClientTest.java | 5 +++++
4 files changed, 26 insertions(+), 4 deletions(-)
create mode 100644 src/main/java/org/casbin/command/EnforceCommand.java
diff --git a/README.md b/README.md
index 9921991..5726c14 100644
--- a/README.md
+++ b/README.md
@@ -33,13 +33,13 @@ mvn clean install
- Check whether Alice has read permission on data1
```shell
- ./casbin -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
+ > Allowed
```shell
- ./casbin -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
+ > Allowed
- Check whether Alice has write permission for data2. If so, display the effective policy.
diff --git a/src/main/java/org/casbin/Client.java b/src/main/java/org/casbin/Client.java
index b7ff039..bb7e872 100644
--- a/src/main/java/org/casbin/Client.java
+++ b/src/main/java/org/casbin/Client.java
@@ -20,6 +20,7 @@ public class Client {
private static final String RBAC_WITH_DOMAINS_COMMAND = "rbac_with_domains";
private static final String ROLEMANAGER_COMMAND = "role_manager";
private static final String MANAGEMENT_COMMAND = "management";
+ private static final String ENFORCE_COMMAND = "enforce";
private static final Map COMMANDS = new HashMap<>();
@@ -29,6 +30,7 @@ public class Client {
COMMANDS.put(RBAC_WITH_DOMAINS_COMMAND, new RBACWithDomainsCommand());
COMMANDS.put(ROLEMANAGER_COMMAND, new RoleManagerCommand());
COMMANDS.put(MANAGEMENT_COMMAND, new ManagementCommand());
+ COMMANDS.put(ENFORCE_COMMAND, new EnforceCommand());
}
public static String run(String... args) {
diff --git a/src/main/java/org/casbin/command/EnforceCommand.java b/src/main/java/org/casbin/command/EnforceCommand.java
new file mode 100644
index 0000000..04c16e8
--- /dev/null
+++ b/src/main/java/org/casbin/command/EnforceCommand.java
@@ -0,0 +1,15 @@
+package org.casbin.command;
+
+import org.casbin.NewEnforcer;
+
+public class EnforceCommand extends AbstractCommand {
+ @Override
+ public String run(NewEnforcer enforcer, String... args) throws Exception {
+ String subject = args[0];
+ String object = args[1];
+ String action = args[2];
+ boolean res = enforcer.enforce(subject, object, action);
+ System.out.println(res ? "Allowed" : "Denied");
+ return String.valueOf(res);
+ }
+}
diff --git a/src/test/java/org/casbin/ClientTest.java b/src/test/java/org/casbin/ClientTest.java
index bd60c50..125a541 100644
--- a/src/test/java/org/casbin/ClientTest.java
+++ b/src/test/java/org/casbin/ClientTest.java
@@ -111,4 +111,9 @@ public void testCustomFunction() throws ParseException {
}
+ @Test
+ public void testEnforce() {
+ assertEquals(Client.run(new String[]{"enforce","-m","examples/rbac_model.conf","-p","examples/rbac_policy.csv", "alice", "data1", "read"}), "true");
+ }
+
}