11import logging
22
3- from casbin .effect import DefaultEffector , Effector
3+ from casbin .effect import Effector , get_effector , effect_to_bool
44from casbin .model import Model , FunctionMap
55from casbin .persist import Adapter
66from casbin .persist .adapters import FileAdapter
@@ -70,7 +70,7 @@ def init_with_model_and_adapter(self, m, adapter=None):
7070
7171 def _initialize (self ):
7272 self .rm_map = dict ()
73- self .eft = DefaultEffector ( )
73+ self .eft = get_effector ( self . model . model [ "e" ][ "e" ]. value )
7474 self .watcher = None
7575
7676 self .enabled = True
@@ -242,6 +242,15 @@ def enforce(self, *rvals):
242242 """decides whether a "subject" can access a "object" with the operation "action",
243243 input parameters are usually: (sub, obj, act).
244244 """
245+ result , _ = self .enforceEx (* rvals )
246+ return result
247+
248+ def enforceEx (self , * rvals ):
249+ """decides whether a "subject" can access a "object" with the operation "action",
250+ input parameters are usually: (sub, obj, act).
251+ return judge result with reason
252+ """
253+ explain_index = - 1
245254
246255 if not self .enabled :
247256 return False
@@ -271,12 +280,12 @@ def enforce(self, *rvals):
271280 expression = self ._get_expression (exp_string , functions )
272281
273282 policy_effects = set ()
274- matcher_results = set ()
275283
276284 r_parameters = dict (zip (r_tokens , rvals ))
277285
278286 policy_len = len (self .model .model ["p" ]["p" ].policy )
279287
288+ explain_index = - 1
280289 if not 0 == policy_len :
281290 for i , pvals in enumerate (self .model .model ["p" ]["p" ].policy ):
282291 if len (p_tokens ) != len (pvals ):
@@ -301,8 +310,6 @@ def enforce(self, *rvals):
301310 if 0 == result :
302311 policy_effects .add (Effector .INDETERMINATE )
303312 continue
304- else :
305- matcher_results .add (result )
306313 else :
307314 raise RuntimeError ("matcher result should be bool, int or float" )
308315
@@ -317,7 +324,8 @@ def enforce(self, *rvals):
317324 else :
318325 policy_effects .add (Effector .ALLOW )
319326
320- if "priority(p_eft) || deny" == self .model .model ["e" ]["e" ].value :
327+ if self .eft .intermediate_effect (policy_effects ) != Effector .INDETERMINATE :
328+ explain_index = i
321329 break
322330
323331 else :
@@ -336,7 +344,8 @@ def enforce(self, *rvals):
336344 else :
337345 policy_effects .add (Effector .INDETERMINATE )
338346
339- result = self .eft .merge_effects (self .model .model ["e" ]["e" ].value , policy_effects , matcher_results )
347+ final_effect = self .eft .final_effect (policy_effects )
348+ result = effect_to_bool (final_effect )
340349
341350 # Log request.
342351
@@ -350,7 +359,11 @@ def enforce(self, *rvals):
350359 # leaving this in error for now, if it's very noise this can be changed to info or debug
351360 self .logger .error (req_str )
352361
353- return result
362+ explain_rule = []
363+ if explain_index != - 1 and explain_index < policy_len :
364+ explain_rule = self .model .model ["p" ]["p" ].policy [explain_index ]
365+
366+ return result , explain_rule
354367
355368 @staticmethod
356369 def _get_expression (expr , functions = None ):
0 commit comments