Fixed #25847 -- Made User.is_(anonymous|authenticated) properties.
This commit is contained in:
parent
c16b9dd8e0
commit
c1aec0feda
1
AUTHORS
1
AUTHORS
|
@ -345,6 +345,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Jérémie Blaser <blaserje@gmail.com>
|
Jérémie Blaser <blaserje@gmail.com>
|
||||||
Jeremy Carbaugh <jcarbaugh@gmail.com>
|
Jeremy Carbaugh <jcarbaugh@gmail.com>
|
||||||
Jeremy Dunck <jdunck@gmail.com>
|
Jeremy Dunck <jdunck@gmail.com>
|
||||||
|
Jeremy Lainé <jeremy.laine@m4x.org>
|
||||||
Jesse Young <adunar@gmail.com>
|
Jesse Young <adunar@gmail.com>
|
||||||
jhenry <jhenry@theonion.com>
|
jhenry <jhenry@theonion.com>
|
||||||
Jim Dalton <jim.dalton@gmail.com>
|
Jim Dalton <jim.dalton@gmail.com>
|
||||||
|
|
|
@ -138,7 +138,7 @@ def logout(request):
|
||||||
# Dispatch the signal before the user is logged out so the receivers have a
|
# Dispatch the signal before the user is logged out so the receivers have a
|
||||||
# chance to find out *who* logged out.
|
# chance to find out *who* logged out.
|
||||||
user = getattr(request, 'user', None)
|
user = getattr(request, 'user', None)
|
||||||
if hasattr(user, 'is_authenticated') and not user.is_authenticated():
|
if hasattr(user, 'is_authenticated') and not user.is_authenticated:
|
||||||
user = None
|
user = None
|
||||||
user_logged_out.send(sender=user.__class__, request=request, user=user)
|
user_logged_out.send(sender=user.__class__, request=request, user=user)
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ class ModelBackend(object):
|
||||||
be either "group" or "user" to return permissions from
|
be either "group" or "user" to return permissions from
|
||||||
`_get_group_permissions` or `_get_user_permissions` respectively.
|
`_get_group_permissions` or `_get_user_permissions` respectively.
|
||||||
"""
|
"""
|
||||||
if not user_obj.is_active or user_obj.is_anonymous() or obj is not None:
|
if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
|
||||||
return set()
|
return set()
|
||||||
|
|
||||||
perm_cache_name = '_%s_perm_cache' % from_name
|
perm_cache_name = '_%s_perm_cache' % from_name
|
||||||
|
@ -73,7 +73,7 @@ class ModelBackend(object):
|
||||||
return self._get_permissions(user_obj, obj, 'group')
|
return self._get_permissions(user_obj, obj, 'group')
|
||||||
|
|
||||||
def get_all_permissions(self, user_obj, obj=None):
|
def get_all_permissions(self, user_obj, obj=None):
|
||||||
if not user_obj.is_active or user_obj.is_anonymous() or obj is not None:
|
if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
|
||||||
return set()
|
return set()
|
||||||
if not hasattr(user_obj, '_perm_cache'):
|
if not hasattr(user_obj, '_perm_cache'):
|
||||||
user_obj._perm_cache = self.get_user_permissions(user_obj)
|
user_obj._perm_cache = self.get_user_permissions(user_obj)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from django.contrib.auth.hashers import (
|
||||||
)
|
)
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.crypto import get_random_string, salted_hmac
|
from django.utils.crypto import get_random_string, salted_hmac
|
||||||
|
from django.utils.deprecation import CallableFalse, CallableTrue
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -79,19 +80,21 @@ class AbstractBaseUser(models.Model):
|
||||||
def natural_key(self):
|
def natural_key(self):
|
||||||
return (self.get_username(),)
|
return (self.get_username(),)
|
||||||
|
|
||||||
|
@property
|
||||||
def is_anonymous(self):
|
def is_anonymous(self):
|
||||||
"""
|
"""
|
||||||
Always return False. This is a way of comparing User objects to
|
Always return False. This is a way of comparing User objects to
|
||||||
anonymous users.
|
anonymous users.
|
||||||
"""
|
"""
|
||||||
return False
|
return CallableFalse
|
||||||
|
|
||||||
|
@property
|
||||||
def is_authenticated(self):
|
def is_authenticated(self):
|
||||||
"""
|
"""
|
||||||
Always return True. This is a way to tell if the user has been
|
Always return True. This is a way to tell if the user has been
|
||||||
authenticated in templates.
|
authenticated in templates.
|
||||||
"""
|
"""
|
||||||
return True
|
return CallableTrue
|
||||||
|
|
||||||
def set_password(self, raw_password):
|
def set_password(self, raw_password):
|
||||||
self.password = make_password(raw_password)
|
self.password = make_password(raw_password)
|
||||||
|
|
|
@ -43,7 +43,7 @@ def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login
|
||||||
to the log-in page if necessary.
|
to the log-in page if necessary.
|
||||||
"""
|
"""
|
||||||
actual_decorator = user_passes_test(
|
actual_decorator = user_passes_test(
|
||||||
lambda u: u.is_authenticated(),
|
lambda u: u.is_authenticated,
|
||||||
login_url=login_url,
|
login_url=login_url,
|
||||||
redirect_field_name=redirect_field_name
|
redirect_field_name=redirect_field_name
|
||||||
)
|
)
|
||||||
|
|
|
@ -70,13 +70,13 @@ class RemoteUserMiddleware(object):
|
||||||
# If specified header doesn't exist then remove any existing
|
# If specified header doesn't exist then remove any existing
|
||||||
# authenticated remote-user, or return (leaving request.user set to
|
# authenticated remote-user, or return (leaving request.user set to
|
||||||
# AnonymousUser by the AuthenticationMiddleware).
|
# AnonymousUser by the AuthenticationMiddleware).
|
||||||
if self.force_logout_if_no_header and request.user.is_authenticated():
|
if self.force_logout_if_no_header and request.user.is_authenticated:
|
||||||
self._remove_invalid_user(request)
|
self._remove_invalid_user(request)
|
||||||
return
|
return
|
||||||
# If the user is already authenticated and that user is the user we are
|
# If the user is already authenticated and that user is the user we are
|
||||||
# getting passed in the headers, then the correct user is already
|
# getting passed in the headers, then the correct user is already
|
||||||
# persisted in the session and we don't need to continue.
|
# persisted in the session and we don't need to continue.
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated:
|
||||||
if request.user.get_username() == self.clean_username(username, request):
|
if request.user.get_username() == self.clean_username(username, request):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -51,7 +51,7 @@ class LoginRequiredMixin(AccessMixin):
|
||||||
CBV mixin which verifies that the current user is authenticated.
|
CBV mixin which verifies that the current user is authenticated.
|
||||||
"""
|
"""
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated:
|
||||||
return self.handle_no_permission()
|
return self.handle_no_permission()
|
||||||
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
|
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ from django.core.mail import send_mail
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.manager import EmptyManager
|
from django.db.models.manager import EmptyManager
|
||||||
from django.utils import six, timezone
|
from django.utils import six, timezone
|
||||||
|
from django.utils.deprecation import CallableFalse, CallableTrue
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -438,11 +439,13 @@ class AnonymousUser(object):
|
||||||
def has_module_perms(self, module):
|
def has_module_perms(self, module):
|
||||||
return _user_has_module_perms(self, module)
|
return _user_has_module_perms(self, module)
|
||||||
|
|
||||||
|
@property
|
||||||
def is_anonymous(self):
|
def is_anonymous(self):
|
||||||
return True
|
return CallableTrue
|
||||||
|
|
||||||
|
@property
|
||||||
def is_authenticated(self):
|
def is_authenticated(self):
|
||||||
return False
|
return CallableFalse
|
||||||
|
|
||||||
def get_username(self):
|
def get_username(self):
|
||||||
return self.username
|
return self.username
|
||||||
|
|
|
@ -68,7 +68,7 @@ def login(request, template_name='registration/login.html',
|
||||||
"""
|
"""
|
||||||
redirect_to = request.POST.get(redirect_field_name, request.GET.get(redirect_field_name, ''))
|
redirect_to = request.POST.get(redirect_field_name, request.GET.get(redirect_field_name, ''))
|
||||||
|
|
||||||
if redirect_authenticated_user and request.user.is_authenticated():
|
if redirect_authenticated_user and request.user.is_authenticated:
|
||||||
redirect_to = _get_login_redirect_url(request, redirect_to)
|
redirect_to = _get_login_redirect_url(request, redirect_to)
|
||||||
if redirect_to == request.path:
|
if redirect_to == request.path:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
|
|
@ -33,7 +33,7 @@ class FlatpageNode(template.Node):
|
||||||
# was provided, filter the list to only public flatpages.
|
# was provided, filter the list to only public flatpages.
|
||||||
if self.user:
|
if self.user:
|
||||||
user = self.user.resolve(context)
|
user = self.user.resolve(context)
|
||||||
if not user.is_authenticated():
|
if not user.is_authenticated:
|
||||||
flatpages = flatpages.filter(registration_required=False)
|
flatpages = flatpages.filter(registration_required=False)
|
||||||
else:
|
else:
|
||||||
flatpages = flatpages.filter(registration_required=False)
|
flatpages = flatpages.filter(registration_required=False)
|
||||||
|
|
|
@ -52,7 +52,7 @@ def render_flatpage(request, f):
|
||||||
"""
|
"""
|
||||||
# If registration is required for accessing this page, and the user isn't
|
# If registration is required for accessing this page, and the user isn't
|
||||||
# logged in, redirect to the login page.
|
# logged in, redirect to the login page.
|
||||||
if f.registration_required and not request.user.is_authenticated():
|
if f.registration_required and not request.user.is_authenticated:
|
||||||
from django.contrib.auth.views import redirect_to_login
|
from django.contrib.auth.views import redirect_to_login
|
||||||
return redirect_to_login(request.path)
|
return redirect_to_login(request.path)
|
||||||
if f.template_name:
|
if f.template_name:
|
||||||
|
|
|
@ -79,3 +79,33 @@ class DeprecationInstanceCheck(type):
|
||||||
self.deprecation_warning, 2
|
self.deprecation_warning, 2
|
||||||
)
|
)
|
||||||
return super(DeprecationInstanceCheck, self).__instancecheck__(instance)
|
return super(DeprecationInstanceCheck, self).__instancecheck__(instance)
|
||||||
|
|
||||||
|
|
||||||
|
class CallableBool:
|
||||||
|
"""
|
||||||
|
An boolean-like object that is also callable for backwards compatibility.
|
||||||
|
"""
|
||||||
|
do_not_call_in_templates = True
|
||||||
|
|
||||||
|
def __init__(self, value):
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
warnings.warn(
|
||||||
|
"Using user.is_authenticated() and user.is_anonymous() as a method "
|
||||||
|
"is deprecated. Remove the parentheses to use it as an attribute.",
|
||||||
|
RemovedInDjango20Warning, stacklevel=2
|
||||||
|
)
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
def __nonzero__(self): # Python 2 compatibility
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'CallableBool(%r)' % self.value
|
||||||
|
|
||||||
|
CallableFalse = CallableBool(False)
|
||||||
|
CallableTrue = CallableBool(True)
|
||||||
|
|
|
@ -256,7 +256,7 @@ given view by setting the ``HttpRequest``’s ``exception_reporter_filter``
|
||||||
attribute::
|
attribute::
|
||||||
|
|
||||||
def my_view(request):
|
def my_view(request):
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated:
|
||||||
request.exception_reporter_filter = CustomExceptionReporterFilter()
|
request.exception_reporter_filter = CustomExceptionReporterFilter()
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,9 @@ details on these changes.
|
||||||
* The shim for supporting custom related manager classes without a
|
* The shim for supporting custom related manager classes without a
|
||||||
``_apply_rel_filters()`` method will be removed.
|
``_apply_rel_filters()`` method will be removed.
|
||||||
|
|
||||||
|
* Using ``User.is_authenticated()`` and ``User.is_anonymous()`` as methods
|
||||||
|
will no longer be supported.
|
||||||
|
|
||||||
.. _deprecation-removed-in-1.10:
|
.. _deprecation-removed-in-1.10:
|
||||||
|
|
||||||
1.10
|
1.10
|
||||||
|
|
|
@ -111,6 +111,41 @@ Fields
|
||||||
A datetime designating when the account was created. Is set to the
|
A datetime designating when the account was created. Is set to the
|
||||||
current date/time by default when the account is created.
|
current date/time by default when the account is created.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. class:: models.User
|
||||||
|
|
||||||
|
.. attribute:: is_authenticated
|
||||||
|
|
||||||
|
Read-only attribute which is always ``True`` (as opposed to
|
||||||
|
``AnonymousUser.is_authenticated`` which is always ``False``). This is
|
||||||
|
a way to tell if the user has been authenticated. This does not imply
|
||||||
|
any permissions and doesn't check if the user is active or has a valid
|
||||||
|
session. Even though normally you will check this attribute on
|
||||||
|
``request.user`` to find out whether it has been populated by the
|
||||||
|
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
|
||||||
|
(representing the currently logged-in user), you should know this
|
||||||
|
attribute is ``True`` for any :class:`~models.User` instance.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.10
|
||||||
|
|
||||||
|
In older versions, this was a method. Backwards-compatibility
|
||||||
|
support for using it as a method will be removed in Django 2.0.
|
||||||
|
|
||||||
|
.. attribute:: is_anonymous
|
||||||
|
|
||||||
|
Read-only attribute which is always ``False``. This is a way of
|
||||||
|
differentiating :class:`~models.User` and :class:`~models.AnonymousUser`
|
||||||
|
objects. Generally, you should prefer using
|
||||||
|
:attr:`~django.contrib.auth.models.User.is_authenticated` to this
|
||||||
|
attribute.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.10
|
||||||
|
|
||||||
|
In older versions, this was a method. Backwards-compatibility
|
||||||
|
support for using it as a method will be removed in Django 2.0.
|
||||||
|
|
||||||
Methods
|
Methods
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -122,28 +157,6 @@ Methods
|
||||||
out, you should use this method instead of referencing the username
|
out, you should use this method instead of referencing the username
|
||||||
attribute directly.
|
attribute directly.
|
||||||
|
|
||||||
.. method:: is_anonymous()
|
|
||||||
|
|
||||||
Always returns ``False``. This is a way of differentiating
|
|
||||||
:class:`~django.contrib.auth.models.User` and
|
|
||||||
:class:`~django.contrib.auth.models.AnonymousUser` objects.
|
|
||||||
Generally, you should prefer using
|
|
||||||
:meth:`~django.contrib.auth.models.User.is_authenticated()` to this
|
|
||||||
method.
|
|
||||||
|
|
||||||
.. method:: is_authenticated()
|
|
||||||
|
|
||||||
Always returns ``True`` (as opposed to
|
|
||||||
``AnonymousUser.is_authenticated()`` which always returns ``False``).
|
|
||||||
This is a way to tell if the user has been authenticated. This does not
|
|
||||||
imply any permissions, and doesn't check if the user is active or has
|
|
||||||
a valid session. Even though normally you will call this method on
|
|
||||||
``request.user`` to find out whether it has been populated by the
|
|
||||||
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
|
|
||||||
(representing the currently logged-in user), you should know this method
|
|
||||||
returns ``True`` for any :class:`~django.contrib.auth.models.User`
|
|
||||||
instance.
|
|
||||||
|
|
||||||
.. method:: get_full_name()
|
.. method:: get_full_name()
|
||||||
|
|
||||||
Returns the :attr:`~django.contrib.auth.models.User.first_name` plus
|
Returns the :attr:`~django.contrib.auth.models.User.first_name` plus
|
||||||
|
@ -287,6 +300,10 @@ Manager methods
|
||||||
string.
|
string.
|
||||||
* :meth:`~django.contrib.auth.models.User.get_username()` always returns
|
* :meth:`~django.contrib.auth.models.User.get_username()` always returns
|
||||||
the empty string.
|
the empty string.
|
||||||
|
* :attr:`~django.contrib.auth.models.User.is_anonymous` is ``True``
|
||||||
|
instead of ``False``.
|
||||||
|
* :attr:`~django.contrib.auth.models.User.is_authenticated` is
|
||||||
|
``False`` instead of ``True``.
|
||||||
* :attr:`~django.contrib.auth.models.User.is_staff` and
|
* :attr:`~django.contrib.auth.models.User.is_staff` and
|
||||||
:attr:`~django.contrib.auth.models.User.is_superuser` are always
|
:attr:`~django.contrib.auth.models.User.is_superuser` are always
|
||||||
``False``.
|
``False``.
|
||||||
|
@ -294,10 +311,6 @@ Manager methods
|
||||||
* :attr:`~django.contrib.auth.models.User.groups` and
|
* :attr:`~django.contrib.auth.models.User.groups` and
|
||||||
:attr:`~django.contrib.auth.models.User.user_permissions` are always
|
:attr:`~django.contrib.auth.models.User.user_permissions` are always
|
||||||
empty.
|
empty.
|
||||||
* :meth:`~django.contrib.auth.models.User.is_anonymous()` returns ``True``
|
|
||||||
instead of ``False``.
|
|
||||||
* :meth:`~django.contrib.auth.models.User.is_authenticated()` returns
|
|
||||||
``False`` instead of ``True``.
|
|
||||||
* :meth:`~django.contrib.auth.models.User.set_password()`,
|
* :meth:`~django.contrib.auth.models.User.set_password()`,
|
||||||
:meth:`~django.contrib.auth.models.User.check_password()`,
|
:meth:`~django.contrib.auth.models.User.check_password()`,
|
||||||
:meth:`~django.db.models.Model.save` and
|
:meth:`~django.db.models.Model.save` and
|
||||||
|
@ -471,21 +484,21 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
|
||||||
|
|
||||||
Returns the set of permission strings the ``user_obj`` has from their
|
Returns the set of permission strings the ``user_obj`` has from their
|
||||||
own user permissions. Returns an empty set if
|
own user permissions. Returns an empty set if
|
||||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
|
:attr:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
|
||||||
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
|
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
|
||||||
|
|
||||||
.. method:: get_group_permissions(user_obj, obj=None)
|
.. method:: get_group_permissions(user_obj, obj=None)
|
||||||
|
|
||||||
Returns the set of permission strings the ``user_obj`` has from the
|
Returns the set of permission strings the ``user_obj`` has from the
|
||||||
permissions of the groups they belong. Returns an empty set if
|
permissions of the groups they belong. Returns an empty set if
|
||||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
|
:attr:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
|
||||||
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
|
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
|
||||||
|
|
||||||
.. method:: get_all_permissions(user_obj, obj=None)
|
.. method:: get_all_permissions(user_obj, obj=None)
|
||||||
|
|
||||||
Returns the set of permission strings the ``user_obj`` has, including both
|
Returns the set of permission strings the ``user_obj`` has, including both
|
||||||
user permissions and group permissions. Returns an empty set if
|
user permissions and group permissions. Returns an empty set if
|
||||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
|
:attr:`~django.contrib.auth.models.AbstractBaseUser.is_anonymous` or
|
||||||
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
|
:attr:`~django.contrib.auth.models.CustomUser.is_active` is ``False``.
|
||||||
|
|
||||||
.. method:: has_perm(user_obj, perm, obj=None)
|
.. method:: has_perm(user_obj, perm, obj=None)
|
||||||
|
|
|
@ -233,9 +233,9 @@ middleware class is listed in :setting:`MIDDLEWARE_CLASSES`.
|
||||||
logged-in user. If the user isn't currently logged in, ``user`` will be set
|
logged-in user. If the user isn't currently logged in, ``user`` will be set
|
||||||
to an instance of :class:`~django.contrib.auth.models.AnonymousUser`. You
|
to an instance of :class:`~django.contrib.auth.models.AnonymousUser`. You
|
||||||
can tell them apart with
|
can tell them apart with
|
||||||
:meth:`~django.contrib.auth.models.User.is_authenticated`, like so::
|
:attr:`~django.contrib.auth.models.User.is_authenticated`, like so::
|
||||||
|
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated:
|
||||||
... # Do something for logged-in users.
|
... # Do something for logged-in users.
|
||||||
else:
|
else:
|
||||||
... # Do something for anonymous users.
|
... # Do something for anonymous users.
|
||||||
|
|
|
@ -730,6 +730,10 @@ Miscellaneous
|
||||||
* Middleware classes are now initialized when the server starts rather than
|
* Middleware classes are now initialized when the server starts rather than
|
||||||
during the first request.
|
during the first request.
|
||||||
|
|
||||||
|
* If you override ``is_authenticated()`` or ``is_anonymous()`` in a custom user
|
||||||
|
model, you must convert them to attributes or properties as described in
|
||||||
|
:ref:`the deprecation note <user-is-auth-anon-deprecation>`.
|
||||||
|
|
||||||
.. _deprecated-features-1.10:
|
.. _deprecated-features-1.10:
|
||||||
|
|
||||||
Features deprecated in 1.10
|
Features deprecated in 1.10
|
||||||
|
@ -857,6 +861,37 @@ features, is deprecated. Replace it with a custom lookup::
|
||||||
models.CharField.register_lookup(Search)
|
models.CharField.register_lookup(Search)
|
||||||
models.TextField.register_lookup(Search)
|
models.TextField.register_lookup(Search)
|
||||||
|
|
||||||
|
.. _user-is-auth-anon-deprecation:
|
||||||
|
|
||||||
|
Using ``User.is_authenticated()`` and ``User.is_anonymous()`` as methods
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
The ``is_authenticated()`` and ``is_anonymous()`` methods of
|
||||||
|
:class:`~django.contrib.auth.models.AbstractBaseUser` and
|
||||||
|
:class:`~django.contrib.auth.models.AnonymousUser` classes are now
|
||||||
|
properties. They will still work as methods until Django 2.0, but all usage
|
||||||
|
in Django now uses attribute access.
|
||||||
|
|
||||||
|
For example, if you use
|
||||||
|
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware` and want
|
||||||
|
to know whether the user is currently logged-in you would use::
|
||||||
|
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
... # Do something for logged-in users.
|
||||||
|
else:
|
||||||
|
... # Do something for anonymous users.
|
||||||
|
|
||||||
|
instead of ``request.user.is_authenticated()``.
|
||||||
|
|
||||||
|
This change avoids accidental information leakage if you forget to call the
|
||||||
|
method, e.g.::
|
||||||
|
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
return sensitive_information
|
||||||
|
|
||||||
|
If you override these methods in a custom user model, you must change them to
|
||||||
|
properties or attributes.
|
||||||
|
|
||||||
Custom manager classes available through ``prefetch_related`` must define a ``_apply_rel_filters()`` method
|
Custom manager classes available through ``prefetch_related`` must define a ``_apply_rel_filters()`` method
|
||||||
-----------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -603,7 +603,7 @@ password resets. You must then provide some key implementation details:
|
||||||
raised a deprecation warning in older versions and is no longer
|
raised a deprecation warning in older versions and is no longer
|
||||||
supported in Django 1.9).
|
supported in Django 1.9).
|
||||||
|
|
||||||
The following methods are available on any subclass of
|
The following attributes and methods are available on any subclass of
|
||||||
:class:`~django.contrib.auth.models.AbstractBaseUser`:
|
:class:`~django.contrib.auth.models.AbstractBaseUser`:
|
||||||
|
|
||||||
.. class:: models.AbstractBaseUser
|
.. class:: models.AbstractBaseUser
|
||||||
|
@ -612,20 +612,34 @@ The following methods are available on any subclass of
|
||||||
|
|
||||||
Returns the value of the field nominated by ``USERNAME_FIELD``.
|
Returns the value of the field nominated by ``USERNAME_FIELD``.
|
||||||
|
|
||||||
.. method:: models.AbstractBaseUser.is_anonymous()
|
.. attribute:: models.AbstractBaseUser.is_authenticated
|
||||||
|
|
||||||
Always returns ``False``. This is a way of differentiating
|
Read-only attribute which is always ``True`` (as opposed to
|
||||||
from :class:`~django.contrib.auth.models.AnonymousUser` objects.
|
``AnonymousUser.is_authenticated`` which is always ``False``).
|
||||||
Generally, you should prefer using
|
This is a way to tell if the user has been authenticated. This does not
|
||||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.is_authenticated()` to this
|
imply any permissions and doesn't check if the user is active or has
|
||||||
method.
|
a valid session. Even though normally you will check this attribute on
|
||||||
|
``request.user`` to find out whether it has been populated by the
|
||||||
|
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
|
||||||
|
(representing the currently logged-in user), you should know this
|
||||||
|
attribute is ``True`` for any :class:`~models.User` instance.
|
||||||
|
|
||||||
.. method:: models.AbstractBaseUser.is_authenticated()
|
.. versionchanged:: 1.10
|
||||||
|
|
||||||
Always returns ``True``. This is a way to tell if the user has been
|
In older versions, this was a method. Backwards-compatibility
|
||||||
authenticated. This does not imply any permissions, and doesn't check
|
support for using it as a method will be removed in Django 2.0.
|
||||||
if the user is active - it only indicates that the user has provided a
|
|
||||||
valid username and password.
|
.. attribute:: models.AbstractBaseUser.is_anonymous
|
||||||
|
|
||||||
|
Read-only attribute which is always ``False``. This is a way of
|
||||||
|
differentiating :class:`~models.User` and :class:`~models.AnonymousUser`
|
||||||
|
objects. Generally, you should prefer using
|
||||||
|
:attr:`~models.User.is_authenticated` to this attribute.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.10
|
||||||
|
|
||||||
|
In older versions, this was a method. Backwards-compatibility
|
||||||
|
support for using it as a method will be removed in Django 2.0.
|
||||||
|
|
||||||
.. method:: models.AbstractBaseUser.set_password(raw_password)
|
.. method:: models.AbstractBaseUser.set_password(raw_password)
|
||||||
|
|
||||||
|
|
|
@ -306,9 +306,9 @@ of :class:`~django.contrib.auth.models.AnonymousUser`, otherwise it will be an
|
||||||
instance of :class:`~django.contrib.auth.models.User`.
|
instance of :class:`~django.contrib.auth.models.User`.
|
||||||
|
|
||||||
You can tell them apart with
|
You can tell them apart with
|
||||||
:meth:`~django.contrib.auth.models.User.is_authenticated()`, like so::
|
:attr:`~django.contrib.auth.models.User.is_authenticated`, like so::
|
||||||
|
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated:
|
||||||
# Do something for authenticated users.
|
# Do something for authenticated users.
|
||||||
...
|
...
|
||||||
else:
|
else:
|
||||||
|
@ -421,15 +421,15 @@ The raw way
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
The simple, raw way to limit access to pages is to check
|
The simple, raw way to limit access to pages is to check
|
||||||
:meth:`request.user.is_authenticated()
|
:attr:`request.user.is_authenticated
|
||||||
<django.contrib.auth.models.User.is_authenticated()>` and either redirect to a
|
<django.contrib.auth.models.User.is_authenticated>` and either redirect to a
|
||||||
login page::
|
login page::
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
|
|
||||||
def my_view(request):
|
def my_view(request):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated:
|
||||||
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
|
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ login page::
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
def my_view(request):
|
def my_view(request):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated:
|
||||||
return render(request, 'myapp/login_error.html')
|
return render(request, 'myapp/login_error.html')
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
|
|
|
@ -1170,7 +1170,7 @@ decorator)::
|
||||||
|
|
||||||
@vary_on_cookie
|
@vary_on_cookie
|
||||||
def list_blog_entries_view(request):
|
def list_blog_entries_view(request):
|
||||||
if request.user.is_anonymous():
|
if request.user.is_anonymous:
|
||||||
response = render_only_public_entries()
|
response = render_only_public_entries()
|
||||||
patch_cache_control(response, public=True)
|
patch_cache_control(response, public=True)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -235,7 +235,7 @@ We'll demonstrate this with the ``Author`` model we used in the
|
||||||
model = Author
|
model = Author
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated:
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
# Look up the author we're interested in.
|
# Look up the author we're interested in.
|
||||||
|
@ -466,7 +466,7 @@ Our new ``AuthorDetail`` looks like this::
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated:
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
form = self.get_form()
|
form = self.get_form()
|
||||||
|
@ -552,7 +552,7 @@ template as ``AuthorDisplay`` is using on ``GET``::
|
||||||
model = Author
|
model = Author
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated:
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
return super(AuthorInterest, self).post(request, *args, **kwargs)
|
return super(AuthorInterest, self).post(request, *args, **kwargs)
|
||||||
|
|
|
@ -12,7 +12,7 @@ from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.test import (
|
from django.test import (
|
||||||
SimpleTestCase, TestCase, modify_settings, override_settings,
|
SimpleTestCase, TestCase, mock, modify_settings, override_settings,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
|
@ -142,8 +142,7 @@ class BaseModelBackendTest(object):
|
||||||
self.assertEqual(backend.get_user_permissions(user), {'auth.test_user', 'auth.test_group'})
|
self.assertEqual(backend.get_user_permissions(user), {'auth.test_user', 'auth.test_group'})
|
||||||
self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'})
|
self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'})
|
||||||
|
|
||||||
user.is_anonymous = lambda: True
|
with mock.patch.object(self.UserModel, 'is_anonymous', True):
|
||||||
|
|
||||||
self.assertEqual(backend.get_all_permissions(user), set())
|
self.assertEqual(backend.get_all_permissions(user), set())
|
||||||
self.assertEqual(backend.get_user_permissions(user), set())
|
self.assertEqual(backend.get_user_permissions(user), set())
|
||||||
self.assertEqual(backend.get_group_permissions(user), set())
|
self.assertEqual(backend.get_group_permissions(user), set())
|
||||||
|
@ -334,14 +333,14 @@ class SimpleRowlevelBackend(object):
|
||||||
if isinstance(obj, TestObj):
|
if isinstance(obj, TestObj):
|
||||||
if user.username == 'test2':
|
if user.username == 'test2':
|
||||||
return True
|
return True
|
||||||
elif user.is_anonymous() and perm == 'anon':
|
elif user.is_anonymous and perm == 'anon':
|
||||||
return True
|
return True
|
||||||
elif not user.is_active and perm == 'inactive':
|
elif not user.is_active and perm == 'inactive':
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def has_module_perms(self, user, app_label):
|
def has_module_perms(self, user, app_label):
|
||||||
if not user.is_anonymous() and not user.is_active:
|
if not user.is_anonymous and not user.is_active:
|
||||||
return False
|
return False
|
||||||
return app_label == "app1"
|
return app_label == "app1"
|
||||||
|
|
||||||
|
@ -352,7 +351,7 @@ class SimpleRowlevelBackend(object):
|
||||||
if not isinstance(obj, TestObj):
|
if not isinstance(obj, TestObj):
|
||||||
return ['none']
|
return ['none']
|
||||||
|
|
||||||
if user.is_anonymous():
|
if user.is_anonymous:
|
||||||
return ['anon']
|
return ['anon']
|
||||||
if user.username == 'test2':
|
if user.username == 'test2':
|
||||||
return ['simple', 'advanced']
|
return ['simple', 'advanced']
|
||||||
|
@ -578,7 +577,7 @@ class ChangedBackendSettingsTest(TestCase):
|
||||||
# Assert that the user retrieval is successful and the user is
|
# Assert that the user retrieval is successful and the user is
|
||||||
# anonymous as the backend is not longer available.
|
# anonymous as the backend is not longer available.
|
||||||
self.assertIsNotNone(user)
|
self.assertIsNotNone(user)
|
||||||
self.assertTrue(user.is_anonymous())
|
self.assertTrue(user.is_anonymous)
|
||||||
|
|
||||||
|
|
||||||
class TypeErrorBackend(object):
|
class TypeErrorBackend(object):
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import AnonymousUser, User
|
from django.contrib.auth.models import AnonymousUser, User
|
||||||
|
@ -44,7 +46,8 @@ class BasicTestCase(TestCase):
|
||||||
self.assertEqual(u.get_username(), 'testuser')
|
self.assertEqual(u.get_username(), 'testuser')
|
||||||
|
|
||||||
# Check authentication/permissions
|
# Check authentication/permissions
|
||||||
self.assertTrue(u.is_authenticated())
|
self.assertFalse(u.is_anonymous)
|
||||||
|
self.assertTrue(u.is_authenticated)
|
||||||
self.assertFalse(u.is_staff)
|
self.assertFalse(u.is_staff)
|
||||||
self.assertTrue(u.is_active)
|
self.assertTrue(u.is_active)
|
||||||
self.assertFalse(u.is_superuser)
|
self.assertFalse(u.is_superuser)
|
||||||
|
@ -53,6 +56,26 @@ class BasicTestCase(TestCase):
|
||||||
u2 = User.objects.create_user('testuser2', 'test2@example.com')
|
u2 = User.objects.create_user('testuser2', 'test2@example.com')
|
||||||
self.assertFalse(u2.has_usable_password())
|
self.assertFalse(u2.has_usable_password())
|
||||||
|
|
||||||
|
def test_is_anonymous_authenticated_method_deprecation(self):
|
||||||
|
deprecation_message = (
|
||||||
|
'Using user.is_authenticated() and user.is_anonymous() as a '
|
||||||
|
'method is deprecated. Remove the parentheses to use it as an '
|
||||||
|
'attribute.'
|
||||||
|
)
|
||||||
|
u = User.objects.create_user('testuser', 'test@example.com', 'testpw')
|
||||||
|
# Backwards-compatibility callables
|
||||||
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
|
warnings.simplefilter('always')
|
||||||
|
self.assertFalse(u.is_anonymous())
|
||||||
|
self.assertEqual(len(warns), 1)
|
||||||
|
self.assertEqual(str(warns[0].message), deprecation_message)
|
||||||
|
|
||||||
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
|
warnings.simplefilter('always')
|
||||||
|
self.assertTrue(u.is_authenticated())
|
||||||
|
self.assertEqual(len(warns), 1)
|
||||||
|
self.assertEqual(str(warns[0].message), deprecation_message)
|
||||||
|
|
||||||
def test_user_no_email(self):
|
def test_user_no_email(self):
|
||||||
"Check that users can be created without an email"
|
"Check that users can be created without an email"
|
||||||
u = User.objects.create_user('testuser1')
|
u = User.objects.create_user('testuser1')
|
||||||
|
@ -70,13 +93,34 @@ class BasicTestCase(TestCase):
|
||||||
self.assertEqual(a.pk, None)
|
self.assertEqual(a.pk, None)
|
||||||
self.assertEqual(a.username, '')
|
self.assertEqual(a.username, '')
|
||||||
self.assertEqual(a.get_username(), '')
|
self.assertEqual(a.get_username(), '')
|
||||||
self.assertFalse(a.is_authenticated())
|
self.assertTrue(a.is_anonymous)
|
||||||
|
self.assertFalse(a.is_authenticated)
|
||||||
self.assertFalse(a.is_staff)
|
self.assertFalse(a.is_staff)
|
||||||
self.assertFalse(a.is_active)
|
self.assertFalse(a.is_active)
|
||||||
self.assertFalse(a.is_superuser)
|
self.assertFalse(a.is_superuser)
|
||||||
self.assertEqual(a.groups.all().count(), 0)
|
self.assertEqual(a.groups.all().count(), 0)
|
||||||
self.assertEqual(a.user_permissions.all().count(), 0)
|
self.assertEqual(a.user_permissions.all().count(), 0)
|
||||||
|
|
||||||
|
def test_anonymous_user_is_anonymous_authenticated_method_deprecation(self):
|
||||||
|
a = AnonymousUser()
|
||||||
|
deprecation_message = (
|
||||||
|
'Using user.is_authenticated() and user.is_anonymous() as a '
|
||||||
|
'method is deprecated. Remove the parentheses to use it as an '
|
||||||
|
'attribute.'
|
||||||
|
)
|
||||||
|
# Backwards-compatibility callables
|
||||||
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
|
warnings.simplefilter('always') # prevent warnings from appearing as errors
|
||||||
|
self.assertTrue(a.is_anonymous())
|
||||||
|
self.assertEqual(len(warns), 1)
|
||||||
|
self.assertEqual(str(warns[0].message), deprecation_message)
|
||||||
|
|
||||||
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
|
warnings.simplefilter('always') # prevent warnings from appearing as errors
|
||||||
|
self.assertFalse(a.is_authenticated())
|
||||||
|
self.assertEqual(len(warns), 1)
|
||||||
|
self.assertEqual(str(warns[0].message), deprecation_message)
|
||||||
|
|
||||||
def test_superuser(self):
|
def test_superuser(self):
|
||||||
"Check the creation and properties of a superuser"
|
"Check the creation and properties of a superuser"
|
||||||
super = User.objects.create_superuser('super', 'super@example.com', 'super')
|
super = User.objects.create_superuser('super', 'super@example.com', 'super')
|
||||||
|
|
|
@ -16,7 +16,7 @@ class TestAuthenticationMiddleware(TestCase):
|
||||||
self.request.session = self.client.session
|
self.request.session = self.client.session
|
||||||
self.middleware.process_request(self.request)
|
self.middleware.process_request(self.request)
|
||||||
self.assertIsNotNone(self.request.user)
|
self.assertIsNotNone(self.request.user)
|
||||||
self.assertFalse(self.request.user.is_anonymous())
|
self.assertFalse(self.request.user.is_anonymous)
|
||||||
|
|
||||||
def test_changed_password_invalidates_session(self):
|
def test_changed_password_invalidates_session(self):
|
||||||
# After password change, user should be anonymous
|
# After password change, user should be anonymous
|
||||||
|
@ -24,6 +24,6 @@ class TestAuthenticationMiddleware(TestCase):
|
||||||
self.user.save()
|
self.user.save()
|
||||||
self.middleware.process_request(self.request)
|
self.middleware.process_request(self.request)
|
||||||
self.assertIsNotNone(self.request.user)
|
self.assertIsNotNone(self.request.user)
|
||||||
self.assertTrue(self.request.user.is_anonymous())
|
self.assertTrue(self.request.user.is_anonymous)
|
||||||
# session should be flushed
|
# session should be flushed
|
||||||
self.assertIsNone(self.request.session.session_key)
|
self.assertIsNone(self.request.session.session_key)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.contrib.auth.mixins import (
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.test import RequestFactory, TestCase
|
from django.test import RequestFactory, TestCase, mock
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,9 +78,9 @@ class AccessMixinTests(TestCase):
|
||||||
with self.assertRaises(PermissionDenied):
|
with self.assertRaises(PermissionDenied):
|
||||||
view(request)
|
view(request)
|
||||||
|
|
||||||
|
@mock.patch.object(models.User, 'is_authenticated', False)
|
||||||
def test_stacked_mixins_not_logged_in(self):
|
def test_stacked_mixins_not_logged_in(self):
|
||||||
user = models.User.objects.create(username='joe', password='qwerty')
|
user = models.User.objects.create(username='joe', password='qwerty')
|
||||||
user.is_authenticated = lambda: False
|
|
||||||
perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser'))
|
perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser'))
|
||||||
user.user_permissions.add(*perms)
|
user.user_permissions.add(*perms)
|
||||||
request = self.factory.get('/rand')
|
request = self.factory.get('/rand')
|
||||||
|
|
|
@ -38,15 +38,15 @@ class RemoteUserTest(TestCase):
|
||||||
num_users = User.objects.count()
|
num_users = User.objects.count()
|
||||||
|
|
||||||
response = self.client.get('/remote_user/')
|
response = self.client.get('/remote_user/')
|
||||||
self.assertTrue(response.context['user'].is_anonymous())
|
self.assertTrue(response.context['user'].is_anonymous)
|
||||||
self.assertEqual(User.objects.count(), num_users)
|
self.assertEqual(User.objects.count(), num_users)
|
||||||
|
|
||||||
response = self.client.get('/remote_user/', **{self.header: None})
|
response = self.client.get('/remote_user/', **{self.header: None})
|
||||||
self.assertTrue(response.context['user'].is_anonymous())
|
self.assertTrue(response.context['user'].is_anonymous)
|
||||||
self.assertEqual(User.objects.count(), num_users)
|
self.assertEqual(User.objects.count(), num_users)
|
||||||
|
|
||||||
response = self.client.get('/remote_user/', **{self.header: ''})
|
response = self.client.get('/remote_user/', **{self.header: ''})
|
||||||
self.assertTrue(response.context['user'].is_anonymous())
|
self.assertTrue(response.context['user'].is_anonymous)
|
||||||
self.assertEqual(User.objects.count(), num_users)
|
self.assertEqual(User.objects.count(), num_users)
|
||||||
|
|
||||||
def test_unknown_user(self):
|
def test_unknown_user(self):
|
||||||
|
@ -118,7 +118,7 @@ class RemoteUserTest(TestCase):
|
||||||
self.assertEqual(response.context['user'].username, 'knownuser')
|
self.assertEqual(response.context['user'].username, 'knownuser')
|
||||||
# During the session, the REMOTE_USER header disappears. Should trigger logout.
|
# During the session, the REMOTE_USER header disappears. Should trigger logout.
|
||||||
response = self.client.get('/remote_user/')
|
response = self.client.get('/remote_user/')
|
||||||
self.assertEqual(response.context['user'].is_anonymous(), True)
|
self.assertTrue(response.context['user'].is_anonymous)
|
||||||
# verify the remoteuser middleware will not remove a user
|
# verify the remoteuser middleware will not remove a user
|
||||||
# authenticated via another backend
|
# authenticated via another backend
|
||||||
User.objects.create_user(username='modeluser', password='foo')
|
User.objects.create_user(username='modeluser', password='foo')
|
||||||
|
@ -148,7 +148,7 @@ class RemoteUserTest(TestCase):
|
||||||
def test_inactive_user(self):
|
def test_inactive_user(self):
|
||||||
User.objects.create(username='knownuser', is_active=False)
|
User.objects.create(username='knownuser', is_active=False)
|
||||||
response = self.client.get('/remote_user/', **{self.header: 'knownuser'})
|
response = self.client.get('/remote_user/', **{self.header: 'knownuser'})
|
||||||
self.assertTrue(response.context['user'].is_anonymous())
|
self.assertTrue(response.context['user'].is_anonymous)
|
||||||
|
|
||||||
|
|
||||||
class RemoteUserNoCreateBackend(RemoteUserBackend):
|
class RemoteUserNoCreateBackend(RemoteUserBackend):
|
||||||
|
@ -167,7 +167,7 @@ class RemoteUserNoCreateTest(RemoteUserTest):
|
||||||
def test_unknown_user(self):
|
def test_unknown_user(self):
|
||||||
num_users = User.objects.count()
|
num_users = User.objects.count()
|
||||||
response = self.client.get('/remote_user/', **{self.header: 'newuser'})
|
response = self.client.get('/remote_user/', **{self.header: 'newuser'})
|
||||||
self.assertTrue(response.context['user'].is_anonymous())
|
self.assertTrue(response.context['user'].is_anonymous)
|
||||||
self.assertEqual(User.objects.count(), num_users)
|
self.assertEqual(User.objects.count(), num_users)
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,5 +268,5 @@ class PersistentRemoteUserTest(RemoteUserTest):
|
||||||
self.assertEqual(response.context['user'].username, 'knownuser')
|
self.assertEqual(response.context['user'].username, 'knownuser')
|
||||||
# Should stay logged in if the REMOTE_USER header disappears.
|
# Should stay logged in if the REMOTE_USER header disappears.
|
||||||
response = self.client.get('/remote_user/')
|
response = self.client.get('/remote_user/')
|
||||||
self.assertEqual(response.context['user'].is_anonymous(), False)
|
self.assertFalse(response.context['user'].is_anonymous)
|
||||||
self.assertEqual(response.context['user'].username, 'knownuser')
|
self.assertEqual(response.context['user'].username, 'knownuser')
|
||||||
|
|
|
@ -45,7 +45,7 @@ class LazyRedirectView(RedirectView):
|
||||||
url = reverse_lazy('named-lazy-url-redirected-to')
|
url = reverse_lazy('named-lazy-url-redirected-to')
|
||||||
|
|
||||||
|
|
||||||
@user_passes_test(lambda u: u.is_authenticated(), login_url=reverse_lazy('some-login-page'))
|
@user_passes_test(lambda u: u.is_authenticated, login_url=reverse_lazy('some-login-page'))
|
||||||
def login_required_view(request):
|
def login_required_view(request):
|
||||||
return HttpResponse('Hello you')
|
return HttpResponse('Hello you')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue