Skip to content

Commit b943f95

Browse files
committed
feat: support file path in the addFuntion option
1 parent 783be0c commit b943f95

File tree

5 files changed

+106
-14
lines changed

5 files changed

+106
-14
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ mvn clean install
1818
```
1919

2020
## Options
21-
| options | description | must | remark |
22-
|-----------------------|----------------------------------------------|------|-----------------------------------------------------------|
23-
| `-m, --model` | The path of the model file or model text | y | Please wrap it with `""` and separate each line with `\|` |
24-
| `-p, --policy` | The path of the policy file or policy text | y | Please wrap it with `""` and separate each line with `\|` |
25-
| `-e, --enforce` | Check permissions | n | Please wrap it with `""` |
26-
| `-ex, --enforceEx` | Check permissions and get which policy it is | n | Please wrap it with `""` |
27-
| `-AF, --addFuntion` | Add custom funtion | n | Please wrap it with `""` and separate each line with `\|` |
28-
| `-ap, --addPolicy` | Add a policy rule to the policy file | n | Please wrap it with `""` |
29-
| `-rp, --removePolicy` | Remove a policy rule from the policy file | n | Please wrap it with `""` |
21+
| options | description | must | remark |
22+
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------|-----------------------------------------------------------|
23+
| `-m, --model` | The path of the model file or model text | y | Please wrap it with `""` and separate each line with `\|` |
24+
| `-p, --policy` | The path of the policy file or policy text | y | Please wrap it with `""` and separate each line with `\|` |
25+
| `-e, --enforce` | Check permissions | n | Please wrap it with `""` |
26+
| `-ex, --enforceEx` | Check permissions and get which policy it is | n | Please wrap it with `""` |
27+
| `-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 `\|` |
28+
| `-ap, --addPolicy` | Add a policy rule to the policy file | n | Please wrap it with `""` |
29+
| `-rp, --removePolicy` | Remove a policy rule from the policy file | n | Please wrap it with `""` |
3030

3131
## Get started
3232

examples/keymatch_function.conf

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[function_definition]
2+
public static boolean keyMatchTest(String key1, String key2) {
3+
int i = key2.indexOf('*');
4+
if (i == -1) {
5+
return key1.equals(key2);
6+
}
7+
8+
if (key1.length() > i) {
9+
return key1.substring(0, i).equals(key2.substring(0, i));
10+
}
11+
return key1.equals(key2.substring(0, i));
12+
}
13+
14+
[function_definition]
15+
public static boolean keyMatchTest2(String key1, String key2) {
16+
int i = key2.indexOf('*');
17+
if (i == -1) {
18+
return key1.equals(key2);
19+
}
20+
21+
if (key1.length() > i) {
22+
return key1.substring(0, i).equals(key2.substring(0, i));
23+
}
24+
return key1.equals(key2.substring(0, i));
25+
}

src/main/java/org/casbin/Client.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ public static String run(String... args) {
4343
NewEnforcer enforcer = new NewEnforcer(model, policy);
4444

4545
if(cmd.hasOption("AF")) {
46-
String codes = cmd.getOptionValue("AF");
47-
String methodName = Util.getMethodName(codes);
48-
CustomFunction customFunction = DynamicClassGenerator.generateClass(methodName, codes);
49-
enforcer.addFunction(methodName, customFunction);
46+
List<String> codes = Util.parse(cmd.getOptionValue("AF"));
47+
for (String code : codes) {
48+
String methodName = Util.getMethodName(code);
49+
CustomFunction customFunction = DynamicClassGenerator.generateClass(methodName, code);
50+
enforcer.addFunction(methodName, customFunction);
51+
}
5052
}
5153
CommandExecutor commandExecutor = new CommandExecutor(enforcer, commandName, cmd.getArgs());
5254
Object o = commandExecutor.outputResult();
@@ -110,7 +112,7 @@ private static void printHelpMessage() {
110112
" Options:\n" +
111113
" -m, --model <model> The path of the model file or model text. Please wrap it with \"\" and separate each line with \"|\"\n" +
112114
" -p, --policy <policy> The path of the policy file or policy text. Please wrap it with \"\" and separate each line with \"|\"\n" +
113-
" -AF, --addFunction <functionDefinition> Add custom function. Please wrap it with \"\" and separate each line with \"|\"\n" +
115+
" -AF, --addFunction <functionDefinition> The path of the function file or function text. Please wrap it with \"\" and separate each line with \"|\"\n" +
114116
"\n" +
115117
" args:\n" +
116118
" Parameters required for the method\n" +

src/main/java/org/casbin/util/Util.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package org.casbin.util;
22

3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.nio.charset.StandardCharsets;
6+
import java.nio.file.Files;
37
import java.util.ArrayList;
48
import java.util.Arrays;
59
import java.util.List;
@@ -26,4 +30,30 @@ public static int getArgsNum(String methodCodes) {
2630
}
2731
return 0;
2832
}
33+
34+
/**
35+
* Parse the input string to get the function definitions List
36+
* @param input
37+
* @return List of function definitions
38+
*/
39+
public static List<String> parse(String input) throws IOException {
40+
if (input == null || input.trim().isEmpty()) {
41+
throw new IllegalArgumentException("Input cannot be null or empty");
42+
}
43+
List<String> codes = new ArrayList<>();
44+
45+
// Check if input is an existing file
46+
File file = new File(input);
47+
if (file.exists() && file.isFile()) {
48+
String content = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
49+
50+
String[] lines = content.split("\\[function_definition\\]");
51+
for (int i = 1; i < lines.length; i++) {
52+
codes.add(lines[i].trim());
53+
}
54+
} else {
55+
codes.add(input);
56+
}
57+
return codes;
58+
}
2959
}

src/test/java/org/casbin/ClientTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,41 @@ public void testCustomFunction() throws ParseException {
116116
assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "cathy", "/cathy_data", "POST"}), "{\"allow\":true,\"explain\":null}");
117117
assertEquals(Client.run(new String[]{"enforce", "-m", model, "-p", "examples/keymatch_policy.csv", "-AF", func, "cathy", "/cathy_data", "DELETE"}), "{\"allow\":false,\"explain\":null}");
118118

119+
// test add Function using file
120+
String methodName2 = "keyMatchTest2";
121+
String model2 = "[request_definition]\n" +
122+
"r = sub, obj, act\n" +
123+
"\n" +
124+
"[policy_definition]\n" +
125+
"p = sub, obj, act\n" +
126+
"\n" +
127+
"[policy_effect]\n" +
128+
"e = some(where (p.eft == allow))\n" +
129+
"\n" +
130+
"[matchers]\n" +
131+
"m = r.sub == p.sub && " + methodName + "(r.obj, p.obj) && " + methodName2 + "(r.obj, p.obj)" + "&& regexMatch(r.act, p.act)\n";
132+
133+
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}");
134+
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}");
135+
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}");
136+
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}");
137+
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}");
138+
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}");
139+
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}");
140+
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}");
141+
142+
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}");
143+
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}");
144+
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}");
145+
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}");
146+
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}");
147+
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}");
148+
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}");
149+
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}");
150+
151+
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}");
152+
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}");
153+
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}");
119154
}
120155

121156
@Test

0 commit comments

Comments
 (0)