From 446f8c700ab13cea5413d311da33e80dd6165f0e Mon Sep 17 00:00:00 2001 From: Zxilly Date: Fri, 13 Aug 2021 18:41:19 +0800 Subject: [PATCH] fix: add full supoort for `in` operator (#310) Signed-off-by: Zxilly --- examples/in_operator_model.conf | 2 +- src/coreEnforcer.ts | 15 +++++++++++---- src/util/util.ts | 8 ++++++++ test/model.test.ts | 12 ++++++------ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/examples/in_operator_model.conf b/examples/in_operator_model.conf index 452325c..c83ac9b 100644 --- a/examples/in_operator_model.conf +++ b/examples/in_operator_model.conf @@ -8,4 +8,4 @@ p = sub, obj, act e = some(where (p.eft == allow)) [matchers] -m = r.sub.Owner == r.obj.Owner && r.sub.Doc in(r.obj.Docs) +m = r.sub.Owner == r.obj.Owner && r.sub.Doc in (r.obj.Docs) diff --git a/src/coreEnforcer.ts b/src/coreEnforcer.ts index 1a9aef7..e3de233 100644 --- a/src/coreEnforcer.ts +++ b/src/coreEnforcer.ts @@ -18,7 +18,16 @@ import { DefaultEffector, Effect, Effector } from './effect'; import { FunctionMap, Model, newModel, PolicyOp } from './model'; import { Adapter, FilteredAdapter, Watcher, BatchAdapter, UpdatableAdapter } from './persist'; import { DefaultRoleManager, RoleManager } from './rbac'; -import { escapeAssertion, generateGFunction, getEvalValue, hasEval, replaceEval, generatorRunSync, generatorRunAsync } from './util'; +import { + escapeAssertion, + generateGFunction, + getEvalValue, + hasEval, + replaceEval, + generatorRunSync, + generatorRunAsync, + customIn, +} from './util'; import { getLogger, logPrint } from './log'; import { MatchingFunc } from './rbac'; @@ -48,9 +57,7 @@ export class CoreEnforcer { private getExpression(asyncCompile: boolean, exp: string): Matcher { const matcherKey = `${asyncCompile ? 'ASYNC[' : 'SYNC['}${exp}]`; - addBinaryOp('in', 1, (a, b) => { - return (((b as unknown) as Array).includes(a) as unknown) as number; - }); + addBinaryOp('in', 1, customIn); let expression = this.matcherMap.get(matcherKey); if (!expression) { diff --git a/src/util/util.ts b/src/util/util.ts index 2d55149..b098394 100644 --- a/src/util/util.ts +++ b/src/util/util.ts @@ -170,6 +170,13 @@ function deepCopy(obj: Array | any): any { return newObj; } +function customIn(a: number | string, b: number | string): number { + if ((b as any) instanceof Array) { + return (((b as any) as Array).includes(a) as unknown) as number; + } + return ((a in (b as any)) as unknown) as number; +} + export { escapeAssertion, removeComments, @@ -187,4 +194,5 @@ export { generatorRunSync, generatorRunAsync, deepCopy, + customIn, }; diff --git a/test/model.test.ts b/test/model.test.ts index 433f5f2..252b551 100644 --- a/test/model.test.ts +++ b/test/model.test.ts @@ -425,9 +425,9 @@ test('ABACModelWithInOperator', async () => { class TestRule1 { public Owner: string; - public Doc: number; + public Doc: string; - constructor(Owner: string, Doc: number) { + constructor(Owner: string, Doc: string) { this.Owner = Owner; this.Doc = Doc; } @@ -435,16 +435,16 @@ test('ABACModelWithInOperator', async () => { class TestRule2 { public Owner: string; - public Docs: Array; + public Docs: Array; - constructor(Owner: string, Doc: Array) { + constructor(Owner: string, Doc: string[]) { this.Owner = Owner; this.Docs = Doc; } } - const rule1 = new TestRule1('alice', 1); - const rule2 = new TestRule2('alice', [1, 2]); + const rule1 = new TestRule1('alice', 'aa'); + const rule2 = new TestRule2('alice', ['aa', 'bb']); await expect(e.enforce(rule1, rule2)).resolves.toBe(true); });