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>
|
||||
Jeremy Carbaugh <jcarbaugh@gmail.com>
|
||||
Jeremy Dunck <jdunck@gmail.com>
|
||||
Jeremy Lainé <jeremy.laine@m4x.org>
|
||||
Jesse Young <adunar@gmail.com>
|
||||
jhenry <jhenry@theonion.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
|
||||
# chance to find out *who* logged out.
|
||||
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_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
|
||||
`_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()
|
||||
|
||||
perm_cache_name = '_%s_perm_cache' % from_name
|
||||
|
@ -73,7 +73,7 @@ class ModelBackend(object):
|
|||
return self._get_permissions(user_obj, obj, 'group')
|
||||
|
||||
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()
|
||||
if not hasattr(user_obj, '_perm_cache'):
|
||||
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.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.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -79,19 +80,21 @@ class AbstractBaseUser(models.Model):
|
|||
def natural_key(self):
|
||||
return (self.get_username(),)
|
||||
|
||||
@property
|
||||
def is_anonymous(self):
|
||||
"""
|
||||
Always return False. This is a way of comparing User objects to
|
||||
anonymous users.
|
||||
"""
|
||||
return False
|
||||
return CallableFalse
|
||||
|
||||
@property
|
||||
def is_authenticated(self):
|
||||
"""
|
||||
Always return True. This is a way to tell if the user has been
|
||||
authenticated in templates.
|
||||
"""
|
||||
return True
|
||||
return CallableTrue
|
||||
|
||||
def set_password(self, 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.
|
||||
"""
|
||||
actual_decorator = user_passes_test(
|
||||
lambda u: u.is_authenticated(),
|
||||
lambda u: u.is_authenticated,
|
||||
login_url=login_url,
|
||||
redirect_field_name=redirect_field_name
|
||||
)
|
||||
|
|
|
@ -70,13 +70,13 @@ class RemoteUserMiddleware(object):
|
|||
# If specified header doesn't exist then remove any existing
|
||||
# authenticated remote-user, or return (leaving request.user set to
|
||||
# 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)
|
||||
return
|
||||
# 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
|
||||
# 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):
|
||||
return
|
||||
else:
|
||||
|
|
|
@ -51,7 +51,7 @@ class LoginRequiredMixin(AccessMixin):
|
|||
CBV mixin which verifies that the current user is authenticated.
|
||||
"""
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return self.handle_no_permission()
|
||||
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.models.manager import EmptyManager
|
||||
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.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -438,11 +439,13 @@ class AnonymousUser(object):
|
|||
def has_module_perms(self, module):
|
||||
return _user_has_module_perms(self, module)
|
||||
|
||||
@property
|
||||
def is_anonymous(self):
|
||||
return True
|
||||
return CallableTrue
|
||||
|
||||
@property
|
||||
def is_authenticated(self):
|
||||
return False
|
||||
return CallableFalse
|
||||
|
||||
def get_username(self):
|
||||
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, ''))
|
||||
|
||||
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)
|
||||
if redirect_to == request.path:
|
||||
raise ValueError(
|
||||
|
|
|
@ -33,7 +33,7 @@ class FlatpageNode(template.Node):
|
|||
# was provided, filter the list to only public flatpages.
|
||||
if self.user:
|
||||
user = self.user.resolve(context)
|
||||
if not user.is_authenticated():
|
||||
if not user.is_authenticated:
|
||||
flatpages = flatpages.filter(registration_required=False)
|
||||
else:
|
||||
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
|
||||
# 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
|
||||
return redirect_to_login(request.path)
|
||||
if f.template_name:
|
||||
|
|
|
@ -79,3 +79,33 @@ class DeprecationInstanceCheck(type):
|
|||
self.deprecation_warning, 2
|
||||
)
|
||||
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::
|
||||
|
||||
def my_view(request):
|
||||
if request.user.is_authenticated():
|
||||
if request.user.is_authenticated:
|
||||
request.exception_reporter_filter = CustomExceptionReporterFilter()
|
||||
...
|
||||
|
||||
|
|
|
@ -147,6 +147,9 @@ details on these changes.
|
|||
* The shim for supporting custom related manager classes without a
|
||||
``_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:
|
||||
|
||||
1.10
|
||||
|
|
|
@ -111,6 +111,41 @@ Fields
|
|||
A datetime designating when the account was created. Is set to the
|
||||
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
|
||||
-------
|
||||
|
||||
|
@ -119,31 +154,9 @@ Methods
|
|||
.. method:: get_username()
|
||||
|
||||
Returns the username for the user. Since the User model can be swapped
|
||||
out, you should use this method instead of referencing the username
|
||||
out, you should use this method instead of referencing the username
|
||||
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()
|
||||
|
||||
Returns the :attr:`~django.contrib.auth.models.User.first_name` plus
|
||||
|
@ -287,6 +300,10 @@ Manager methods
|
|||
string.
|
||||
* :meth:`~django.contrib.auth.models.User.get_username()` always returns
|
||||
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_superuser` are always
|
||||
``False``.
|
||||
|
@ -294,10 +311,6 @@ Manager methods
|
|||
* :attr:`~django.contrib.auth.models.User.groups` and
|
||||
:attr:`~django.contrib.auth.models.User.user_permissions` are always
|
||||
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.check_password()`,
|
||||
: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
|
||||
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``.
|
||||
|
||||
.. method:: get_group_permissions(user_obj, obj=None)
|
||||
|
||||
Returns the set of permission strings the ``user_obj`` has from the
|
||||
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``.
|
||||
|
||||
.. method:: get_all_permissions(user_obj, obj=None)
|
||||
|
||||
Returns the set of permission strings the ``user_obj`` has, including both
|
||||
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``.
|
||||
|
||||
.. 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
|
||||
to an instance of :class:`~django.contrib.auth.models.AnonymousUser`. 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 logged-in users.
|
||||
else:
|
||||
... # Do something for anonymous users.
|
||||
|
|
|
@ -730,6 +730,10 @@ Miscellaneous
|
|||
* Middleware classes are now initialized when the server starts rather than
|
||||
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:
|
||||
|
||||
Features deprecated in 1.10
|
||||
|
@ -857,6 +861,37 @@ features, is deprecated. Replace it with a custom lookup::
|
|||
models.CharField.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
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
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:: 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``.
|
||||
|
||||
.. method:: models.AbstractBaseUser.is_anonymous()
|
||||
.. attribute:: models.AbstractBaseUser.is_authenticated
|
||||
|
||||
Always returns ``False``. This is a way of differentiating
|
||||
from :class:`~django.contrib.auth.models.AnonymousUser` objects.
|
||||
Generally, you should prefer using
|
||||
:meth:`~django.contrib.auth.models.AbstractBaseUser.is_authenticated()` to this
|
||||
method.
|
||||
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.
|
||||
|
||||
.. method:: models.AbstractBaseUser.is_authenticated()
|
||||
.. versionchanged:: 1.10
|
||||
|
||||
Always returns ``True``. 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 - it only indicates that the user has provided a
|
||||
valid username and password.
|
||||
In older versions, this was a method. Backwards-compatibility
|
||||
support for using it as a method will be removed in Django 2.0.
|
||||
|
||||
.. 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)
|
||||
|
||||
|
|
|
@ -306,9 +306,9 @@ of :class:`~django.contrib.auth.models.AnonymousUser`, otherwise it will be an
|
|||
instance of :class:`~django.contrib.auth.models.User`.
|
||||
|
||||
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.
|
||||
...
|
||||
else:
|
||||
|
@ -421,15 +421,15 @@ The raw way
|
|||
~~~~~~~~~~~
|
||||
|
||||
The simple, raw way to limit access to pages is to check
|
||||
:meth:`request.user.is_authenticated()
|
||||
<django.contrib.auth.models.User.is_authenticated()>` and either redirect to a
|
||||
:attr:`request.user.is_authenticated
|
||||
<django.contrib.auth.models.User.is_authenticated>` and either redirect to a
|
||||
login page::
|
||||
|
||||
from django.conf import settings
|
||||
from django.shortcuts import redirect
|
||||
|
||||
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))
|
||||
# ...
|
||||
|
||||
|
@ -438,7 +438,7 @@ login page::
|
|||
from django.shortcuts import render
|
||||
|
||||
def my_view(request):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return render(request, 'myapp/login_error.html')
|
||||
# ...
|
||||
|
||||
|
|
|
@ -1170,7 +1170,7 @@ decorator)::
|
|||
|
||||
@vary_on_cookie
|
||||
def list_blog_entries_view(request):
|
||||
if request.user.is_anonymous():
|
||||
if request.user.is_anonymous:
|
||||
response = render_only_public_entries()
|
||||
patch_cache_control(response, public=True)
|
||||
else:
|
||||
|
|
|
@ -235,7 +235,7 @@ We'll demonstrate this with the ``Author`` model we used in the
|
|||
model = Author
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return HttpResponseForbidden()
|
||||
|
||||
# Look up the author we're interested in.
|
||||
|
@ -466,7 +466,7 @@ Our new ``AuthorDetail`` looks like this::
|
|||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return HttpResponseForbidden()
|
||||
self.object = self.get_object()
|
||||
form = self.get_form()
|
||||
|
@ -552,7 +552,7 @@ template as ``AuthorDisplay`` is using on ``GET``::
|
|||
model = Author
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
if not request.user.is_authenticated:
|
||||
return HttpResponseForbidden()
|
||||
self.object = self.get_object()
|
||||
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.http import HttpRequest
|
||||
from django.test import (
|
||||
SimpleTestCase, TestCase, modify_settings, override_settings,
|
||||
SimpleTestCase, TestCase, mock, modify_settings, override_settings,
|
||||
)
|
||||
|
||||
from .models import (
|
||||
|
@ -142,11 +142,10 @@ class BaseModelBackendTest(object):
|
|||
self.assertEqual(backend.get_user_permissions(user), {'auth.test_user', 'auth.test_group'})
|
||||
self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'})
|
||||
|
||||
user.is_anonymous = lambda: True
|
||||
|
||||
self.assertEqual(backend.get_all_permissions(user), set())
|
||||
self.assertEqual(backend.get_user_permissions(user), set())
|
||||
self.assertEqual(backend.get_group_permissions(user), set())
|
||||
with mock.patch.object(self.UserModel, 'is_anonymous', True):
|
||||
self.assertEqual(backend.get_all_permissions(user), set())
|
||||
self.assertEqual(backend.get_user_permissions(user), set())
|
||||
self.assertEqual(backend.get_group_permissions(user), set())
|
||||
|
||||
def test_inactive_has_no_permissions(self):
|
||||
"""
|
||||
|
@ -334,14 +333,14 @@ class SimpleRowlevelBackend(object):
|
|||
if isinstance(obj, TestObj):
|
||||
if user.username == 'test2':
|
||||
return True
|
||||
elif user.is_anonymous() and perm == 'anon':
|
||||
elif user.is_anonymous and perm == 'anon':
|
||||
return True
|
||||
elif not user.is_active and perm == 'inactive':
|
||||
return True
|
||||
return False
|
||||
|
||||
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 app_label == "app1"
|
||||
|
||||
|
@ -352,7 +351,7 @@ class SimpleRowlevelBackend(object):
|
|||
if not isinstance(obj, TestObj):
|
||||
return ['none']
|
||||
|
||||
if user.is_anonymous():
|
||||
if user.is_anonymous:
|
||||
return ['anon']
|
||||
if user.username == 'test2':
|
||||
return ['simple', 'advanced']
|
||||
|
@ -578,7 +577,7 @@ class ChangedBackendSettingsTest(TestCase):
|
|||
# Assert that the user retrieval is successful and the user is
|
||||
# anonymous as the backend is not longer available.
|
||||
self.assertIsNotNone(user)
|
||||
self.assertTrue(user.is_anonymous())
|
||||
self.assertTrue(user.is_anonymous)
|
||||
|
||||
|
||||
class TypeErrorBackend(object):
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import warnings
|
||||
|
||||
from django.apps import apps
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
|
@ -44,7 +46,8 @@ class BasicTestCase(TestCase):
|
|||
self.assertEqual(u.get_username(), 'testuser')
|
||||
|
||||
# Check authentication/permissions
|
||||
self.assertTrue(u.is_authenticated())
|
||||
self.assertFalse(u.is_anonymous)
|
||||
self.assertTrue(u.is_authenticated)
|
||||
self.assertFalse(u.is_staff)
|
||||
self.assertTrue(u.is_active)
|
||||
self.assertFalse(u.is_superuser)
|
||||
|
@ -53,6 +56,26 @@ class BasicTestCase(TestCase):
|
|||
u2 = User.objects.create_user('testuser2', 'test2@example.com')
|
||||
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):
|
||||
"Check that users can be created without an email"
|
||||
u = User.objects.create_user('testuser1')
|
||||
|
@ -70,13 +93,34 @@ class BasicTestCase(TestCase):
|
|||
self.assertEqual(a.pk, None)
|
||||
self.assertEqual(a.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_active)
|
||||
self.assertFalse(a.is_superuser)
|
||||
self.assertEqual(a.groups.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):
|
||||
"Check the creation and properties of a superuser"
|
||||
super = User.objects.create_superuser('super', 'super@example.com', 'super')
|
||||
|
|
|
@ -16,7 +16,7 @@ class TestAuthenticationMiddleware(TestCase):
|
|||
self.request.session = self.client.session
|
||||
self.middleware.process_request(self.request)
|
||||
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):
|
||||
# After password change, user should be anonymous
|
||||
|
@ -24,6 +24,6 @@ class TestAuthenticationMiddleware(TestCase):
|
|||
self.user.save()
|
||||
self.middleware.process_request(self.request)
|
||||
self.assertIsNotNone(self.request.user)
|
||||
self.assertTrue(self.request.user.is_anonymous())
|
||||
self.assertTrue(self.request.user.is_anonymous)
|
||||
# session should be flushed
|
||||
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.core.exceptions import PermissionDenied
|
||||
from django.http import HttpResponse
|
||||
from django.test import RequestFactory, TestCase
|
||||
from django.test import RequestFactory, TestCase, mock
|
||||
from django.views.generic import View
|
||||
|
||||
|
||||
|
@ -78,9 +78,9 @@ class AccessMixinTests(TestCase):
|
|||
with self.assertRaises(PermissionDenied):
|
||||
view(request)
|
||||
|
||||
@mock.patch.object(models.User, 'is_authenticated', False)
|
||||
def test_stacked_mixins_not_logged_in(self):
|
||||
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'))
|
||||
user.user_permissions.add(*perms)
|
||||
request = self.factory.get('/rand')
|
||||
|
|
|
@ -38,15 +38,15 @@ class RemoteUserTest(TestCase):
|
|||
num_users = User.objects.count()
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def test_unknown_user(self):
|
||||
|
@ -118,7 +118,7 @@ class RemoteUserTest(TestCase):
|
|||
self.assertEqual(response.context['user'].username, 'knownuser')
|
||||
# During the session, the REMOTE_USER header disappears. Should trigger logout.
|
||||
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
|
||||
# authenticated via another backend
|
||||
User.objects.create_user(username='modeluser', password='foo')
|
||||
|
@ -148,7 +148,7 @@ class RemoteUserTest(TestCase):
|
|||
def test_inactive_user(self):
|
||||
User.objects.create(username='knownuser', is_active=False)
|
||||
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):
|
||||
|
@ -167,7 +167,7 @@ class RemoteUserNoCreateTest(RemoteUserTest):
|
|||
def test_unknown_user(self):
|
||||
num_users = User.objects.count()
|
||||
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)
|
||||
|
||||
|
||||
|
@ -268,5 +268,5 @@ class PersistentRemoteUserTest(RemoteUserTest):
|
|||
self.assertEqual(response.context['user'].username, 'knownuser')
|
||||
# Should stay logged in if the REMOTE_USER header disappears.
|
||||
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')
|
||||
|
|
|
@ -45,7 +45,7 @@ class LazyRedirectView(RedirectView):
|
|||
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):
|
||||
return HttpResponse('Hello you')
|
||||
|
||||
|
|
Loading…
Reference in New Issue