Skip to content

Commit 2cebcf5

Browse files
Copilothsluoyz
andcommitted
refactor: add policy type reference check like Go Casbin
Check if matcher contains policy type tokens (e.g., p_, p2_) before evaluating, consistent with Go Casbin implementation. Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
1 parent 755b02a commit 2cebcf5

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/coreEnforcer.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ export class CoreEnforcer {
490490
let effectDone = false;
491491
if (hasPolicies) {
492492
// Iterate through all policy types (p, p2, p3, etc.)
493+
// This allows a single matcher to reference multiple policy types
494+
// For example: m = r.sub == p.sub && ... || r.sub == p2.sub && ...
493495
for (const ptype of policyTypes) {
494496
if (effectDone) {
495497
break;
@@ -500,6 +502,12 @@ export class CoreEnforcer {
500502
continue;
501503
}
502504

505+
// Check if the matcher expression contains references to this policy type
506+
// This is consistent with Go Casbin's behavior
507+
if (!expString.includes(`${ptype}_`)) {
508+
continue;
509+
}
510+
503511
const policyLen = policyDef.policy.length;
504512

505513
// Iterate through all policies of this type
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { newModel, newEnforcer, StringAdapter } from '../src';
2+
3+
describe('Exact issue scenario', () => {
4+
test('Matcher only references p (not p2) - like issue screenshot', async () => {
5+
// This is the EXACT scenario from the issue screenshot
6+
// Matcher ONLY references p, not p2
7+
const modelText = `
8+
[request_definition]
9+
r = sub, obj, act
10+
11+
[policy_definition]
12+
p = sub, obj, act
13+
p2 = sub, act
14+
15+
[policy_effect]
16+
e = some(where (p.eft == allow))
17+
18+
[matchers]
19+
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
20+
`;
21+
22+
const policyText = `
23+
p, alice, data1, read
24+
p2, bob, write-all-objects
25+
`;
26+
27+
const m = newModel(modelText);
28+
const a = new StringAdapter(policyText);
29+
const e = await newEnforcer(m, a);
30+
31+
// Test 1: alice with p policy - should work
32+
await expect(e.enforce('alice', 'data1', 'read')).resolves.toBe(true);
33+
34+
// Test 2: bob with p2 policy - won't work because matcher doesn't reference p2
35+
// This matches Go Casbin's behavior
36+
await expect(e.enforce('bob', 'data1', 'write-all-objects')).resolves.toBe(false);
37+
});
38+
});

0 commit comments

Comments
 (0)