diff --git a/README.md b/README.md index f3dee59..19a9343 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ mvn clean install ``` > {"allow":true,"explain":null} ```shell - ./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" + ./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" ``` > {"allow":true,"explain":null} diff --git a/src/main/java/org/casbin/Client.java b/src/main/java/org/casbin/Client.java index b404d78..09af32a 100644 --- a/src/main/java/org/casbin/Client.java +++ b/src/main/java/org/casbin/Client.java @@ -1,6 +1,5 @@ package org.casbin; - import org.apache.commons.cli.*; import org.casbin.generate.DynamicClassGenerator; import org.casbin.jcasbin.util.function.CustomFunction; @@ -8,7 +7,6 @@ import java.util.*; - public class Client { public static String run(String... args) { @@ -25,12 +23,18 @@ public static String run(String... args) { return result; } - CommandLine cmd = getCmd(Arrays.copyOfRange(args, 1, args.length)); + // processing line breaks in parameters + String[] processedArgs = new String[args.length]; + processedArgs[0] = args[0]; + for (int i = 1; i < args.length; i++) { + processedArgs[i] = args[i] != null ? args[i].replace("\\n", "\n") : null; + } + + CommandLine cmd = getCmd(Arrays.copyOfRange(processedArgs, 1, processedArgs.length)); String model = cmd.getOptionValue("model"); String policy = cmd.getOptionValue("policy"); NewEnforcer enforcer = new NewEnforcer(model, policy); - if(cmd.hasOption("AF")) { String codes = cmd.getOptionValue("AF"); String methodName = Util.getMethodName(codes); @@ -50,7 +54,6 @@ public static String run(String... args) { return result; } - private static void printUsageMessageAndExit(String commandName) throws Exception { if (commandName.isEmpty()) { System.out.println("Error: " + commandName + " not recognised"); diff --git a/src/main/java/org/casbin/NewEnforcer.java b/src/main/java/org/casbin/NewEnforcer.java index 31736f1..5e98501 100644 --- a/src/main/java/org/casbin/NewEnforcer.java +++ b/src/main/java/org/casbin/NewEnforcer.java @@ -1,72 +1,77 @@ package org.casbin; import org.casbin.jcasbin.main.Enforcer; -import org.casbin.jcasbin.util.function.CustomFunction; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; import java.util.regex.Pattern; public class NewEnforcer extends Enforcer { + private static final Pattern MODEL_SECTION_PATTERN = Pattern.compile( + "\\[request_definition\\].*?" + + "\\[policy_definition\\].*?" + + "\\[policy_effect\\].*?" + + "\\[matchers\\]", + Pattern.DOTALL + ); + + private static final Pattern POLICY_LINE_PATTERN = Pattern.compile( + "^\\s*(p|g),.*", + Pattern.MULTILINE + ); + public NewEnforcer(String modelPath, String policyFile) { - super(parse(modelPath, ".conf"), parse(policyFile, ".csv")); + super(parse(modelPath, true), parse(policyFile, false)); } - public static String parse(String string, String suffix) { - string = string.replace("|","\n"); - boolean isFile = string.endsWith(suffix); - if(suffix.equals(".conf")) { - if(isFile) { - try { - simpleCheck(new String(Files.readAllBytes(Paths.get(string)), StandardCharsets.UTF_8)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } else { - simpleCheck(string); + public static String parse(String input, boolean isModel) { + if (input == null || input.trim().isEmpty()) { + throw new IllegalArgumentException("Input cannot be null or empty"); + } + + // Check if input is an existing file + File file = new File(input); + if (file.exists() && file.isFile()) { + return input; + } + + // If not a file, validate content format + if (isModel) { + if (!isValidModelContent(input)) { + throw new IllegalArgumentException("Invalid model format. Model must contain required sections: [request_definition], [policy_definition], [policy_effect], and [matchers]"); + } + } else { + if (!input.trim().isEmpty() && !isValidPolicyContent(input)) { + throw new IllegalArgumentException("Invalid policy format. Policy must contain lines starting with 'p,' or 'g,' or be empty"); } } - return isFile ? string : writeToTempFile(string, suffix); + + // If content is valid, write to temp file + return writeToTempFile(input); + } + + private static boolean isValidModelContent(String content) { + return MODEL_SECTION_PATTERN.matcher(content).find(); } - public static String writeToTempFile(String str, String suffix) { + private static boolean isValidPolicyContent(String content) { + return content.trim().isEmpty() || POLICY_LINE_PATTERN.matcher(content).find(); + } + + public static String writeToTempFile(String content) { File tempFile = null; try { - tempFile = File.createTempFile("default", suffix); + tempFile = File.createTempFile("casbin_temp_", ""); tempFile.deleteOnExit(); try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { - writer.write(str); + writer.write(content); } } catch (IOException e) { - e.printStackTrace(); + throw new RuntimeException("Error creating temporary file", e); } return tempFile.getAbsolutePath(); } - - private static void simpleCheck(String fileString) { - fileString = fileString.replace(" ",""); - String[] requiredSubstrings = {"[request_definition]", "[policy_definition]", "[policy_effect]", "[matchers]", "r=", "p=", "e=", "m="}; - List missingSubstrings = new ArrayList<>(); - - for (String substring : requiredSubstrings) { - Pattern pattern = Pattern.compile(Pattern.quote(substring)); - Matcher matcher = pattern.matcher(fileString); - if (!matcher.find()) { - missingSubstrings.add(substring); - } - } - - if(!missingSubstrings.isEmpty()) { - throw new RuntimeException("missing required sections: " + String.join(", ", missingSubstrings)); - } - } } \ No newline at end of file