-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
bitwise permissions not working when combine has_object_permission and has_permission #7117
Comments
I have been able to work around this issue. I found that the order of classes in
I first tried my view written like this:
In this case only the breakpoint in If I instead wrote the class like this:
Now only the breakpoint in I worked around it by writing
The issue is
I'm opening up a pull request that attempts to fix this issue |
I think at some point bitwise permissions should enforce to have both |
I think that a better default would be to make |
@Dog this will not work in case of complex permission logic like:
We need to check both methods to make it work as expected |
why has this not been merged?, the only quick fix I could do for this type of use case where it would check is admin (has_permission) or is owner (has_object_permission) class IsStaff(permissions.BasePermission):
def has_permission(self, request, view):
return request.user.groups.filter(name="staff").exists()
def has_object_permission(self, request, view, obj):
return request.user.groups.filter(name="staff").exists()
class IsOwner(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
"""
message = "user making the request is not the owner of this object"
def has_object_permission(self, request, view, obj):
return request.user == obj |
@DrJfrost Unfortunately, this solution still not working for complex bitwise operations. We need to do not stop checking permissions on first |
Happy to accept #6605, or anyone issuing a fresh PR based on that and updating the required test case. |
This workaround is not working for me. I have a similar issue. I am using 2 permission classes using "|" operator with |
@tomchristie #7155 is still waiting for review. |
@Ishma59 is not really related with the problem |
How is this bug still not fixed?! It is so obvious and everyone doing a serious project will fall into it! |
there has been several PR but none seems to review them, I think the resolution of this problem is crucial for a 3.12 version to be released |
I appreciate #7155 and that is how I was intending to fix this issue when I came here to submit an issue/PR. However, when I searched to find this issue, I also found #6598 which points out that the behavior of NOT is also affected by the fact than a permission that doesn't implement |
How about we let the methods return In case every permission classes return As per backwards compatibility, Side note: this appears to be a duplicate of #6402. |
I ran into this same issue today. Ended up following the above advice, and implemented my own IsAdminUser, since the built-in one doesn't implement has_object_permissions() My new IsAdminUser simply has has_object_permissions() return has_permission() |
As you can see, I require an object must not have the flag to be True. But without access to an object within A possible solution would be to split permissions by types: object level, view level, mixed. So the object level permission will only be called in get_object method, not ever earlier, view level permission - never to be called within get_object and mixed - simply the same structure and behavior as we have now implemented. Unfortunately, permissions in DRF have not required flexibility, another example: will not be superfluous if view level permission gets filtered queryset as a parameter. As it's lazy, that change would not impact on performance, but gives more freedom to an end developer. Another solution for that example, would be if we split view layer Within the current architecture of the DRF permissions, I have to write a custom permission for every complicated case, instead of building a logical formula with already written permissions. |
I like this suggestion. You are right that My PR was originally submitted back in October and still hasn't gotten a reviewer or any comments. There are several other outstanding PRs attempting to fix this issue as well as a handful of issues related to composing permissions in addition to this one, and it doesn't look like any of them have have much activity lately. How can I get my PR looked at/reviewed so we can move this forward? I've found a way to monkey-patch my PR into my current project for now (can share if anyone needs), but I'd like to see this resolved for real. |
@sparkyb I just realized that NotImplemented shall not be evaluated in boolean context, and future versions of Python will throw TypeError on such attempts. My apologies if this would mean that your effort was (partly) wasted. Perhaps it's wise to revisit this apporach. |
Some alternative approaches:
|
Good catch. I had actually originally implemented as raising NotImplementedError and catching it, but changed to returning NotImplemented when someone suggested it. I think at this point I will probably keep it and just check for it explicitly. It will make the code slightly more verbose, but maybe more clear what it is doing. I'll update the PR with that fix and updating the docstrings when I get a chance, hopefully in a few days, although things are quite busy right now. |
This is an absolutely glaring security concern for otherwise great software. I would like to urge the developers to address this issue as soon as possible. Until then, anyone who uses this framework with a permissions class of the form The only legitimate reason for this issue not being prioritized as most important is if there are other issues pertaining to greater security concerns. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Is this still not fixed? In my project the simple permission composition of |
Spent hours bashing my head against this today, wondering why I could edit objects when I wasn't even logged in. This seems to me like a pretty serious bug waiting to bite someone... |
Agreed and agreed. Anyways. PR #7522 (Based on #6605) looks like the right approach to me. (A better approach might be for the base permission implementations to raise |
It took me a while to know what was going on why my class inheriting from I do not understand why some permission classes like |
Because @Dog's workaround is quite buried above, I'll rephrase it here. The easiest temporary workaround is to make a new, custom
This works because it includes both the required has_object_permission and has_permission classes. |
Yeah, I'm aware of how to check if a user Another "workaround" is to call Again, I don't understand why we would need a workaround for something that's not defective but rather just implemented to not do what it's supposed to i.e. check if |
Should #6462 be reverted or updated now? |
Checklist
master
branch of Django REST framework.Steps to reproduce
Set
Do put request
I also found similar issue on https://stackoverflow.com/a/55773420/1786016
Expected behavior
has_object_permission
must be called and return False in my caseActual behavior
has_object_permission
not calledThe text was updated successfully, but these errors were encountered: