88from casbin .util import generate_g_function , SimpleEval , util
99
1010
11+ class EnforceContext :
12+ """
13+ EnforceContext is used as the first element of the parameter "rvals" in method "enforce"
14+ """
15+
16+ def __init__ (self , rtype : str , ptype : str , etype : str , mtype : str ):
17+ self .rtype : str = rtype
18+ self .ptype : str = ptype
19+ self .etype : str = etype
20+ self .mtype : str = mtype
21+
22+
1123class CoreEnforcer :
1224 """CoreEnforcer defines the core functionality of an enforcer."""
1325
@@ -250,6 +262,15 @@ def add_named_domain_matching_func(self, ptype, fn):
250262
251263 return False
252264
265+ def new_enforce_context (self , suffix : str ) -> EnforceContext :
266+
267+ return EnforceContext (
268+ rtype = "r" + suffix ,
269+ ptype = "p" + suffix ,
270+ etype = "e" + suffix ,
271+ mtype = "m" + suffix ,
272+ )
273+
253274 def enforce (self , * rvals ):
254275 """decides whether a "subject" can access a "object" with the operation "action",
255276 input parameters are usually: (sub, obj, act).
@@ -263,6 +284,11 @@ def enforce_ex(self, *rvals):
263284 return judge result with reason
264285 """
265286
287+ rtype = "r"
288+ ptype = "p"
289+ etype = "e"
290+ mtype = "m"
291+
266292 if not self .enabled :
267293 return [False , []]
268294
@@ -273,19 +299,28 @@ def enforce_ex(self, *rvals):
273299 rm = ast .rm
274300 functions [key ] = generate_g_function (rm )
275301
302+ if len (rvals ) != 0 :
303+ if isinstance (rvals [0 ], EnforceContext ):
304+ enforce_context = rvals [0 ]
305+ rtype = enforce_context .rtype
306+ ptype = enforce_context .ptype
307+ etype = enforce_context .etype
308+ mtype = enforce_context .mtype
309+ rvals = rvals [1 :]
310+
276311 if "m" not in self .model .keys ():
277312 raise RuntimeError ("model is undefined" )
278313
279314 if "m" not in self .model ["m" ].keys ():
280315 raise RuntimeError ("model is undefined" )
281316
282- r_tokens = self .model ["r" ]["r" ].tokens
283- p_tokens = self .model ["p" ]["p" ].tokens
317+ r_tokens = self .model ["r" ][rtype ].tokens
318+ p_tokens = self .model ["p" ][ptype ].tokens
284319
285320 if len (r_tokens ) != len (rvals ):
286321 raise RuntimeError ("invalid request size" )
287322
288- exp_string = self .model ["m" ]["m" ].value
323+ exp_string = self .model ["m" ][mtype ].value
289324 has_eval = util .has_eval (exp_string )
290325 if not has_eval :
291326 expression = self ._get_expression (exp_string , functions )
@@ -294,11 +329,11 @@ def enforce_ex(self, *rvals):
294329
295330 r_parameters = dict (zip (r_tokens , rvals ))
296331
297- policy_len = len (self .model ["p" ]["p" ].policy )
332+ policy_len = len (self .model ["p" ][ptype ].policy )
298333
299334 explain_index = - 1
300335 if not 0 == policy_len :
301- for i , pvals in enumerate (self .model ["p" ]["p" ].policy ):
336+ for i , pvals in enumerate (self .model ["p" ][ptype ].policy ):
302337 if len (p_tokens ) != len (pvals ):
303338 raise RuntimeError ("invalid policy size" )
304339
@@ -327,8 +362,9 @@ def enforce_ex(self, *rvals):
327362 else :
328363 raise RuntimeError ("matcher result should be bool, int or float" )
329364
330- if "p_eft" in parameters .keys ():
331- eft = parameters ["p_eft" ]
365+ p_eft_key = ptype + "_eft"
366+ if p_eft_key in parameters .keys ():
367+ eft = parameters [p_eft_key ]
332368 if "allow" == eft :
333369 policy_effects .add (Effector .ALLOW )
334370 elif "deny" == eft :
@@ -353,7 +389,7 @@ def enforce_ex(self, *rvals):
353389
354390 parameters = r_parameters .copy ()
355391
356- for token in self .model ["p" ]["p" ].tokens :
392+ for token in self .model ["p" ][ptype ].tokens :
357393 parameters [token ] = ""
358394
359395 result = expression .eval (parameters )
@@ -380,7 +416,7 @@ def enforce_ex(self, *rvals):
380416
381417 explain_rule = []
382418 if explain_index != - 1 and explain_index < policy_len :
383- explain_rule = self .model ["p" ]["p" ].policy [explain_index ]
419+ explain_rule = self .model ["p" ][ptype ].policy [explain_index ]
384420
385421 return result , explain_rule
386422
0 commit comments