Opened 18 years ago
Closed 17 years ago
#3032 closed defect (fixed)
AnonymousUser has no attribute is_staff/is_superuser (django.contrib.auth)
Reported by: | Owned by: | Ilya Semenov | |
---|---|---|---|
Component: | Contrib apps | Version: | dev |
Severity: | normal | Keywords: | authentication, auth, anonymous |
Cc: | dev@… | 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
This raises a traceback if some attempts to use is_staff/is_superuser when the user is not logged in (i.e. AnonymousUser is the class).
People probably shouldn't be directly using these (but e.g. checking is_authenticated first, before trying to access these), however this certainly shouldn't raise an error like this.
Index: models.py =================================================================== --- models.py (revision 4065) +++ models.py (working copy) @@ -313,3 +313,9 @@ def is_authenticated(self): return False + + def is_staff(self): + return False + + def is_superuser(self): + return False \ No newline at end of file
This fix is trivial, but a far better solution than trying to keep these in sync. in future, would be to have an e.g. BaseUser class which is extended by both User and AnonymousUser
Attachments (2)
Change History (12)
comment:1 by , 18 years ago
comment:2 by , 18 years ago
Patch needs improvement: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
Probably worth fixing the groups issue too then.
comment:4 by , 18 years ago
I'm not convinced that there's an issue here; code which doesn't know whether it's been handed a "real" user or an AnonymousUser
should always be checking is_authenticated()
before doing anything which assumes the user is authenticated.
follow-up: 6 comment:5 by , 17 years ago
Something has to be fixed here. From documentation http://www.djangoproject.com/documentation/authentication/:
django.contrib.auth.models.AnonymousUser is a class that implements the django.contrib.auth.models.User interface, with these differences: ...
So documentation should be changed or AnonymousUser should implement all the methods and fields.
comment:6 by , 17 years ago
Summary: | [patch] AnonymousUser has no attribute is_staff/is_superuser (django.contrib.auth) → AnonymousUser has no attribute is_staff/is_superuser (django.contrib.auth) |
---|
Replying to hauser:
Something has to be fixed here. From documentation http://www.djangoproject.com/documentation/authentication/:
django.contrib.auth.models.AnonymousUser is a class that implements the django.contrib.auth.models.User interface, with these differences: ...
So documentation should be changed or AnonymousUser should implement all the methods and fields.
It also says:
set_password(), check_password(), save(), delete(), set_groups() and set_permissions() raise NotImplementedError.
So maybe we should add to this list every possible method from User (yes: .objects, .get_profile() and so on) or simply say:
This class only implements .is_anonymous() and is_authenticated() and .has_perm() so you should first check .is_authenticated if you plan to use any other function from User, do not assume that AnonymousUser has everything User has.
Maybe .is_staff and .is_superuser could be implemented to be a bit more DRY (if you want to place an "admin" link in a site it doesn't make sense to place two 'if' blocks:)
{% if user.is_authenticated %}{% is user.is_staff %}<link to admin>{% endif %}{% endif %}
On the other methods, for me, it doesn't seem a good idea as AnonymousUser is not a model and User is, so not all methods make sense.
Comment on this to make a docs patch (the easiest, hence my favourites :P), or decide whether to implement all methods from User...
comment:7 by , 17 years ago
Hi,
I think AnonymousUser should have an is_superuser attribute like real users.
The above patch inserts a method (not an attribute). Attention: then " is u.is_superuser" is allways
true!.
comment:8 by , 17 years ago
Owner: | changed from | to
---|---|
Patch needs improvement: | unset |
Status: | new → assigned |
Triage Stage: | Accepted → Design decision needed |
Marc Fargas, your example is incorrect - placing two {% if %}
blocks is not required (a sole internal
{% if user.is_staff %}
works just fine). Template engine silently skips non-existent attributes/methods calls (see http://www.djangoproject.com/documentation/templates/#variables).
As for the python code which would fail at request.user.is_staff
if the user is not logged on, the current behaviour is properly documented.
If we want to change that behaviour, we need a design decision here.
I'm attaching a better patch, which uses properties instead of member methods, as per User
model contract. It also has
groups
and
user_permissions
property implemented, using new class
django.db.models.managers.EmptyManager
(which naming conforms to already-existent
django.db.models.query.EmptyQuerySet
). The documentation is updated to reflect the changes.
by , 17 years ago
Attachment: | anonymous-user-properties.diff added |
---|
by , 17 years ago
Attachment: | anonymous-user-properties.2.diff added |
---|
comment:9 by , 17 years ago
Keywords: | anonymous added |
---|---|
Triage Stage: | Design decision needed → Ready for checkin |
Added tests.
comment:10 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
& a similar problem with AnonymousUser raising a NotImplementError if you try to get groups (user.groups.all())