New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ABAC eval not working with empty dict #178
Comments
I'm checking the issue... |
Signed-off-by: ffyuanda <46557895+ffyuanda@users.noreply.github.com>
Hi, I've been checking the issue, and I think I have found the problem. It has nothing to do with the In your case, the first line of the policy is evaluated to Ideally you need to build a The I've drafted some examples on my branch, you can refer to that about the usage of ABAC. Happy using PyCasbin! |
@ffyuanda thanks for getting back with me! I'll take a look now. |
@killswitch-GUI Sure, I've just updated my comment above, you can check it now. |
@ffyuanda we are actually implementing this within FastAPI and using primary Pydantic to model the data. we have been doing EDIT: I know our use case may be wired since we are passing various models into Enforce. Maybe we need to apply a filter? |
Ok so putting in a Pedantic Class model does work. But like you said it still requires the "object" that is going to evaluated and the field present. from uuid import UUID, uuid4
import casbin
from pydantic import BaseModel, Field
class User(BaseModel):
admin: bool = Field(
..., description="Designates that this user has all permissions without explicitly assigning them."
)
identifier: UUID = Field(default_factory=uuid4, description="A unique identifier of the user.")
abac_enforcer = casbin.Enforcer("model.conf", "policy.csv")
user_1 = User(admin=True)
if abac_enforcer.enforce(user_1, user_1, "user", "read"):
print("You can move forward")
if abac_enforcer.enforce(user_1, user_1, "user", "delete"):
print("You can move forward") |
@killswitch-GUI yeah the object is needed to use ABAC. If you insist using a |
This can work I think. Just make sure |
@ffyuanda if this works within the Casbin editor should this issue be raised to simpleeval? You can it working at: https://casbin.org/casbin-editor/#7MX2727D9 EDIT: After talking with the team we found one way to short-circuit the eval by placing it after the type and act but its still to seen how long that will last:
|
@killswitch-GUI Since the Casbin editor is built on Javascript and Node.js (on the Node.js version of Casbin), I believe the issue may not be reproduced when you use the editor. But yeah I think it could work better for our scenario if simpleeval spits out a But generally I think simpleeval performs very well and does not need to change much of its syntax parser to cater this need. You can still try to catch this error, or make a better use of ABAC to avoid the issue, I guess. Or maybe rewrite part of the simpleeval to suit your need? |
And if you feel this issue is not needed anymore, please close it when you leave :) |
@ffyuanda We can catch the possible error and return False in |
@Zxilly I don't think it's quite necessary, since this error comes from the nature of ABAC model. |
@Zxilly and @ffyuanda since PyCasbin is already monkey patching we just monkey patched it to work. Before I close this, what would you suggest the right way is to use ABAC/Policy here. You seemed to hint we may be misusing it. from uuid import UUID, uuid4
import casbin
from pydantic import BaseModel, Field
def eval(self, names=None):
try:
return self.__eval(names)
except AttributeDoesNotExist as e:
return False
casbin.util.expression.SimpleEval.__eval = casbin.util.expression.SimpleEval.eval
casbin.util.expression.SimpleEval.eval = eval
class User(BaseModel):
admin: bool = Field(
..., description="Designates that this user has all permissions without explicitly assigning them."
)
identifier: UUID = Field(default_factory=uuid4, description="A unique identifier of the user.")
abac_enforcer = casbin.Enforcer("model.conf", "policy.csv")
user_1 = User(admin=True)
if abac_enforcer.enforce(user_1, user_1, "user", "read"):
print("You can move forward")
if abac_enforcer.enforce(user_1, user_1, "user", "delete"):
print("You can move forward")
if abac_enforcer.enforce(user_1, {}, "user", "delete"):
print("This now works") It passed our test suite as well 🎉 |
@killswitch-GUI I don't quite suggest change PyCasbin or simpleeval. You should instead follow the "object all the way down" logic when you use A(ttribute)BAC. user_1 = User(admin=True) It evaluates the first line in policy and turns out to be True and ignored the second line :) |
@ffyuanda we used this on our production models as example (We also moved the eval to end to reduce down the policy evaluation that is triggered): EDIT: Sorry we forgot to add the models and policies used.
Model:
worked good! To be 100% honest here we are mixing RBAC and ABAC here to support a superuser context. |
Sure then that's great. Though I didn't see any RBAC definition around here haha, it contains a Anyway, happy using PyCasbin! |
100% using that |
@killswitch-GUI Sure, no worries! |
Model:
Policy:
When attempting to eval the following:
Raises the following:
I attempted this within the online editor and it works fine. Sorry if I'm missing something. New PyCasbin user here!
The text was updated successfully, but these errors were encountered: