Skip to content

Commit

Permalink
feat: fix ConcurrentModificationException bug that breaks Enforcer wh…
Browse files Browse the repository at this point in the history
…en calling Enforce() (#390)
  • Loading branch information
LMay001 authored and hsluoyz committed Mar 13, 2024
1 parent 95ed353 commit c56af29
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
14 changes: 14 additions & 0 deletions examples/haslink_synchronized_model.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[request_definition]
r = sub, obj

[policy_definition]
p = sub, obj, eft

[role_definition]
g = _, _

[policy_effect]
e = !some(where (p.eft == deny))

[matchers]
m = r.sub == p.sub && g(r.obj, p.obj)
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public void deleteLink(String name1, String name2, String... domain) {
* hasLink determines whether role: name1 inherits role: name2. domain is a prefix to the roles.
*/
@Override
public boolean hasLink(String name1, String name2, String... domain) {
public synchronized boolean hasLink(String name1, String name2, String... domain) {
if (name1.equals(name2) || (this.matchingFunc != null && this.matchingFunc.test(name1, name2))) {
return true;
}
Expand Down
62 changes: 62 additions & 0 deletions src/test/java/org/casbin/jcasbin/main/EnforcerUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@
import org.casbin.jcasbin.model.Model;
import org.casbin.jcasbin.persist.Adapter;
import org.casbin.jcasbin.persist.file_adapter.FileAdapter;
import org.casbin.jcasbin.util.BuiltInFunctions;
import org.casbin.jcasbin.util.EnforceContext;
import org.casbin.jcasbin.util.Util;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

import static java.util.Arrays.asList;
import static org.casbin.jcasbin.main.CoreEnforcer.newModel;
Expand Down Expand Up @@ -632,6 +636,64 @@ public void testMultiplePolicyDefinitions() {
testEnforceWithContext(e, enforceContext, new AbacAPIUnitTest.TestEvalRule("alice", 30), "/data1", "read", true);
}

@Test
public void testHasLinkSynchronized(){
File testingDir = null;
try {
testingDir = Files.createTempDirectory("testingDir").toFile();
} catch (IOException e) {
throw new RuntimeException(e);
}

File f = null;
try {
f = File.createTempFile("policies", null, testingDir);
} catch (IOException e) {
throw new RuntimeException(e);
}

FileAdapter a = new FileAdapter(f.getAbsolutePath());

Enforcer e = new Enforcer("examples/haslink_synchronized_model.conf", a);

e.enableAutoSave(true);
e.addNamedMatchingFunc("g", "keyMatch4", BuiltInFunctions::keyMatch4);

// 添加 gs 角色的关系
String[][] gs = new String[1001][3];
gs[0] = new String[]{"[email protected]", "temp", "alice"};
for (int i = 0; i < 1000; i++) {
gs[i+1] = new String[]{i + "@alice.co", "temp", "alice"};
}
e.addGroupingPolicies(gs);

String[][] policy = {{"alice", "/data", "allow"}};
e.addPolicies(policy);
e.savePolicy();

int n = 100;
CountDownLatch countDownLatch = new CountDownLatch(n);

for (int i = 0; i < n; i++) {
int finalI = i;
new Thread(() -> {
boolean res = e.enforce("alice", "data");
if (!res){
System.out.println("result failure: " + finalI);
}
countDownLatch.countDown();
}).start();
}

try {
countDownLatch.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
}

System.out.println("Done!");
}

public static class TestSub{
private String name;

Expand Down

0 comments on commit c56af29

Please sign in to comment.