@@ -18,9 +18,10 @@ import { DefaultEffector, Effect, Effector } from './effect';
18
18
import { FunctionMap , Model , newModel } from './model' ;
19
19
import { Adapter , Filter , FilteredAdapter , Watcher } from './persist' ;
20
20
import { DefaultRoleManager , RoleManager } from './rbac' ;
21
- import { generateGFunction } from './util' ;
21
+ import { generateGFunction , hasEval , getEvalValue , escapeAssertion , replaceEval } from './util' ;
22
22
import { getLogger , logPrint } from './log' ;
23
23
24
+ type Matcher = ( ( context : object ) => Promise < any > ) | ( ( context : object ) => any ) ;
24
25
/**
25
26
* CoreEnforcer defines the core functionality of an enforcer.
26
27
*/
@@ -29,7 +30,7 @@ export class CoreEnforcer {
29
30
protected model : Model ;
30
31
protected fm : FunctionMap = FunctionMap . loadFunctionMap ( ) ;
31
32
protected eft : Effector = new DefaultEffector ( ) ;
32
- private matcherMap : Map < string , ( ( context : object ) => Promise < any > ) | ( ( context : object ) => any ) > = new Map ( ) ;
33
+ private matcherMap : Map < string , Matcher > = new Map ( ) ;
33
34
34
35
protected adapter : FilteredAdapter | Adapter ;
35
36
protected watcher : Watcher | null = null ;
@@ -40,6 +41,17 @@ export class CoreEnforcer {
40
41
protected autoBuildRoleLinks = true ;
41
42
protected autoNotifyWatcher = true ;
42
43
44
+ private getExpression ( asyncCompile : boolean , exp : string ) : Matcher {
45
+ const matcherKey = `${ asyncCompile ? 'ASYNC[' : 'SYNC[' } ${ exp } ]` ;
46
+
47
+ let expression = this . matcherMap . get ( matcherKey ) ;
48
+ if ( ! expression ) {
49
+ expression = asyncCompile ? compileAsync ( exp ) : compile ( exp ) ;
50
+ this . matcherMap . set ( matcherKey , expression ) ;
51
+ }
52
+ return expression ;
53
+ }
54
+
43
55
/**
44
56
* loadModel reloads the model from the model CONF file.
45
57
* Because the policy is attached to a model,
@@ -279,12 +291,11 @@ export class CoreEnforcer {
279
291
throw new Error ( 'Unable to find policy_effect in model' ) ;
280
292
}
281
293
282
- const matcherKey = `${ asyncCompile ? 'ASYNC[' : 'SYNC[' } ${ expString } ]` ;
294
+ const HasEval : boolean = hasEval ( expString ) ;
295
+ let expression ;
283
296
284
- let expression = this . matcherMap . get ( matcherKey ) ;
285
- if ( ! expression ) {
286
- expression = asyncCompile ? compileAsync ( expString ) : compile ( expString ) ;
287
- this . matcherMap . set ( matcherKey , expression ) ;
297
+ if ( ! HasEval ) {
298
+ expression = this . getExpression ( asyncCompile , expString ) ;
288
299
}
289
300
290
301
let policyEffects : Effect [ ] ;
@@ -315,8 +326,26 @@ export class CoreEnforcer {
315
326
parameters [ token ] = p ?. policy [ i ] [ j ] ;
316
327
} ) ;
317
328
318
- const context = { ...parameters , ...functions } ;
319
- const result = asyncCompile ? await expression ( context ) : expression ( context ) ;
329
+ if ( HasEval ) {
330
+ const ruleNames : string [ ] = getEvalValue ( expString ) ;
331
+ let expWithRule = expString ;
332
+ for ( const ruleName of ruleNames ) {
333
+ if ( ruleName in parameters ) {
334
+ const rule = escapeAssertion ( parameters [ ruleName ] ) ;
335
+ expWithRule = replaceEval ( expWithRule , rule ) ;
336
+ } else {
337
+ return false ;
338
+ }
339
+
340
+ expression = this . getExpression ( asyncCompile , expWithRule ) ;
341
+ }
342
+ }
343
+
344
+ let result ;
345
+ if ( expression != undefined ) {
346
+ const context = { ...parameters , ...functions } ;
347
+ result = asyncCompile ? await expression ( context ) : expression ( context ) ;
348
+ }
320
349
321
350
switch ( typeof result ) {
322
351
case 'boolean' :
@@ -368,8 +397,12 @@ export class CoreEnforcer {
368
397
parameters [ token ] = '' ;
369
398
} ) ;
370
399
371
- const context = { ...parameters , ...functions } ;
372
- const result = asyncCompile ? await expression ( context ) : expression ( context ) ;
400
+ let result = false ;
401
+
402
+ if ( expression != undefined ) {
403
+ const context = { ...parameters , ...functions } ;
404
+ result = asyncCompile ? await expression ( context ) : expression ( context ) ;
405
+ }
373
406
374
407
if ( result ) {
375
408
policyEffects [ 0 ] = Effect . Allow ;
0 commit comments