Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support file path in the addFuntion option #29

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ mvn clean install
```

## Options
| options | description | must | remark |
|-----------------------|----------------------------------------------|------|-----------------------------------------------------------|
| `-m, --model` | The path of the model file or model text | y | Please wrap it with `""` and separate each line with `\|` |
| `-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 `""` |
| options | description | must | remark |
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------------------|
| `-m, --model` | The path of the model file or model text | y | Please wrap it with `""` and separate each line with `\|` |
| `-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 using text or function file.<br/>file format see [function.conf](https://github.com/jcasbin/casbin-java-cli/blob/master/examples/keymatch_function.conf) | 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 `""` |

## Get started

Expand Down
25 changes: 25 additions & 0 deletions examples/keymatch_function.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[function_definition]
public static boolean keyMatchTest(String key1, String key2) {
int i = key2.indexOf('*');
if (i == -1) {
return key1.equals(key2);
}

if (key1.length() > i) {
return key1.substring(0, i).equals(key2.substring(0, i));
}
return key1.equals(key2.substring(0, i));
}

[function_definition]
public static boolean keyMatchTest2(String key1, String key2) {
int i = key2.indexOf('*');
if (i == -1) {
return key1.equals(key2);
}

if (key1.length() > i) {
return key1.substring(0, i).equals(key2.substring(0, i));
}
return key1.equals(key2.substring(0, i));
}
12 changes: 7 additions & 5 deletions src/main/java/org/casbin/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ public static String run(String... args) {
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);
List<String> codes = Util.parse(cmd.getOptionValue("AF"));
for (String code : codes) {
String methodName = Util.getMethodName(code);
CustomFunction customFunction = DynamicClassGenerator.generateClass(methodName, code);
enforcer.addFunction(methodName, customFunction);
}
}
CommandExecutor commandExecutor = new CommandExecutor(enforcer, commandName, cmd.getArgs());
Object o = commandExecutor.outputResult();
Expand Down Expand Up @@ -110,7 +112,7 @@ private static void printHelpMessage() {
" Options:\n" +
" -m, --model <model> The path of the model file or model text. Please wrap it with \"\" and separate each line with \"|\"\n" +
" -p, --policy <policy> The path of the policy file or policy text. Please wrap it with \"\" and separate each line with \"|\"\n" +
" -AF, --addFunction <functionDefinition> Add custom function. Please wrap it with \"\" and separate each line with \"|\"\n" +
" -AF, --addFunction <functionDefinition> The path of the function file or function text. Please wrap it with \"\" and separate each line with \"|\"\n" +
"\n" +
" args:\n" +
" Parameters required for the method\n" +
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/org/casbin/util/Util.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.casbin.util;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand All @@ -26,4 +30,30 @@ public static int getArgsNum(String methodCodes) {
}
return 0;
}

/**
* Parse the input string to get the function definitions List
* @param input
* @return List of function definitions
*/
public static List<String> parse(String input) throws IOException {
if (input == null || input.trim().isEmpty()) {
throw new IllegalArgumentException("Input cannot be null or empty");
}
List<String> codes = new ArrayList<>();

// Check if input is an existing file
File file = new File(input);
if (file.exists() && file.isFile()) {
String content = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);

String[] lines = content.split("\\[function_definition\\]");
for (int i = 1; i < lines.length; i++) {
codes.add(lines[i].trim());
}
} else {
codes.add(input);
}
return codes;
}
}
35 changes: 35 additions & 0 deletions src/test/java/org/casbin/ClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,41 @@ public void testCustomFunction() throws ParseException {
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 add Function using file
String methodName2 = "keyMatchTest2";
String model2 = "[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) && " + methodName2 + "(r.obj, p.obj)" + "&& regexMatch(r.act, p.act)\n";

assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/alice_data/resource1", "GET"}), "{\"allow\":true,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/alice_data/resource1", "POST"}), "{\"allow\":true,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/alice_data/resource2", "GET"}), "{\"allow\":true,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/alice_data/resource2", "POST"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/bob_data/resource1", "GET"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/bob_data/resource1", "POST"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/bob_data/resource2", "GET"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "alice", "/bob_data/resource2", "POST"}), "{\"allow\":false,\"explain\":null}");

assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/alice_data/resource1", "GET"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/alice_data/resource1", "POST"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/alice_data/resource2", "GET"}), "{\"allow\":true,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/alice_data/resource2", "POST"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/bob_data/resource1", "GET"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/bob_data/resource1", "POST"}), "{\"allow\":true,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/bob_data/resource2", "GET"}), "{\"allow\":false,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "bob", "/bob_data/resource2", "POST"}), "{\"allow\":true,\"explain\":null}");

assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "cathy", "/cathy_data", "GET"}), "{\"allow\":true,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "cathy", "/cathy_data", "POST"}), "{\"allow\":true,\"explain\":null}");
assertEquals(Client.run(new String[]{"enforce", "-m", model2, "-p", "examples/keymatch_policy.csv", "-AF", "examples/keymatch_function.conf", "cathy", "/cathy_data", "DELETE"}), "{\"allow\":false,\"explain\":null}");
}

@Test
Expand Down
Loading