Django

Code

Ticket #3032 (closed: fixed)

Opened 2 years ago

Last modified 1 year ago

AnonymousUser has no attribute is_staff/is_superuser (django.contrib.auth)

Reported by: Simon Greenhill <dev@simon.net.nz> Assigned to: semenov
Milestone: Component: Contrib apps
Version: SVN Keywords: authentication, auth, anonymous
Cc: dev@simon.net.nz Triage Stage: Ready for checkin
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

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

anonymous-user-properties.diff (2.3 kB) - added by semenov on 09/14/07 13:40:36.
anonymous-user-properties.2.diff (3.0 kB) - added by semenov on 09/14/07 18:15:39.

Change History

11/24/06 16:22:00 changed by Simon Greenhill <dev@simon.net.nz>

& a similar problem with AnonymousUser? raising a NotImplementError? if you try to get groups (user.groups.all())

02/21/07 15:13:34 changed by SmileyChris

  • needs_better_patch set to 1.
  • stage changed from Unreviewed to Accepted.

Probably worth fixing the groups issue too then.

05/10/07 02:42:10 changed by hauser

Please fix it.

05/10/07 18:22:48 changed by ubernostrum

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 ) 05/21/07 10:08:35 changed by 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.

(in reply to: ↑ 5 ) 05/21/07 12:37:34 changed by Marc Fargas <telenieko@telenieko.com>

  • summary changed from [patch] AnonymousUser has no attribute is_staff/is_superuser (django.contrib.auth) to 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...

07/17/07 06:49:51 changed by Thomas Güttler <hv@tbz-pariv.de>

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!.

09/14/07 13:40:06 changed by semenov

  • owner changed from nobody to semenov.
  • needs_better_patch deleted.
  • status changed from new to assigned.
  • stage changed from Accepted to 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.

09/14/07 13:40:36 changed by semenov

  • attachment anonymous-user-properties.diff added.

09/14/07 18:15:39 changed by semenov

  • attachment anonymous-user-properties.2.diff added.

09/14/07 18:16:50 changed by semenov

  • keywords changed from authentication, auth to authentication, auth, anonymous.
  • stage changed from Design decision needed to Ready for checkin.

Added tests.

09/15/07 13:01:29 changed by mtredinnick

  • status changed from assigned to closed.
  • resolution set to fixed.

(In [6299]) Fixed #3032 -- Added some useful methods and attributes so that AnonymousUser? can proxy for a User a bit more logically. Patch from semenov.


Add/Change #3032 (AnonymousUser has no attribute is_staff/is_superuser (django.contrib.auth))




Change Properties
Action