Skip to content

Commit

Permalink
feat: improve keyMatch4(), align with Casbin Editor (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
PokIsemaine authored Aug 8, 2023
1 parent a13ba2f commit cf4dd31
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 45 deletions.
92 changes: 47 additions & 45 deletions src/main/java/org/casbin/jcasbin/util/BuiltInFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,58 +119,60 @@ public static boolean keyMatch3(String key1, String key2) {
* @return whether key1 matches key2.
*/
public static boolean keyMatch4(String key1, String key2) {
String regEx = "\\{[^/]+\\}";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(key2);
key2 = key2.replace("/*", "/.*");

String[] tmp = p.split(key2);
List<String> tokens = new ArrayList<>();
if (tmp.length > 0) {
int count = 0;
while (count < tmp.length) {
tokens.add(tmp[count]);
if (m.find()) {
tokens.add(m.group());
}
count++;
ArrayList<String> tokens = new ArrayList<>();

Pattern p = Pattern.compile("\\{[^{}]*\\}");
Matcher m = p.matcher(key2);
StringBuffer sb = new StringBuffer();
while(m.find()) {
String group = m.group();
tokens.add(group);
if(group.contains("/")) {
group = group.replace("{", "\\{")
.replace("}", "\\}")
.replace("/", "\\/");
m.appendReplacement(sb, Matcher.quoteReplacement(group));
} else {
m.appendReplacement(sb, "([^/]+)");
}
}
int off = 0;
for (String token : tokens) {
if (!p.matcher(token).matches()) {
while (off < key1.length() && key1.charAt(off) != token.charAt(0)) {
off++;
}
if (key1.length() - (off + 1) < token.length()) {
return false;
}
if (!key1.startsWith(token, off)) {
return false;
}
key1 = key1.replaceFirst(token, ",");
m.appendTail(sb);
key2 = sb.toString();

p = Pattern.compile("^" + key2 + "$");
m = p.matcher(key1);

ArrayList<String> matches = new ArrayList<>();
if (m.find()) {
for (int i = 0; i <= m.groupCount(); i++) {
matches.add(m.group(i));
}
}
String[] values = key1.split(",");
int i = 0;
Map<String, String> params = new HashMap<>();
for (String token : tokens) {
if (p.matcher(token).matches()) {
while (i < values.length && "".equals(values[i])) {
i++;
}
if (i == values.length) {
return false;
}
if (params.containsKey(token)) {
if (!values[i].equals(params.get(token))) {
return false;
}
} else {
params.put(token, values[i]);
}
i++;

if(matches.isEmpty()) {
return false;
}

matches.remove(0);

if(tokens.size() != matches.size()) {
throw new RuntimeException("KeyMatch4: number of tokens is not equal to number of values");
}

Map<String ,String> values = new HashMap<>();

for (int key = 0; key < tokens.size(); ++key) {
String token = tokens.get(key);
if(!values.containsKey(token)) {
values.put(token, matches.get(key));
}
if(!values.get(token).equals(matches.get(key))) {
return false;
}
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ public void testKeyMatch4Func() {
testKeyMatch4("/parent/123/child/456", "/parent/{id}/child/{id}/book/{id}", false);

testKeyMatch4("/parent/123/child/123", "/parent/{i/d}/child/{i/d}", false);

testKeyMatch4("/pipeline/work-order/sit/deploy", "/pipeline/work-order/*/deploy", true);
}

@Test
Expand Down

0 comments on commit cf4dd31

Please sign in to comment.