Skip to content

Commit 48b0d8f

Browse files
nodeceGabriel-403
andauthored
feat: Multiple sections type (#442)
(cherry picked from commit 2635601ab1b1dd8d613bbb6b62d52f1cb86400f6) Signed-off-by: Gabriel-403 <1499015923@qq.com> Signed-off-by: Zixuan Liu <nodeces@gmail.com> Co-authored-by: Gabriel-403 <1499015923@qq.com>
1 parent 1d362b6 commit 48b0d8f

File tree

6 files changed

+143
-12
lines changed

6 files changed

+143
-12
lines changed

examples/mulitple_policy.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
p2, alice, data1, read
2+
p2, bob, data2, write

src/coreEnforcer.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { DefaultEffector, Effect, Effector } from './effect';
1818
import { FunctionMap, Model, newModelFromFile, PolicyOp } from './model';
1919
import { Adapter, FilteredAdapter, Watcher, BatchAdapter, UpdatableAdapter, WatcherEx } from './persist';
2020
import { DefaultRoleManager, RoleManager } from './rbac';
21+
import { EnforceContext } from './enforceContext';
22+
2123
import {
2224
escapeAssertion,
2325
generateGFunction,
@@ -47,6 +49,7 @@ export class CoreEnforcer {
4749
protected fm: FunctionMap = FunctionMap.loadFunctionMap();
4850
protected eft: Effector = new DefaultEffector();
4951
private matcherMap: Map<string, Matcher> = new Map();
52+
private defaultEnforceContext: EnforceContext = new EnforceContext('r', 'p', 'e', 'm');
5053

5154
protected adapter: UpdatableAdapter | FilteredAdapter | Adapter | BatchAdapter;
5255
protected watcher: Watcher | null = null;
@@ -411,7 +414,12 @@ export class CoreEnforcer {
411414
}
412415
}
413416

414-
private *privateEnforce(asyncCompile = true, explain = false, ...rvals: any[]): EnforceResult {
417+
private *privateEnforce(
418+
asyncCompile = true,
419+
explain = false,
420+
enforceContext: EnforceContext = new EnforceContext('r', 'p', 'e', 'm'),
421+
...rvals: any[]
422+
): EnforceResult {
415423
if (!this.enabled) {
416424
return true;
417425
}
@@ -430,23 +438,23 @@ export class CoreEnforcer {
430438
functions[key] = asyncCompile ? generateGFunction(rm) : generateSyncedGFunction(rm);
431439
});
432440

433-
const expString = this.model.model.get('m')?.get('m')?.value;
441+
const expString = this.model.model.get('m')?.get(enforceContext.mType)?.value;
434442
if (!expString) {
435443
throw new Error('Unable to find matchers in model');
436444
}
437445

438-
const effectExpr = this.model.model.get('e')?.get('e')?.value;
446+
const effectExpr = this.model.model.get('e')?.get(enforceContext.eType)?.value;
439447
if (!effectExpr) {
440448
throw new Error('Unable to find policy_effect in model');
441449
}
442450

443451
const HasEval: boolean = hasEval(expString);
444452
let expression: Matcher | undefined = undefined;
445453

446-
const p = this.model.model.get('p')?.get('p');
454+
const p = this.model.model.get('p')?.get(enforceContext.pType);
447455
const policyLen = p?.policy?.length;
448456

449-
const rTokens = this.model.model.get('r')?.get('r')?.tokens;
457+
const rTokens = this.model.model.get('r')?.get(enforceContext.rType)?.tokens;
450458
const rTokensLen = rTokens?.length;
451459

452460
const effectStream = this.eft.newStream(effectExpr);
@@ -594,7 +602,11 @@ export class CoreEnforcer {
594602
* @return whether to allow the request.
595603
*/
596604
public enforceSync(...rvals: any[]): boolean {
597-
return generatorRunSync(this.privateEnforce(false, false, ...rvals));
605+
if (rvals[0] instanceof EnforceContext) {
606+
const enforceContext: EnforceContext = rvals.shift();
607+
return generatorRunSync(this.privateEnforce(false, false, enforceContext, ...rvals));
608+
}
609+
return generatorRunSync(this.privateEnforce(false, false, this.defaultEnforceContext, ...rvals));
598610
}
599611

600612
/**
@@ -608,7 +620,11 @@ export class CoreEnforcer {
608620
* @return whether to allow the request and the reason rule.
609621
*/
610622
public enforceExSync(...rvals: any[]): [boolean, string[]] {
611-
return generatorRunSync(this.privateEnforce(false, true, ...rvals));
623+
if (rvals[0] instanceof EnforceContext) {
624+
const enforceContext: EnforceContext = rvals.shift();
625+
return generatorRunSync(this.privateEnforce(false, true, enforceContext, ...rvals));
626+
}
627+
return generatorRunSync(this.privateEnforce(false, true, this.defaultEnforceContext, ...rvals));
612628
}
613629

614630
/**
@@ -627,7 +643,11 @@ export class CoreEnforcer {
627643
* @return whether to allow the request.
628644
*/
629645
public async enforce(...rvals: any[]): Promise<boolean> {
630-
return generatorRunAsync(this.privateEnforce(true, false, ...rvals));
646+
if (rvals[0] instanceof EnforceContext) {
647+
const enforceContext: EnforceContext = rvals.shift();
648+
return generatorRunAsync(this.privateEnforce(true, false, enforceContext, ...rvals));
649+
}
650+
return generatorRunAsync(this.privateEnforce(true, false, this.defaultEnforceContext, ...rvals));
631651
}
632652

633653
/**
@@ -639,7 +659,11 @@ export class CoreEnforcer {
639659
* @return whether to allow the request and the reason rule.
640660
*/
641661
public async enforceEx(...rvals: any[]): Promise<[boolean, string[]]> {
642-
return generatorRunAsync(this.privateEnforce(true, true, ...rvals));
662+
if (rvals[0] instanceof EnforceContext) {
663+
const enforceContext: EnforceContext = rvals.shift();
664+
return generatorRunAsync(this.privateEnforce(true, true, enforceContext, ...rvals));
665+
}
666+
return generatorRunAsync(this.privateEnforce(true, true, this.defaultEnforceContext, ...rvals));
643667
}
644668

645669
/**

src/enforceContext.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2023 The Casbin Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
export class EnforceContext {
16+
public pType: string;
17+
public rType: string;
18+
public eType: string;
19+
public mType: string;
20+
21+
constructor(rType: string, pType: string, eType: string, mType: string) {
22+
this.pType = pType;
23+
this.eType = eType;
24+
this.mType = mType;
25+
this.rType = rType;
26+
}
27+
}
28+
29+
export const newEnforceContext = (index: string): EnforceContext => {
30+
return new EnforceContext('r' + index, 'p' + index, 'e' + index, 'm' + index);
31+
};

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ export * from './model';
2424
export * from './persist';
2525
export * from './rbac';
2626
export * from './log';
27+
export * from './enforceContext';
2728
export * from './frontend';
2829
export { Util };

src/util/util.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414

1515
// escapeAssertion escapes the dots in the assertion,
1616
// because the expression evaluation doesn't support such variable names.
17+
1718
import { mustGetDefaultFileSystem } from '../persist';
1819

1920
function escapeAssertion(s: string): string {
20-
s = s.replace(/(?<!\w)r\./g, 'r_');
21-
s = s.replace(/(?<!\w)p\./g, 'p_');
21+
s = s.replace(/(?<!\w)r[0-9]*\./g, (match) => {
22+
return match.replace('.', '_');
23+
});
24+
s = s.replace(/(?<!\w)p[0-9]*\./g, (match) => {
25+
return match.replace('.', '_');
26+
});
2227
return s;
2328
}
2429

test/enforcer.test.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import fs, { readFileSync } from 'fs';
1616

17-
import { newModel, newEnforcer, Enforcer, FileAdapter, StringAdapter, Util } from '../src';
17+
import { EnforceContext, Enforcer, FileAdapter, newEnforceContext, newEnforcer, newModel, StringAdapter, Util } from '../src';
1818

1919
async function testEnforce(e: Enforcer, sub: any, obj: string, act: string, res: boolean): Promise<void> {
2020
await expect(e.enforce(sub, obj, act)).resolves.toBe(res);
@@ -753,3 +753,71 @@ test('TestEnforcerWithScopeFileSystem', async () => {
753753
await testEnforce(e, 'bob', 'data2', 'write', true);
754754
await testEnforce(e, 'bob', 'data2', 'read', false);
755755
});
756+
757+
test('TestEnforce Multiple policies config', async () => {
758+
const m = newModel();
759+
m.addDef('r', 'r2', 'sub, obj, act');
760+
m.addDef('p', 'p2', 'sub, obj, act');
761+
m.addDef('g', 'g', '_, _');
762+
m.addDef('e', 'e2', 'some(where (p.eft == allow))');
763+
m.addDef('m', 'm2', 'g(r2.sub, p2.sub) && r2.obj == p2.obj && r2.act == p2.act');
764+
const a = new FileAdapter('examples/mulitple_policy.csv');
765+
766+
const e = await newEnforcer(m, a);
767+
768+
//const e = await getEnforcerWithPath(m);
769+
const enforceContext = new EnforceContext('r2', 'p2', 'e2', 'm2');
770+
await expect(e.enforce(enforceContext, 'alice', 'data1', 'read')).resolves.toStrictEqual(true);
771+
await expect(e.enforce(enforceContext, 'bob', 'data2', 'write')).resolves.toStrictEqual(true);
772+
});
773+
774+
test('new EnforceContext config', async () => {
775+
const m = newModel();
776+
m.addDef('r', 'r2', 'sub, obj, act');
777+
m.addDef('p', 'p2', 'sub, obj, act');
778+
m.addDef('g', 'g', '_, _');
779+
m.addDef('e', 'e2', 'some(where (p.eft == allow))');
780+
m.addDef('m', 'm2', 'g(r2.sub, p2.sub) && r2.obj == p2.obj && r2.act == p2.act');
781+
const a = new FileAdapter('examples/mulitple_policy.csv');
782+
783+
const e = await newEnforcer(m, a);
784+
785+
//const e = await getEnforcerWithPath(m);
786+
const enforceContext = newEnforceContext('2');
787+
await expect(e.enforce(enforceContext, 'alice', 'data1', 'read')).resolves.toStrictEqual(true);
788+
await expect(e.enforce(enforceContext, 'bob', 'data2', 'write')).resolves.toStrictEqual(true);
789+
});
790+
791+
test('TestEnforceEX Multiple policies config', async () => {
792+
const m = newModel();
793+
m.addDef('r', 'r2', 'sub, obj, act');
794+
m.addDef('p', 'p2', 'sub, obj, act');
795+
m.addDef('g', 'g', '_, _');
796+
m.addDef('e', 'e2', 'some(where (p.eft == allow))');
797+
m.addDef('m', 'm2', 'g(r2.sub, p2.sub) && r2.obj == p2.obj && r2.act == p2.act');
798+
const a = new FileAdapter('examples/mulitple_policy.csv');
799+
800+
const e = await newEnforcer(m, a);
801+
802+
//const e = await getEnforcerWithPath(m);
803+
const enforceContext = new EnforceContext('r2', 'p2', 'e2', 'm2');
804+
await expect(e.enforceEx(enforceContext, 'alice', 'data1', 'read')).resolves.toStrictEqual([true, ['alice', 'data1', 'read']]);
805+
await expect(e.enforceEx(enforceContext, 'bob', 'data2', 'write')).resolves.toStrictEqual([true, ['bob', 'data2', 'write']]);
806+
});
807+
808+
test('new EnforceContextEX config', async () => {
809+
const m = newModel();
810+
m.addDef('r', 'r2', 'sub, obj, act');
811+
m.addDef('p', 'p2', 'sub, obj, act');
812+
m.addDef('g', 'g', '_, _');
813+
m.addDef('e', 'e2', 'some(where (p.eft == allow))');
814+
m.addDef('m', 'm2', 'g(r2.sub, p2.sub) && r2.obj == p2.obj && r2.act == p2.act');
815+
const a = new FileAdapter('examples/mulitple_policy.csv');
816+
817+
const e = await newEnforcer(m, a);
818+
819+
//const e = await getEnforcerWithPath(m);
820+
const enforceContext = newEnforceContext('2');
821+
await expect(e.enforceEx(enforceContext, 'alice', 'data1', 'read')).resolves.toStrictEqual([true, ['alice', 'data1', 'read']]);
822+
await expect(e.enforceEx(enforceContext, 'bob', 'data2', 'write')).resolves.toStrictEqual([true, ['bob', 'data2', 'write']]);
823+
});

0 commit comments

Comments
 (0)