Skip to content

Commit bad4575

Browse files
authored
feat: remove file extension limit for model and policy files (#26)
* fix: processing line breaks in parameters * refactor: add content format validation for model and policy input * feat: update README.md
1 parent 49231e0 commit bad4575

File tree

3 files changed

+57
-49
lines changed

3 files changed

+57
-49
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ mvn clean install
3737
```
3838
> {"allow":true,"explain":null}
3939
```shell
40-
./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"
40+
./casbin enforce -m "[request_definition]\nr = sub, obj, act\n[policy_definition]\np = sub, obj, act\n[role_definition]\ng = _, _\n[policy_effect]\ne = some(where (p.eft == allow))\n[matchers]\nm = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act" -p "p, alice, data1, read\np, bob, data2, write\np, data2_admin, data2, read\np, data2_admin, data2, write\ng, alice, data2_admin" "alice" "data1" "read"
4141
```
4242
> {"allow":true,"explain":null}
4343

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package org.casbin;
22

3-
43
import org.apache.commons.cli.*;
54
import org.casbin.generate.DynamicClassGenerator;
65
import org.casbin.jcasbin.util.function.CustomFunction;
76
import org.casbin.util.Util;
87

98
import java.util.*;
109

11-
1210
public class Client {
1311

1412
public static String run(String... args) {
@@ -25,12 +23,18 @@ public static String run(String... args) {
2523
return result;
2624
}
2725

28-
CommandLine cmd = getCmd(Arrays.copyOfRange(args, 1, args.length));
26+
// processing line breaks in parameters
27+
String[] processedArgs = new String[args.length];
28+
processedArgs[0] = args[0];
29+
for (int i = 1; i < args.length; i++) {
30+
processedArgs[i] = args[i] != null ? args[i].replace("\\n", "\n") : null;
31+
}
32+
33+
CommandLine cmd = getCmd(Arrays.copyOfRange(processedArgs, 1, processedArgs.length));
2934
String model = cmd.getOptionValue("model");
3035
String policy = cmd.getOptionValue("policy");
3136
NewEnforcer enforcer = new NewEnforcer(model, policy);
3237

33-
3438
if(cmd.hasOption("AF")) {
3539
String codes = cmd.getOptionValue("AF");
3640
String methodName = Util.getMethodName(codes);
@@ -50,7 +54,6 @@ public static String run(String... args) {
5054
return result;
5155
}
5256

53-
5457
private static void printUsageMessageAndExit(String commandName) throws Exception {
5558
if (commandName.isEmpty()) {
5659
System.out.println("Error: " + commandName + " not recognised");
+48-43
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,77 @@
11
package org.casbin;
22

33
import org.casbin.jcasbin.main.Enforcer;
4-
import org.casbin.jcasbin.util.function.CustomFunction;
54

65
import java.io.BufferedWriter;
76
import java.io.File;
87
import java.io.FileWriter;
98
import java.io.IOException;
10-
import java.nio.charset.StandardCharsets;
11-
import java.nio.file.Files;
12-
import java.nio.file.Paths;
13-
import java.util.ArrayList;
14-
import java.util.List;
15-
import java.util.regex.Matcher;
169
import java.util.regex.Pattern;
1710

1811
public class NewEnforcer extends Enforcer {
1912

13+
private static final Pattern MODEL_SECTION_PATTERN = Pattern.compile(
14+
"\\[request_definition\\].*?" +
15+
"\\[policy_definition\\].*?" +
16+
"\\[policy_effect\\].*?" +
17+
"\\[matchers\\]",
18+
Pattern.DOTALL
19+
);
20+
21+
private static final Pattern POLICY_LINE_PATTERN = Pattern.compile(
22+
"^\\s*(p|g),.*",
23+
Pattern.MULTILINE
24+
);
25+
2026
public NewEnforcer(String modelPath, String policyFile) {
21-
super(parse(modelPath, ".conf"), parse(policyFile, ".csv"));
27+
super(parse(modelPath, true), parse(policyFile, false));
2228
}
2329

24-
public static String parse(String string, String suffix) {
25-
string = string.replace("|","\n");
26-
boolean isFile = string.endsWith(suffix);
27-
if(suffix.equals(".conf")) {
28-
if(isFile) {
29-
try {
30-
simpleCheck(new String(Files.readAllBytes(Paths.get(string)), StandardCharsets.UTF_8));
31-
} catch (IOException e) {
32-
throw new RuntimeException(e);
33-
}
34-
} else {
35-
simpleCheck(string);
30+
public static String parse(String input, boolean isModel) {
31+
if (input == null || input.trim().isEmpty()) {
32+
throw new IllegalArgumentException("Input cannot be null or empty");
33+
}
34+
35+
// Check if input is an existing file
36+
File file = new File(input);
37+
if (file.exists() && file.isFile()) {
38+
return input;
39+
}
40+
41+
// If not a file, validate content format
42+
if (isModel) {
43+
if (!isValidModelContent(input)) {
44+
throw new IllegalArgumentException("Invalid model format. Model must contain required sections: [request_definition], [policy_definition], [policy_effect], and [matchers]");
45+
}
46+
} else {
47+
if (!input.trim().isEmpty() && !isValidPolicyContent(input)) {
48+
throw new IllegalArgumentException("Invalid policy format. Policy must contain lines starting with 'p,' or 'g,' or be empty");
3649
}
3750
}
38-
return isFile ? string : writeToTempFile(string, suffix);
51+
52+
// If content is valid, write to temp file
53+
return writeToTempFile(input);
54+
}
55+
56+
private static boolean isValidModelContent(String content) {
57+
return MODEL_SECTION_PATTERN.matcher(content).find();
3958
}
4059

41-
public static String writeToTempFile(String str, String suffix) {
60+
private static boolean isValidPolicyContent(String content) {
61+
return content.trim().isEmpty() || POLICY_LINE_PATTERN.matcher(content).find();
62+
}
63+
64+
public static String writeToTempFile(String content) {
4265
File tempFile = null;
4366
try {
44-
tempFile = File.createTempFile("default", suffix);
67+
tempFile = File.createTempFile("casbin_temp_", "");
4568
tempFile.deleteOnExit();
4669
try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) {
47-
writer.write(str);
70+
writer.write(content);
4871
}
4972
} catch (IOException e) {
50-
e.printStackTrace();
73+
throw new RuntimeException("Error creating temporary file", e);
5174
}
5275
return tempFile.getAbsolutePath();
5376
}
54-
55-
private static void simpleCheck(String fileString) {
56-
fileString = fileString.replace(" ","");
57-
String[] requiredSubstrings = {"[request_definition]", "[policy_definition]", "[policy_effect]", "[matchers]", "r=", "p=", "e=", "m="};
58-
List<String> missingSubstrings = new ArrayList<>();
59-
60-
for (String substring : requiredSubstrings) {
61-
Pattern pattern = Pattern.compile(Pattern.quote(substring));
62-
Matcher matcher = pattern.matcher(fileString);
63-
if (!matcher.find()) {
64-
missingSubstrings.add(substring);
65-
}
66-
}
67-
68-
if(!missingSubstrings.isEmpty()) {
69-
throw new RuntimeException("missing required sections: " + String.join(", ", missingSubstrings));
70-
}
71-
}
7277
}

0 commit comments

Comments
 (0)