From 9c19aff7c7561e3a82978a272ecdaad40dda5c00 Mon Sep 17 00:00:00 2001 From: django-bot Date: Thu, 3 Feb 2022 20:24:19 +0100 Subject: Refs #33476 -- Reformatted code with Black. --- tests/auth_tests/backend_alias.py | 2 +- tests/auth_tests/client.py | 6 +- tests/auth_tests/models/__init__.py | 33 +- tests/auth_tests/models/custom_permissions.py | 9 +- tests/auth_tests/models/custom_user.py | 31 +- tests/auth_tests/models/invalid_models.py | 5 +- tests/auth_tests/models/is_active.py | 3 +- tests/auth_tests/models/minimal.py | 2 +- tests/auth_tests/models/no_password.py | 2 +- tests/auth_tests/models/proxy.py | 8 +- tests/auth_tests/models/uuid_pk.py | 2 + tests/auth_tests/models/with_custom_email_field.py | 4 +- tests/auth_tests/models/with_foreign_key.py | 12 +- tests/auth_tests/models/with_integer_username.py | 4 +- tests/auth_tests/models/with_many_to_many.py | 10 +- tests/auth_tests/settings.py | 30 +- tests/auth_tests/test_admin_multidb.py | 27 +- tests/auth_tests/test_auth_backends.py | 505 +++++---- tests/auth_tests/test_basic.py | 75 +- tests/auth_tests/test_checks.py | 374 ++++--- tests/auth_tests/test_context_processors.py | 64 +- tests/auth_tests/test_decorators.py | 68 +- tests/auth_tests/test_forms.py | 891 ++++++++------- tests/auth_tests/test_handlers.py | 46 +- tests/auth_tests/test_hashers.py | 708 ++++++------ tests/auth_tests/test_management.py | 888 ++++++++------- tests/auth_tests/test_middleware.py | 6 +- tests/auth_tests/test_migrations.py | 138 ++- tests/auth_tests/test_mixins.py | 114 +- tests/auth_tests/test_models.py | 330 +++--- tests/auth_tests/test_remote_user.py | 189 ++-- tests/auth_tests/test_signals.py | 51 +- tests/auth_tests/test_templates.py | 83 +- tests/auth_tests/test_tokens.py | 57 +- tests/auth_tests/test_validators.py | 179 +-- tests/auth_tests/test_views.py | 1168 ++++++++++++-------- tests/auth_tests/urls.py | 180 +-- tests/auth_tests/urls_admin.py | 4 +- tests/auth_tests/urls_custom_user_admin.py | 4 +- 39 files changed, 3573 insertions(+), 2739 deletions(-) (limited to 'tests/auth_tests') diff --git a/tests/auth_tests/backend_alias.py b/tests/auth_tests/backend_alias.py index ae14d1538c..fe398d1674 100644 --- a/tests/auth_tests/backend_alias.py +++ b/tests/auth_tests/backend_alias.py @@ -1,4 +1,4 @@ # For testing that auth backends can be referenced using a convenience import from .test_auth_backends import ImportedModelBackend -__all__ = ['ImportedModelBackend'] +__all__ = ["ImportedModelBackend"] diff --git a/tests/auth_tests/client.py b/tests/auth_tests/client.py index c2ce1102ce..7426f93e6e 100644 --- a/tests/auth_tests/client.py +++ b/tests/auth_tests/client.py @@ -1,13 +1,14 @@ import re from django.contrib.auth.views import ( - INTERNAL_RESET_SESSION_TOKEN, PasswordResetConfirmView, + INTERNAL_RESET_SESSION_TOKEN, + PasswordResetConfirmView, ) from django.test import Client def extract_token_from_url(url): - token_search = re.search(r'/reset/.*/(.+?)/', url) + token_search = re.search(r"/reset/.*/(.+?)/", url) if token_search: return token_search[1] @@ -22,6 +23,7 @@ class PasswordResetConfirmClient(Client): >>> client = PasswordResetConfirmClient() >>> client.get('/reset/bla/my-token/') """ + reset_url_token = PasswordResetConfirmView.reset_url_token def _get_password_reset_confirm_redirect_url(self, url): diff --git a/tests/auth_tests/models/__init__.py b/tests/auth_tests/models/__init__.py index b3e06cd7b8..bce5edf883 100644 --- a/tests/auth_tests/models/__init__.py +++ b/tests/auth_tests/models/__init__.py @@ -1,7 +1,5 @@ from .custom_permissions import CustomPermissionsUser -from .custom_user import ( - CustomUser, CustomUserWithoutIsActiveField, ExtensionUser, -) +from .custom_user import CustomUser, CustomUserWithoutIsActiveField, ExtensionUser from .invalid_models import CustomUserNonUniqueUsername from .is_active import IsActiveTestUser1 from .minimal import MinimalUser @@ -12,15 +10,26 @@ from .with_custom_email_field import CustomEmailField from .with_foreign_key import CustomUserWithFK, Email from .with_integer_username import IntegerUsernameUser from .with_last_login_attr import UserWithDisabledLastLoginField -from .with_many_to_many import ( - CustomUserWithM2M, CustomUserWithM2MThrough, Organization, -) +from .with_many_to_many import CustomUserWithM2M, CustomUserWithM2MThrough, Organization __all__ = ( - 'CustomEmailField', 'CustomPermissionsUser', 'CustomUser', - 'CustomUserNonUniqueUsername', 'CustomUserWithFK', 'CustomUserWithM2M', - 'CustomUserWithM2MThrough', 'CustomUserWithoutIsActiveField', 'Email', - 'ExtensionUser', 'IntegerUsernameUser', 'IsActiveTestUser1', 'MinimalUser', - 'NoPasswordUser', 'Organization', 'Proxy', 'UUIDUser', 'UserProxy', - 'UserWithDisabledLastLoginField', + "CustomEmailField", + "CustomPermissionsUser", + "CustomUser", + "CustomUserNonUniqueUsername", + "CustomUserWithFK", + "CustomUserWithM2M", + "CustomUserWithM2MThrough", + "CustomUserWithoutIsActiveField", + "Email", + "ExtensionUser", + "IntegerUsernameUser", + "IsActiveTestUser1", + "MinimalUser", + "NoPasswordUser", + "Organization", + "Proxy", + "UUIDUser", + "UserProxy", + "UserWithDisabledLastLoginField", ) diff --git a/tests/auth_tests/models/custom_permissions.py b/tests/auth_tests/models/custom_permissions.py index bddcfde2eb..52d28bd276 100644 --- a/tests/auth_tests/models/custom_permissions.py +++ b/tests/auth_tests/models/custom_permissions.py @@ -18,14 +18,17 @@ class CustomPermissionsUserManager(CustomUserManager): with RemoveGroupsAndPermissions(): + class CustomPermissionsUser(AbstractBaseUser, PermissionsMixin): - email = models.EmailField(verbose_name='email address', max_length=255, unique=True) + email = models.EmailField( + verbose_name="email address", max_length=255, unique=True + ) date_of_birth = models.DateField() custom_objects = CustomPermissionsUserManager() - USERNAME_FIELD = 'email' - REQUIRED_FIELDS = ['date_of_birth'] + USERNAME_FIELD = "email" + REQUIRED_FIELDS = ["date_of_birth"] def __str__(self): return self.email diff --git a/tests/auth_tests/models/custom_user.py b/tests/auth_tests/models/custom_user.py index a46f1d5a9c..b9938681ca 100644 --- a/tests/auth_tests/models/custom_user.py +++ b/tests/auth_tests/models/custom_user.py @@ -1,6 +1,11 @@ from django.contrib.auth.models import ( - AbstractBaseUser, AbstractUser, BaseUserManager, Group, Permission, - PermissionsMixin, UserManager, + AbstractBaseUser, + AbstractUser, + BaseUserManager, + Group, + Permission, + PermissionsMixin, + UserManager, ) from django.db import models @@ -14,12 +19,10 @@ class CustomUserManager(BaseUserManager): Creates and saves a User with the given email and password. """ if not email: - raise ValueError('Users must have an email address') + raise ValueError("Users must have an email address") user = self.model( - email=self.normalize_email(email), - date_of_birth=date_of_birth, - **fields + email=self.normalize_email(email), date_of_birth=date_of_birth, **fields ) user.set_password(password) @@ -27,14 +30,16 @@ class CustomUserManager(BaseUserManager): return user def create_superuser(self, email, password, date_of_birth, **fields): - u = self.create_user(email, password=password, date_of_birth=date_of_birth, **fields) + u = self.create_user( + email, password=password, date_of_birth=date_of_birth, **fields + ) u.is_admin = True u.save(using=self._db) return u class CustomUser(AbstractBaseUser): - email = models.EmailField(verbose_name='email address', max_length=255, unique=True) + email = models.EmailField(verbose_name="email address", max_length=255, unique=True) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) date_of_birth = models.DateField() @@ -42,8 +47,8 @@ class CustomUser(AbstractBaseUser): custom_objects = CustomUserManager() - USERNAME_FIELD = 'email' - REQUIRED_FIELDS = ['date_of_birth', 'first_name'] + USERNAME_FIELD = "email" + REQUIRED_FIELDS = ["date_of_birth", "first_name"] def __str__(self): return self.email @@ -76,6 +81,7 @@ class RemoveGroupsAndPermissions: fields from the AbstractUser class, so they don't clash with the related_name sets. """ + def __enter__(self): self._old_au_local_m2m = AbstractUser._meta.local_many_to_many self._old_pm_local_m2m = PermissionsMixin._meta.local_many_to_many @@ -97,16 +103,17 @@ class CustomUserWithoutIsActiveField(AbstractBaseUser): objects = UserManager() - USERNAME_FIELD = 'username' + USERNAME_FIELD = "username" # The extension user is a simple extension of the built-in user class, # adding a required date_of_birth field. This allows us to check for # any hard references to the name "User" in forms/handlers etc. with RemoveGroupsAndPermissions(): + class ExtensionUser(AbstractUser): date_of_birth = models.DateField() custom_objects = UserManager() - REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + ['date_of_birth'] + REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + ["date_of_birth"] diff --git a/tests/auth_tests/models/invalid_models.py b/tests/auth_tests/models/invalid_models.py index 123ed4d865..280c690faa 100644 --- a/tests/auth_tests/models/invalid_models.py +++ b/tests/auth_tests/models/invalid_models.py @@ -9,12 +9,13 @@ class CustomUserNonUniqueUsername(AbstractBaseUser): This model is not invalid if it is used with a custom authentication backend which supports non-unique usernames. """ + username = models.CharField(max_length=30) email = models.EmailField(blank=True) is_staff = models.BooleanField(default=False) is_superuser = models.BooleanField(default=False) - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = ['email'] + USERNAME_FIELD = "username" + REQUIRED_FIELDS = ["email"] objects = UserManager() diff --git a/tests/auth_tests/models/is_active.py b/tests/auth_tests/models/is_active.py index 4c3144ffdc..cc91b8b97e 100644 --- a/tests/auth_tests/models/is_active.py +++ b/tests/auth_tests/models/is_active.py @@ -6,10 +6,11 @@ class IsActiveTestUser1(AbstractBaseUser): """ This test user class and derivatives test the default is_active behavior """ + username = models.CharField(max_length=30, unique=True) custom_objects = BaseUserManager() - USERNAME_FIELD = 'username' + USERNAME_FIELD = "username" # the is_active attr is provided by AbstractBaseUser diff --git a/tests/auth_tests/models/minimal.py b/tests/auth_tests/models/minimal.py index 7b8931b231..6fd986848c 100644 --- a/tests/auth_tests/models/minimal.py +++ b/tests/auth_tests/models/minimal.py @@ -3,4 +3,4 @@ from django.db import models class MinimalUser(models.Model): REQUIRED_FIELDS = () - USERNAME_FIELD = 'id' + USERNAME_FIELD = "id" diff --git a/tests/auth_tests/models/no_password.py b/tests/auth_tests/models/no_password.py index c7c40f76f6..33c08b4692 100644 --- a/tests/auth_tests/models/no_password.py +++ b/tests/auth_tests/models/no_password.py @@ -17,5 +17,5 @@ class NoPasswordUser(AbstractBaseUser): last_login = None username = models.CharField(max_length=50, unique=True) - USERNAME_FIELD = 'username' + USERNAME_FIELD = "username" objects = UserManager() diff --git a/tests/auth_tests/models/proxy.py b/tests/auth_tests/models/proxy.py index 9e82a398c2..ddcdfd582c 100644 --- a/tests/auth_tests/models/proxy.py +++ b/tests/auth_tests/models/proxy.py @@ -9,14 +9,10 @@ class Concrete(models.Model): class Proxy(Concrete): class Meta: proxy = True - permissions = ( - ('display_proxys', 'May display proxys information'), - ) + permissions = (("display_proxys", "May display proxys information"),) class UserProxy(User): class Meta: proxy = True - permissions = ( - ('use_different_app_label', 'May use a different app label'), - ) + permissions = (("use_different_app_label", "May use a different app label"),) diff --git a/tests/auth_tests/models/uuid_pk.py b/tests/auth_tests/models/uuid_pk.py index 87a4ee0658..d753660cbe 100644 --- a/tests/auth_tests/models/uuid_pk.py +++ b/tests/auth_tests/models/uuid_pk.py @@ -6,6 +6,8 @@ from django.db import models from .custom_user import RemoveGroupsAndPermissions with RemoveGroupsAndPermissions(): + class UUIDUser(AbstractUser): """A user with a UUID as primary key""" + id = models.UUIDField(default=uuid.uuid4, primary_key=True) diff --git a/tests/auth_tests/models/with_custom_email_field.py b/tests/auth_tests/models/with_custom_email_field.py index 278cd137a4..3cba8802d9 100644 --- a/tests/auth_tests/models/with_custom_email_field.py +++ b/tests/auth_tests/models/with_custom_email_field.py @@ -18,7 +18,7 @@ class CustomEmailField(AbstractBaseUser): email_address = models.EmailField(null=True) is_active = models.BooleanField(default=True) - EMAIL_FIELD = 'email_address' - USERNAME_FIELD = 'username' + EMAIL_FIELD = "email_address" + USERNAME_FIELD = "username" objects = CustomEmailFieldUserManager() diff --git a/tests/auth_tests/models/with_foreign_key.py b/tests/auth_tests/models/with_foreign_key.py index d16329a04b..13100accff 100644 --- a/tests/auth_tests/models/with_foreign_key.py +++ b/tests/auth_tests/models/with_foreign_key.py @@ -3,7 +3,7 @@ from django.db import models class Email(models.Model): - email = models.EmailField(verbose_name='email address', max_length=255, unique=True) + email = models.EmailField(verbose_name="email address", max_length=255, unique=True) class CustomUserWithFKManager(BaseUserManager): @@ -15,11 +15,13 @@ class CustomUserWithFKManager(BaseUserManager): class CustomUserWithFK(AbstractBaseUser): - username = models.ForeignKey(Email, models.CASCADE, related_name='primary') - email = models.ForeignKey(Email, models.CASCADE, to_field='email', related_name='secondary') + username = models.ForeignKey(Email, models.CASCADE, related_name="primary") + email = models.ForeignKey( + Email, models.CASCADE, to_field="email", related_name="secondary" + ) group = models.ForeignKey(Group, models.CASCADE) custom_objects = CustomUserWithFKManager() - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = ['email', 'group'] + USERNAME_FIELD = "username" + REQUIRED_FIELDS = ["email", "group"] diff --git a/tests/auth_tests/models/with_integer_username.py b/tests/auth_tests/models/with_integer_username.py index fc3728d798..8d99bee13a 100644 --- a/tests/auth_tests/models/with_integer_username.py +++ b/tests/auth_tests/models/with_integer_username.py @@ -17,7 +17,7 @@ class IntegerUsernameUser(AbstractBaseUser): username = models.IntegerField() password = models.CharField(max_length=255) - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = ['username', 'password'] + USERNAME_FIELD = "username" + REQUIRED_FIELDS = ["username", "password"] objects = IntegerUsernameUserManager() diff --git a/tests/auth_tests/models/with_many_to_many.py b/tests/auth_tests/models/with_many_to_many.py index 82142048ec..0c51365143 100644 --- a/tests/auth_tests/models/with_many_to_many.py +++ b/tests/auth_tests/models/with_many_to_many.py @@ -21,18 +21,18 @@ class CustomUserWithM2M(AbstractBaseUser): custom_objects = CustomUserWithM2MManager() - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = ['orgs'] + USERNAME_FIELD = "username" + REQUIRED_FIELDS = ["orgs"] class CustomUserWithM2MThrough(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) - orgs = models.ManyToManyField(Organization, through='Membership') + orgs = models.ManyToManyField(Organization, through="Membership") custom_objects = CustomUserWithM2MManager() - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = ['orgs'] + USERNAME_FIELD = "username" + REQUIRED_FIELDS = ["orgs"] class Membership(models.Model): diff --git a/tests/auth_tests/settings.py b/tests/auth_tests/settings.py index 5de7f3be45..9cf7855d44 100644 --- a/tests/auth_tests/settings.py +++ b/tests/auth_tests/settings.py @@ -1,19 +1,21 @@ import os AUTH_MIDDLEWARE = [ - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', + "django.contrib.sessions.middleware.SessionMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", ] -AUTH_TEMPLATES = [{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, -}] +AUTH_TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [os.path.join(os.path.dirname(__file__), "templates")], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + } +] diff --git a/tests/auth_tests/test_admin_multidb.py b/tests/auth_tests/test_admin_multidb.py index fac2c0fc7e..20faab25d8 100644 --- a/tests/auth_tests/test_admin_multidb.py +++ b/tests/auth_tests/test_admin_multidb.py @@ -16,17 +16,17 @@ class Router: db_for_write = db_for_read -site = admin.AdminSite(name='test_adminsite') +site = admin.AdminSite(name="test_adminsite") site.register(User, admin_class=UserAdmin) urlpatterns = [ - path('admin/', site.urls), + path("admin/", site.urls), ] -@override_settings(ROOT_URLCONF=__name__, DATABASE_ROUTERS=['%s.Router' % __name__]) +@override_settings(ROOT_URLCONF=__name__, DATABASE_ROUTERS=["%s.Router" % __name__]) class MultiDatabaseTests(TestCase): - databases = {'default', 'other'} + databases = {"default", "other"} @classmethod def setUpTestData(cls): @@ -34,18 +34,23 @@ class MultiDatabaseTests(TestCase): for db in cls.databases: Router.target_db = db cls.superusers[db] = User.objects.create_superuser( - username='admin', password='something', email='test@test.org', + username="admin", + password="something", + email="test@test.org", ) - @mock.patch('django.contrib.auth.admin.transaction') + @mock.patch("django.contrib.auth.admin.transaction") def test_add_view(self, mock): for db in self.databases: with self.subTest(db_connection=db): Router.target_db = db self.client.force_login(self.superusers[db]) - self.client.post(reverse('test_adminsite:auth_user_add'), { - 'username': 'some_user', - 'password1': 'helloworld', - 'password2': 'helloworld', - }) + self.client.post( + reverse("test_adminsite:auth_user_add"), + { + "username": "some_user", + "password1": "helloworld", + "password2": "helloworld", + }, + ) mock.atomic.assert_called_with(using=db) diff --git a/tests/auth_tests/test_auth_backends.py b/tests/auth_tests/test_auth_backends.py index d1471466d7..a535f329d2 100644 --- a/tests/auth_tests/test_auth_backends.py +++ b/tests/auth_tests/test_auth_backends.py @@ -3,8 +3,12 @@ from datetime import date from unittest import mock from django.contrib.auth import ( - BACKEND_SESSION_KEY, SESSION_KEY, _clean_credentials, authenticate, - get_user, signals, + BACKEND_SESSION_KEY, + SESSION_KEY, + _clean_credentials, + authenticate, + get_user, + signals, ) from django.contrib.auth.backends import BaseBackend, ModelBackend from django.contrib.auth.hashers import MD5PasswordHasher @@ -13,50 +17,58 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.http import HttpRequest from django.test import ( - RequestFactory, SimpleTestCase, TestCase, modify_settings, + RequestFactory, + SimpleTestCase, + TestCase, + modify_settings, override_settings, ) from django.views.debug import technical_500_response from django.views.decorators.debug import sensitive_variables from .models import ( - CustomPermissionsUser, CustomUser, CustomUserWithoutIsActiveField, - ExtensionUser, UUIDUser, + CustomPermissionsUser, + CustomUser, + CustomUserWithoutIsActiveField, + ExtensionUser, + UUIDUser, ) class SimpleBackend(BaseBackend): def get_user_permissions(self, user_obj, obj=None): - return ['user_perm'] + return ["user_perm"] def get_group_permissions(self, user_obj, obj=None): - return ['group_perm'] + return ["group_perm"] -@override_settings(AUTHENTICATION_BACKENDS=['auth_tests.test_auth_backends.SimpleBackend']) +@override_settings( + AUTHENTICATION_BACKENDS=["auth_tests.test_auth_backends.SimpleBackend"] +) class BaseBackendTest(TestCase): @classmethod def setUpTestData(cls): - cls.user = User.objects.create_user('test', 'test@example.com', 'test') + cls.user = User.objects.create_user("test", "test@example.com", "test") def test_get_user_permissions(self): - self.assertEqual(self.user.get_user_permissions(), {'user_perm'}) + self.assertEqual(self.user.get_user_permissions(), {"user_perm"}) def test_get_group_permissions(self): - self.assertEqual(self.user.get_group_permissions(), {'group_perm'}) + self.assertEqual(self.user.get_group_permissions(), {"group_perm"}) def test_get_all_permissions(self): - self.assertEqual(self.user.get_all_permissions(), {'user_perm', 'group_perm'}) + self.assertEqual(self.user.get_all_permissions(), {"user_perm", "group_perm"}) def test_has_perm(self): - self.assertIs(self.user.has_perm('user_perm'), True) - self.assertIs(self.user.has_perm('group_perm'), True) - self.assertIs(self.user.has_perm('other_perm', TestObj()), False) + self.assertIs(self.user.has_perm("user_perm"), True) + self.assertIs(self.user.has_perm("group_perm"), True) + self.assertIs(self.user.has_perm("other_perm", TestObj()), False) def test_has_perms_perm_list_invalid(self): - msg = 'perm_list must be an iterable of permissions.' + msg = "perm_list must be an iterable of permissions." with self.assertRaisesMessage(ValueError, msg): - self.user.has_perms('user_perm') + self.user.has_perms("user_perm") with self.assertRaisesMessage(ValueError, msg): self.user.has_perms(object()) @@ -78,11 +90,12 @@ class BaseModelBackendTest: level UserModel attribute, and a create_users() method to construct two users for test purposes. """ - backend = 'django.contrib.auth.backends.ModelBackend' + + backend = "django.contrib.auth.backends.ModelBackend" def setUp(self): self.patched_settings = modify_settings( - AUTHENTICATION_BACKENDS={'append': self.backend}, + AUTHENTICATION_BACKENDS={"append": self.backend}, ) self.patched_settings.enable() self.create_users() @@ -96,72 +109,84 @@ class BaseModelBackendTest: def test_has_perm(self): user = self.UserModel._default_manager.get(pk=self.user.pk) - self.assertIs(user.has_perm('auth.test'), False) + self.assertIs(user.has_perm("auth.test"), False) user.is_staff = True user.save() - self.assertIs(user.has_perm('auth.test'), False) + self.assertIs(user.has_perm("auth.test"), False) user.is_superuser = True user.save() - self.assertIs(user.has_perm('auth.test'), True) + self.assertIs(user.has_perm("auth.test"), True) user.is_staff = True user.is_superuser = True user.is_active = False user.save() - self.assertIs(user.has_perm('auth.test'), False) + self.assertIs(user.has_perm("auth.test"), False) def test_custom_perms(self): user = self.UserModel._default_manager.get(pk=self.user.pk) content_type = ContentType.objects.get_for_model(Group) - perm = Permission.objects.create(name='test', content_type=content_type, codename='test') + perm = Permission.objects.create( + name="test", content_type=content_type, codename="test" + ) user.user_permissions.add(perm) # reloading user to purge the _perm_cache user = self.UserModel._default_manager.get(pk=self.user.pk) - self.assertEqual(user.get_all_permissions(), {'auth.test'}) - self.assertEqual(user.get_user_permissions(), {'auth.test'}) + self.assertEqual(user.get_all_permissions(), {"auth.test"}) + self.assertEqual(user.get_user_permissions(), {"auth.test"}) self.assertEqual(user.get_group_permissions(), set()) - self.assertIs(user.has_module_perms('Group'), False) - self.assertIs(user.has_module_perms('auth'), True) + self.assertIs(user.has_module_perms("Group"), False) + self.assertIs(user.has_module_perms("auth"), True) - perm = Permission.objects.create(name='test2', content_type=content_type, codename='test2') + perm = Permission.objects.create( + name="test2", content_type=content_type, codename="test2" + ) user.user_permissions.add(perm) - perm = Permission.objects.create(name='test3', content_type=content_type, codename='test3') + perm = Permission.objects.create( + name="test3", content_type=content_type, codename="test3" + ) user.user_permissions.add(perm) user = self.UserModel._default_manager.get(pk=self.user.pk) - expected_user_perms = {'auth.test2', 'auth.test', 'auth.test3'} + expected_user_perms = {"auth.test2", "auth.test", "auth.test3"} self.assertEqual(user.get_all_permissions(), expected_user_perms) - self.assertIs(user.has_perm('test'), False) - self.assertIs(user.has_perm('auth.test'), True) - self.assertIs(user.has_perms(['auth.test2', 'auth.test3']), True) + self.assertIs(user.has_perm("test"), False) + self.assertIs(user.has_perm("auth.test"), True) + self.assertIs(user.has_perms(["auth.test2", "auth.test3"]), True) - perm = Permission.objects.create(name='test_group', content_type=content_type, codename='test_group') - group = Group.objects.create(name='test_group') + perm = Permission.objects.create( + name="test_group", content_type=content_type, codename="test_group" + ) + group = Group.objects.create(name="test_group") group.permissions.add(perm) user.groups.add(group) user = self.UserModel._default_manager.get(pk=self.user.pk) - self.assertEqual(user.get_all_permissions(), {*expected_user_perms, 'auth.test_group'}) + self.assertEqual( + user.get_all_permissions(), {*expected_user_perms, "auth.test_group"} + ) self.assertEqual(user.get_user_permissions(), expected_user_perms) - self.assertEqual(user.get_group_permissions(), {'auth.test_group'}) - self.assertIs(user.has_perms(['auth.test3', 'auth.test_group']), True) + self.assertEqual(user.get_group_permissions(), {"auth.test_group"}) + self.assertIs(user.has_perms(["auth.test3", "auth.test_group"]), True) user = AnonymousUser() - self.assertIs(user.has_perm('test'), False) - self.assertIs(user.has_perms(['auth.test2', 'auth.test3']), False) + self.assertIs(user.has_perm("test"), False) + self.assertIs(user.has_perms(["auth.test2", "auth.test3"]), False) def test_has_no_object_perm(self): """Regressiontest for #12462""" user = self.UserModel._default_manager.get(pk=self.user.pk) content_type = ContentType.objects.get_for_model(Group) - perm = Permission.objects.create(name='test', content_type=content_type, codename='test') + perm = Permission.objects.create( + name="test", content_type=content_type, codename="test" + ) user.user_permissions.add(perm) - self.assertIs(user.has_perm('auth.test', 'object'), False) - self.assertEqual(user.get_all_permissions('object'), set()) - self.assertIs(user.has_perm('auth.test'), True) - self.assertEqual(user.get_all_permissions(), {'auth.test'}) + self.assertIs(user.has_perm("auth.test", "object"), False) + self.assertEqual(user.get_all_permissions("object"), set()) + self.assertIs(user.has_perm("auth.test"), True) + self.assertEqual(user.get_all_permissions(), {"auth.test"}) def test_anonymous_has_no_permissions(self): """ @@ -172,19 +197,25 @@ class BaseModelBackendTest: user = self.UserModel._default_manager.get(pk=self.user.pk) content_type = ContentType.objects.get_for_model(Group) - user_perm = Permission.objects.create(name='test', content_type=content_type, codename='test_user') - group_perm = Permission.objects.create(name='test2', content_type=content_type, codename='test_group') + user_perm = Permission.objects.create( + name="test", content_type=content_type, codename="test_user" + ) + group_perm = Permission.objects.create( + name="test2", content_type=content_type, codename="test_group" + ) user.user_permissions.add(user_perm) - group = Group.objects.create(name='test_group') + group = Group.objects.create(name="test_group") user.groups.add(group) group.permissions.add(group_perm) - self.assertEqual(backend.get_all_permissions(user), {'auth.test_user', 'auth.test_group'}) - self.assertEqual(backend.get_user_permissions(user), {'auth.test_user'}) - self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'}) + self.assertEqual( + backend.get_all_permissions(user), {"auth.test_user", "auth.test_group"} + ) + self.assertEqual(backend.get_user_permissions(user), {"auth.test_user"}) + self.assertEqual(backend.get_group_permissions(user), {"auth.test_group"}) - with mock.patch.object(self.UserModel, 'is_anonymous', True): + 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()) @@ -198,17 +229,23 @@ class BaseModelBackendTest: user = self.UserModel._default_manager.get(pk=self.user.pk) content_type = ContentType.objects.get_for_model(Group) - user_perm = Permission.objects.create(name='test', content_type=content_type, codename='test_user') - group_perm = Permission.objects.create(name='test2', content_type=content_type, codename='test_group') + user_perm = Permission.objects.create( + name="test", content_type=content_type, codename="test_user" + ) + group_perm = Permission.objects.create( + name="test2", content_type=content_type, codename="test_group" + ) user.user_permissions.add(user_perm) - group = Group.objects.create(name='test_group') + group = Group.objects.create(name="test_group") user.groups.add(group) group.permissions.add(group_perm) - self.assertEqual(backend.get_all_permissions(user), {'auth.test_user', 'auth.test_group'}) - self.assertEqual(backend.get_user_permissions(user), {'auth.test_user'}) - self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'}) + self.assertEqual( + backend.get_all_permissions(user), {"auth.test_user", "auth.test_group"} + ) + self.assertEqual(backend.get_user_permissions(user), {"auth.test_user"}) + self.assertEqual(backend.get_group_permissions(user), {"auth.test_group"}) user.is_active = False user.save() @@ -222,29 +259,33 @@ class BaseModelBackendTest: user = self.UserModel._default_manager.get(pk=self.superuser.pk) self.assertEqual(len(user.get_all_permissions()), len(Permission.objects.all())) - @override_settings(PASSWORD_HASHERS=['auth_tests.test_auth_backends.CountingMD5PasswordHasher']) + @override_settings( + PASSWORD_HASHERS=["auth_tests.test_auth_backends.CountingMD5PasswordHasher"] + ) def test_authentication_timing(self): """Hasher is run once regardless of whether the user exists. Refs #20760.""" # Re-set the password, because this tests overrides PASSWORD_HASHERS - self.user.set_password('test') + self.user.set_password("test") self.user.save() CountingMD5PasswordHasher.calls = 0 username = getattr(self.user, self.UserModel.USERNAME_FIELD) - authenticate(username=username, password='test') + authenticate(username=username, password="test") self.assertEqual(CountingMD5PasswordHasher.calls, 1) CountingMD5PasswordHasher.calls = 0 - authenticate(username='no_such_user', password='test') + authenticate(username="no_such_user", password="test") self.assertEqual(CountingMD5PasswordHasher.calls, 1) - @override_settings(PASSWORD_HASHERS=['auth_tests.test_auth_backends.CountingMD5PasswordHasher']) + @override_settings( + PASSWORD_HASHERS=["auth_tests.test_auth_backends.CountingMD5PasswordHasher"] + ) def test_authentication_without_credentials(self): CountingMD5PasswordHasher.calls = 0 for credentials in ( {}, - {'username': getattr(self.user, self.UserModel.USERNAME_FIELD)}, - {'password': 'test'}, + {"username": getattr(self.user, self.UserModel.USERNAME_FIELD)}, + {"password": "test"}, ): with self.subTest(credentials=credentials): with self.assertNumQueries(0): @@ -256,15 +297,18 @@ class ModelBackendTest(BaseModelBackendTest, TestCase): """ Tests for the ModelBackend using the default User model. """ + UserModel = User - user_credentials = {'username': 'test', 'password': 'test'} + user_credentials = {"username": "test", "password": "test"} def create_users(self): - self.user = User.objects.create_user(email='test@example.com', **self.user_credentials) + self.user = User.objects.create_user( + email="test@example.com", **self.user_credentials + ) self.superuser = User.objects.create_superuser( - username='test2', - email='test2@example.com', - password='test', + username="test2", + email="test2@example.com", + password="test", ) def test_authenticate_inactive(self): @@ -276,18 +320,20 @@ class ModelBackendTest(BaseModelBackendTest, TestCase): self.user.save() self.assertIsNone(authenticate(**self.user_credentials)) - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserWithoutIsActiveField') + @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithoutIsActiveField") def test_authenticate_user_without_is_active_field(self): """ A custom user without an `is_active` field is allowed to authenticate. """ user = CustomUserWithoutIsActiveField.objects._create_user( - username='test', email='test@example.com', password='test', + username="test", + email="test@example.com", + password="test", ) - self.assertEqual(authenticate(username='test', password='test'), user) + self.assertEqual(authenticate(username="test", password="test"), user) -@override_settings(AUTH_USER_MODEL='auth_tests.ExtensionUser') +@override_settings(AUTH_USER_MODEL="auth_tests.ExtensionUser") class ExtensionUserModelBackendTest(BaseModelBackendTest, TestCase): """ Tests for the ModelBackend using the custom ExtensionUser model. @@ -309,20 +355,20 @@ class ExtensionUserModelBackendTest(BaseModelBackendTest, TestCase): def create_users(self): self.user = ExtensionUser._default_manager.create_user( - username='test', - email='test@example.com', - password='test', - date_of_birth=date(2006, 4, 25) + username="test", + email="test@example.com", + password="test", + date_of_birth=date(2006, 4, 25), ) self.superuser = ExtensionUser._default_manager.create_superuser( - username='test2', - email='test2@example.com', - password='test', - date_of_birth=date(1976, 11, 8) + username="test2", + email="test2@example.com", + password="test", + date_of_birth=date(1976, 11, 8), ) -@override_settings(AUTH_USER_MODEL='auth_tests.CustomPermissionsUser') +@override_settings(AUTH_USER_MODEL="auth_tests.CustomPermissionsUser") class CustomPermissionsUserModelBackendTest(BaseModelBackendTest, TestCase): """ Tests for the ModelBackend using the CustomPermissionsUser model. @@ -336,18 +382,14 @@ class CustomPermissionsUserModelBackendTest(BaseModelBackendTest, TestCase): def create_users(self): self.user = CustomPermissionsUser._default_manager.create_user( - email='test@example.com', - password='test', - date_of_birth=date(2006, 4, 25) + email="test@example.com", password="test", date_of_birth=date(2006, 4, 25) ) self.superuser = CustomPermissionsUser._default_manager.create_superuser( - email='test2@example.com', - password='test', - date_of_birth=date(1976, 11, 8) + email="test2@example.com", password="test", date_of_birth=date(1976, 11, 8) ) -@override_settings(AUTH_USER_MODEL='auth_tests.CustomUser') +@override_settings(AUTH_USER_MODEL="auth_tests.CustomUser") class CustomUserModelBackendAuthenticateTest(TestCase): """ The model backend can accept a credentials kwarg labeled with @@ -356,24 +398,23 @@ class CustomUserModelBackendAuthenticateTest(TestCase): def test_authenticate(self): test_user = CustomUser._default_manager.create_user( - email='test@example.com', - password='test', - date_of_birth=date(2006, 4, 25) + email="test@example.com", password="test", date_of_birth=date(2006, 4, 25) ) - authenticated_user = authenticate(email='test@example.com', password='test') + authenticated_user = authenticate(email="test@example.com", password="test") self.assertEqual(test_user, authenticated_user) -@override_settings(AUTH_USER_MODEL='auth_tests.UUIDUser') +@override_settings(AUTH_USER_MODEL="auth_tests.UUIDUser") class UUIDUserTests(TestCase): - def test_login(self): """ A custom user with a UUID primary key should be able to login. """ - user = UUIDUser.objects.create_user(username='uuid', password='test') - self.assertTrue(self.client.login(username='uuid', password='test')) - self.assertEqual(UUIDUser.objects.get(pk=self.client.session[SESSION_KEY]), user) + user = UUIDUser.objects.create_user(username="uuid", password="test") + self.assertTrue(self.client.login(username="uuid", password="test")) + self.assertEqual( + UUIDUser.objects.get(pk=self.client.session[SESSION_KEY]), user + ) class TestObj: @@ -386,47 +427,49 @@ class SimpleRowlevelBackend: return # We only support row level perms if isinstance(obj, TestObj): - if user.username == 'test2': + 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': + elif not user.is_active and perm == "inactive": return True return False def has_module_perms(self, user, app_label): - return (user.is_anonymous or user.is_active) and app_label == 'app1' + return (user.is_anonymous or user.is_active) and app_label == "app1" def get_all_permissions(self, user, obj=None): if not obj: return [] # We only support row level perms if not isinstance(obj, TestObj): - return ['none'] + return ["none"] if user.is_anonymous: - return ['anon'] - if user.username == 'test2': - return ['simple', 'advanced'] + return ["anon"] + if user.username == "test2": + return ["simple", "advanced"] else: - return ['simple'] + return ["simple"] def get_group_permissions(self, user, obj=None): if not obj: return # We only support row level perms if not isinstance(obj, TestObj): - return ['none'] + return ["none"] - if 'test_group' in [group.name for group in user.groups.all()]: - return ['group_perm'] + if "test_group" in [group.name for group in user.groups.all()]: + return ["group_perm"] else: - return ['none'] + return ["none"] -@modify_settings(AUTHENTICATION_BACKENDS={ - 'append': 'auth_tests.test_auth_backends.SimpleRowlevelBackend', -}) +@modify_settings( + AUTHENTICATION_BACKENDS={ + "append": "auth_tests.test_auth_backends.SimpleRowlevelBackend", + } +) class RowlevelBackendTest(TestCase): """ Tests for auth backend that supports object level permissions @@ -434,9 +477,9 @@ class RowlevelBackendTest(TestCase): @classmethod def setUpTestData(cls): - cls.user1 = User.objects.create_user('test', 'test@example.com', 'test') - cls.user2 = User.objects.create_user('test2', 'test2@example.com', 'test') - cls.user3 = User.objects.create_user('test3', 'test3@example.com', 'test') + cls.user1 = User.objects.create_user("test", "test@example.com", "test") + cls.user2 = User.objects.create_user("test2", "test2@example.com", "test") + cls.user3 = User.objects.create_user("test3", "test3@example.com", "test") def tearDown(self): # The get_group_permissions test messes with ContentTypes, which will @@ -445,27 +488,29 @@ class RowlevelBackendTest(TestCase): ContentType.objects.clear_cache() def test_has_perm(self): - self.assertIs(self.user1.has_perm('perm', TestObj()), False) - self.assertIs(self.user2.has_perm('perm', TestObj()), True) - self.assertIs(self.user2.has_perm('perm'), False) - self.assertIs(self.user2.has_perms(['simple', 'advanced'], TestObj()), True) - self.assertIs(self.user3.has_perm('perm', TestObj()), False) - self.assertIs(self.user3.has_perm('anon', TestObj()), False) - self.assertIs(self.user3.has_perms(['simple', 'advanced'], TestObj()), False) + self.assertIs(self.user1.has_perm("perm", TestObj()), False) + self.assertIs(self.user2.has_perm("perm", TestObj()), True) + self.assertIs(self.user2.has_perm("perm"), False) + self.assertIs(self.user2.has_perms(["simple", "advanced"], TestObj()), True) + self.assertIs(self.user3.has_perm("perm", TestObj()), False) + self.assertIs(self.user3.has_perm("anon", TestObj()), False) + self.assertIs(self.user3.has_perms(["simple", "advanced"], TestObj()), False) def test_get_all_permissions(self): - self.assertEqual(self.user1.get_all_permissions(TestObj()), {'simple'}) - self.assertEqual(self.user2.get_all_permissions(TestObj()), {'simple', 'advanced'}) + self.assertEqual(self.user1.get_all_permissions(TestObj()), {"simple"}) + self.assertEqual( + self.user2.get_all_permissions(TestObj()), {"simple", "advanced"} + ) self.assertEqual(self.user2.get_all_permissions(), set()) def test_get_group_permissions(self): - group = Group.objects.create(name='test_group') + group = Group.objects.create(name="test_group") self.user3.groups.add(group) - self.assertEqual(self.user3.get_group_permissions(TestObj()), {'group_perm'}) + self.assertEqual(self.user3.get_group_permissions(TestObj()), {"group_perm"}) @override_settings( - AUTHENTICATION_BACKENDS=['auth_tests.test_auth_backends.SimpleRowlevelBackend'], + AUTHENTICATION_BACKENDS=["auth_tests.test_auth_backends.SimpleRowlevelBackend"], ) class AnonymousUserBackendTest(SimpleTestCase): """ @@ -476,17 +521,17 @@ class AnonymousUserBackendTest(SimpleTestCase): self.user1 = AnonymousUser() def test_has_perm(self): - self.assertIs(self.user1.has_perm('perm', TestObj()), False) - self.assertIs(self.user1.has_perm('anon', TestObj()), True) + self.assertIs(self.user1.has_perm("perm", TestObj()), False) + self.assertIs(self.user1.has_perm("anon", TestObj()), True) def test_has_perms(self): - self.assertIs(self.user1.has_perms(['anon'], TestObj()), True) - self.assertIs(self.user1.has_perms(['anon', 'perm'], TestObj()), False) + self.assertIs(self.user1.has_perms(["anon"], TestObj()), True) + self.assertIs(self.user1.has_perms(["anon", "perm"], TestObj()), False) def test_has_perms_perm_list_invalid(self): - msg = 'perm_list must be an iterable of permissions.' + msg = "perm_list must be an iterable of permissions." with self.assertRaisesMessage(ValueError, msg): - self.user1.has_perms('perm') + self.user1.has_perms("perm") with self.assertRaisesMessage(ValueError, msg): self.user1.has_perms(object()) @@ -495,7 +540,7 @@ class AnonymousUserBackendTest(SimpleTestCase): self.assertIs(self.user1.has_module_perms("app2"), False) def test_get_all_permissions(self): - self.assertEqual(self.user1.get_all_permissions(TestObj()), {'anon'}) + self.assertEqual(self.user1.get_all_permissions(TestObj()), {"anon"}) @override_settings(AUTHENTICATION_BACKENDS=[]) @@ -503,20 +548,23 @@ class NoBackendsTest(TestCase): """ An appropriate error is raised if no auth backends are provided. """ + @classmethod def setUpTestData(cls): - cls.user = User.objects.create_user('test', 'test@example.com', 'test') + cls.user = User.objects.create_user("test", "test@example.com", "test") def test_raises_exception(self): msg = ( - 'No authentication backends have been defined. ' - 'Does AUTHENTICATION_BACKENDS contain anything?' + "No authentication backends have been defined. " + "Does AUTHENTICATION_BACKENDS contain anything?" ) with self.assertRaisesMessage(ImproperlyConfigured, msg): - self.user.has_perm(('perm', TestObj())) + self.user.has_perm(("perm", TestObj())) -@override_settings(AUTHENTICATION_BACKENDS=['auth_tests.test_auth_backends.SimpleRowlevelBackend']) +@override_settings( + AUTHENTICATION_BACKENDS=["auth_tests.test_auth_backends.SimpleRowlevelBackend"] +) class InActiveUserBackendTest(TestCase): """ Tests for an inactive user @@ -524,13 +572,13 @@ class InActiveUserBackendTest(TestCase): @classmethod def setUpTestData(cls): - cls.user1 = User.objects.create_user('test', 'test@example.com', 'test') + cls.user1 = User.objects.create_user("test", "test@example.com", "test") cls.user1.is_active = False cls.user1.save() def test_has_perm(self): - self.assertIs(self.user1.has_perm('perm', TestObj()), False) - self.assertIs(self.user1.has_perm('inactive', TestObj()), True) + self.assertIs(self.user1.has_perm("perm", TestObj()), False) + self.assertIs(self.user1.has_perm("inactive", TestObj()), True) def test_has_module_perms(self): self.assertIs(self.user1.has_module_perms("app1"), False) @@ -556,11 +604,12 @@ class PermissionDeniedBackendTest(TestCase): """ Other backends are not checked once a backend raises PermissionDenied """ - backend = 'auth_tests.test_auth_backends.PermissionDeniedBackend' + + backend = "auth_tests.test_auth_backends.PermissionDeniedBackend" @classmethod def setUpTestData(cls): - cls.user1 = User.objects.create_user('test', 'test@example.com', 'test') + cls.user1 = User.objects.create_user("test", "test@example.com", "test") def setUp(self): self.user_login_failed = [] @@ -572,34 +621,41 @@ class PermissionDeniedBackendTest(TestCase): def user_login_failed_listener(self, sender, credentials, **kwargs): self.user_login_failed.append(credentials) - @modify_settings(AUTHENTICATION_BACKENDS={'prepend': backend}) + @modify_settings(AUTHENTICATION_BACKENDS={"prepend": backend}) def test_permission_denied(self): "user is not authenticated after a backend raises permission denied #2550" - self.assertIsNone(authenticate(username='test', password='test')) + self.assertIsNone(authenticate(username="test", password="test")) # user_login_failed signal is sent. - self.assertEqual(self.user_login_failed, [{'password': '********************', 'username': 'test'}]) + self.assertEqual( + self.user_login_failed, + [{"password": "********************", "username": "test"}], + ) - @modify_settings(AUTHENTICATION_BACKENDS={'append': backend}) + @modify_settings(AUTHENTICATION_BACKENDS={"append": backend}) def test_authenticates(self): - self.assertEqual(authenticate(username='test', password='test'), self.user1) + self.assertEqual(authenticate(username="test", password="test"), self.user1) - @modify_settings(AUTHENTICATION_BACKENDS={'prepend': backend}) + @modify_settings(AUTHENTICATION_BACKENDS={"prepend": backend}) def test_has_perm_denied(self): content_type = ContentType.objects.get_for_model(Group) - perm = Permission.objects.create(name='test', content_type=content_type, codename='test') + perm = Permission.objects.create( + name="test", content_type=content_type, codename="test" + ) self.user1.user_permissions.add(perm) - self.assertIs(self.user1.has_perm('auth.test'), False) - self.assertIs(self.user1.has_module_perms('auth'), False) + self.assertIs(self.user1.has_perm("auth.test"), False) + self.assertIs(self.user1.has_module_perms("auth"), False) - @modify_settings(AUTHENTICATION_BACKENDS={'append': backend}) + @modify_settings(AUTHENTICATION_BACKENDS={"append": backend}) def test_has_perm(self): content_type = ContentType.objects.get_for_model(Group) - perm = Permission.objects.create(name='test', content_type=content_type, codename='test') + perm = Permission.objects.create( + name="test", content_type=content_type, codename="test" + ) self.user1.user_permissions.add(perm) - self.assertIs(self.user1.has_perm('auth.test'), True) - self.assertIs(self.user1.has_module_perms('auth'), True) + self.assertIs(self.user1.has_perm("auth.test"), True) + self.assertIs(self.user1.has_module_perms("auth"), True) class NewModelBackend(ModelBackend): @@ -610,11 +666,12 @@ class ChangedBackendSettingsTest(TestCase): """ Tests for changes in the settings.AUTHENTICATION_BACKENDS """ - backend = 'auth_tests.test_auth_backends.NewModelBackend' - TEST_USERNAME = 'test_user' - TEST_PASSWORD = 'test_password' - TEST_EMAIL = 'test@example.com' + backend = "auth_tests.test_auth_backends.NewModelBackend" + + TEST_USERNAME = "test_user" + TEST_PASSWORD = "test_password" + TEST_EMAIL = "test@example.com" @classmethod def setUpTestData(cls): @@ -627,16 +684,19 @@ class ChangedBackendSettingsTest(TestCase): logged-in users disconnect. """ # Get a session for the test user - self.assertTrue(self.client.login( - username=self.TEST_USERNAME, - password=self.TEST_PASSWORD, - )) + self.assertTrue( + self.client.login( + username=self.TEST_USERNAME, + password=self.TEST_PASSWORD, + ) + ) # Prepare a request object request = HttpRequest() request.session = self.client.session # Remove NewModelBackend - with self.settings(AUTHENTICATION_BACKENDS=[ - 'django.contrib.auth.backends.ModelBackend']): + with self.settings( + AUTHENTICATION_BACKENDS=["django.contrib.auth.backends.ModelBackend"] + ): # Get the user from the request user = get_user(request) @@ -651,7 +711,7 @@ class TypeErrorBackend: Always raises TypeError. """ - @sensitive_variables('password') + @sensitive_variables("password") def authenticate(self, request, username=None, password=None): raise TypeError @@ -671,31 +731,35 @@ class SkippedBackendWithDecoratedMethod: class AuthenticateTests(TestCase): @classmethod def setUpTestData(cls): - cls.user1 = User.objects.create_user('test', 'test@example.com', 'test') + cls.user1 = User.objects.create_user("test", "test@example.com", "test") def setUp(self): - self.sensitive_password = 'mypassword' + self.sensitive_password = "mypassword" - @override_settings(AUTHENTICATION_BACKENDS=['auth_tests.test_auth_backends.TypeErrorBackend']) + @override_settings( + AUTHENTICATION_BACKENDS=["auth_tests.test_auth_backends.TypeErrorBackend"] + ) def test_type_error_raised(self): """A TypeError within a backend is propagated properly (#18171).""" with self.assertRaises(TypeError): - authenticate(username='test', password='test') + authenticate(username="test", password="test") - @override_settings(AUTHENTICATION_BACKENDS=['auth_tests.test_auth_backends.TypeErrorBackend']) + @override_settings( + AUTHENTICATION_BACKENDS=["auth_tests.test_auth_backends.TypeErrorBackend"] + ) def test_authenticate_sensitive_variables(self): try: - authenticate(username='testusername', password=self.sensitive_password) + authenticate(username="testusername", password=self.sensitive_password) except TypeError: exc_info = sys.exc_info() rf = RequestFactory() - response = technical_500_response(rf.get('/'), *exc_info) + response = technical_500_response(rf.get("/"), *exc_info) self.assertNotContains(response, self.sensitive_password, status_code=500) - self.assertContains(response, 'TypeErrorBackend', status_code=500) + self.assertContains(response, "TypeErrorBackend", status_code=500) self.assertContains( response, 'credentials' - '
'********************'
', + "
'********************'
", html=True, status_code=500, ) @@ -707,33 +771,37 @@ class AuthenticateTests(TestCase): except TypeError: exc_info = sys.exc_info() rf = RequestFactory() - response = technical_500_response(rf.get('/'), *exc_info) + response = technical_500_response(rf.get("/"), *exc_info) self.assertNotContains(response, self.sensitive_password, status_code=500) self.assertContains( response, 'credentials' - '
'********************'
', + "
'********************'
", html=True, status_code=500, ) - @override_settings(AUTHENTICATION_BACKENDS=( - 'auth_tests.test_auth_backends.SkippedBackend', - 'django.contrib.auth.backends.ModelBackend', - )) + @override_settings( + AUTHENTICATION_BACKENDS=( + "auth_tests.test_auth_backends.SkippedBackend", + "django.contrib.auth.backends.ModelBackend", + ) + ) def test_skips_backends_without_arguments(self): """ A backend (SkippedBackend) is ignored if it doesn't accept the credentials as arguments. """ - self.assertEqual(authenticate(username='test', password='test'), self.user1) + self.assertEqual(authenticate(username="test", password="test"), self.user1) - @override_settings(AUTHENTICATION_BACKENDS=( - 'auth_tests.test_auth_backends.SkippedBackendWithDecoratedMethod', - 'django.contrib.auth.backends.ModelBackend', - )) + @override_settings( + AUTHENTICATION_BACKENDS=( + "auth_tests.test_auth_backends.SkippedBackendWithDecoratedMethod", + "django.contrib.auth.backends.ModelBackend", + ) + ) def test_skips_backends_with_decorated_method(self): - self.assertEqual(authenticate(username='test', password='test'), self.user1) + self.assertEqual(authenticate(username="test", password="test"), self.user1) class ImproperlyConfiguredUserModelTest(TestCase): @@ -741,14 +809,15 @@ class ImproperlyConfiguredUserModelTest(TestCase): An exception from within get_user_model() is propagated and doesn't raise an UnboundLocalError (#21439). """ + @classmethod def setUpTestData(cls): - cls.user1 = User.objects.create_user('test', 'test@example.com', 'test') + cls.user1 = User.objects.create_user("test", "test@example.com", "test") def setUp(self): - self.client.login(username='test', password='test') + self.client.login(username="test", password="test") - @override_settings(AUTH_USER_MODEL='thismodel.doesntexist') + @override_settings(AUTH_USER_MODEL="thismodel.doesntexist") def test_does_not_shadow_exception(self): # Prepare a request object request = HttpRequest() @@ -780,13 +849,13 @@ class ImportedBackendTests(TestCase): as the one defined in AUTHENTICATION_BACKENDS setting. """ - backend = 'auth_tests.backend_alias.ImportedModelBackend' + backend = "auth_tests.backend_alias.ImportedModelBackend" @override_settings(AUTHENTICATION_BACKENDS=[backend]) def test_backend_path(self): - username = 'username' - password = 'password' - User.objects.create_user(username, 'email', password) + username = "username" + password = "password" + User.objects.create_user(username, "email", password) self.assertTrue(self.client.login(username=username, password=password)) request = HttpRequest() request.session = self.client.session @@ -794,10 +863,10 @@ class ImportedBackendTests(TestCase): class SelectingBackendTests(TestCase): - backend = 'auth_tests.test_auth_backends.CustomModelBackend' - other_backend = 'auth_tests.test_auth_backends.OtherModelBackend' - username = 'username' - password = 'password' + backend = "auth_tests.test_auth_backends.CustomModelBackend" + other_backend = "auth_tests.test_auth_backends.OtherModelBackend" + username = "username" + password = "password" def assertBackendInSession(self, backend): request = HttpRequest() @@ -806,49 +875,51 @@ class SelectingBackendTests(TestCase): @override_settings(AUTHENTICATION_BACKENDS=[backend]) def test_backend_path_login_without_authenticate_single_backend(self): - user = User.objects.create_user(self.username, 'email', self.password) + user = User.objects.create_user(self.username, "email", self.password) self.client._login(user) self.assertBackendInSession(self.backend) @override_settings(AUTHENTICATION_BACKENDS=[backend, other_backend]) def test_backend_path_login_without_authenticate_multiple_backends(self): - user = User.objects.create_user(self.username, 'email', self.password) + user = User.objects.create_user(self.username, "email", self.password) expected_message = ( - 'You have multiple authentication backends configured and ' - 'therefore must provide the `backend` argument or set the ' - '`backend` attribute on the user.' + "You have multiple authentication backends configured and " + "therefore must provide the `backend` argument or set the " + "`backend` attribute on the user." ) with self.assertRaisesMessage(ValueError, expected_message): self.client._login(user) def test_non_string_backend(self): - user = User.objects.create_user(self.username, 'email', self.password) + user = User.objects.create_user(self.username, "email", self.password) expected_message = ( - 'backend must be a dotted import path string (got ' - ').' + "backend must be a dotted import path string (got " + ")." ) with self.assertRaisesMessage(TypeError, expected_message): self.client._login(user, backend=ModelBackend) @override_settings(AUTHENTICATION_BACKENDS=[backend, other_backend]) def test_backend_path_login_with_explicit_backends(self): - user = User.objects.create_user(self.username, 'email', self.password) + user = User.objects.create_user(self.username, "email", self.password) self.client._login(user, self.other_backend) self.assertBackendInSession(self.other_backend) -@override_settings(AUTHENTICATION_BACKENDS=['django.contrib.auth.backends.AllowAllUsersModelBackend']) +@override_settings( + AUTHENTICATION_BACKENDS=["django.contrib.auth.backends.AllowAllUsersModelBackend"] +) class AllowAllUsersModelBackendTest(TestCase): """ Inactive users may authenticate with the AllowAllUsersModelBackend. """ - user_credentials = {'username': 'test', 'password': 'test'} + + user_credentials = {"username": "test", "password": "test"} @classmethod def setUpTestData(cls): cls.user = User.objects.create_user( - email='test@example.com', is_active=False, - **cls.user_credentials + email="test@example.com", is_active=False, **cls.user_credentials ) def test_authenticate(self): diff --git a/tests/auth_tests/test_basic.py b/tests/auth_tests/test_basic.py index 4cba35eb41..4b491e521e 100644 --- a/tests/auth_tests/test_basic.py +++ b/tests/auth_tests/test_basic.py @@ -12,23 +12,23 @@ from .models import CustomUser class BasicTestCase(TestCase): def test_user(self): "Users can be created and can set their password" - u = User.objects.create_user('testuser', 'test@example.com', 'testpw') + u = User.objects.create_user("testuser", "test@example.com", "testpw") self.assertTrue(u.has_usable_password()) - self.assertFalse(u.check_password('bad')) - self.assertTrue(u.check_password('testpw')) + self.assertFalse(u.check_password("bad")) + self.assertTrue(u.check_password("testpw")) # Check we can manually set an unusable password u.set_unusable_password() u.save() - self.assertFalse(u.check_password('testpw')) + self.assertFalse(u.check_password("testpw")) self.assertFalse(u.has_usable_password()) - u.set_password('testpw') - self.assertTrue(u.check_password('testpw')) + u.set_password("testpw") + self.assertTrue(u.check_password("testpw")) u.set_password(None) self.assertFalse(u.has_usable_password()) # Check username getter - self.assertEqual(u.get_username(), 'testuser') + self.assertEqual(u.get_username(), "testuser") # Check authentication/permissions self.assertFalse(u.is_anonymous) @@ -38,15 +38,15 @@ class BasicTestCase(TestCase): self.assertFalse(u.is_superuser) # Check API-based user creation with no password - u2 = User.objects.create_user('testuser2', 'test2@example.com') + u2 = User.objects.create_user("testuser2", "test2@example.com") self.assertFalse(u2.has_usable_password()) def test_unicode_username(self): - User.objects.create_user('jörg') - User.objects.create_user('Григорий') + User.objects.create_user("jörg") + User.objects.create_user("Григорий") # Two equivalent Unicode normalized usernames are duplicates. - omega_username = 'iamtheΩ' # U+03A9 GREEK CAPITAL LETTER OMEGA - ohm_username = 'iamtheΩ' # U+2126 OHM SIGN + omega_username = "iamtheΩ" # U+03A9 GREEK CAPITAL LETTER OMEGA + ohm_username = "iamtheΩ" # U+2126 OHM SIGN User.objects.create_user(ohm_username) with self.assertRaises(IntegrityError): User.objects.create_user(omega_username) @@ -55,20 +55,17 @@ class BasicTestCase(TestCase): "Users can be created without an email" cases = [ {}, - {'email': ''}, - {'email': None}, + {"email": ""}, + {"email": None}, ] for i, kwargs in enumerate(cases): with self.subTest(**kwargs): - u = User.objects.create_user( - 'testuser{}'.format(i), - **kwargs - ) - self.assertEqual(u.email, '') + u = User.objects.create_user("testuser{}".format(i), **kwargs) + self.assertEqual(u.email, "") def test_superuser(self): "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") self.assertTrue(super.is_superuser) self.assertTrue(super.is_active) self.assertTrue(super.is_staff) @@ -76,38 +73,35 @@ class BasicTestCase(TestCase): def test_superuser_no_email_or_password(self): cases = [ {}, - {'email': ''}, - {'email': None}, - {'password': None}, + {"email": ""}, + {"email": None}, + {"password": None}, ] for i, kwargs in enumerate(cases): with self.subTest(**kwargs): - superuser = User.objects.create_superuser( - 'super{}'.format(i), - **kwargs - ) - self.assertEqual(superuser.email, '') + superuser = User.objects.create_superuser("super{}".format(i), **kwargs) + self.assertEqual(superuser.email, "") self.assertFalse(superuser.has_usable_password()) def test_get_user_model(self): "The current user model can be retrieved" self.assertEqual(get_user_model(), User) - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUser') + @override_settings(AUTH_USER_MODEL="auth_tests.CustomUser") def test_swappable_user(self): "The current user model can be swapped out for another" self.assertEqual(get_user_model(), CustomUser) with self.assertRaises(AttributeError): User.objects.all() - @override_settings(AUTH_USER_MODEL='badsetting') + @override_settings(AUTH_USER_MODEL="badsetting") def test_swappable_user_bad_setting(self): "The alternate user setting must point to something in the format app.model" msg = "AUTH_USER_MODEL must be of the form 'app_label.model_name'" with self.assertRaisesMessage(ImproperlyConfigured, msg): get_user_model() - @override_settings(AUTH_USER_MODEL='thismodel.doesntexist') + @override_settings(AUTH_USER_MODEL="thismodel.doesntexist") def test_swappable_user_nonexistent_model(self): "The current user model must point to an installed model" msg = ( @@ -119,16 +113,15 @@ class BasicTestCase(TestCase): def test_user_verbose_names_translatable(self): "Default User model verbose names are translatable (#19945)" - with translation.override('en'): - self.assertEqual(User._meta.verbose_name, 'user') - self.assertEqual(User._meta.verbose_name_plural, 'users') - with translation.override('es'): - self.assertEqual(User._meta.verbose_name, 'usuario') - self.assertEqual(User._meta.verbose_name_plural, 'usuarios') + with translation.override("en"): + self.assertEqual(User._meta.verbose_name, "user") + self.assertEqual(User._meta.verbose_name_plural, "users") + with translation.override("es"): + self.assertEqual(User._meta.verbose_name, "usuario") + self.assertEqual(User._meta.verbose_name_plural, "usuarios") class TestGetUser(TestCase): - def test_get_user_anonymous(self): request = HttpRequest() request.session = self.client.session @@ -136,8 +129,10 @@ class TestGetUser(TestCase): self.assertIsInstance(user, AnonymousUser) def test_get_user(self): - created_user = User.objects.create_user('testuser', 'test@example.com', 'testpw') - self.client.login(username='testuser', password='testpw') + created_user = User.objects.create_user( + "testuser", "test@example.com", "testpw" + ) + self.client.login(username="testuser", password="testpw") request = HttpRequest() request.session = self.client.session user = get_user(request) diff --git a/tests/auth_tests/test_checks.py b/tests/auth_tests/test_checks.py index 4dc1ef4aec..cd19fbcc9b 100644 --- a/tests/auth_tests/test_checks.py +++ b/tests/auth_tests/test_checks.py @@ -1,154 +1,171 @@ -from django.contrib.auth.checks import ( - check_models_permissions, check_user_model, -) +from django.contrib.auth.checks import check_models_permissions, check_user_model from django.contrib.auth.models import AbstractBaseUser from django.core import checks from django.db import models from django.db.models import Q, UniqueConstraint -from django.test import ( - SimpleTestCase, override_settings, override_system_checks, -) +from django.test import SimpleTestCase, override_settings, override_system_checks from django.test.utils import isolate_apps from .models import CustomUserNonUniqueUsername -@isolate_apps('auth_tests', attr_name='apps') +@isolate_apps("auth_tests", attr_name="apps") @override_system_checks([check_user_model]) class UserModelChecksTests(SimpleTestCase): - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserNonListRequiredFields') + @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserNonListRequiredFields") def test_required_fields_is_list(self): """REQUIRED_FIELDS should be a list.""" + class CustomUserNonListRequiredFields(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) date_of_birth = models.DateField() - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = 'date_of_birth' + USERNAME_FIELD = "username" + REQUIRED_FIELDS = "date_of_birth" errors = checks.run_checks(app_configs=self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "'REQUIRED_FIELDS' must be a list or tuple.", - obj=CustomUserNonListRequiredFields, - id='auth.E001', - ), - ]) - - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserBadRequiredFields') + self.assertEqual( + errors, + [ + checks.Error( + "'REQUIRED_FIELDS' must be a list or tuple.", + obj=CustomUserNonListRequiredFields, + id="auth.E001", + ), + ], + ) + + @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserBadRequiredFields") def test_username_not_in_required_fields(self): """USERNAME_FIELD should not appear in REQUIRED_FIELDS.""" + class CustomUserBadRequiredFields(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) date_of_birth = models.DateField() - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = ['username', 'date_of_birth'] + USERNAME_FIELD = "username" + REQUIRED_FIELDS = ["username", "date_of_birth"] errors = checks.run_checks(self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "The field named as the 'USERNAME_FIELD' for a custom user model " - "must not be included in 'REQUIRED_FIELDS'.", - hint=( - "The 'USERNAME_FIELD' is currently set to 'username', you " - "should remove 'username' from the 'REQUIRED_FIELDS'." + self.assertEqual( + errors, + [ + checks.Error( + "The field named as the 'USERNAME_FIELD' for a custom user model " + "must not be included in 'REQUIRED_FIELDS'.", + hint=( + "The 'USERNAME_FIELD' is currently set to 'username', you " + "should remove 'username' from the 'REQUIRED_FIELDS'." + ), + obj=CustomUserBadRequiredFields, + id="auth.E002", ), - obj=CustomUserBadRequiredFields, - id='auth.E002', - ), - ]) + ], + ) - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserNonUniqueUsername') + @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserNonUniqueUsername") def test_username_non_unique(self): """ A non-unique USERNAME_FIELD raises an error only if the default authentication backend is used. Otherwise, a warning is raised. """ errors = checks.run_checks() - self.assertEqual(errors, [ - checks.Error( - "'CustomUserNonUniqueUsername.username' must be " - "unique because it is named as the 'USERNAME_FIELD'.", - obj=CustomUserNonUniqueUsername, - id='auth.E003', - ), - ]) - with self.settings(AUTHENTICATION_BACKENDS=['my.custom.backend']): - errors = checks.run_checks() - self.assertEqual(errors, [ - checks.Warning( - "'CustomUserNonUniqueUsername.username' is named as " - "the 'USERNAME_FIELD', but it is not unique.", - hint='Ensure that your authentication backend(s) can handle non-unique usernames.', + self.assertEqual( + errors, + [ + checks.Error( + "'CustomUserNonUniqueUsername.username' must be " + "unique because it is named as the 'USERNAME_FIELD'.", obj=CustomUserNonUniqueUsername, - id='auth.W004', + id="auth.E003", ), - ]) + ], + ) + with self.settings(AUTHENTICATION_BACKENDS=["my.custom.backend"]): + errors = checks.run_checks() + self.assertEqual( + errors, + [ + checks.Warning( + "'CustomUserNonUniqueUsername.username' is named as " + "the 'USERNAME_FIELD', but it is not unique.", + hint="Ensure that your authentication backend(s) can handle non-unique usernames.", + obj=CustomUserNonUniqueUsername, + id="auth.W004", + ), + ], + ) - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserPartiallyUnique') + @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserPartiallyUnique") def test_username_partially_unique(self): class CustomUserPartiallyUnique(AbstractBaseUser): username = models.CharField(max_length=30) - USERNAME_FIELD = 'username' + USERNAME_FIELD = "username" class Meta: constraints = [ UniqueConstraint( - fields=['username'], - name='partial_username_unique', + fields=["username"], + name="partial_username_unique", condition=Q(password__isnull=False), ), ] errors = checks.run_checks(app_configs=self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "'CustomUserPartiallyUnique.username' must be unique because " - "it is named as the 'USERNAME_FIELD'.", - obj=CustomUserPartiallyUnique, - id='auth.E003', - ), - ]) - with self.settings(AUTHENTICATION_BACKENDS=['my.custom.backend']): - errors = checks.run_checks(app_configs=self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Warning( - "'CustomUserPartiallyUnique.username' is named as the " - "'USERNAME_FIELD', but it is not unique.", - hint=( - 'Ensure that your authentication backend(s) can ' - 'handle non-unique usernames.' - ), + self.assertEqual( + errors, + [ + checks.Error( + "'CustomUserPartiallyUnique.username' must be unique because " + "it is named as the 'USERNAME_FIELD'.", obj=CustomUserPartiallyUnique, - id='auth.W004', + id="auth.E003", ), - ]) + ], + ) + with self.settings(AUTHENTICATION_BACKENDS=["my.custom.backend"]): + errors = checks.run_checks(app_configs=self.apps.get_app_configs()) + self.assertEqual( + errors, + [ + checks.Warning( + "'CustomUserPartiallyUnique.username' is named as the " + "'USERNAME_FIELD', but it is not unique.", + hint=( + "Ensure that your authentication backend(s) can " + "handle non-unique usernames." + ), + obj=CustomUserPartiallyUnique, + id="auth.W004", + ), + ], + ) - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserUniqueConstraint') + @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserUniqueConstraint") def test_username_unique_with_model_constraint(self): class CustomUserUniqueConstraint(AbstractBaseUser): username = models.CharField(max_length=30) - USERNAME_FIELD = 'username' + USERNAME_FIELD = "username" class Meta: constraints = [ - UniqueConstraint(fields=['username'], name='username_unique'), + UniqueConstraint(fields=["username"], name="username_unique"), ] self.assertEqual(checks.run_checks(app_configs=self.apps.get_app_configs()), []) - with self.settings(AUTHENTICATION_BACKENDS=['my.custom.backend']): + with self.settings(AUTHENTICATION_BACKENDS=["my.custom.backend"]): errors = checks.run_checks(app_configs=self.apps.get_app_configs()) self.assertEqual(errors, []) - @override_settings(AUTH_USER_MODEL='auth_tests.BadUser') + @override_settings(AUTH_USER_MODEL="auth_tests.BadUser") def test_is_anonymous_authenticated_methods(self): """ .is_anonymous/is_authenticated must not be methods. """ + class BadUser(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) - USERNAME_FIELD = 'username' + USERNAME_FIELD = "username" def is_anonymous(self): return True @@ -157,50 +174,56 @@ class UserModelChecksTests(SimpleTestCase): 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') + 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]) class ModelsPermissionsChecksTests(SimpleTestCase): def test_clashing_default_permissions(self): class Checked(models.Model): class Meta: - permissions = [ - ('change_checked', 'Can edit permission (duplicate)') - ] + permissions = [("change_checked", "Can edit permission (duplicate)")] + errors = checks.run_checks(self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "The permission codenamed 'change_checked' clashes with a builtin " - "permission for model 'auth_tests.Checked'.", - obj=Checked, - id='auth.E005', - ), - ]) + self.assertEqual( + errors, + [ + checks.Error( + "The permission codenamed 'change_checked' clashes with a builtin " + "permission for model 'auth_tests.Checked'.", + obj=Checked, + id="auth.E005", + ), + ], + ) def test_non_clashing_custom_permissions(self): class Checked(models.Model): class Meta: permissions = [ - ('my_custom_permission', 'Some permission'), - ('other_one', 'Some other permission'), + ("my_custom_permission", "Some permission"), + ("other_one", "Some other permission"), ] + errors = checks.run_checks(self.apps.get_app_configs()) self.assertEqual(errors, []) @@ -208,84 +231,109 @@ class ModelsPermissionsChecksTests(SimpleTestCase): class Checked(models.Model): class Meta: permissions = [ - ('my_custom_permission', 'Some permission'), - ('other_one', 'Some other permission'), - ('my_custom_permission', 'Some permission with duplicate permission code'), + ("my_custom_permission", "Some permission"), + ("other_one", "Some other permission"), + ( + "my_custom_permission", + "Some permission with duplicate permission code", + ), ] + errors = checks.run_checks(self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "The permission codenamed 'my_custom_permission' is duplicated for " - "model 'auth_tests.Checked'.", - obj=Checked, - id='auth.E006', - ), - ]) + self.assertEqual( + errors, + [ + checks.Error( + "The permission codenamed 'my_custom_permission' is duplicated for " + "model 'auth_tests.Checked'.", + obj=Checked, + id="auth.E006", + ), + ], + ) def test_verbose_name_max_length(self): class Checked(models.Model): class Meta: - verbose_name = 'some ridiculously long verbose name that is out of control' * 5 + verbose_name = ( + "some ridiculously long verbose name that is out of control" * 5 + ) + errors = checks.run_checks(self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "The verbose_name of model 'auth_tests.Checked' must be at most 244 " - "characters for its builtin permission names to be at most 255 characters.", - obj=Checked, - id='auth.E007', - ), - ]) + self.assertEqual( + errors, + [ + checks.Error( + "The verbose_name of model 'auth_tests.Checked' must be at most 244 " + "characters for its builtin permission names to be at most 255 characters.", + obj=Checked, + id="auth.E007", + ), + ], + ) def test_model_name_max_length(self): - model_name = 'X' * 94 - model = type(model_name, (models.Model,), {'__module__': self.__module__}) + model_name = "X" * 94 + model = type(model_name, (models.Model,), {"__module__": self.__module__}) errors = checks.run_checks(self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "The name of model 'auth_tests.%s' must be at most 93 " - "characters for its builtin permission codenames to be at " - "most 100 characters." % model_name, - obj=model, - id='auth.E011', - ), - ]) + self.assertEqual( + errors, + [ + checks.Error( + "The name of model 'auth_tests.%s' must be at most 93 " + "characters for its builtin permission codenames to be at " + "most 100 characters." % model_name, + obj=model, + id="auth.E011", + ), + ], + ) def test_custom_permission_name_max_length(self): - custom_permission_name = 'some ridiculously long verbose name that is out of control' * 5 + custom_permission_name = ( + "some ridiculously long verbose name that is out of control" * 5 + ) class Checked(models.Model): class Meta: permissions = [ - ('my_custom_permission', custom_permission_name), + ("my_custom_permission", custom_permission_name), ] + errors = checks.run_checks(self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "The permission named '%s' of model 'auth_tests.Checked' is longer " - "than 255 characters." % custom_permission_name, - obj=Checked, - id='auth.E008', - ), - ]) + self.assertEqual( + errors, + [ + checks.Error( + "The permission named '%s' of model 'auth_tests.Checked' is longer " + "than 255 characters." % custom_permission_name, + obj=Checked, + id="auth.E008", + ), + ], + ) def test_custom_permission_codename_max_length(self): - custom_permission_codename = 'x' * 101 + custom_permission_codename = "x" * 101 class Checked(models.Model): class Meta: permissions = [ - (custom_permission_codename, 'Custom permission'), + (custom_permission_codename, "Custom permission"), ] errors = checks.run_checks(self.apps.get_app_configs()) - self.assertEqual(errors, [ - checks.Error( - "The permission codenamed '%s' of model 'auth_tests.Checked' " - "is longer than 100 characters." % custom_permission_codename, - obj=Checked, - id='auth.E012', - ), - ]) + self.assertEqual( + errors, + [ + checks.Error( + "The permission codenamed '%s' of model 'auth_tests.Checked' " + "is longer than 100 characters." % custom_permission_codename, + obj=Checked, + id="auth.E012", + ), + ], + ) def test_empty_default_permissions(self): class Checked(models.Model): diff --git a/tests/auth_tests/test_context_processors.py b/tests/auth_tests/test_context_processors.py index 98e51a62d9..ab621313e8 100644 --- a/tests/auth_tests/test_context_processors.py +++ b/tests/auth_tests/test_context_processors.py @@ -10,23 +10,25 @@ from .settings import AUTH_MIDDLEWARE, AUTH_TEMPLATES class MockUser: def __repr__(self): - return 'MockUser()' + return "MockUser()" def has_module_perms(self, perm): - return perm == 'mockapp' + return perm == "mockapp" def has_perm(self, perm, obj=None): - return perm == 'mockapp.someperm' + return perm == "mockapp.someperm" class PermWrapperTests(SimpleTestCase): """ Test some details of the PermWrapper implementation. """ + class EQLimiterObject: """ This object makes sure __eq__ will not be called endlessly. """ + def __init__(self): self.eq_calls = 0 @@ -38,7 +40,7 @@ class PermWrapperTests(SimpleTestCase): def test_repr(self): perms = PermWrapper(MockUser()) - self.assertEqual(repr(perms), 'PermWrapper(MockUser())') + self.assertEqual(repr(perms), "PermWrapper(MockUser())") def test_permwrapper_in(self): """ @@ -46,25 +48,25 @@ class PermWrapperTests(SimpleTestCase): """ perms = PermWrapper(MockUser()) # Works for modules and full permissions. - self.assertIn('mockapp', perms) - self.assertNotIn('nonexistent', perms) - self.assertIn('mockapp.someperm', perms) - self.assertNotIn('mockapp.nonexistent', perms) + self.assertIn("mockapp", perms) + self.assertNotIn("nonexistent", perms) + self.assertIn("mockapp.someperm", perms) + self.assertNotIn("mockapp.nonexistent", perms) def test_permlookupdict_in(self): """ No endless loops if accessed with 'in' - refs #18979. """ - pldict = PermLookupDict(MockUser(), 'mockapp') + pldict = PermLookupDict(MockUser(), "mockapp") with self.assertRaises(TypeError): self.EQLimiterObject() in pldict def test_iter(self): - with self.assertRaisesMessage(TypeError, 'PermWrapper is not iterable.'): + with self.assertRaisesMessage(TypeError, "PermWrapper is not iterable."): iter(PermWrapper(MockUser())) -@override_settings(ROOT_URLCONF='auth_tests.urls', TEMPLATES=AUTH_TEMPLATES) +@override_settings(ROOT_URLCONF="auth_tests.urls", TEMPLATES=AUTH_TEMPLATES) class AuthContextProcessorTests(TestCase): """ Tests for the ``django.contrib.auth.context_processors.auth`` processor @@ -72,7 +74,9 @@ class AuthContextProcessorTests(TestCase): @classmethod def setUpTestData(cls): - cls.superuser = User.objects.create_superuser(username='super', password='secret', email='super@example.com') + cls.superuser = User.objects.create_superuser( + username="super", password="secret", email="super@example.com" + ) @override_settings(MIDDLEWARE=AUTH_MIDDLEWARE) def test_session_not_accessed(self): @@ -80,7 +84,7 @@ class AuthContextProcessorTests(TestCase): The session is not accessed simply by including the auth context processor """ - response = self.client.get('/auth_processor_no_attr_access/') + response = self.client.get("/auth_processor_no_attr_access/") self.assertContains(response, "Session not accessed") @override_settings(MIDDLEWARE=AUTH_MIDDLEWARE) @@ -89,36 +93,40 @@ class AuthContextProcessorTests(TestCase): The session is accessed if the auth context processor is used and relevant attributes accessed. """ - response = self.client.get('/auth_processor_attr_access/') + response = self.client.get("/auth_processor_attr_access/") self.assertContains(response, "Session accessed") def test_perms_attrs(self): - u = User.objects.create_user(username='normal', password='secret') + u = User.objects.create_user(username="normal", password="secret") u.user_permissions.add( Permission.objects.get( content_type=ContentType.objects.get_for_model(Permission), - codename='add_permission')) + codename="add_permission", + ) + ) self.client.force_login(u) - response = self.client.get('/auth_processor_perms/') + response = self.client.get("/auth_processor_perms/") self.assertContains(response, "Has auth permissions") self.assertContains(response, "Has auth.add_permission permissions") self.assertNotContains(response, "nonexistent") def test_perm_in_perms_attrs(self): - u = User.objects.create_user(username='normal', password='secret') + u = User.objects.create_user(username="normal", password="secret") u.user_permissions.add( Permission.objects.get( content_type=ContentType.objects.get_for_model(Permission), - codename='add_permission')) - self.client.login(username='normal', password='secret') - response = self.client.get('/auth_processor_perm_in_perms/') + codename="add_permission", + ) + ) + self.client.login(username="normal", password="secret") + response = self.client.get("/auth_processor_perm_in_perms/") self.assertContains(response, "Has auth permissions") self.assertContains(response, "Has auth.add_permission permissions") self.assertNotContains(response, "nonexistent") def test_message_attrs(self): self.client.force_login(self.superuser) - response = self.client.get('/auth_processor_messages/') + response = self.client.get("/auth_processor_messages/") self.assertContains(response, "Message 1") def test_user_attrs(self): @@ -128,9 +136,9 @@ class AuthContextProcessorTests(TestCase): # These are 'functional' level tests for common use cases. Direct # testing of the implementation (SimpleLazyObject) is in the 'utils' # tests. - self.client.login(username='super', password='secret') - user = authenticate(username='super', password='secret') - response = self.client.get('/auth_processor_user/') + self.client.login(username="super", password="secret") + user = authenticate(username="super", password="secret") + response = self.client.get("/auth_processor_user/") self.assertContains(response, "unicode: super") self.assertContains(response, "id: %d" % self.superuser.pk) self.assertContains(response, "username: super") @@ -138,10 +146,10 @@ class AuthContextProcessorTests(TestCase): self.assertContains(response, "url: /userpage/super/") # A Q() comparing a user and with another Q() (in an AND or OR fashion). - Q(user=response.context['user']) & Q(someflag=True) + Q(user=response.context["user"]) & Q(someflag=True) # Tests for user equality. This is hard because User defines # equality in a non-duck-typing way # See bug #12060 - self.assertEqual(response.context['user'], user) - self.assertEqual(user, response.context['user']) + self.assertEqual(response.context["user"], user) + self.assertEqual(user, response.context["user"]) diff --git a/tests/auth_tests/test_decorators.py b/tests/auth_tests/test_decorators.py index 469b1ad0ac..ae43adcb0a 100644 --- a/tests/auth_tests/test_decorators.py +++ b/tests/auth_tests/test_decorators.py @@ -9,7 +9,7 @@ from django.test.client import RequestFactory from .test_views import AuthViewsTestCase -@override_settings(ROOT_URLCONF='auth_tests.urls') +@override_settings(ROOT_URLCONF="auth_tests.urls") class LoginRequiredTestCase(AuthViewsTestCase): """ Tests the login_required decorators @@ -19,20 +19,24 @@ class LoginRequiredTestCase(AuthViewsTestCase): """ login_required is assignable to callable objects. """ + class CallableView: def __call__(self, *args, **kwargs): pass + login_required(CallableView()) def test_view(self): """ login_required is assignable to normal views. """ + def normal_view(request): pass + login_required(normal_view) - def test_login_required(self, view_url='/login_required/', login_url=None): + def test_login_required(self, view_url="/login_required/", login_url=None): """ login_required works on a simple view wrapped in a login_required decorator. @@ -51,70 +55,90 @@ class LoginRequiredTestCase(AuthViewsTestCase): login_required works on a simple view wrapped in a login_required decorator with a login_url set. """ - self.test_login_required(view_url='/login_required_login_url/', login_url='/somewhere/') + self.test_login_required( + view_url="/login_required_login_url/", login_url="/somewhere/" + ) class PermissionsRequiredDecoratorTest(TestCase): """ Tests for the permission_required decorator """ + factory = RequestFactory() @classmethod def setUpTestData(cls): - cls.user = models.User.objects.create(username='joe', password='qwerty') + cls.user = models.User.objects.create(username="joe", password="qwerty") # Add permissions auth.add_customuser and auth.change_customuser - perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser')) + perms = models.Permission.objects.filter( + codename__in=("add_customuser", "change_customuser") + ) cls.user.user_permissions.add(*perms) def test_many_permissions_pass(self): - - @permission_required(['auth_tests.add_customuser', 'auth_tests.change_customuser']) + @permission_required( + ["auth_tests.add_customuser", "auth_tests.change_customuser"] + ) def a_view(request): return HttpResponse() - request = self.factory.get('/rand') + + request = self.factory.get("/rand") request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_many_permissions_in_set_pass(self): - - @permission_required({'auth_tests.add_customuser', 'auth_tests.change_customuser'}) + @permission_required( + {"auth_tests.add_customuser", "auth_tests.change_customuser"} + ) def a_view(request): return HttpResponse() - request = self.factory.get('/rand') + + request = self.factory.get("/rand") request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_single_permission_pass(self): - - @permission_required('auth_tests.add_customuser') + @permission_required("auth_tests.add_customuser") def a_view(request): return HttpResponse() - request = self.factory.get('/rand') + + request = self.factory.get("/rand") request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_permissioned_denied_redirect(self): - - @permission_required(['auth_tests.add_customuser', 'auth_tests.change_customuser', 'nonexistent-permission']) + @permission_required( + [ + "auth_tests.add_customuser", + "auth_tests.change_customuser", + "nonexistent-permission", + ] + ) def a_view(request): return HttpResponse() - request = self.factory.get('/rand') + + request = self.factory.get("/rand") request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 302) def test_permissioned_denied_exception_raised(self): - - @permission_required([ - 'auth_tests.add_customuser', 'auth_tests.change_customuser', 'nonexistent-permission' - ], raise_exception=True) + @permission_required( + [ + "auth_tests.add_customuser", + "auth_tests.change_customuser", + "nonexistent-permission", + ], + raise_exception=True, + ) def a_view(request): return HttpResponse() - request = self.factory.get('/rand') + + request = self.factory.get("/rand") request.user = self.user with self.assertRaises(PermissionDenied): a_view(request) diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index e208305fc6..1713d367c3 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -3,9 +3,15 @@ import re from unittest import mock from django.contrib.auth.forms import ( - AdminPasswordChangeForm, AuthenticationForm, PasswordChangeForm, - PasswordResetForm, ReadOnlyPasswordHashField, ReadOnlyPasswordHashWidget, - SetPasswordForm, UserChangeForm, UserCreationForm, + AdminPasswordChangeForm, + AuthenticationForm, + PasswordChangeForm, + PasswordResetForm, + ReadOnlyPasswordHashField, + ReadOnlyPasswordHashWidget, + SetPasswordForm, + UserChangeForm, + UserCreationForm, ) from django.contrib.auth.models import User from django.contrib.auth.signals import user_login_failed @@ -21,7 +27,9 @@ from django.utils.text import capfirst from django.utils.translation import gettext as _ from .models.custom_user import ( - CustomUser, CustomUserWithoutIsActiveField, ExtensionUser, + CustomUser, + CustomUserWithoutIsActiveField, + ExtensionUser, ) from .models.with_custom_email_field import CustomEmailField from .models.with_integer_username import IntegerUsernameUser @@ -29,75 +37,84 @@ from .settings import AUTH_TEMPLATES class TestDataMixin: - @classmethod def setUpTestData(cls): - cls.u1 = User.objects.create_user(username='testclient', password='password', email='testclient@example.com') - cls.u2 = User.objects.create_user(username='inactive', password='password', is_active=False) - cls.u3 = User.objects.create_user(username='staff', password='password') - cls.u4 = User.objects.create(username='empty_password', password='') - cls.u5 = User.objects.create(username='unmanageable_password', password='$') - cls.u6 = User.objects.create(username='unknown_password', password='foo$bar') + cls.u1 = User.objects.create_user( + username="testclient", password="password", email="testclient@example.com" + ) + cls.u2 = User.objects.create_user( + username="inactive", password="password", is_active=False + ) + cls.u3 = User.objects.create_user(username="staff", password="password") + cls.u4 = User.objects.create(username="empty_password", password="") + cls.u5 = User.objects.create(username="unmanageable_password", password="$") + cls.u6 = User.objects.create(username="unknown_password", password="foo$bar") class UserCreationFormTest(TestDataMixin, TestCase): - def test_user_already_exists(self): data = { - 'username': 'testclient', - 'password1': 'test123', - 'password2': 'test123', + "username": "testclient", + "password1": "test123", + "password2": "test123", } form = UserCreationForm(data) self.assertFalse(form.is_valid()) - self.assertEqual(form["username"].errors, - [str(User._meta.get_field('username').error_messages['unique'])]) + self.assertEqual( + form["username"].errors, + [str(User._meta.get_field("username").error_messages["unique"])], + ) def test_invalid_data(self): data = { - 'username': 'jsmith!', - 'password1': 'test123', - 'password2': 'test123', + "username": "jsmith!", + "password1": "test123", + "password2": "test123", } form = UserCreationForm(data) self.assertFalse(form.is_valid()) - validator = next(v for v in User._meta.get_field('username').validators if v.code == 'invalid') + validator = next( + v + for v in User._meta.get_field("username").validators + if v.code == "invalid" + ) self.assertEqual(form["username"].errors, [str(validator.message)]) def test_password_verification(self): # The verification password is incorrect. data = { - 'username': 'jsmith', - 'password1': 'test123', - 'password2': 'test', + "username": "jsmith", + "password1": "test123", + "password2": "test", } form = UserCreationForm(data) self.assertFalse(form.is_valid()) - self.assertEqual(form["password2"].errors, - [str(form.error_messages['password_mismatch'])]) + self.assertEqual( + form["password2"].errors, [str(form.error_messages["password_mismatch"])] + ) def test_both_passwords(self): # One (or both) passwords weren't given - data = {'username': 'jsmith'} + data = {"username": "jsmith"} form = UserCreationForm(data) - required_error = [str(Field.default_error_messages['required'])] + required_error = [str(Field.default_error_messages["required"])] self.assertFalse(form.is_valid()) - self.assertEqual(form['password1'].errors, required_error) - self.assertEqual(form['password2'].errors, required_error) + self.assertEqual(form["password1"].errors, required_error) + self.assertEqual(form["password2"].errors, required_error) - data['password2'] = 'test123' + data["password2"] = "test123" form = UserCreationForm(data) self.assertFalse(form.is_valid()) - self.assertEqual(form['password1'].errors, required_error) - self.assertEqual(form['password2'].errors, []) + self.assertEqual(form["password1"].errors, required_error) + self.assertEqual(form["password2"].errors, []) - @mock.patch('django.contrib.auth.password_validation.password_changed') + @mock.patch("django.contrib.auth.password_validation.password_changed") def test_success(self, password_changed): # The success case. data = { - 'username': 'jsmith@example.com', - 'password1': 'test123', - 'password2': 'test123', + "username": "jsmith@example.com", + "password1": "test123", + "password2": "test123", } form = UserCreationForm(data) self.assertTrue(form.is_valid()) @@ -105,33 +122,33 @@ class UserCreationFormTest(TestDataMixin, TestCase): self.assertEqual(password_changed.call_count, 0) u = form.save() self.assertEqual(password_changed.call_count, 1) - self.assertEqual(repr(u), '') + self.assertEqual(repr(u), "") def test_unicode_username(self): data = { - 'username': '宝', - 'password1': 'test123', - 'password2': 'test123', + "username": "宝", + "password1": "test123", + "password2": "test123", } form = UserCreationForm(data) self.assertTrue(form.is_valid()) u = form.save() - self.assertEqual(u.username, '宝') + self.assertEqual(u.username, "宝") def test_normalize_username(self): # The normalization happens in AbstractBaseUser.clean() and ModelForm # validation calls Model.clean(). - ohm_username = 'testΩ' # U+2126 OHM SIGN + ohm_username = "testΩ" # U+2126 OHM SIGN data = { - 'username': ohm_username, - 'password1': 'pwd2', - 'password2': 'pwd2', + "username": ohm_username, + "password1": "pwd2", + "password2": "pwd2", } form = UserCreationForm(data) self.assertTrue(form.is_valid()) user = form.save() self.assertNotEqual(user.username, ohm_username) - self.assertEqual(user.username, 'testΩ') # U+03A9 GREEK CAPITAL LETTER OMEGA + self.assertEqual(user.username, "testΩ") # U+03A9 GREEK CAPITAL LETTER OMEGA def test_duplicate_normalized_unicode(self): """ @@ -139,53 +156,62 @@ class UserCreationFormTest(TestDataMixin, TestCase): by their unicode code points only, Unicode NFKC normalization should make appear them equal to Django. """ - omega_username = 'iamtheΩ' # U+03A9 GREEK CAPITAL LETTER OMEGA - ohm_username = 'iamtheΩ' # U+2126 OHM SIGN + omega_username = "iamtheΩ" # U+03A9 GREEK CAPITAL LETTER OMEGA + ohm_username = "iamtheΩ" # U+2126 OHM SIGN self.assertNotEqual(omega_username, ohm_username) - User.objects.create_user(username=omega_username, password='pwd') + User.objects.create_user(username=omega_username, password="pwd") data = { - 'username': ohm_username, - 'password1': 'pwd2', - 'password2': 'pwd2', + "username": ohm_username, + "password1": "pwd2", + "password2": "pwd2", } form = UserCreationForm(data) self.assertFalse(form.is_valid()) self.assertEqual( - form.errors['username'], ["A user with that username already exists."] + form.errors["username"], ["A user with that username already exists."] ) - @override_settings(AUTH_PASSWORD_VALIDATORS=[ - {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, - {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'OPTIONS': { - 'min_length': 12, - }}, - ]) + @override_settings( + AUTH_PASSWORD_VALIDATORS=[ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + "OPTIONS": { + "min_length": 12, + }, + }, + ] + ) def test_validates_password(self): data = { - 'username': 'testclient', - 'password1': 'testclient', - 'password2': 'testclient', + "username": "testclient", + "password1": "testclient", + "password2": "testclient", } form = UserCreationForm(data) self.assertFalse(form.is_valid()) - self.assertEqual(len(form['password2'].errors), 2) - self.assertIn('The password is too similar to the username.', form['password2'].errors) + self.assertEqual(len(form["password2"].errors), 2) + self.assertIn( + "The password is too similar to the username.", form["password2"].errors + ) self.assertIn( - 'This password is too short. It must contain at least 12 characters.', - form['password2'].errors + "This password is too short. It must contain at least 12 characters.", + form["password2"].errors, ) def test_custom_form(self): class CustomUserCreationForm(UserCreationForm): class Meta(UserCreationForm.Meta): model = ExtensionUser - fields = UserCreationForm.Meta.fields + ('date_of_birth',) + fields = UserCreationForm.Meta.fields + ("date_of_birth",) data = { - 'username': 'testclient', - 'password1': 'testclient', - 'password2': 'testclient', - 'date_of_birth': '1988-02-24', + "username": "testclient", + "password1": "testclient", + "password2": "testclient", + "date_of_birth": "1988-02-24", } form = CustomUserCreationForm(data) self.assertTrue(form.is_valid()) @@ -194,13 +220,13 @@ class UserCreationFormTest(TestDataMixin, TestCase): class CustomUserCreationForm(UserCreationForm): class Meta(UserCreationForm.Meta): model = CustomUser - fields = ('email', 'date_of_birth') + fields = ("email", "date_of_birth") data = { - 'email': 'test@client222.com', - 'password1': 'testclient', - 'password2': 'testclient', - 'date_of_birth': '1988-02-24', + "email": "test@client222.com", + "password1": "testclient", + "password2": "testclient", + "date_of_birth": "1988-02-24", } form = CustomUserCreationForm(data) self.assertTrue(form.is_valid()) @@ -209,123 +235,144 @@ class UserCreationFormTest(TestDataMixin, TestCase): class CustomUserCreationForm(UserCreationForm): class Meta(UserCreationForm.Meta): model = CustomUserWithoutIsActiveField - fields = ('email',) # without USERNAME_FIELD + fields = ("email",) # without USERNAME_FIELD data = { - 'email': 'testclient@example.com', - 'password1': 'testclient', - 'password2': 'testclient', + "email": "testclient@example.com", + "password1": "testclient", + "password2": "testclient", } form = CustomUserCreationForm(data) self.assertTrue(form.is_valid()) def test_password_whitespace_not_stripped(self): data = { - 'username': 'testuser', - 'password1': ' testpassword ', - 'password2': ' testpassword ', + "username": "testuser", + "password1": " testpassword ", + "password2": " testpassword ", } form = UserCreationForm(data) self.assertTrue(form.is_valid()) - self.assertEqual(form.cleaned_data['password1'], data['password1']) - self.assertEqual(form.cleaned_data['password2'], data['password2']) - - @override_settings(AUTH_PASSWORD_VALIDATORS=[ - {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, - ]) + self.assertEqual(form.cleaned_data["password1"], data["password1"]) + self.assertEqual(form.cleaned_data["password2"], data["password2"]) + + @override_settings( + AUTH_PASSWORD_VALIDATORS=[ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, + ] + ) def test_password_help_text(self): form = UserCreationForm() self.assertEqual( - form.fields['password1'].help_text, - '
  • Your password can’t be too similar to your other personal information.
' + form.fields["password1"].help_text, + "
  • Your password can’t be too similar to your other personal information.
", ) - @override_settings(AUTH_PASSWORD_VALIDATORS=[ - {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, - ]) + @override_settings( + AUTH_PASSWORD_VALIDATORS=[ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, + ] + ) def test_user_create_form_validates_password_with_all_data(self): """UserCreationForm password validation uses all of the form's data.""" + class CustomUserCreationForm(UserCreationForm): class Meta(UserCreationForm.Meta): model = User - fields = ('username', 'email', 'first_name', 'last_name') - form = CustomUserCreationForm({ - 'username': 'testuser', - 'password1': 'testpassword', - 'password2': 'testpassword', - 'first_name': 'testpassword', - 'last_name': 'lastname', - }) + fields = ("username", "email", "first_name", "last_name") + + form = CustomUserCreationForm( + { + "username": "testuser", + "password1": "testpassword", + "password2": "testpassword", + "first_name": "testpassword", + "last_name": "lastname", + } + ) self.assertFalse(form.is_valid()) self.assertEqual( - form.errors['password2'], - ['The password is too similar to the first name.'], + form.errors["password2"], + ["The password is too similar to the first name."], ) def test_username_field_autocapitalize_none(self): form = UserCreationForm() - self.assertEqual(form.fields['username'].widget.attrs.get('autocapitalize'), 'none') + self.assertEqual( + form.fields["username"].widget.attrs.get("autocapitalize"), "none" + ) def test_html_autocomplete_attributes(self): form = UserCreationForm() tests = ( - ('username', 'username'), - ('password1', 'new-password'), - ('password2', 'new-password'), + ("username", "username"), + ("password1", "new-password"), + ("password2", "new-password"), ) for field_name, autocomplete in tests: with self.subTest(field_name=field_name, autocomplete=autocomplete): - self.assertEqual(form.fields[field_name].widget.attrs['autocomplete'], autocomplete) + self.assertEqual( + form.fields[field_name].widget.attrs["autocomplete"], autocomplete + ) # To verify that the login form rejects inactive users, use an authentication # backend that allows them. -@override_settings(AUTHENTICATION_BACKENDS=['django.contrib.auth.backends.AllowAllUsersModelBackend']) +@override_settings( + AUTHENTICATION_BACKENDS=["django.contrib.auth.backends.AllowAllUsersModelBackend"] +) class AuthenticationFormTest(TestDataMixin, TestCase): - def test_invalid_username(self): # The user submits an invalid username. data = { - 'username': 'jsmith_does_not_exist', - 'password': 'test123', + "username": "jsmith_does_not_exist", + "password": "test123", } form = AuthenticationForm(None, data) self.assertFalse(form.is_valid()) self.assertEqual( - form.non_field_errors(), [ - form.error_messages['invalid_login'] % { - 'username': User._meta.get_field('username').verbose_name - } - ] + form.non_field_errors(), + [ + form.error_messages["invalid_login"] + % {"username": User._meta.get_field("username").verbose_name} + ], ) def test_inactive_user(self): # The user is inactive. data = { - 'username': 'inactive', - 'password': 'password', + "username": "inactive", + "password": "password", } form = AuthenticationForm(None, data) self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), [str(form.error_messages['inactive'])]) + self.assertEqual( + form.non_field_errors(), [str(form.error_messages["inactive"])] + ) # Use an authentication backend that rejects inactive users. - @override_settings(AUTHENTICATION_BACKENDS=['django.contrib.auth.backends.ModelBackend']) + @override_settings( + AUTHENTICATION_BACKENDS=["django.contrib.auth.backends.ModelBackend"] + ) def test_inactive_user_incorrect_password(self): """An invalid login doesn't leak the inactive status of a user.""" data = { - 'username': 'inactive', - 'password': 'incorrect', + "username": "inactive", + "password": "incorrect", } form = AuthenticationForm(None, data) self.assertFalse(form.is_valid()) self.assertEqual( - form.non_field_errors(), [ - form.error_messages['invalid_login'] % { - 'username': User._meta.get_field('username').verbose_name - } - ] + form.non_field_errors(), + [ + form.error_messages["invalid_login"] + % {"username": User._meta.get_field("username").verbose_name} + ], ) def test_login_failed(self): @@ -337,33 +384,44 @@ class AuthenticationFormTest(TestDataMixin, TestCase): user_login_failed.connect(signal_handler) fake_request = object() try: - form = AuthenticationForm(fake_request, { - 'username': 'testclient', - 'password': 'incorrect', - }) + form = AuthenticationForm( + fake_request, + { + "username": "testclient", + "password": "incorrect", + }, + ) self.assertFalse(form.is_valid()) - self.assertIs(signal_calls[0]['request'], fake_request) + self.assertIs(signal_calls[0]["request"], fake_request) finally: user_login_failed.disconnect(signal_handler) def test_inactive_user_i18n(self): - with self.settings(USE_I18N=True), translation.override('pt-br', deactivate=True): + with self.settings(USE_I18N=True), translation.override( + "pt-br", deactivate=True + ): # The user is inactive. data = { - 'username': 'inactive', - 'password': 'password', + "username": "inactive", + "password": "password", } form = AuthenticationForm(None, data) self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), [str(form.error_messages['inactive'])]) + self.assertEqual( + form.non_field_errors(), [str(form.error_messages["inactive"])] + ) # Use an authentication backend that allows inactive users. - @override_settings(AUTHENTICATION_BACKENDS=['django.contrib.auth.backends.AllowAllUsersModelBackend']) + @override_settings( + AUTHENTICATION_BACKENDS=[ + "django.contrib.auth.backends.AllowAllUsersModelBackend" + ] + ) def test_custom_login_allowed_policy(self): # The user is inactive, but our custom form policy allows them to log in. data = { - 'username': 'inactive', - 'password': 'password', + "username": "inactive", + "password": "password", } class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm): @@ -383,11 +441,11 @@ class AuthenticationFormTest(TestDataMixin, TestCase): form = PickyAuthenticationForm(None, data) self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), ['This user is disallowed.']) + self.assertEqual(form.non_field_errors(), ["This user is disallowed."]) data = { - 'username': 'testclient', - 'password': 'password', + "username": "testclient", + "password": "password", } form = PickyAuthenticationForm(None, data) self.assertFalse(form.is_valid()) @@ -396,102 +454,103 @@ class AuthenticationFormTest(TestDataMixin, TestCase): def test_success(self): # The success case data = { - 'username': 'testclient', - 'password': 'password', + "username": "testclient", + "password": "password", } form = AuthenticationForm(None, data) self.assertTrue(form.is_valid()) self.assertEqual(form.non_field_errors(), []) def test_unicode_username(self): - User.objects.create_user(username='Σαρα', password='pwd') + User.objects.create_user(username="Σαρα", password="pwd") data = { - 'username': 'Σαρα', - 'password': 'pwd', + "username": "Σαρα", + "password": "pwd", } form = AuthenticationForm(None, data) self.assertTrue(form.is_valid()) self.assertEqual(form.non_field_errors(), []) - @override_settings(AUTH_USER_MODEL='auth_tests.CustomEmailField') + @override_settings(AUTH_USER_MODEL="auth_tests.CustomEmailField") def test_username_field_max_length_matches_user_model(self): - self.assertEqual(CustomEmailField._meta.get_field('username').max_length, 255) + self.assertEqual(CustomEmailField._meta.get_field("username").max_length, 255) data = { - 'username': 'u' * 255, - 'password': 'pwd', - 'email': 'test@example.com', + "username": "u" * 255, + "password": "pwd", + "email": "test@example.com", } CustomEmailField.objects.create_user(**data) form = AuthenticationForm(None, data) - self.assertEqual(form.fields['username'].max_length, 255) - self.assertEqual(form.fields['username'].widget.attrs.get('maxlength'), 255) + self.assertEqual(form.fields["username"].max_length, 255) + self.assertEqual(form.fields["username"].widget.attrs.get("maxlength"), 255) self.assertEqual(form.errors, {}) - @override_settings(AUTH_USER_MODEL='auth_tests.IntegerUsernameUser') + @override_settings(AUTH_USER_MODEL="auth_tests.IntegerUsernameUser") def test_username_field_max_length_defaults_to_254(self): - self.assertIsNone(IntegerUsernameUser._meta.get_field('username').max_length) + self.assertIsNone(IntegerUsernameUser._meta.get_field("username").max_length) data = { - 'username': '0123456', - 'password': 'password', + "username": "0123456", + "password": "password", } IntegerUsernameUser.objects.create_user(**data) form = AuthenticationForm(None, data) - self.assertEqual(form.fields['username'].max_length, 254) - self.assertEqual(form.fields['username'].widget.attrs.get('maxlength'), 254) + self.assertEqual(form.fields["username"].max_length, 254) + self.assertEqual(form.fields["username"].widget.attrs.get("maxlength"), 254) self.assertEqual(form.errors, {}) def test_username_field_label(self): - class CustomAuthenticationForm(AuthenticationForm): username = CharField(label="Name", max_length=75) form = CustomAuthenticationForm() - self.assertEqual(form['username'].label, "Name") + self.assertEqual(form["username"].label, "Name") def test_username_field_label_not_set(self): - class CustomAuthenticationForm(AuthenticationForm): username = CharField() form = CustomAuthenticationForm() username_field = User._meta.get_field(User.USERNAME_FIELD) - self.assertEqual(form.fields['username'].label, capfirst(username_field.verbose_name)) + self.assertEqual( + form.fields["username"].label, capfirst(username_field.verbose_name) + ) def test_username_field_autocapitalize_none(self): form = AuthenticationForm() - self.assertEqual(form.fields['username'].widget.attrs.get('autocapitalize'), 'none') + self.assertEqual( + form.fields["username"].widget.attrs.get("autocapitalize"), "none" + ) def test_username_field_label_empty_string(self): - class CustomAuthenticationForm(AuthenticationForm): - username = CharField(label='') + username = CharField(label="") form = CustomAuthenticationForm() - self.assertEqual(form.fields['username'].label, "") + self.assertEqual(form.fields["username"].label, "") def test_password_whitespace_not_stripped(self): data = { - 'username': 'testuser', - 'password': ' pass ', + "username": "testuser", + "password": " pass ", } form = AuthenticationForm(None, data) form.is_valid() # Not necessary to have valid credentails for the test. - self.assertEqual(form.cleaned_data['password'], data['password']) + self.assertEqual(form.cleaned_data["password"], data["password"]) - @override_settings(AUTH_USER_MODEL='auth_tests.IntegerUsernameUser') + @override_settings(AUTH_USER_MODEL="auth_tests.IntegerUsernameUser") def test_integer_username(self): class CustomAuthenticationForm(AuthenticationForm): username = IntegerField() - user = IntegerUsernameUser.objects.create_user(username=0, password='pwd') + user = IntegerUsernameUser.objects.create_user(username=0, password="pwd") data = { - 'username': 0, - 'password': 'pwd', + "username": 0, + "password": "pwd", } form = CustomAuthenticationForm(None, data) self.assertTrue(form.is_valid()) - self.assertEqual(form.cleaned_data['username'], data['username']) - self.assertEqual(form.cleaned_data['password'], data['password']) + self.assertEqual(form.cleaned_data["username"], data["username"]) + self.assertEqual(form.cleaned_data["password"], data["password"]) self.assertEqual(form.errors, {}) self.assertEqual(form.user_cache, user) @@ -500,45 +559,46 @@ class AuthenticationFormTest(TestDataMixin, TestCase): self.assertIsInstance(error, ValidationError) self.assertEqual( error.message, - 'Please enter a correct %(username)s and password. Note that both ' - 'fields may be case-sensitive.', + "Please enter a correct %(username)s and password. Note that both " + "fields may be case-sensitive.", ) - self.assertEqual(error.code, 'invalid_login') - self.assertEqual(error.params, {'username': 'username'}) + self.assertEqual(error.code, "invalid_login") + self.assertEqual(error.params, {"username": "username"}) def test_html_autocomplete_attributes(self): form = AuthenticationForm() tests = ( - ('username', 'username'), - ('password', 'current-password'), + ("username", "username"), + ("password", "current-password"), ) for field_name, autocomplete in tests: with self.subTest(field_name=field_name, autocomplete=autocomplete): - self.assertEqual(form.fields[field_name].widget.attrs['autocomplete'], autocomplete) + self.assertEqual( + form.fields[field_name].widget.attrs["autocomplete"], autocomplete + ) class SetPasswordFormTest(TestDataMixin, TestCase): - def test_password_verification(self): # The two new passwords do not match. - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'new_password1': 'abc123', - 'new_password2': 'abc', + "new_password1": "abc123", + "new_password2": "abc", } form = SetPasswordForm(user, data) self.assertFalse(form.is_valid()) self.assertEqual( form["new_password2"].errors, - [str(form.error_messages['password_mismatch'])] + [str(form.error_messages["password_mismatch"])], ) - @mock.patch('django.contrib.auth.password_validation.password_changed') + @mock.patch("django.contrib.auth.password_validation.password_changed") def test_success(self, password_changed): - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'new_password1': 'abc123', - 'new_password2': 'abc123', + "new_password1": "abc123", + "new_password2": "abc123", } form = SetPasswordForm(user, data) self.assertTrue(form.is_valid()) @@ -547,51 +607,67 @@ class SetPasswordFormTest(TestDataMixin, TestCase): form.save() self.assertEqual(password_changed.call_count, 1) - @override_settings(AUTH_PASSWORD_VALIDATORS=[ - {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, - {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'OPTIONS': { - 'min_length': 12, - }}, - ]) + @override_settings( + AUTH_PASSWORD_VALIDATORS=[ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + "OPTIONS": { + "min_length": 12, + }, + }, + ] + ) def test_validates_password(self): - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'new_password1': 'testclient', - 'new_password2': 'testclient', + "new_password1": "testclient", + "new_password2": "testclient", } form = SetPasswordForm(user, data) self.assertFalse(form.is_valid()) self.assertEqual(len(form["new_password2"].errors), 2) - self.assertIn('The password is too similar to the username.', form["new_password2"].errors) self.assertIn( - 'This password is too short. It must contain at least 12 characters.', - form["new_password2"].errors + "The password is too similar to the username.", form["new_password2"].errors + ) + self.assertIn( + "This password is too short. It must contain at least 12 characters.", + form["new_password2"].errors, ) def test_password_whitespace_not_stripped(self): - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'new_password1': ' password ', - 'new_password2': ' password ', + "new_password1": " password ", + "new_password2": " password ", } form = SetPasswordForm(user, data) self.assertTrue(form.is_valid()) - self.assertEqual(form.cleaned_data['new_password1'], data['new_password1']) - self.assertEqual(form.cleaned_data['new_password2'], data['new_password2']) - - @override_settings(AUTH_PASSWORD_VALIDATORS=[ - {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, - {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'OPTIONS': { - 'min_length': 12, - }}, - ]) + self.assertEqual(form.cleaned_data["new_password1"], data["new_password1"]) + self.assertEqual(form.cleaned_data["new_password2"], data["new_password2"]) + + @override_settings( + AUTH_PASSWORD_VALIDATORS=[ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + "OPTIONS": { + "min_length": 12, + }, + }, + ] + ) def test_help_text_translation(self): french_help_texts = [ - 'Votre mot de passe ne peut pas trop ressembler à vos autres informations personnelles.', - 'Votre mot de passe doit contenir au minimum 12 caractères.', + "Votre mot de passe ne peut pas trop ressembler à vos autres informations personnelles.", + "Votre mot de passe doit contenir au minimum 12 caractères.", ] form = SetPasswordForm(self.u1) - with translation.override('fr'): + with translation.override("fr"): html = form.as_p() for french_text in french_help_texts: self.assertIn(french_text, html) @@ -599,47 +675,54 @@ class SetPasswordFormTest(TestDataMixin, TestCase): def test_html_autocomplete_attributes(self): form = SetPasswordForm(self.u1) tests = ( - ('new_password1', 'new-password'), - ('new_password2', 'new-password'), + ("new_password1", "new-password"), + ("new_password2", "new-password"), ) for field_name, autocomplete in tests: with self.subTest(field_name=field_name, autocomplete=autocomplete): - self.assertEqual(form.fields[field_name].widget.attrs['autocomplete'], autocomplete) + self.assertEqual( + form.fields[field_name].widget.attrs["autocomplete"], autocomplete + ) class PasswordChangeFormTest(TestDataMixin, TestCase): - def test_incorrect_password(self): - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'old_password': 'test', - 'new_password1': 'abc123', - 'new_password2': 'abc123', + "old_password": "test", + "new_password1": "abc123", + "new_password2": "abc123", } form = PasswordChangeForm(user, data) self.assertFalse(form.is_valid()) - self.assertEqual(form["old_password"].errors, [str(form.error_messages['password_incorrect'])]) + self.assertEqual( + form["old_password"].errors, + [str(form.error_messages["password_incorrect"])], + ) def test_password_verification(self): # The two new passwords do not match. - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'old_password': 'password', - 'new_password1': 'abc123', - 'new_password2': 'abc', + "old_password": "password", + "new_password1": "abc123", + "new_password2": "abc", } form = PasswordChangeForm(user, data) self.assertFalse(form.is_valid()) - self.assertEqual(form["new_password2"].errors, [str(form.error_messages['password_mismatch'])]) + self.assertEqual( + form["new_password2"].errors, + [str(form.error_messages["password_mismatch"])], + ) - @mock.patch('django.contrib.auth.password_validation.password_changed') + @mock.patch("django.contrib.auth.password_validation.password_changed") def test_success(self, password_changed): # The success case. - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'old_password': 'password', - 'new_password1': 'abc123', - 'new_password2': 'abc123', + "old_password": "password", + "new_password1": "abc123", + "new_password2": "abc123", } form = PasswordChangeForm(user, data) self.assertTrue(form.is_valid()) @@ -650,37 +733,45 @@ class PasswordChangeFormTest(TestDataMixin, TestCase): def test_field_order(self): # Regression test - check the order of fields: - user = User.objects.get(username='testclient') - self.assertEqual(list(PasswordChangeForm(user, {}).fields), ['old_password', 'new_password1', 'new_password2']) + user = User.objects.get(username="testclient") + self.assertEqual( + list(PasswordChangeForm(user, {}).fields), + ["old_password", "new_password1", "new_password2"], + ) def test_password_whitespace_not_stripped(self): - user = User.objects.get(username='testclient') - user.set_password(' oldpassword ') + user = User.objects.get(username="testclient") + user.set_password(" oldpassword ") data = { - 'old_password': ' oldpassword ', - 'new_password1': ' pass ', - 'new_password2': ' pass ', + "old_password": " oldpassword ", + "new_password1": " pass ", + "new_password2": " pass ", } form = PasswordChangeForm(user, data) self.assertTrue(form.is_valid()) - self.assertEqual(form.cleaned_data['old_password'], data['old_password']) - self.assertEqual(form.cleaned_data['new_password1'], data['new_password1']) - self.assertEqual(form.cleaned_data['new_password2'], data['new_password2']) + self.assertEqual(form.cleaned_data["old_password"], data["old_password"]) + self.assertEqual(form.cleaned_data["new_password1"], data["new_password1"]) + self.assertEqual(form.cleaned_data["new_password2"], data["new_password2"]) def test_html_autocomplete_attributes(self): - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") form = PasswordChangeForm(user) - self.assertEqual(form.fields['old_password'].widget.attrs['autocomplete'], 'current-password') + self.assertEqual( + form.fields["old_password"].widget.attrs["autocomplete"], "current-password" + ) class UserChangeFormTest(TestDataMixin, TestCase): - def test_username_validity(self): - user = User.objects.get(username='testclient') - data = {'username': 'not valid'} + user = User.objects.get(username="testclient") + data = {"username": "not valid"} form = UserChangeForm(data, instance=user) self.assertFalse(form.is_valid()) - validator = next(v for v in User._meta.get_field('username').validators if v.code == 'invalid') + validator = next( + v + for v in User._meta.get_field("username").validators + if v.code == "invalid" + ) self.assertEqual(form["username"].errors, [str(validator.message)]) def test_bug_14242(self): @@ -690,40 +781,46 @@ class UserChangeFormTest(TestDataMixin, TestCase): class MyUserForm(UserChangeForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['groups'].help_text = 'These groups give users different permissions' + self.fields[ + "groups" + ].help_text = "These groups give users different permissions" class Meta(UserChangeForm.Meta): - fields = ('groups',) + fields = ("groups",) # Just check we can create it MyUserForm({}) def test_unusable_password(self): - user = User.objects.get(username='empty_password') + user = User.objects.get(username="empty_password") user.set_unusable_password() user.save() form = UserChangeForm(instance=user) self.assertIn(_("No password set."), form.as_table()) def test_bug_17944_empty_password(self): - user = User.objects.get(username='empty_password') + user = User.objects.get(username="empty_password") form = UserChangeForm(instance=user) self.assertIn(_("No password set."), form.as_table()) def test_bug_17944_unmanageable_password(self): - user = User.objects.get(username='unmanageable_password') + user = User.objects.get(username="unmanageable_password") form = UserChangeForm(instance=user) - self.assertIn(_("Invalid password format or unknown hashing algorithm."), form.as_table()) + self.assertIn( + _("Invalid password format or unknown hashing algorithm."), form.as_table() + ) def test_bug_17944_unknown_password_algorithm(self): - user = User.objects.get(username='unknown_password') + user = User.objects.get(username="unknown_password") form = UserChangeForm(instance=user) - self.assertIn(_("Invalid password format or unknown hashing algorithm."), form.as_table()) + self.assertIn( + _("Invalid password format or unknown hashing algorithm."), form.as_table() + ) def test_bug_19133(self): "The change form does not return the password value" # Use the form to construct the POST data - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") form_for_data = UserChangeForm(instance=user) post_data = form_for_data.initial @@ -731,38 +828,42 @@ class UserChangeFormTest(TestDataMixin, TestCase): # posted here should be ignored; the form will be # valid, and give back the 'initial' value for the # password field. - post_data['password'] = 'new password' + post_data["password"] = "new password" form = UserChangeForm(instance=user, data=post_data) self.assertTrue(form.is_valid()) # original hashed password contains $ - self.assertIn('$', form.cleaned_data['password']) + self.assertIn("$", form.cleaned_data["password"]) def test_bug_19349_bound_password_field(self): - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") form = UserChangeForm(data={}, instance=user) # When rendering the bound password field, # ReadOnlyPasswordHashWidget needs the initial # value to render correctly - self.assertEqual(form.initial['password'], form['password'].value()) + self.assertEqual(form.initial["password"], form["password"].value()) def test_custom_form(self): class CustomUserChangeForm(UserChangeForm): class Meta(UserChangeForm.Meta): model = ExtensionUser - fields = ('username', 'password', 'date_of_birth',) + fields = ( + "username", + "password", + "date_of_birth", + ) - user = User.objects.get(username='testclient') + user = User.objects.get(username="testclient") data = { - 'username': 'testclient', - 'password': 'testclient', - 'date_of_birth': '1998-02-24', + "username": "testclient", + "password": "testclient", + "date_of_birth": "1998-02-24", } form = CustomUserChangeForm(data, instance=user) self.assertTrue(form.is_valid()) form.save() - self.assertEqual(form.cleaned_data['username'], 'testclient') - self.assertEqual(form.cleaned_data['date_of_birth'], datetime.date(1998, 2, 24)) + self.assertEqual(form.cleaned_data["username"], "testclient") + self.assertEqual(form.cleaned_data["date_of_birth"], datetime.date(1998, 2, 24)) def test_password_excluded(self): class UserChangeFormWithoutPassword(UserChangeForm): @@ -770,19 +871,20 @@ class UserChangeFormTest(TestDataMixin, TestCase): class Meta: model = User - exclude = ['password'] + exclude = ["password"] form = UserChangeFormWithoutPassword() - self.assertNotIn('password', form.fields) + self.assertNotIn("password", form.fields) def test_username_field_autocapitalize_none(self): form = UserChangeForm() - self.assertEqual(form.fields['username'].widget.attrs.get('autocapitalize'), 'none') + self.assertEqual( + form.fields["username"].widget.attrs.get("autocapitalize"), "none" + ) @override_settings(TEMPLATES=AUTH_TEMPLATES) class PasswordResetFormTest(TestDataMixin, TestCase): - @classmethod def setUpClass(cls): super().setUpClass() @@ -794,48 +896,48 @@ class PasswordResetFormTest(TestDataMixin, TestCase): """ Create a user and return a tuple (user_object, username, email). """ - username = 'jsmith' - email = 'jsmith@example.com' - user = User.objects.create_user(username, email, 'test123') + username = "jsmith" + email = "jsmith@example.com" + user = User.objects.create_user(username, email, "test123") return (user, username, email) def test_invalid_email(self): - data = {'email': 'not valid'} + data = {"email": "not valid"} form = PasswordResetForm(data) self.assertFalse(form.is_valid()) - self.assertEqual(form['email'].errors, [_('Enter a valid email address.')]) + self.assertEqual(form["email"].errors, [_("Enter a valid email address.")]) def test_user_email_unicode_collision(self): - User.objects.create_user('mike123', 'mike@example.org', 'test123') - User.objects.create_user('mike456', 'mıke@example.org', 'test123') - data = {'email': 'mıke@example.org'} + User.objects.create_user("mike123", "mike@example.org", "test123") + User.objects.create_user("mike456", "mıke@example.org", "test123") + data = {"email": "mıke@example.org"} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) form.save() self.assertEqual(len(mail.outbox), 1) - self.assertEqual(mail.outbox[0].to, ['mıke@example.org']) + self.assertEqual(mail.outbox[0].to, ["mıke@example.org"]) def test_user_email_domain_unicode_collision(self): - User.objects.create_user('mike123', 'mike@ixample.org', 'test123') - User.objects.create_user('mike456', 'mike@ıxample.org', 'test123') - data = {'email': 'mike@ıxample.org'} + User.objects.create_user("mike123", "mike@ixample.org", "test123") + User.objects.create_user("mike456", "mike@ıxample.org", "test123") + data = {"email": "mike@ıxample.org"} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) form.save() self.assertEqual(len(mail.outbox), 1) - self.assertEqual(mail.outbox[0].to, ['mike@ıxample.org']) + self.assertEqual(mail.outbox[0].to, ["mike@ıxample.org"]) def test_user_email_unicode_collision_nonexistent(self): - User.objects.create_user('mike123', 'mike@example.org', 'test123') - data = {'email': 'mıke@example.org'} + User.objects.create_user("mike123", "mike@example.org", "test123") + data = {"email": "mıke@example.org"} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) form.save() self.assertEqual(len(mail.outbox), 0) def test_user_email_domain_unicode_collision_nonexistent(self): - User.objects.create_user('mike123', 'mike@ixample.org', 'test123') - data = {'email': 'mike@ıxample.org'} + User.objects.create_user("mike123", "mike@ixample.org", "test123") + data = {"email": "mike@ıxample.org"} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) form.save() @@ -846,44 +948,51 @@ class PasswordResetFormTest(TestDataMixin, TestCase): Test nonexistent email address. This should not fail because it would expose information about registered users. """ - data = {'email': 'foo@bar.com'} + data = {"email": "foo@bar.com"} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) self.assertEqual(len(mail.outbox), 0) def test_cleaned_data(self): (user, username, email) = self.create_dummy_user() - data = {'email': email} + data = {"email": email} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) - form.save(domain_override='example.com') - self.assertEqual(form.cleaned_data['email'], email) + form.save(domain_override="example.com") + self.assertEqual(form.cleaned_data["email"], email) self.assertEqual(len(mail.outbox), 1) def test_custom_email_subject(self): - data = {'email': 'testclient@example.com'} + data = {"email": "testclient@example.com"} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) # Since we're not providing a request object, we must provide a # domain_override to prevent the save operation from failing in the # potential case where contrib.sites is not installed. Refs #16412. - form.save(domain_override='example.com') + form.save(domain_override="example.com") self.assertEqual(len(mail.outbox), 1) - self.assertEqual(mail.outbox[0].subject, 'Custom password reset on example.com') + self.assertEqual(mail.outbox[0].subject, "Custom password reset on example.com") def test_custom_email_constructor(self): - data = {'email': 'testclient@example.com'} + data = {"email": "testclient@example.com"} class CustomEmailPasswordResetForm(PasswordResetForm): - def send_mail(self, subject_template_name, email_template_name, - context, from_email, to_email, - html_email_template_name=None): + def send_mail( + self, + subject_template_name, + email_template_name, + context, + from_email, + to_email, + html_email_template_name=None, + ): EmailMultiAlternatives( "Forgot your password?", "Sorry to hear you forgot your password.", - None, [to_email], - ['site_monitor@example.com'], - headers={'Reply-To': 'webmaster@example.com'}, + None, + [to_email], + ["site_monitor@example.com"], + headers={"Reply-To": "webmaster@example.com"}, alternatives=[ ("Really sorry to hear you forgot your password.", "text/html") ], @@ -894,10 +1003,10 @@ class PasswordResetFormTest(TestDataMixin, TestCase): # Since we're not providing a request object, we must provide a # domain_override to prevent the save operation from failing in the # potential case where contrib.sites is not installed. Refs #16412. - form.save(domain_override='example.com') + form.save(domain_override="example.com") self.assertEqual(len(mail.outbox), 1) - self.assertEqual(mail.outbox[0].subject, 'Forgot your password?') - self.assertEqual(mail.outbox[0].bcc, ['site_monitor@example.com']) + self.assertEqual(mail.outbox[0].subject, "Forgot your password?") + self.assertEqual(mail.outbox[0].bcc, ["site_monitor@example.com"]) self.assertEqual(mail.outbox[0].content_subtype, "plain") def test_preserve_username_case(self): @@ -905,10 +1014,10 @@ class PasswordResetFormTest(TestDataMixin, TestCase): Preserve the case of the user name (before the @ in the email address) when creating a user (#5605). """ - user = User.objects.create_user('forms_test2', 'tesT@EXAMple.com', 'test') - self.assertEqual(user.email, 'tesT@example.com') - user = User.objects.create_user('forms_test3', 'tesT', 'test') - self.assertEqual(user.email, 'tesT') + user = User.objects.create_user("forms_test2", "tesT@EXAMple.com", "test") + self.assertEqual(user.email, "tesT@example.com") + user = User.objects.create_user("forms_test3", "tesT", "test") + self.assertEqual(user.email, "tesT") def test_inactive_user(self): """ @@ -917,13 +1026,13 @@ class PasswordResetFormTest(TestDataMixin, TestCase): (user, username, email) = self.create_dummy_user() user.is_active = False user.save() - form = PasswordResetForm({'email': email}) + form = PasswordResetForm({"email": email}) self.assertTrue(form.is_valid()) form.save() self.assertEqual(len(mail.outbox), 0) def test_unusable_password(self): - user = User.objects.create_user('testuser', 'test@example.com', 'test') + user = User.objects.create_user("testuser", "test@example.com", "test") data = {"email": "test@example.com"} form = PasswordResetForm(data) self.assertTrue(form.is_valid()) @@ -948,11 +1057,13 @@ class PasswordResetFormTest(TestDataMixin, TestCase): self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0].message() self.assertFalse(message.is_multipart()) - self.assertEqual(message.get_content_type(), 'text/plain') - self.assertEqual(message.get('subject'), 'Custom password reset on example.com') + self.assertEqual(message.get_content_type(), "text/plain") + self.assertEqual(message.get("subject"), "Custom password reset on example.com") self.assertEqual(len(mail.outbox[0].alternatives), 0) - self.assertEqual(message.get_all('to'), [email]) - self.assertTrue(re.match(r'^http://example.com/reset/[\w+/-]', message.get_payload())) + self.assertEqual(message.get_all("to"), [email]) + self.assertTrue( + re.match(r"^http://example.com/reset/[\w+/-]", message.get_payload()) + ) def test_save_html_email_template_name(self): """ @@ -964,53 +1075,63 @@ class PasswordResetFormTest(TestDataMixin, TestCase): (user, username, email) = self.create_dummy_user() form = PasswordResetForm({"email": email}) self.assertTrue(form.is_valid()) - form.save(html_email_template_name='registration/html_password_reset_email.html') + form.save( + html_email_template_name="registration/html_password_reset_email.html" + ) self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox[0].alternatives), 1) message = mail.outbox[0].message() - self.assertEqual(message.get('subject'), 'Custom password reset on example.com') + self.assertEqual(message.get("subject"), "Custom password reset on example.com") self.assertEqual(len(message.get_payload()), 2) self.assertTrue(message.is_multipart()) - self.assertEqual(message.get_payload(0).get_content_type(), 'text/plain') - self.assertEqual(message.get_payload(1).get_content_type(), 'text/html') - self.assertEqual(message.get_all('to'), [email]) - self.assertTrue(re.match(r'^http://example.com/reset/[\w/-]+', message.get_payload(0).get_payload())) - self.assertTrue(re.match( - r'^Link$', - message.get_payload(1).get_payload() - )) - - @override_settings(AUTH_USER_MODEL='auth_tests.CustomEmailField') + self.assertEqual(message.get_payload(0).get_content_type(), "text/plain") + self.assertEqual(message.get_payload(1).get_content_type(), "text/html") + self.assertEqual(message.get_all("to"), [email]) + self.assertTrue( + re.match( + r"^http://example.com/reset/[\w/-]+", + message.get_payload(0).get_payload(), + ) + ) + self.assertTrue( + re.match( + r'^Link$', + message.get_payload(1).get_payload(), + ) + ) + + @override_settings(AUTH_USER_MODEL="auth_tests.CustomEmailField") def test_custom_email_field(self): - email = 'test@mail.com' - CustomEmailField.objects.create_user('test name', 'test password', email) - form = PasswordResetForm({'email': email}) + email = "test@mail.com" + CustomEmailField.objects.create_user("test name", "test password", email) + form = PasswordResetForm({"email": email}) self.assertTrue(form.is_valid()) form.save() - self.assertEqual(form.cleaned_data['email'], email) + self.assertEqual(form.cleaned_data["email"], email) self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].to, [email]) def test_html_autocomplete_attributes(self): form = PasswordResetForm() - self.assertEqual(form.fields['email'].widget.attrs['autocomplete'], 'email') + self.assertEqual(form.fields["email"].widget.attrs["autocomplete"], "email") class ReadOnlyPasswordHashTest(SimpleTestCase): - def test_bug_19349_render_with_none_value(self): # Rendering the widget with value set to None # mustn't raise an exception. widget = ReadOnlyPasswordHashWidget() - html = widget.render(name='password', value=None, attrs={}) + html = widget.render(name="password", value=None, attrs={}) self.assertIn(_("No password set."), html) - @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.PBKDF2PasswordHasher']) + @override_settings( + PASSWORD_HASHERS=["django.contrib.auth.hashers.PBKDF2PasswordHasher"] + ) def test_render(self): widget = ReadOnlyPasswordHashWidget() - value = 'pbkdf2_sha256$100000$a6Pucb1qSFcD$WmCkn9Hqidj48NVe5x0FEM6A9YiOqQcl/83m2Z5udm0=' + value = "pbkdf2_sha256$100000$a6Pucb1qSFcD$WmCkn9Hqidj48NVe5x0FEM6A9YiOqQcl/83m2Z5udm0=" self.assertHTMLEqual( - widget.render('name', value, {'id': 'id_password'}), + widget.render("name", value, {"id": "id_password"}), """
algorithm: pbkdf2_sha256 @@ -1018,35 +1139,35 @@ class ReadOnlyPasswordHashTest(SimpleTestCase): salt: a6Pucb****** hash: WmCkn9**************************************
- """ + """, ) def test_readonly_field_has_changed(self): field = ReadOnlyPasswordHashField() self.assertIs(field.disabled, True) - self.assertFalse(field.has_changed('aaa', 'bbb')) + self.assertFalse(field.has_changed("aaa", "bbb")) def test_label(self): """ ReadOnlyPasswordHashWidget doesn't contain a for attribute in the