Opened 17 years ago
Closed 17 years ago
#4376 closed (fixed)
login_required doesn't work with bound methods
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Uncategorized | Version: | dev |
Severity: | Keywords: | auth login_required decorator | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The django.contrib.auth.decorators.login_required decorator doesn't work correctly with bound methods. If I have code like:
class ViewManager(object): @login_required def get_main_view(self, request): return HttpResponse('hello') view_manager = ViewManager() urlpatterns = patterns('', (r'^$', view_manager.get_main_view), )
I'll get an error saying:
AttributeError at / 'ViewManager' object has no attribute 'user'
I believe this is because __get__
is being invoked on the _checklogin
function returned by login_required
and so the ViewManager instance is being bound as the request
argument of _checklogin
instead of being bound as the self
argument of get_main_view
as it should be. To fix this, I had to replace the _dec
function in django.contrib.auth.decorators.user_passes_test
like so::
def user_passes_test(test_func, login_url=None): if not login_url: from django.conf import settings login_url = settings.LOGIN_URL class CheckLogin(object): def __init__(self, func): self.func = func def __get__(self, obj, cls=None): return CheckLogin(self.func.__get__(obj, cls)) def __call__(self, request, *args, **kwargs): if test_func(request.user): return view_func(request, *args, **kwargs) return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path()))) return CheckLogin
This simply redirects the __get__
call to the wrapped function, instead of allowing it to be called on the _checklogin
function.
Attachments (4)
Change History (11)
by , 17 years ago
Attachment: | django.contrib.auth.decorators.diff added |
---|
comment:1 by , 17 years ago
Has patch: | set |
---|---|
Needs tests: | set |
I don't know how to write unit tests for Django, but if someone can point me in the right direction, I can make some tests for this. I need to know know how to programatically visit, say, '/' and verify that it returns the appropriate output.
by , 17 years ago
Attachment: | django.contrib.auth.decorators.3.diff added |
---|
updated version with tests
comment:3 by , 17 years ago
Needs tests: | unset |
---|
Thanks for the pointer. I think I figured out how to modify modeltests.test_client
where the only existing django.contrib.auth.decorators
test I could find was. The patch I just uploaded rewrites the decorators module to handle methods properly, and adds three new tests: test_view_with_method_login
, test_view_with_permissions
and test_view_with_method_permissions
.
Note that I didn't see the @permission_required
decorator tested anywhere, so I added both a regular function test and a method test for that one. Both of these tests have TODO comments on them - I was able to test that when the permissions are wrong, they redirect to a login page, but I wasn't sure how to get a user with the right permissions to complete the tests. Of course, if @permission_required
really wasn't tested at all before, half-way there is better than nothing, right? ;-)
comment:4 by , 17 years ago
Triage Stage: | Unreviewed → Ready for checkin |
---|
comment:5 by , 17 years ago
Patch needs improvement: | set |
---|---|
Triage Stage: | Ready for checkin → Accepted |
I like this patch. Code looks code and everything.
Unfortunately, due to the changes during the sprint over the last few days, in particular, it no longer cleanly applies and at least one of the changes (django.contrib.auth.decorators) requires a bit of reworking of the code.
If somebody could update the patch, it's then ready to go in.
by , 17 years ago
Attachment: | django.contrib.auth.decorators.4.diff added |
---|
Patch against revision 6364. This should now apply cleanly.
comment:6 by , 17 years ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
I think this patch may have fallen through the cracks. I've just applied it against revision 6652 and it still applies cleanly, so I'm going to tweak this ticket so somebody sees it. I hope that's cool with the powers that be.
comment:7 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
rewrite of django.contrib.auth.decorators to handle bound methods properly