Commit 03efa304 authored by Tim Graham's avatar Tim Graham
Browse files

Refs #25847 -- Added system check for UserModel.is_anonymous/is_authenticated methods.

parent b3acf35f
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ from itertools import chain
from django.apps import apps
from django.conf import settings
from django.core import checks
from django.utils import six

from .management import _get_builtin_permissions

@@ -73,6 +74,26 @@ def check_user_model(app_configs=None, **kwargs):
                )
            )

    if isinstance(cls().is_anonymous, six.types.MethodType):
        errors.append(
            checks.Critical(
                '%s.is_anonymous must be an attribute or property rather than '
                'a method. Ignoring this is a security issue as anonymous '
                'users will be treated as authenticated!' % cls,
                obj=cls,
                id='auth.C009',
            )
        )
    if isinstance(cls().is_authenticated, six.types.MethodType):
        errors.append(
            checks.Critical(
                '%s.is_authenticated must be an attribute or property rather '
                'than a method. Ignoring this is a security issue as anonymous '
                'users will be treated as authenticated!' % cls,
                obj=cls,
                id='auth.C010',
            )
        )
    return errors


+6 −0
Original line number Diff line number Diff line
@@ -450,6 +450,12 @@ Auth
  to be at most 255 characters.
* **auth.E008**: The permission named ``<name>`` of model ``<model>`` is longer
  than 255 characters.
* **auth.C009**: ``<User model>.is_anonymous`` must be an attribute or property
  rather than a method. Ignoring this is a security issue as anonymous users
  will be treated as authenticated!
* **auth.C010**: ``<User model>.is_authenticated`` must be an attribute or
  property rather than a method. Ignoring this is a security issue as anonymous
  users will be treated as authenticated!


Content Types
+33 −0
Original line number Diff line number Diff line
@@ -83,6 +83,39 @@ class UserModelChecksTests(SimpleTestCase):
                ),
            ])

    @override_settings(AUTH_USER_MODEL='auth_tests.BadUser')
    def test_is_anonymous_authenticated_methods(self):
        """
        <User Model>.is_anonymous/is_authenticated must not be methods.
        """
        class BadUser(AbstractBaseUser):
            username = models.CharField(max_length=30, unique=True)
            USERNAME_FIELD = 'username'

            def is_anonymous(self):
                return True

            def is_authenticated(self):
                return True

        errors = checks.run_checks(app_configs=self.apps.get_app_configs())
        self.assertEqual(errors, [
            checks.Critical(
                '%s.is_anonymous must be an attribute or property rather than '
                'a method. Ignoring this is a security issue as anonymous '
                'users will be treated as authenticated!' % BadUser,
                obj=BadUser,
                id='auth.C009',
            ),
            checks.Critical(
                '%s.is_authenticated must be an attribute or property rather '
                'than a method. Ignoring this is a security issue as anonymous '
                'users will be treated as authenticated!' % BadUser,
                obj=BadUser,
                id='auth.C010',
            ),
        ])


@isolate_apps('auth_tests', attr_name='apps')
@override_system_checks([check_models_permissions])