diff options
| author | Tim Graham <timograham@gmail.com> | 2015-02-10 09:17:08 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-02-11 10:19:22 -0500 |
| commit | 2d7aca3da0a46c09e9c70ebdb56ed340691a999f (patch) | |
| tree | ac7c041d73e922d8e83a1944d56a27138875fe8e /django | |
| parent | 8192a164defa24d75672e6b10cec650489b8c748 (diff) | |
Moved contrib.auth tests out of contrib.
Diffstat (limited to 'django')
42 files changed, 0 insertions, 4539 deletions
diff --git a/django/contrib/auth/fixtures/authtestdata.json b/django/contrib/auth/fixtures/authtestdata.json deleted file mode 100644 index 931328899b..0000000000 --- a/django/contrib/auth/fixtures/authtestdata.json +++ /dev/null @@ -1,110 +0,0 @@ -[ - { - "pk": "1", - "model": "auth.user", - "fields": { - "username": "testclient", - "first_name": "Test", - "last_name": "Client", - "is_active": true, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "2", - "model": "auth.user", - "fields": { - "username": "inactive", - "first_name": "Inactive", - "last_name": "User", - "is_active": false, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "testclient2@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "3", - "model": "auth.user", - "fields": { - "username": "staff", - "first_name": "Staff", - "last_name": "Member", - "is_active": true, - "is_superuser": false, - "is_staff": true, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "email": "staffmember@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "4", - "model": "auth.user", - "fields": { - "username": "empty_password", - "first_name": "Empty", - "last_name": "Password", - "is_active": true, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "", - "email": "empty_password@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "5", - "model": "auth.user", - "fields": { - "username": "unmanageable_password", - "first_name": "Unmanageable", - "last_name": "Password", - "is_active": true, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "$", - "email": "unmanageable_password@example.com", - "date_joined": "2006-12-17 07:03:31" - } - }, - { - "pk": "6", - "model": "auth.user", - "fields": { - "username": "unknown_password", - "first_name": "Unknown", - "last_name": "Password", - "is_active": true, - "is_superuser": false, - "is_staff": false, - "last_login": "2006-12-17 07:03:31", - "groups": [], - "user_permissions": [], - "password": "foo$bar", - "email": "unknown_password@example.com", - "date_joined": "2006-12-17 07:03:31" - } - } -] diff --git a/django/contrib/auth/fixtures/context-processors-users.xml b/django/contrib/auth/fixtures/context-processors-users.xml deleted file mode 100644 index aba8f4aace..0000000000 --- a/django/contrib/auth/fixtures/context-processors-users.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<django-objects version="1.0"> - <object pk="100" model="auth.user"> - <field type="CharField" name="username">super</field> - <field type="CharField" name="first_name">Super</field> - <field type="CharField" name="last_name">User</field> - <field type="CharField" name="email">super@example.com</field> - <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> - <field type="BooleanField" name="is_staff">True</field> - <field type="BooleanField" name="is_active">True</field> - <field type="BooleanField" name="is_superuser">True</field> - <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> - <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> - <field to="auth.group" name="groups" rel="ManyToManyRel"></field> - <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> - </object> -</django-objects> diff --git a/django/contrib/auth/fixtures/custom_user.json b/django/contrib/auth/fixtures/custom_user.json deleted file mode 100644 index 770bea6541..0000000000 --- a/django/contrib/auth/fixtures/custom_user.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "pk": "1", - "model": "auth.customuser", - "fields": { - "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", - "last_login": "2006-12-17 07:03:31", - "email": "staffmember@example.com", - "is_active": true, - "is_admin": false, - "date_of_birth": "1976-11-08" - } - } -]
\ No newline at end of file diff --git a/django/contrib/auth/fixtures/natural.json b/django/contrib/auth/fixtures/natural.json deleted file mode 100644 index 7811c7a548..0000000000 --- a/django/contrib/auth/fixtures/natural.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "pk": 1, - "model": "auth.group", - "fields": { - "name": "my_group", - "permissions": [] - } - }, - { - "pk": 1, - "model": "auth.user", - "fields": { - "username": "my_username", - "first_name": "", - "last_name": "", - "is_active": true, - "is_superuser": true, - "is_staff": true, - "last_login": "2012-01-13 00:14:00", - "groups": [ - [ - "my_group" - ] - ], - "user_permissions": [], - "password": "pbkdf2_sha256$10000$LUyhxJjuLwXF$f6Zbpnx1L5dPze8m0itBaHMDyZ/n6JyhuavQy2RrBIM=", - "email": "email@example.com", - "date_joined": "2012-01-13 00:14:00" - } - } -] diff --git a/django/contrib/auth/fixtures/regular.json b/django/contrib/auth/fixtures/regular.json deleted file mode 100644 index b9f2680766..0000000000 --- a/django/contrib/auth/fixtures/regular.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "pk": 1, - "model": "auth.group", - "fields": { - "name": "my_group", - "permissions": [] - } - }, - { - "pk": 1, - "model": "auth.user", - "fields": { - "username": "my_username", - "first_name": "", - "last_name": "", - "is_active": true, - "is_superuser": true, - "is_staff": true, - "last_login": "2012-01-13 00:14:00", - "groups": [ - 1 - ], - "user_permissions": [], - "password": "pbkdf2_sha256$10000$LUyhxJjuLwXF$f6Zbpnx1L5dPze8m0itBaHMDyZ/n6JyhuavQy2RrBIM=", - "email": "email@example.com", - "date_joined": "2012-01-13 00:14:00" - } - } -] diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py index 2c308642e5..e69de29bb2 100644 --- a/django/contrib/auth/tests/__init__.py +++ b/django/contrib/auth/tests/__init__.py @@ -1 +0,0 @@ -# The password for the fixture data users is 'password' diff --git a/django/contrib/auth/tests/backend_alias.py b/django/contrib/auth/tests/backend_alias.py deleted file mode 100644 index 7314bac4ee..0000000000 --- a/django/contrib/auth/tests/backend_alias.py +++ /dev/null @@ -1,4 +0,0 @@ -# For testing that auth backends can be referenced using a convenience import -from django.contrib.auth.tests.test_auth_backends import ImportedModelBackend - -__all__ = ['ImportedModelBackend'] diff --git a/django/contrib/auth/tests/settings.py b/django/contrib/auth/tests/settings.py deleted file mode 100644 index 7da6144d4b..0000000000 --- a/django/contrib/auth/tests/settings.py +++ /dev/null @@ -1,20 +0,0 @@ -import os - -from django.utils._os import upath - -AUTH_MIDDLEWARE_CLASSES = [ - '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(upath(__file__)), 'templates')], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, -}] diff --git a/django/contrib/auth/tests/templates/context_processors/auth_attrs_access.html b/django/contrib/auth/tests/templates/context_processors/auth_attrs_access.html deleted file mode 100644 index b5c65db28d..0000000000 --- a/django/contrib/auth/tests/templates/context_processors/auth_attrs_access.html +++ /dev/null @@ -1 +0,0 @@ -{{ user }} diff --git a/django/contrib/auth/tests/templates/context_processors/auth_attrs_messages.html b/django/contrib/auth/tests/templates/context_processors/auth_attrs_messages.html deleted file mode 100644 index 7b7e448ad2..0000000000 --- a/django/contrib/auth/tests/templates/context_processors/auth_attrs_messages.html +++ /dev/null @@ -1 +0,0 @@ -{% for m in messages %}{{ m }}{% endfor %} diff --git a/django/contrib/auth/tests/templates/context_processors/auth_attrs_no_access.html b/django/contrib/auth/tests/templates/context_processors/auth_attrs_no_access.html deleted file mode 100644 index 8b13789179..0000000000 --- a/django/contrib/auth/tests/templates/context_processors/auth_attrs_no_access.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/django/contrib/auth/tests/templates/context_processors/auth_attrs_perm_in_perms.html b/django/contrib/auth/tests/templates/context_processors/auth_attrs_perm_in_perms.html deleted file mode 100644 index 3a18cd7405..0000000000 --- a/django/contrib/auth/tests/templates/context_processors/auth_attrs_perm_in_perms.html +++ /dev/null @@ -1,4 +0,0 @@ -{% if 'auth' in perms %}Has auth permissions{% endif %} -{% if 'auth.add_permission' in perms %}Has auth.add_permission permissions{% endif %} -{% if 'nonexisting' in perms %}nonexisting perm found{% endif %} -{% if 'auth.nonexisting' in perms %}auth.nonexisting perm found{% endif %} diff --git a/django/contrib/auth/tests/templates/context_processors/auth_attrs_perms.html b/django/contrib/auth/tests/templates/context_processors/auth_attrs_perms.html deleted file mode 100644 index 6f441afc10..0000000000 --- a/django/contrib/auth/tests/templates/context_processors/auth_attrs_perms.html +++ /dev/null @@ -1,4 +0,0 @@ -{% if perms.auth %}Has auth permissions{% endif %} -{% if perms.auth.add_permission %}Has auth.add_permission permissions{% endif %} -{% if perms.nonexisting %}nonexisting perm found{% endif %} -{% if perms.auth.nonexisting in perms %}auth.nonexisting perm found{% endif %} diff --git a/django/contrib/auth/tests/templates/context_processors/auth_attrs_test_access.html b/django/contrib/auth/tests/templates/context_processors/auth_attrs_test_access.html deleted file mode 100644 index a28ff937f8..0000000000 --- a/django/contrib/auth/tests/templates/context_processors/auth_attrs_test_access.html +++ /dev/null @@ -1 +0,0 @@ -{% if session_accessed %}Session accessed{% else %}Session not accessed{% endif %} diff --git a/django/contrib/auth/tests/templates/context_processors/auth_attrs_user.html b/django/contrib/auth/tests/templates/context_processors/auth_attrs_user.html deleted file mode 100644 index dc4c6b17c1..0000000000 --- a/django/contrib/auth/tests/templates/context_processors/auth_attrs_user.html +++ /dev/null @@ -1,4 +0,0 @@ -unicode: {{ user }} -id: {{ user.pk }} -username: {{ user.username }} -url: {% url 'userpage' user %} diff --git a/django/contrib/auth/tests/templates/registration/html_password_reset_email.html b/django/contrib/auth/tests/templates/registration/html_password_reset_email.html deleted file mode 100644 index 1ebb550048..0000000000 --- a/django/contrib/auth/tests/templates/registration/html_password_reset_email.html +++ /dev/null @@ -1 +0,0 @@ -<html><a href="{{ protocol }}://{{ domain }}/reset/{{ uid }}/{{ token }}/">Link</a></html> diff --git a/django/contrib/auth/tests/templates/registration/logged_out.html b/django/contrib/auth/tests/templates/registration/logged_out.html deleted file mode 100644 index 0a06d9554a..0000000000 --- a/django/contrib/auth/tests/templates/registration/logged_out.html +++ /dev/null @@ -1 +0,0 @@ -Logged out diff --git a/django/contrib/auth/tests/templates/registration/login.html b/django/contrib/auth/tests/templates/registration/login.html deleted file mode 100644 index 5dd03cba72..0000000000 --- a/django/contrib/auth/tests/templates/registration/login.html +++ /dev/null @@ -1 +0,0 @@ -{{ form.as_ul }} diff --git a/django/contrib/auth/tests/templates/registration/password_change_form.html b/django/contrib/auth/tests/templates/registration/password_change_form.html deleted file mode 100644 index f9a859ae9f..0000000000 --- a/django/contrib/auth/tests/templates/registration/password_change_form.html +++ /dev/null @@ -1 +0,0 @@ -{{ form }} diff --git a/django/contrib/auth/tests/templates/registration/password_reset_complete.html b/django/contrib/auth/tests/templates/registration/password_reset_complete.html deleted file mode 100644 index b6569b29d4..0000000000 --- a/django/contrib/auth/tests/templates/registration/password_reset_complete.html +++ /dev/null @@ -1 +0,0 @@ -Password reset successfully diff --git a/django/contrib/auth/tests/templates/registration/password_reset_confirm.html b/django/contrib/auth/tests/templates/registration/password_reset_confirm.html deleted file mode 100644 index 42677d6766..0000000000 --- a/django/contrib/auth/tests/templates/registration/password_reset_confirm.html +++ /dev/null @@ -1,7 +0,0 @@ -Hello, {{ form.user }}. - -{% if validlink %} -Please enter your new password: {{ form }} -{% else %} -The password reset link was invalid -{% endif %} diff --git a/django/contrib/auth/tests/templates/registration/password_reset_done.html b/django/contrib/auth/tests/templates/registration/password_reset_done.html deleted file mode 100644 index 3a764cadf1..0000000000 --- a/django/contrib/auth/tests/templates/registration/password_reset_done.html +++ /dev/null @@ -1 +0,0 @@ -Email sent diff --git a/django/contrib/auth/tests/templates/registration/password_reset_email.html b/django/contrib/auth/tests/templates/registration/password_reset_email.html deleted file mode 100644 index baac2fc2dd..0000000000 --- a/django/contrib/auth/tests/templates/registration/password_reset_email.html +++ /dev/null @@ -1 +0,0 @@ -{{ protocol }}://{{ domain }}/reset/{{ uid }}/{{ token }}/ diff --git a/django/contrib/auth/tests/templates/registration/password_reset_form.html b/django/contrib/auth/tests/templates/registration/password_reset_form.html deleted file mode 100644 index f9a859ae9f..0000000000 --- a/django/contrib/auth/tests/templates/registration/password_reset_form.html +++ /dev/null @@ -1 +0,0 @@ -{{ form }} diff --git a/django/contrib/auth/tests/templates/registration/password_reset_subject.txt b/django/contrib/auth/tests/templates/registration/password_reset_subject.txt deleted file mode 100644 index 904b645c6c..0000000000 --- a/django/contrib/auth/tests/templates/registration/password_reset_subject.txt +++ /dev/null @@ -1 +0,0 @@ -{% autoescape off %}Custom password reset on {{ site_name }}{% endautoescape %}
\ No newline at end of file diff --git a/django/contrib/auth/tests/test_auth_backends.py b/django/contrib/auth/tests/test_auth_backends.py deleted file mode 100644 index 2abdc4d797..0000000000 --- a/django/contrib/auth/tests/test_auth_backends.py +++ /dev/null @@ -1,623 +0,0 @@ -from __future__ import unicode_literals - -from datetime import date - -from django.contrib.auth import BACKEND_SESSION_KEY, authenticate, get_user -from django.contrib.auth.backends import ModelBackend -from django.contrib.auth.hashers import MD5PasswordHasher -from django.contrib.auth.models import AnonymousUser, Group, Permission, User -from django.contrib.auth.tests.custom_user import ( - CustomPermissionsUser, CustomUser, ExtensionUser, -) -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import ImproperlyConfigured, PermissionDenied -from django.http import HttpRequest -from django.test import TestCase, modify_settings, override_settings - - -class CountingMD5PasswordHasher(MD5PasswordHasher): - """Hasher that counts how many times it computes a hash.""" - - calls = 0 - - def encode(self, *args, **kwargs): - type(self).calls += 1 - return super(CountingMD5PasswordHasher, self).encode(*args, **kwargs) - - -class BaseModelBackendTest(object): - """ - A base class for tests that need to validate the ModelBackend - with different User models. Subclasses should define a class - level UserModel attribute, and a create_users() method to - construct two users for test purposes. - """ - backend = 'django.contrib.auth.backends.ModelBackend' - - def setUp(self): - self.patched_settings = modify_settings( - AUTHENTICATION_BACKENDS={'append': self.backend}, - ) - self.patched_settings.enable() - self.create_users() - - def tearDown(self): - self.patched_settings.disable() - # The custom_perms test messes with ContentTypes, which will - # be cached; flush the cache to ensure there are no side effects - # Refs #14975, #14925 - ContentType.objects.clear_cache() - - def test_has_perm(self): - user = self.UserModel._default_manager.get(pk=self.user.pk) - self.assertEqual(user.has_perm('auth.test'), False) - - user.is_staff = True - user.save() - self.assertEqual(user.has_perm('auth.test'), False) - - user.is_superuser = True - user.save() - self.assertEqual(user.has_perm('auth.test'), True) - - user.is_staff = True - user.is_superuser = True - user.is_active = False - user.save() - self.assertEqual(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') - 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'}, True) - self.assertEqual(user.get_group_permissions(), set()) - self.assertEqual(user.has_module_perms('Group'), False) - self.assertEqual(user.has_module_perms('auth'), True) - - 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') - user.user_permissions.add(perm) - user = self.UserModel._default_manager.get(pk=self.user.pk) - self.assertEqual(user.get_all_permissions(), {'auth.test2', 'auth.test', 'auth.test3'}) - self.assertEqual(user.has_perm('test'), False) - self.assertEqual(user.has_perm('auth.test'), True) - self.assertEqual(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') - group.permissions.add(perm) - user.groups.add(group) - user = self.UserModel._default_manager.get(pk=self.user.pk) - exp = {'auth.test2', 'auth.test', 'auth.test3', 'auth.test_group'} - self.assertEqual(user.get_all_permissions(), exp) - self.assertEqual(user.get_group_permissions(), {'auth.test_group'}) - self.assertEqual(user.has_perms(['auth.test3', 'auth.test_group']), True) - - user = AnonymousUser() - self.assertEqual(user.has_perm('test'), False) - self.assertEqual(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') - user.user_permissions.add(perm) - - self.assertEqual(user.has_perm('auth.test', 'object'), False) - self.assertEqual(user.get_all_permissions('object'), set()) - self.assertEqual(user.has_perm('auth.test'), True) - self.assertEqual(user.get_all_permissions(), {'auth.test'}) - - def test_anonymous_has_no_permissions(self): - """ - #17903 -- Anonymous users shouldn't have permissions in - ModelBackend.get_(all|user|group)_permissions(). - """ - backend = ModelBackend() - - 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.user_permissions.add(user_perm) - - 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', 'auth.test_group'}) - self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'}) - - user.is_anonymous = lambda: True - - self.assertEqual(backend.get_all_permissions(user), set()) - self.assertEqual(backend.get_user_permissions(user), set()) - self.assertEqual(backend.get_group_permissions(user), set()) - - def test_inactive_has_no_permissions(self): - """ - #17903 -- Inactive users shouldn't have permissions in - ModelBackend.get_(all|user|group)_permissions(). - """ - backend = ModelBackend() - - 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.user_permissions.add(user_perm) - - 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', 'auth.test_group'}) - self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'}) - - user.is_active = False - user.save() - - self.assertEqual(backend.get_all_permissions(user), set()) - self.assertEqual(backend.get_user_permissions(user), set()) - self.assertEqual(backend.get_group_permissions(user), set()) - - def test_get_all_superuser_permissions(self): - """A superuser has all permissions. Refs #14795.""" - 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=['django.contrib.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.save() - - CountingMD5PasswordHasher.calls = 0 - username = getattr(self.user, self.UserModel.USERNAME_FIELD) - authenticate(username=username, password='test') - self.assertEqual(CountingMD5PasswordHasher.calls, 1) - - CountingMD5PasswordHasher.calls = 0 - authenticate(username='no_such_user', password='test') - self.assertEqual(CountingMD5PasswordHasher.calls, 1) - - -@skipIfCustomUser -class ModelBackendTest(BaseModelBackendTest, TestCase): - """ - Tests for the ModelBackend using the default User model. - """ - UserModel = User - - def create_users(self): - self.user = User.objects.create_user( - username='test', - email='test@example.com', - password='test', - ) - self.superuser = User.objects.create_superuser( - username='test2', - email='test2@example.com', - password='test', - ) - - -@override_settings(AUTH_USER_MODEL='auth.ExtensionUser') -class ExtensionUserModelBackendTest(BaseModelBackendTest, TestCase): - """ - Tests for the ModelBackend using the custom ExtensionUser model. - - This isn't a perfect test, because both the User and ExtensionUser are - synchronized to the database, which wouldn't ordinary happen in - production. As a result, it doesn't catch errors caused by the non- - existence of the User table. - - The specific problem is queries on .filter(groups__user) et al, which - makes an implicit assumption that the user model is called 'User'. In - production, the auth.User table won't exist, so the requested join - won't exist either; in testing, the auth.User *does* exist, and - so does the join. However, the join table won't contain any useful - data; for testing, we check that the data we expect actually does exist. - """ - - UserModel = ExtensionUser - - 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) - ) - self.superuser = ExtensionUser._default_manager.create_superuser( - username='test2', - email='test2@example.com', - password='test', - date_of_birth=date(1976, 11, 8) - ) - - -@override_settings(AUTH_USER_MODEL='auth.CustomPermissionsUser') -class CustomPermissionsUserModelBackendTest(BaseModelBackendTest, TestCase): - """ - Tests for the ModelBackend using the CustomPermissionsUser model. - - As with the ExtensionUser test, this isn't a perfect test, because both - the User and CustomPermissionsUser are synchronized to the database, - which wouldn't ordinary happen in production. - """ - - UserModel = CustomPermissionsUser - - def create_users(self): - self.user = CustomPermissionsUser._default_manager.create_user( - 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) - ) - - -@override_settings(AUTH_USER_MODEL='auth.CustomUser') -class CustomUserModelBackendAuthenticateTest(TestCase): - """ - Tests that the model backend can accept a credentials kwarg labeled with - custom user model's USERNAME_FIELD. - """ - - def test_authenticate(self): - test_user = CustomUser._default_manager.create_user( - email='test@example.com', - password='test', - date_of_birth=date(2006, 4, 25) - ) - authenticated_user = authenticate(email='test@example.com', password='test') - self.assertEqual(test_user, authenticated_user) - - -class TestObj(object): - pass - - -class SimpleRowlevelBackend(object): - def has_perm(self, user, perm, obj=None): - if not obj: - return # We only support row level perms - - if isinstance(obj, TestObj): - if user.username == 'test2': - return True - elif user.is_anonymous() and perm == 'anon': - return True - elif not user.is_active and perm == 'inactive': - return True - return False - - def has_module_perms(self, user, app_label): - if not user.is_anonymous() and not user.is_active: - return False - return 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'] - - if user.is_anonymous(): - return ['anon'] - if user.username == 'test2': - return ['simple', 'advanced'] - else: - 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'] - - if 'test_group' in [group.name for group in user.groups.all()]: - return ['group_perm'] - else: - return ['none'] - - -@skipIfCustomUser -@modify_settings(AUTHENTICATION_BACKENDS={ - 'append': 'django.contrib.auth.tests.test_auth_backends.SimpleRowlevelBackend', -}) -class RowlevelBackendTest(TestCase): - """ - Tests for auth backend that supports object level permissions - """ - - def setUp(self): - self.user1 = User.objects.create_user('test', 'test@example.com', 'test') - self.user2 = User.objects.create_user('test2', 'test2@example.com', 'test') - self.user3 = User.objects.create_user('test3', 'test3@example.com', 'test') - - def tearDown(self): - # The get_group_permissions test messes with ContentTypes, which will - # be cached; flush the cache to ensure there are no side effects - # Refs #14975, #14925 - ContentType.objects.clear_cache() - - def test_has_perm(self): - self.assertEqual(self.user1.has_perm('perm', TestObj()), False) - self.assertEqual(self.user2.has_perm('perm', TestObj()), True) - self.assertEqual(self.user2.has_perm('perm'), False) - self.assertEqual(self.user2.has_perms(['simple', 'advanced'], TestObj()), True) - self.assertEqual(self.user3.has_perm('perm', TestObj()), False) - self.assertEqual(self.user3.has_perm('anon', TestObj()), False) - self.assertEqual(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.user2.get_all_permissions(), set()) - - def test_get_group_permissions(self): - group = Group.objects.create(name='test_group') - self.user3.groups.add(group) - self.assertEqual(self.user3.get_group_permissions(TestObj()), {'group_perm'}) - - -@override_settings( - AUTHENTICATION_BACKENDS=['django.contrib.auth.tests.test_auth_backends.SimpleRowlevelBackend'], -) -class AnonymousUserBackendTest(TestCase): - """ - Tests for AnonymousUser delegating to backend. - """ - - def setUp(self): - self.user1 = AnonymousUser() - - def test_has_perm(self): - self.assertEqual(self.user1.has_perm('perm', TestObj()), False) - self.assertEqual(self.user1.has_perm('anon', TestObj()), True) - - def test_has_perms(self): - self.assertEqual(self.user1.has_perms(['anon'], TestObj()), True) - self.assertEqual(self.user1.has_perms(['anon', 'perm'], TestObj()), False) - - def test_has_module_perms(self): - self.assertEqual(self.user1.has_module_perms("app1"), True) - self.assertEqual(self.user1.has_module_perms("app2"), False) - - def test_get_all_permissions(self): - self.assertEqual(self.user1.get_all_permissions(TestObj()), {'anon'}) - - -@skipIfCustomUser -@override_settings(AUTHENTICATION_BACKENDS=[]) -class NoBackendsTest(TestCase): - """ - Tests that an appropriate error is raised if no auth backends are provided. - """ - def setUp(self): - self.user = User.objects.create_user('test', 'test@example.com', 'test') - - def test_raises_exception(self): - self.assertRaises(ImproperlyConfigured, self.user.has_perm, ('perm', TestObj(),)) - - -@skipIfCustomUser -@override_settings(AUTHENTICATION_BACKENDS=['django.contrib.auth.tests.test_auth_backends.SimpleRowlevelBackend']) -class InActiveUserBackendTest(TestCase): - """ - Tests for an inactive user - """ - - def setUp(self): - self.user1 = User.objects.create_user('test', 'test@example.com', 'test') - self.user1.is_active = False - self.user1.save() - - def test_has_perm(self): - self.assertEqual(self.user1.has_perm('perm', TestObj()), False) - self.assertEqual(self.user1.has_perm('inactive', TestObj()), True) - - def test_has_module_perms(self): - self.assertEqual(self.user1.has_module_perms("app1"), False) - self.assertEqual(self.user1.has_module_perms("app2"), False) - - -class PermissionDeniedBackend(object): - """ - Always raises PermissionDenied in `authenticate`, `has_perm` and `has_module_perms`. - """ - supports_object_permissions = True - supports_anonymous_user = True - supports_inactive_user = True - - def authenticate(self, username=None, password=None): - raise PermissionDenied - - def has_perm(self, user_obj, perm, obj=None): - raise PermissionDenied - - def has_module_perms(self, user_obj, app_label): - raise PermissionDenied - - -@skipIfCustomUser -class PermissionDeniedBackendTest(TestCase): - """ - Tests that other backends are not checked once a backend raises PermissionDenied - """ - backend = 'django.contrib.auth.tests.test_auth_backends.PermissionDeniedBackend' - - def setUp(self): - self.user1 = User.objects.create_user('test', 'test@example.com', 'test') - self.user1.save() - - @modify_settings(AUTHENTICATION_BACKENDS={'prepend': backend}) - def test_permission_denied(self): - "user is not authenticated after a backend raises permission denied #2550" - self.assertEqual(authenticate(username='test', password='test'), None) - - @modify_settings(AUTHENTICATION_BACKENDS={'append': backend}) - def test_authenticates(self): - self.assertEqual(authenticate(username='test', password='test'), self.user1) - - @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') - self.user1.user_permissions.add(perm) - - self.assertIs(self.user1.has_perm('auth.test'), False) - self.assertIs(self.user1.has_module_perms('auth'), False) - - @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') - self.user1.user_permissions.add(perm) - - self.assertIs(self.user1.has_perm('auth.test'), True) - self.assertIs(self.user1.has_module_perms('auth'), True) - - -class NewModelBackend(ModelBackend): - pass - - -@skipIfCustomUser -class ChangedBackendSettingsTest(TestCase): - """ - Tests for changes in the settings.AUTHENTICATION_BACKENDS - """ - backend = 'django.contrib.auth.tests.test_auth_backends.NewModelBackend' - - TEST_USERNAME = 'test_user' - TEST_PASSWORD = 'test_password' - TEST_EMAIL = 'test@example.com' - - def setUp(self): - User.objects.create_user(self.TEST_USERNAME, - self.TEST_EMAIL, - self.TEST_PASSWORD) - - @override_settings(AUTHENTICATION_BACKENDS=[backend]) - def test_changed_backend_settings(self): - """ - Tests that removing a backend configured in AUTHENTICATION_BACKENDS - make already logged-in users disconnect. - """ - - # Get a session for the test user - 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']): - # Get the user from the request - user = get_user(request) - - # Assert that the user retrieval is successful and the user is - # anonymous as the backend is not longer available. - self.assertIsNotNone(user) - self.assertTrue(user.is_anonymous()) - - -class TypeErrorBackend(object): - """ - Always raises TypeError. - """ - supports_object_permissions = True - supports_anonymous_user = True - supports_inactive_user = True - - def authenticate(self, username=None, password=None): - raise TypeError - - -@skipIfCustomUser -class TypeErrorBackendTest(TestCase): - """ - Tests that a TypeError within a backend is propagated properly. - - Regression test for ticket #18171 - """ - backend = 'django.contrib.auth.tests.test_auth_backends.TypeErrorBackend' - - def setUp(self): - self.user1 = User.objects.create_user('test', 'test@example.com', 'test') - - @override_settings(AUTHENTICATION_BACKENDS=[backend]) - def test_type_error_raised(self): - self.assertRaises(TypeError, authenticate, username='test', password='test') - - -@skipIfCustomUser -class ImproperlyConfiguredUserModelTest(TestCase): - """ - Tests that an exception from within get_user_model is propagated and doesn't - raise an UnboundLocalError. - - Regression test for ticket #21439 - """ - def setUp(self): - self.user1 = User.objects.create_user('test', 'test@example.com', 'test') - self.client.login( - username='test', - password='test' - ) - - @override_settings(AUTH_USER_MODEL='thismodel.doesntexist') - def test_does_not_shadow_exception(self): - # Prepare a request object - request = HttpRequest() - request.session = self.client.session - - self.assertRaises(ImproperlyConfigured, get_user, request) - - -class ImportedModelBackend(ModelBackend): - pass - - -class ImportedBackendTests(TestCase): - """ - #23925 - The backend path added to the session should be the same - as the one defined in AUTHENTICATION_BACKENDS setting. - """ - - backend = 'django.contrib.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) - self.assertTrue(self.client.login(username=username, password=password)) - request = HttpRequest() - request.session = self.client.session - self.assertEqual(request.session[BACKEND_SESSION_KEY], self.backend) diff --git a/django/contrib/auth/tests/test_basic.py b/django/contrib/auth/tests/test_basic.py deleted file mode 100644 index ca7db755e6..0000000000 --- a/django/contrib/auth/tests/test_basic.py +++ /dev/null @@ -1,119 +0,0 @@ -from __future__ import unicode_literals - -from django.apps import apps -from django.contrib.auth import get_user_model -from django.contrib.auth.models import AnonymousUser, User -from django.contrib.auth.tests.custom_user import CustomUser -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.core.exceptions import ImproperlyConfigured -from django.dispatch import receiver -from django.test import TestCase, override_settings -from django.test.signals import setting_changed -from django.utils import translation - - -@receiver(setting_changed) -def user_model_swapped(**kwargs): - if kwargs['setting'] == 'AUTH_USER_MODEL': - from django.db.models.manager import ensure_default_manager - # Reset User manager - setattr(User, 'objects', User._default_manager) - ensure_default_manager(User) - apps.clear_cache() - - -@skipIfCustomUser -class BasicTestCase(TestCase): - def test_user(self): - "Check that users can be created and can set their password" - 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')) - - # Check we can manually set an unusable password - u.set_unusable_password() - u.save() - 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(None) - self.assertFalse(u.has_usable_password()) - - # Check username getter - self.assertEqual(u.get_username(), 'testuser') - - # Check authentication/permissions - self.assertTrue(u.is_authenticated()) - self.assertFalse(u.is_staff) - self.assertTrue(u.is_active) - self.assertFalse(u.is_superuser) - - # Check API-based user creation with no password - u2 = User.objects.create_user('testuser2', 'test2@example.com') - self.assertFalse(u2.has_usable_password()) - - def test_user_no_email(self): - "Check that users can be created without an email" - u = User.objects.create_user('testuser1') - self.assertEqual(u.email, '') - - u2 = User.objects.create_user('testuser2', email='') - self.assertEqual(u2.email, '') - - u3 = User.objects.create_user('testuser3', email=None) - self.assertEqual(u3.email, '') - - def test_anonymous_user(self): - "Check the properties of the anonymous user" - a = AnonymousUser() - self.assertEqual(a.pk, None) - self.assertEqual(a.username, '') - self.assertEqual(a.get_username(), '') - self.assertFalse(a.is_authenticated()) - self.assertFalse(a.is_staff) - self.assertFalse(a.is_active) - self.assertFalse(a.is_superuser) - self.assertEqual(a.groups.all().count(), 0) - self.assertEqual(a.user_permissions.all().count(), 0) - - def test_superuser(self): - "Check the creation and properties of a superuser" - 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) - - 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.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') - def test_swappable_user_bad_setting(self): - "The alternate user setting must point to something in the format app.model" - with self.assertRaises(ImproperlyConfigured): - get_user_model() - - @override_settings(AUTH_USER_MODEL='thismodel.doesntexist') - def test_swappable_user_nonexistent_model(self): - "The current user model must point to an installed model" - with self.assertRaises(ImproperlyConfigured): - get_user_model() - - @skipIfCustomUser - 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') diff --git a/django/contrib/auth/tests/test_context_processors.py b/django/contrib/auth/tests/test_context_processors.py deleted file mode 100644 index 3e1c19e91d..0000000000 --- a/django/contrib/auth/tests/test_context_processors.py +++ /dev/null @@ -1,158 +0,0 @@ -from django.contrib.auth import authenticate -from django.contrib.auth.context_processors import PermLookupDict, PermWrapper -from django.contrib.auth.models import Permission, User -from django.contrib.contenttypes.models import ContentType -from django.db.models import Q -from django.test import TestCase, override_settings - -from .settings import AUTH_MIDDLEWARE_CLASSES, AUTH_TEMPLATES -from .utils import skipIfCustomUser - - -class MockUser(object): - def has_module_perms(self, perm): - if perm == 'mockapp': - return True - return False - - def has_perm(self, perm): - if perm == 'mockapp.someperm': - return True - return False - - -class PermWrapperTests(TestCase): - """ - Test some details of the PermWrapper implementation. - """ - class EQLimiterObject(object): - """ - This object makes sure __eq__ will not be called endlessly. - """ - def __init__(self): - self.eq_calls = 0 - - def __eq__(self, other): - if self.eq_calls > 0: - return True - self.eq_calls += 1 - return False - - def test_permwrapper_in(self): - """ - Test that 'something' in PermWrapper works as expected. - """ - perms = PermWrapper(MockUser()) - # Works for modules and full permissions. - self.assertIn('mockapp', perms) - self.assertNotIn('nonexisting', perms) - self.assertIn('mockapp.someperm', perms) - self.assertNotIn('mockapp.nonexisting', perms) - - def test_permlookupdict_in(self): - """ - No endless loops if accessed with 'in' - refs #18979. - """ - pldict = PermLookupDict(MockUser(), 'mockapp') - with self.assertRaises(TypeError): - self.EQLimiterObject() in pldict - - -@skipIfCustomUser -@override_settings( - PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], - ROOT_URLCONF='django.contrib.auth.tests.urls', - TEMPLATES=AUTH_TEMPLATES, - USE_TZ=False, # required for loading the fixture -) -class AuthContextProcessorTests(TestCase): - """ - Tests for the ``django.contrib.auth.context_processors.auth`` processor - """ - fixtures = ['context-processors-users.xml'] - - @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES) - def test_session_not_accessed(self): - """ - Tests that the session is not accessed simply by including - the auth context processor - """ - response = self.client.get('/auth_processor_no_attr_access/') - self.assertContains(response, "Session not accessed") - - @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES) - def test_session_is_accessed(self): - """ - Tests that the session is accessed if the auth context processor - is used and relevant attributes accessed. - """ - 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_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_perms/') - self.assertContains(response, "Has auth permissions") - self.assertContains(response, "Has auth.add_permission permissions") - self.assertNotContains(response, "nonexisting") - - def test_perm_in_perms_attrs(self): - 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/') - self.assertContains(response, "Has auth permissions") - self.assertContains(response, "Has auth.add_permission permissions") - self.assertNotContains(response, "nonexisting") - - def test_message_attrs(self): - self.client.login(username='super', password='secret') - response = self.client.get('/auth_processor_messages/') - self.assertContains(response, "Message 1") - - def test_user_attrs(self): - """ - Test that the lazy objects returned behave just like the wrapped objects. - """ - # 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.assertContains(response, "unicode: super") - self.assertContains(response, "id: 100") - self.assertContains(response, "username: super") - # bug #12037 is tested by the {% url %} in the template: - self.assertContains(response, "url: /userpage/super/") - - # See if this object can be used for queries where a Q() comparing - # a user can be used with another Q() (in an AND or OR fashion). - # This simulates what a template tag might do with the user from the - # context. Note that we don't need to execute a query, just build it. - # - # The failure case (bug #12049) on Python 2.4 with a LazyObject-wrapped - # User is a fatal TypeError: "function() takes at least 2 arguments - # (0 given)" deep inside deepcopy(). - # - # Python 2.5 and 2.6 succeeded, but logged internally caught exception - # spew: - # - # Exception RuntimeError: 'maximum recursion depth exceeded while - # calling a Python object' in <type 'exceptions.AttributeError'> - # ignored" - 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']) diff --git a/django/contrib/auth/tests/test_decorators.py b/django/contrib/auth/tests/test_decorators.py deleted file mode 100644 index c5602be219..0000000000 --- a/django/contrib/auth/tests/test_decorators.py +++ /dev/null @@ -1,109 +0,0 @@ -from django.conf import settings -from django.contrib.auth import models -from django.contrib.auth.decorators import login_required, permission_required -from django.contrib.auth.tests.test_views import AuthViewsTestCase -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.core.exceptions import PermissionDenied -from django.http import HttpResponse -from django.test import TestCase, override_settings -from django.test.client import RequestFactory - - -@skipIfCustomUser -@override_settings(ROOT_URLCONF='django.contrib.auth.tests.urls') -class LoginRequiredTestCase(AuthViewsTestCase): - """ - Tests the login_required decorators - """ - - def testCallable(self): - """ - Check that login_required is assignable to callable objects. - """ - class CallableView(object): - def __call__(self, *args, **kwargs): - pass - login_required(CallableView()) - - def testView(self): - """ - Check that login_required is assignable to normal views. - """ - def normal_view(request): - pass - login_required(normal_view) - - def testLoginRequired(self, view_url='/login_required/', login_url=None): - """ - Check that login_required works on a simple view wrapped in a - login_required decorator. - """ - if login_url is None: - login_url = settings.LOGIN_URL - response = self.client.get(view_url) - self.assertEqual(response.status_code, 302) - self.assertIn(login_url, response.url) - self.login() - response = self.client.get(view_url) - self.assertEqual(response.status_code, 200) - - def testLoginRequiredNextUrl(self): - """ - Check that login_required works on a simple view wrapped in a - login_required decorator with a login_url set. - """ - self.testLoginRequired(view_url='/login_required_login_url/', - login_url='/somewhere/') - - -class PermissionsRequiredDecoratorTest(TestCase): - """ - Tests for the permission_required decorator - """ - def setUp(self): - self.user = models.User.objects.create(username='joe', password='qwerty') - self.factory = RequestFactory() - # Add permissions auth.add_customuser and auth.change_customuser - perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser')) - self.user.user_permissions.add(*perms) - - def test_many_permissions_pass(self): - - @permission_required(['auth.add_customuser', 'auth.change_customuser']) - def a_view(request): - return HttpResponse() - 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.add_customuser') - def a_view(request): - return HttpResponse() - 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.add_customuser', 'auth.change_customuser', 'non-existent-permission']) - def a_view(request): - return HttpResponse() - 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.add_customuser', 'auth.change_customuser', 'non-existent-permission' - ], raise_exception=True) - def a_view(request): - return HttpResponse() - request = self.factory.get('/rand') - request.user = self.user - self.assertRaises(PermissionDenied, a_view, request) diff --git a/django/contrib/auth/tests/test_forms.py b/django/contrib/auth/tests/test_forms.py deleted file mode 100644 index 6437ef6b2e..0000000000 --- a/django/contrib/auth/tests/test_forms.py +++ /dev/null @@ -1,536 +0,0 @@ -from __future__ import unicode_literals - -import re - -from django import forms -from django.contrib.auth.forms import ( - AuthenticationForm, PasswordChangeForm, PasswordResetForm, - ReadOnlyPasswordHashField, ReadOnlyPasswordHashWidget, SetPasswordForm, - UserChangeForm, UserCreationForm, -) -from django.contrib.auth.models import User -from django.core import mail -from django.core.mail import EmailMultiAlternatives -from django.forms.fields import CharField, Field -from django.test import TestCase, override_settings -from django.utils import translation -from django.utils.encoding import force_text -from django.utils.text import capfirst -from django.utils.translation import ugettext as _ - -from .settings import AUTH_TEMPLATES -from .utils import skipIfCustomUser - - -@skipIfCustomUser -@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher']) -class UserCreationFormTest(TestCase): - - fixtures = ['authtestdata.json'] - - def test_user_already_exists(self): - data = { - 'username': 'testclient', - 'password1': 'test123', - 'password2': 'test123', - } - form = UserCreationForm(data) - self.assertFalse(form.is_valid()) - self.assertEqual(form["username"].errors, - [force_text(User._meta.get_field('username').error_messages['unique'])]) - - def test_invalid_data(self): - data = { - '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') - self.assertEqual(form["username"].errors, [force_text(validator.message)]) - - def test_password_verification(self): - # The verification password is incorrect. - data = { - 'username': 'jsmith', - 'password1': 'test123', - 'password2': 'test', - } - form = UserCreationForm(data) - self.assertFalse(form.is_valid()) - self.assertEqual(form["password2"].errors, - [force_text(form.error_messages['password_mismatch'])]) - - def test_both_passwords(self): - # One (or both) passwords weren't given - data = {'username': 'jsmith'} - form = UserCreationForm(data) - required_error = [force_text(Field.default_error_messages['required'])] - self.assertFalse(form.is_valid()) - self.assertEqual(form['password1'].errors, required_error) - self.assertEqual(form['password2'].errors, required_error) - - data['password2'] = 'test123' - form = UserCreationForm(data) - self.assertFalse(form.is_valid()) - self.assertEqual(form['password1'].errors, required_error) - self.assertEqual(form['password2'].errors, []) - - def test_success(self): - # The success case. - data = { - 'username': 'jsmith@example.com', - 'password1': 'test123', - 'password2': 'test123', - } - form = UserCreationForm(data) - self.assertTrue(form.is_valid()) - u = form.save() - self.assertEqual(repr(u), '<User: jsmith@example.com>') - - -@skipIfCustomUser -@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher']) -class AuthenticationFormTest(TestCase): - - fixtures = ['authtestdata.json'] - - def test_invalid_username(self): - # The user submits an invalid username. - - data = { - 'username': 'jsmith_does_not_exist', - 'password': 'test123', - } - form = AuthenticationForm(None, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), - [force_text(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', - } - form = AuthenticationForm(None, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), - [force_text(form.error_messages['inactive'])]) - - def test_inactive_user_i18n(self): - with self.settings(USE_I18N=True), translation.override('pt-br', deactivate=True): - # The user is inactive. - data = { - 'username': 'inactive', - 'password': 'password', - } - form = AuthenticationForm(None, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), - [force_text(form.error_messages['inactive'])]) - - 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', - } - - class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm): - def confirm_login_allowed(self, user): - pass - - form = AuthenticationFormWithInactiveUsersOkay(None, data) - self.assertTrue(form.is_valid()) - - # If we want to disallow some logins according to custom logic, - # we should raise a django.forms.ValidationError in the form. - class PickyAuthenticationForm(AuthenticationForm): - def confirm_login_allowed(self, user): - if user.username == "inactive": - raise forms.ValidationError("This user is disallowed.") - raise forms.ValidationError("Sorry, nobody's allowed in.") - - form = PickyAuthenticationForm(None, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), ['This user is disallowed.']) - - data = { - 'username': 'testclient', - 'password': 'password', - } - form = PickyAuthenticationForm(None, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form.non_field_errors(), ["Sorry, nobody's allowed in."]) - - def test_success(self): - # The success case - data = { - 'username': 'testclient', - 'password': 'password', - } - form = AuthenticationForm(None, data) - self.assertTrue(form.is_valid()) - self.assertEqual(form.non_field_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") - - 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)) - - def test_username_field_label_empty_string(self): - - class CustomAuthenticationForm(AuthenticationForm): - username = CharField(label='') - - form = CustomAuthenticationForm() - self.assertEqual(form.fields['username'].label, "") - - -@skipIfCustomUser -@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher']) -class SetPasswordFormTest(TestCase): - - fixtures = ['authtestdata.json'] - - def test_password_verification(self): - # The two new passwords do not match. - user = User.objects.get(username='testclient') - data = { - 'new_password1': 'abc123', - 'new_password2': 'abc', - } - form = SetPasswordForm(user, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form["new_password2"].errors, - [force_text(form.error_messages['password_mismatch'])]) - - def test_success(self): - user = User.objects.get(username='testclient') - data = { - 'new_password1': 'abc123', - 'new_password2': 'abc123', - } - form = SetPasswordForm(user, data) - self.assertTrue(form.is_valid()) - - -@skipIfCustomUser -@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher']) -class PasswordChangeFormTest(TestCase): - - fixtures = ['authtestdata.json'] - - def test_incorrect_password(self): - user = User.objects.get(username='testclient') - data = { - 'old_password': 'test', - 'new_password1': 'abc123', - 'new_password2': 'abc123', - } - form = PasswordChangeForm(user, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form["old_password"].errors, - [force_text(form.error_messages['password_incorrect'])]) - - def test_password_verification(self): - # The two new passwords do not match. - user = User.objects.get(username='testclient') - data = { - 'old_password': 'password', - 'new_password1': 'abc123', - 'new_password2': 'abc', - } - form = PasswordChangeForm(user, data) - self.assertFalse(form.is_valid()) - self.assertEqual(form["new_password2"].errors, - [force_text(form.error_messages['password_mismatch'])]) - - def test_success(self): - # The success case. - user = User.objects.get(username='testclient') - data = { - 'old_password': 'password', - 'new_password1': 'abc123', - 'new_password2': 'abc123', - } - form = PasswordChangeForm(user, data) - self.assertTrue(form.is_valid()) - - 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']) - - -@skipIfCustomUser -@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher']) -class UserChangeFormTest(TestCase): - - fixtures = ['authtestdata.json'] - - def test_username_validity(self): - 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') - self.assertEqual(form["username"].errors, [force_text(validator.message)]) - - def test_bug_14242(self): - # A regression test, introduce by adding an optimization for the - # UserChangeForm. - - class MyUserForm(UserChangeForm): - def __init__(self, *args, **kwargs): - super(MyUserForm, self).__init__(*args, **kwargs) - self.fields['groups'].help_text = 'These groups give users different permissions' - - class Meta(UserChangeForm.Meta): - fields = ('groups',) - - # Just check we can create it - MyUserForm({}) - - def test_unsuable_password(self): - 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') - 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') - form = UserChangeForm(instance=user) - 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') - form = UserChangeForm(instance=user) - 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') - form_for_data = UserChangeForm(instance=user) - post_data = form_for_data.initial - - # The password field should be readonly, so anything - # 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' - form = UserChangeForm(instance=user, data=post_data) - - self.assertTrue(form.is_valid()) - self.assertEqual(form.cleaned_data['password'], 'sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161') - - def test_bug_19349_bound_password_field(self): - 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()) - - -@skipIfCustomUser -@override_settings( - PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], - TEMPLATES=AUTH_TEMPLATES, - USE_TZ=False, -) -class PasswordResetFormTest(TestCase): - - fixtures = ['authtestdata.json'] - - def create_dummy_user(self): - """ - 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') - return (user, username, email) - - def test_invalid_email(self): - data = {'email': 'not valid'} - form = PasswordResetForm(data) - self.assertFalse(form.is_valid()) - self.assertEqual(form['email'].errors, [_('Enter a valid email address.')]) - - def test_nonexistent_email(self): - """ - Test nonexistent email address. This should not fail because it would - expose information about registered users. - """ - 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} - form = PasswordResetForm(data) - self.assertTrue(form.is_valid()) - 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'} - 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') - self.assertEqual(len(mail.outbox), 1) - self.assertEqual(mail.outbox[0].subject, 'Custom password reset on example.com') - - def test_custom_email_constructor(self): - 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): - EmailMultiAlternatives( - "Forgot your password?", - "Sorry to hear you forgot your password.", - None, [to_email], - ['site_monitor@example.com'], - headers={'Reply-To': 'webmaster@example.com'}, - alternatives=[("Really sorry to hear you forgot your password.", - "text/html")]).send() - - form = CustomEmailPasswordResetForm(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') - 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].content_subtype, "plain") - - def test_preserve_username_case(self): - """ - 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') - - def test_inactive_user(self): - """ - Test that inactive user cannot receive password reset email. - """ - (user, username, email) = self.create_dummy_user() - user.is_active = False - user.save() - 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') - data = {"email": "test@example.com"} - form = PasswordResetForm(data) - self.assertTrue(form.is_valid()) - user.set_unusable_password() - user.save() - form = PasswordResetForm(data) - # The form itself is valid, but no email is sent - self.assertTrue(form.is_valid()) - form.save() - self.assertEqual(len(mail.outbox), 0) - - def test_save_plaintext_email(self): - """ - Test the PasswordResetForm.save() method with no html_email_template_name - parameter passed in. - Test to ensure original behavior is unchanged after the parameter was added. - """ - (user, username, email) = self.create_dummy_user() - form = PasswordResetForm({"email": email}) - self.assertTrue(form.is_valid()) - form.save() - 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(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())) - - def test_save_html_email_template_name(self): - """ - Test the PasswordResetFOrm.save() method with html_email_template_name - parameter specified. - Test to ensure that a multipart email is sent with both text/plain - and text/html parts. - """ - (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') - 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(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'^<html><a href="http://example.com/reset/[\w/-]+/">Link</a></html>$', - message.get_payload(1).get_payload()) - ) - - -class ReadOnlyPasswordHashTest(TestCase): - - 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={}) - self.assertIn(_("No password set."), html) - - def test_readonly_field_has_changed(self): - field = ReadOnlyPasswordHashField() - self.assertFalse(field.has_changed('aaa', 'bbb')) diff --git a/django/contrib/auth/tests/test_handlers.py b/django/contrib/auth/tests/test_handlers.py deleted file mode 100644 index a6a4f9cd06..0000000000 --- a/django/contrib/auth/tests/test_handlers.py +++ /dev/null @@ -1,80 +0,0 @@ -from __future__ import unicode_literals - -from django.contrib.auth.handlers.modwsgi import ( - check_password, groups_for_user, -) -from django.contrib.auth.models import Group, User -from django.contrib.auth.tests.custom_user import CustomUser -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.test import TransactionTestCase, override_settings - - -# This must be a TransactionTestCase because the WSGI auth handler performs -# its own transaction management. -class ModWsgiHandlerTestCase(TransactionTestCase): - """ - Tests for the mod_wsgi authentication handler - """ - - available_apps = [ - 'django.contrib.auth', - 'django.contrib.contenttypes', - ] - - @skipIfCustomUser - def test_check_password(self): - """ - Verify that check_password returns the correct values as per - http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms#Apache_Authentication_Provider - """ - User.objects.create_user('test', 'test@example.com', 'test') - - # User not in database - self.assertIsNone(check_password({}, 'unknown', '')) - - # Valid user with correct password - self.assertTrue(check_password({}, 'test', 'test')) - - # correct password, but user is inactive - User.objects.filter(username='test').update(is_active=False) - self.assertFalse(check_password({}, 'test', 'test')) - - # Valid user with incorrect password - self.assertFalse(check_password({}, 'test', 'incorrect')) - - @override_settings(AUTH_USER_MODEL='auth.CustomUser') - def test_check_password_custom_user(self): - """ - Verify that check_password returns the correct values as per - http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms#Apache_Authentication_Provider - - with custom user installed - """ - - CustomUser._default_manager.create_user('test@example.com', '1990-01-01', 'test') - - # User not in database - self.assertIsNone(check_password({}, 'unknown', '')) - - # Valid user with correct password' - self.assertTrue(check_password({}, 'test@example.com', 'test')) - - # Valid user with incorrect password - self.assertFalse(check_password({}, 'test@example.com', 'incorrect')) - - @skipIfCustomUser - def test_groups_for_user(self): - """ - Check that groups_for_user returns correct values as per - http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms#Apache_Group_Authorisation - """ - user1 = User.objects.create_user('test', 'test@example.com', 'test') - User.objects.create_user('test1', 'test1@example.com', 'test1') - group = Group.objects.create(name='test_group') - user1.groups.add(group) - - # User not in database - self.assertEqual(groups_for_user({}, 'unknown'), []) - - self.assertEqual(groups_for_user({}, 'test'), [b'test_group']) - self.assertEqual(groups_for_user({}, 'test1'), []) diff --git a/django/contrib/auth/tests/test_hashers.py b/django/contrib/auth/tests/test_hashers.py deleted file mode 100644 index 52253d6efb..0000000000 --- a/django/contrib/auth/tests/test_hashers.py +++ /dev/null @@ -1,327 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from unittest import skipUnless - -from django.conf.global_settings import PASSWORD_HASHERS -from django.contrib.auth.hashers import ( - UNUSABLE_PASSWORD_PREFIX, UNUSABLE_PASSWORD_SUFFIX_LENGTH, - BasePasswordHasher, PBKDF2PasswordHasher, PBKDF2SHA1PasswordHasher, - check_password, get_hasher, identify_hasher, is_password_usable, - make_password, -) -from django.test import SimpleTestCase -from django.test.utils import override_settings -from django.utils import six - -try: - import crypt -except ImportError: - crypt = None - -try: - import bcrypt -except ImportError: - bcrypt = None - - -class PBKDF2SingleIterationHasher(PBKDF2PasswordHasher): - iterations = 1 - - -@override_settings(PASSWORD_HASHERS=PASSWORD_HASHERS) -class TestUtilsHashPass(SimpleTestCase): - - def test_simple(self): - encoded = make_password('lètmein') - self.assertTrue(encoded.startswith('pbkdf2_sha256$')) - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - # Blank passwords - blank_encoded = make_password('') - self.assertTrue(blank_encoded.startswith('pbkdf2_sha256$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - def test_pkbdf2(self): - encoded = make_password('lètmein', 'seasalt', 'pbkdf2_sha256') - self.assertEqual(encoded, - 'pbkdf2_sha256$24000$seasalt$V9DfCAVoweeLwxC/L2mb+7swhzF0XYdyQMqmusZqiTc=') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "pbkdf2_sha256") - # Blank passwords - blank_encoded = make_password('', 'seasalt', 'pbkdf2_sha256') - self.assertTrue(blank_encoded.startswith('pbkdf2_sha256$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - def test_sha1(self): - encoded = make_password('lètmein', 'seasalt', 'sha1') - self.assertEqual(encoded, - 'sha1$seasalt$cff36ea83f5706ce9aa7454e63e431fc726b2dc8') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "sha1") - # Blank passwords - blank_encoded = make_password('', 'seasalt', 'sha1') - self.assertTrue(blank_encoded.startswith('sha1$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - def test_md5(self): - encoded = make_password('lètmein', 'seasalt', 'md5') - self.assertEqual(encoded, - 'md5$seasalt$3f86d0d3d465b7b458c231bf3555c0e3') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "md5") - # Blank passwords - blank_encoded = make_password('', 'seasalt', 'md5') - self.assertTrue(blank_encoded.startswith('md5$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - def test_unsalted_md5(self): - encoded = make_password('lètmein', '', 'unsalted_md5') - self.assertEqual(encoded, '88a434c88cca4e900f7874cd98123f43') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "unsalted_md5") - # Alternate unsalted syntax - alt_encoded = "md5$$%s" % encoded - self.assertTrue(is_password_usable(alt_encoded)) - self.assertTrue(check_password('lètmein', alt_encoded)) - self.assertFalse(check_password('lètmeinz', alt_encoded)) - # Blank passwords - blank_encoded = make_password('', '', 'unsalted_md5') - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - def test_unsalted_sha1(self): - encoded = make_password('lètmein', '', 'unsalted_sha1') - self.assertEqual(encoded, 'sha1$$6d138ca3ae545631b3abd71a4f076ce759c5700b') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "unsalted_sha1") - # Raw SHA1 isn't acceptable - alt_encoded = encoded[6:] - self.assertFalse(check_password('lètmein', alt_encoded)) - # Blank passwords - blank_encoded = make_password('', '', 'unsalted_sha1') - self.assertTrue(blank_encoded.startswith('sha1$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - @skipUnless(crypt, "no crypt module to generate password.") - def test_crypt(self): - encoded = make_password('lètmei', 'ab', 'crypt') - self.assertEqual(encoded, 'crypt$$ab1Hv2Lg7ltQo') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(check_password('lètmei', encoded)) - self.assertFalse(check_password('lètmeiz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "crypt") - # Blank passwords - blank_encoded = make_password('', 'ab', 'crypt') - self.assertTrue(blank_encoded.startswith('crypt$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - @skipUnless(bcrypt, "bcrypt not installed") - def test_bcrypt_sha256(self): - encoded = make_password('lètmein', hasher='bcrypt_sha256') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(encoded.startswith('bcrypt_sha256$')) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "bcrypt_sha256") - - # Verify that password truncation no longer works - password = ('VSK0UYV6FFQVZ0KG88DYN9WADAADZO1CTSIVDJUNZSUML6IBX7LN7ZS3R5' - 'JGB3RGZ7VI7G7DJQ9NI8BQFSRPTG6UWTTVESA5ZPUN') - encoded = make_password(password, hasher='bcrypt_sha256') - self.assertTrue(check_password(password, encoded)) - self.assertFalse(check_password(password[:72], encoded)) - # Blank passwords - blank_encoded = make_password('', hasher='bcrypt_sha256') - self.assertTrue(blank_encoded.startswith('bcrypt_sha256$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - @skipUnless(bcrypt, "bcrypt not installed") - def test_bcrypt(self): - encoded = make_password('lètmein', hasher='bcrypt') - self.assertTrue(is_password_usable(encoded)) - self.assertTrue(encoded.startswith('bcrypt$')) - self.assertTrue(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertEqual(identify_hasher(encoded).algorithm, "bcrypt") - # Blank passwords - blank_encoded = make_password('', hasher='bcrypt') - self.assertTrue(blank_encoded.startswith('bcrypt$')) - self.assertTrue(is_password_usable(blank_encoded)) - self.assertTrue(check_password('', blank_encoded)) - self.assertFalse(check_password(' ', blank_encoded)) - - def test_unusable(self): - encoded = make_password(None) - self.assertEqual(len(encoded), len(UNUSABLE_PASSWORD_PREFIX) + UNUSABLE_PASSWORD_SUFFIX_LENGTH) - self.assertFalse(is_password_usable(encoded)) - self.assertFalse(check_password(None, encoded)) - self.assertFalse(check_password(encoded, encoded)) - self.assertFalse(check_password(UNUSABLE_PASSWORD_PREFIX, encoded)) - self.assertFalse(check_password('', encoded)) - self.assertFalse(check_password('lètmein', encoded)) - self.assertFalse(check_password('lètmeinz', encoded)) - self.assertRaises(ValueError, identify_hasher, encoded) - # Assert that the unusable passwords actually contain a random part. - # This might fail one day due to a hash collision. - self.assertNotEqual(encoded, make_password(None), "Random password collision?") - - def test_unspecified_password(self): - """ - Makes sure specifying no plain password with a valid encoded password - returns `False`. - """ - self.assertFalse(check_password(None, make_password('lètmein'))) - - def test_bad_algorithm(self): - with self.assertRaises(ValueError): - make_password('lètmein', hasher='lolcat') - self.assertRaises(ValueError, identify_hasher, "lolcat$salt$hash") - - def test_bad_encoded(self): - self.assertFalse(is_password_usable('lètmein_badencoded')) - self.assertFalse(is_password_usable('')) - - def test_low_level_pkbdf2(self): - hasher = PBKDF2PasswordHasher() - encoded = hasher.encode('lètmein', 'seasalt2') - self.assertEqual(encoded, - 'pbkdf2_sha256$24000$seasalt2$TUDkfilKHVC7BkaKSZgIKhm0aTtXlmcw/5C1FeS/DPk=') - self.assertTrue(hasher.verify('lètmein', encoded)) - - def test_low_level_pbkdf2_sha1(self): - hasher = PBKDF2SHA1PasswordHasher() - encoded = hasher.encode('lètmein', 'seasalt2') - self.assertEqual(encoded, - 'pbkdf2_sha1$24000$seasalt2$L37ETdd9trqrsJDwapU3P+2Edhg=') - self.assertTrue(hasher.verify('lètmein', encoded)) - - def test_upgrade(self): - self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm) - for algo in ('sha1', 'md5'): - encoded = make_password('lètmein', hasher=algo) - state = {'upgraded': False} - - def setter(password): - state['upgraded'] = True - self.assertTrue(check_password('lètmein', encoded, setter)) - self.assertTrue(state['upgraded']) - - def test_no_upgrade(self): - encoded = make_password('lètmein') - state = {'upgraded': False} - - def setter(): - state['upgraded'] = True - self.assertFalse(check_password('WRONG', encoded, setter)) - self.assertFalse(state['upgraded']) - - def test_no_upgrade_on_incorrect_pass(self): - self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm) - for algo in ('sha1', 'md5'): - encoded = make_password('lètmein', hasher=algo) - state = {'upgraded': False} - - def setter(): - state['upgraded'] = True - self.assertFalse(check_password('WRONG', encoded, setter)) - self.assertFalse(state['upgraded']) - - def test_pbkdf2_upgrade(self): - hasher = get_hasher('default') - self.assertEqual('pbkdf2_sha256', hasher.algorithm) - self.assertNotEqual(hasher.iterations, 1) - - old_iterations = hasher.iterations - try: - # Generate a password with 1 iteration. - hasher.iterations = 1 - encoded = make_password('letmein') - algo, iterations, salt, hash = encoded.split('$', 3) - self.assertEqual(iterations, '1') - - state = {'upgraded': False} - - def setter(password): - state['upgraded'] = True - - # Check that no upgrade is triggered - self.assertTrue(check_password('letmein', encoded, setter)) - self.assertFalse(state['upgraded']) - - # Revert to the old iteration count and ... - hasher.iterations = old_iterations - - # ... check if the password would get updated to the new iteration count. - self.assertTrue(check_password('letmein', encoded, setter)) - self.assertTrue(state['upgraded']) - finally: - hasher.iterations = old_iterations - - def test_pbkdf2_upgrade_new_hasher(self): - hasher = get_hasher('default') - self.assertEqual('pbkdf2_sha256', hasher.algorithm) - self.assertNotEqual(hasher.iterations, 1) - - state = {'upgraded': False} - - def setter(password): - state['upgraded'] = True - - with self.settings(PASSWORD_HASHERS=[ - 'django.contrib.auth.tests.test_hashers.PBKDF2SingleIterationHasher']): - encoded = make_password('letmein') - algo, iterations, salt, hash = encoded.split('$', 3) - self.assertEqual(iterations, '1') - - # Check that no upgrade is triggered - self.assertTrue(check_password('letmein', encoded, setter)) - self.assertFalse(state['upgraded']) - - # Revert to the old iteration count and check if the password would get - # updated to the new iteration count. - with self.settings(PASSWORD_HASHERS=[ - 'django.contrib.auth.hashers.PBKDF2PasswordHasher', - 'django.contrib.auth.tests.test_hashers.PBKDF2SingleIterationHasher']): - self.assertTrue(check_password('letmein', encoded, setter)) - self.assertTrue(state['upgraded']) - - def test_load_library_no_algorithm(self): - with self.assertRaises(ValueError) as e: - BasePasswordHasher()._load_library() - self.assertEqual("Hasher 'BasePasswordHasher' doesn't specify a " - "library attribute", str(e.exception)) - - def test_load_library_importerror(self): - PlainHasher = type(str('PlainHasher'), (BasePasswordHasher,), - {'algorithm': 'plain', 'library': 'plain'}) - # Python 3.3 adds quotes around module name - with six.assertRaisesRegex(self, ValueError, - "Couldn't load 'PlainHasher' algorithm library: No module named '?plain'?"): - PlainHasher()._load_library() diff --git a/django/contrib/auth/tests/test_management.py b/django/contrib/auth/tests/test_management.py deleted file mode 100644 index cb785ba8fd..0000000000 --- a/django/contrib/auth/tests/test_management.py +++ /dev/null @@ -1,577 +0,0 @@ -from __future__ import unicode_literals - -import locale -import sys -from datetime import date - -from django.apps import apps -from django.contrib.auth import management, models -from django.contrib.auth.checks import check_user_model -from django.contrib.auth.management import create_permissions -from django.contrib.auth.management.commands import ( - changepassword, createsuperuser, -) -from django.contrib.auth.models import Group, User -from django.contrib.auth.tests.custom_user import ( - CustomUser, CustomUserWithFK, Email, -) -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.contrib.contenttypes.models import ContentType -from django.core import checks, exceptions -from django.core.management import call_command -from django.core.management.base import CommandError -from django.test import TestCase, override_settings, override_system_checks -from django.utils import six -from django.utils.encoding import force_str - - -def mock_inputs(inputs): - """ - Decorator to temporarily replace input/getpass to allow interactive - createsuperuser. - """ - def inner(test_func): - def wrapped(*args): - class mock_getpass: - @staticmethod - def getpass(prompt=b'Password: ', stream=None): - if six.PY2: - # getpass on Windows only supports prompt as bytestring (#19807) - assert isinstance(prompt, six.binary_type) - return inputs['password'] - - def mock_input(prompt): - # prompt should be encoded in Python 2. This line will raise an - # Exception if prompt contains unencoded non-ASCII on Python 2. - prompt = str(prompt) - assert str('__proxy__') not in prompt - response = '' - for key, val in inputs.items(): - if force_str(key) in prompt.lower(): - response = val - break - return response - - old_getpass = createsuperuser.getpass - old_input = createsuperuser.input - createsuperuser.getpass = mock_getpass - createsuperuser.input = mock_input - try: - test_func(*args) - finally: - createsuperuser.getpass = old_getpass - createsuperuser.input = old_input - return wrapped - return inner - - -class MockTTY(object): - """ - A fake stdin object that pretends to be a TTY to be used in conjunction - with mock_inputs. - """ - def isatty(self): - return True - - -@skipIfCustomUser -class GetDefaultUsernameTestCase(TestCase): - - def setUp(self): - self.old_get_system_username = management.get_system_username - - def tearDown(self): - management.get_system_username = self.old_get_system_username - - def test_actual_implementation(self): - self.assertIsInstance(management.get_system_username(), six.text_type) - - def test_simple(self): - management.get_system_username = lambda: 'joe' - self.assertEqual(management.get_default_username(), 'joe') - - def test_existing(self): - models.User.objects.create(username='joe') - management.get_system_username = lambda: 'joe' - self.assertEqual(management.get_default_username(), '') - self.assertEqual( - management.get_default_username(check_db=False), 'joe') - - def test_i18n(self): - # 'Julia' with accented 'u': - management.get_system_username = lambda: 'J\xfalia' - self.assertEqual(management.get_default_username(), 'julia') - - -@skipIfCustomUser -class ChangepasswordManagementCommandTestCase(TestCase): - - def setUp(self): - self.user = models.User.objects.create_user(username='joe', password='qwerty') - self.stdout = six.StringIO() - self.stderr = six.StringIO() - - def tearDown(self): - self.stdout.close() - self.stderr.close() - - def test_that_changepassword_command_changes_joes_password(self): - "Executing the changepassword management command should change joe's password" - self.assertTrue(self.user.check_password('qwerty')) - command = changepassword.Command() - command._get_pass = lambda *args: 'not qwerty' - - command.execute(username="joe", stdout=self.stdout) - command_output = self.stdout.getvalue().strip() - - self.assertEqual( - command_output, - "Changing password for user 'joe'\nPassword changed successfully for user 'joe'" - ) - self.assertTrue(models.User.objects.get(username="joe").check_password("not qwerty")) - - def test_that_max_tries_exits_1(self): - """ - A CommandError should be thrown by handle() if the user enters in - mismatched passwords three times. - """ - command = changepassword.Command() - command._get_pass = lambda *args: args or 'foo' - - with self.assertRaises(CommandError): - command.execute(username="joe", stdout=self.stdout, stderr=self.stderr) - - def test_that_changepassword_command_works_with_nonascii_output(self): - """ - #21627 -- Executing the changepassword management command should allow - non-ASCII characters from the User object representation. - """ - # 'Julia' with accented 'u': - models.User.objects.create_user(username='J\xfalia', password='qwerty') - - command = changepassword.Command() - command._get_pass = lambda *args: 'not qwerty' - - command.execute(username="J\xfalia", stdout=self.stdout) - - -@skipIfCustomUser -@override_settings(SILENCED_SYSTEM_CHECKS=['fields.W342']) # ForeignKey(unique=True) -class CreatesuperuserManagementCommandTestCase(TestCase): - - def test_basic_usage(self): - "Check the operation of the createsuperuser management command" - # We can use the management command to create a superuser - new_io = six.StringIO() - call_command( - "createsuperuser", - interactive=False, - username="joe", - email="joe@somewhere.org", - stdout=new_io - ) - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, 'Superuser created successfully.') - u = User.objects.get(username="joe") - self.assertEqual(u.email, 'joe@somewhere.org') - - # created password should be unusable - self.assertFalse(u.has_usable_password()) - - @mock_inputs({'password': "nopasswd"}) - def test_nolocale(self): - """ - Check that createsuperuser does not break when no locale is set. See - ticket #16017. - """ - - old_getdefaultlocale = locale.getdefaultlocale - try: - # Temporarily remove locale information - locale.getdefaultlocale = lambda: (None, None) - - # Call the command in this new environment - call_command( - "createsuperuser", - interactive=True, - username="nolocale@somewhere.org", - email="nolocale@somewhere.org", - verbosity=0, - stdin=MockTTY(), - ) - - except TypeError: - self.fail("createsuperuser fails if the OS provides no information about the current locale") - - finally: - # Re-apply locale information - locale.getdefaultlocale = old_getdefaultlocale - - # If we were successful, a user should have been created - u = User.objects.get(username="nolocale@somewhere.org") - self.assertEqual(u.email, 'nolocale@somewhere.org') - - @mock_inputs({ - 'password': "nopasswd", - 'u\u017eivatel': 'foo', # username (cz) - 'email': 'nolocale@somewhere.org'}) - def test_non_ascii_verbose_name(self): - # Aliased so the string doesn't get extracted - from django.utils.translation import ugettext_lazy as ulazy - username_field = User._meta.get_field('username') - old_verbose_name = username_field.verbose_name - username_field.verbose_name = ulazy('u\u017eivatel') - new_io = six.StringIO() - try: - call_command( - "createsuperuser", - interactive=True, - stdout=new_io, - stdin=MockTTY(), - ) - finally: - username_field.verbose_name = old_verbose_name - - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, 'Superuser created successfully.') - - def test_verbosity_zero(self): - # We can suppress output on the management command - new_io = six.StringIO() - call_command( - "createsuperuser", - interactive=False, - username="joe2", - email="joe2@somewhere.org", - verbosity=0, - stdout=new_io - ) - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, '') - u = User.objects.get(username="joe2") - self.assertEqual(u.email, 'joe2@somewhere.org') - self.assertFalse(u.has_usable_password()) - - def test_email_in_username(self): - new_io = six.StringIO() - call_command( - "createsuperuser", - interactive=False, - username="joe+admin@somewhere.org", - email="joe@somewhere.org", - stdout=new_io - ) - u = User._default_manager.get(username="joe+admin@somewhere.org") - self.assertEqual(u.email, 'joe@somewhere.org') - self.assertFalse(u.has_usable_password()) - - @override_settings(AUTH_USER_MODEL='auth.CustomUser') - def test_swappable_user(self): - "A superuser can be created when a custom User model is in use" - # We can use the management command to create a superuser - # We skip validation because the temporary substitution of the - # swappable User model messes with validation. - new_io = six.StringIO() - call_command( - "createsuperuser", - interactive=False, - email="joe@somewhere.org", - date_of_birth="1976-04-01", - stdout=new_io, - ) - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, 'Superuser created successfully.') - u = CustomUser._default_manager.get(email="joe@somewhere.org") - self.assertEqual(u.date_of_birth, date(1976, 4, 1)) - - # created password should be unusable - self.assertFalse(u.has_usable_password()) - - @override_settings(AUTH_USER_MODEL='auth.CustomUser') - def test_swappable_user_missing_required_field(self): - "A Custom superuser won't be created when a required field isn't provided" - # We can use the management command to create a superuser - # We skip validation because the temporary substitution of the - # swappable User model messes with validation. - new_io = six.StringIO() - with self.assertRaises(CommandError): - call_command( - "createsuperuser", - interactive=False, - username="joe@somewhere.org", - stdout=new_io, - stderr=new_io, - ) - - self.assertEqual(CustomUser._default_manager.count(), 0) - - def test_skip_if_not_in_TTY(self): - """ - If the command is not called from a TTY, it should be skipped and a - message should be displayed (#7423). - """ - class FakeStdin(object): - """A fake stdin object that has isatty() return False.""" - def isatty(self): - return False - - out = six.StringIO() - call_command( - "createsuperuser", - stdin=FakeStdin(), - stdout=out, - interactive=True, - ) - - self.assertEqual(User._default_manager.count(), 0) - self.assertIn("Superuser creation skipped", out.getvalue()) - - def test_passing_stdin(self): - """ - You can pass a stdin object as an option and it should be - available on self.stdin. - If no such option is passed, it defaults to sys.stdin. - """ - sentinel = object() - command = createsuperuser.Command() - command.check = lambda: [] - command.execute( - stdin=sentinel, - stdout=six.StringIO(), - stderr=six.StringIO(), - interactive=False, - verbosity=0, - username='janet', - email='janet@example.com', - ) - self.assertIs(command.stdin, sentinel) - - command = createsuperuser.Command() - command.check = lambda: [] - command.execute( - stdout=six.StringIO(), - stderr=six.StringIO(), - interactive=False, - verbosity=0, - username='joe', - email='joe@example.com', - ) - self.assertIs(command.stdin, sys.stdin) - - @override_settings(AUTH_USER_MODEL='auth.CustomUserWithFK') - def test_fields_with_fk(self): - new_io = six.StringIO() - group = Group.objects.create(name='mygroup') - email = Email.objects.create(email='mymail@gmail.com') - call_command( - 'createsuperuser', - interactive=False, - username=email.pk, - email=email.email, - group=group.pk, - stdout=new_io, - ) - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, 'Superuser created successfully.') - u = CustomUserWithFK._default_manager.get(email=email) - self.assertEqual(u.username, email) - self.assertEqual(u.group, group) - - non_existent_email = 'mymail2@gmail.com' - with self.assertRaisesMessage(CommandError, - 'email instance with email %r does not exist.' % non_existent_email): - call_command( - 'createsuperuser', - interactive=False, - username=email.pk, - email=non_existent_email, - stdout=new_io, - ) - - @override_settings(AUTH_USER_MODEL='auth.CustomUserWithFK') - def test_fields_with_fk_interactive(self): - new_io = six.StringIO() - group = Group.objects.create(name='mygroup') - email = Email.objects.create(email='mymail@gmail.com') - - @mock_inputs({ - 'password': 'nopasswd', - 'username (email.id)': email.pk, - 'email (email.email)': email.email, - 'group (group.id)': group.pk, - }) - def test(self): - call_command( - 'createsuperuser', - interactive=True, - stdout=new_io, - stdin=MockTTY(), - ) - - command_output = new_io.getvalue().strip() - self.assertEqual(command_output, 'Superuser created successfully.') - u = CustomUserWithFK._default_manager.get(email=email) - self.assertEqual(u.username, email) - self.assertEqual(u.group, group) - - test(self) - - -class CustomUserModelValidationTestCase(TestCase): - @override_settings(AUTH_USER_MODEL='auth.CustomUserNonListRequiredFields') - @override_system_checks([check_user_model]) - def test_required_fields_is_list(self): - "REQUIRED_FIELDS should be a list." - - from .custom_user import CustomUserNonListRequiredFields - errors = checks.run_checks() - expected = [ - checks.Error( - "'REQUIRED_FIELDS' must be a list or tuple.", - hint=None, - obj=CustomUserNonListRequiredFields, - id='auth.E001', - ), - ] - self.assertEqual(errors, expected) - - @override_settings(AUTH_USER_MODEL='auth.CustomUserBadRequiredFields') - @override_system_checks([check_user_model]) - def test_username_not_in_required_fields(self): - "USERNAME_FIELD should not appear in REQUIRED_FIELDS." - - from .custom_user import CustomUserBadRequiredFields - errors = checks.run_checks() - expected = [ - checks.Error( - ("The field named as the 'USERNAME_FIELD' for a custom user model " - "must not be included in 'REQUIRED_FIELDS'."), - hint=None, - obj=CustomUserBadRequiredFields, - id='auth.E002', - ), - ] - self.assertEqual(errors, expected) - - @override_settings(AUTH_USER_MODEL='auth.CustomUserNonUniqueUsername') - @override_system_checks([check_user_model]) - def test_username_non_unique(self): - "A non-unique USERNAME_FIELD should raise a model validation error." - - from .custom_user import CustomUserNonUniqueUsername - errors = checks.run_checks() - expected = [ - checks.Error( - ("'CustomUserNonUniqueUsername.username' must be " - "unique because it is named as the 'USERNAME_FIELD'."), - hint=None, - obj=CustomUserNonUniqueUsername, - id='auth.E003', - ), - ] - self.assertEqual(errors, expected) - - @override_settings(AUTH_USER_MODEL='auth.CustomUserNonUniqueUsername', - AUTHENTICATION_BACKENDS=[ - 'my.custom.backend', - ]) - @override_system_checks([check_user_model]) - def test_username_non_unique_with_custom_backend(self): - """ A non-unique USERNAME_FIELD should raise an error only if we use the - default authentication backend. Otherwise, an warning should be raised. - """ - - from .custom_user import CustomUserNonUniqueUsername - errors = checks.run_checks() - expected = [ - 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', - ) - ] - self.assertEqual(errors, expected) - - -class PermissionTestCase(TestCase): - - def setUp(self): - self._original_permissions = models.Permission._meta.permissions[:] - self._original_default_permissions = models.Permission._meta.default_permissions - self._original_verbose_name = models.Permission._meta.verbose_name - - def tearDown(self): - models.Permission._meta.permissions = self._original_permissions - models.Permission._meta.default_permissions = self._original_default_permissions - models.Permission._meta.verbose_name = self._original_verbose_name - ContentType.objects.clear_cache() - - def test_duplicated_permissions(self): - """ - Test that we show proper error message if we are trying to create - duplicate permissions. - """ - auth_app_config = apps.get_app_config('auth') - - # check duplicated default permission - models.Permission._meta.permissions = [ - ('change_permission', 'Can edit permission (duplicate)')] - six.assertRaisesRegex(self, CommandError, - "The permission codename 'change_permission' clashes with a " - "builtin permission for model 'auth.Permission'.", - create_permissions, auth_app_config, verbosity=0) - - # check duplicated custom permissions - models.Permission._meta.permissions = [ - ('my_custom_permission', 'Some permission'), - ('other_one', 'Some other permission'), - ('my_custom_permission', 'Some permission with duplicate permission code'), - ] - six.assertRaisesRegex(self, CommandError, - "The permission codename 'my_custom_permission' is duplicated for model " - "'auth.Permission'.", - create_permissions, auth_app_config, verbosity=0) - - # should not raise anything - models.Permission._meta.permissions = [ - ('my_custom_permission', 'Some permission'), - ('other_one', 'Some other permission'), - ] - create_permissions(auth_app_config, verbosity=0) - - def test_default_permissions(self): - auth_app_config = apps.get_app_config('auth') - - permission_content_type = ContentType.objects.get_by_natural_key('auth', 'permission') - models.Permission._meta.permissions = [ - ('my_custom_permission', 'Some permission'), - ] - create_permissions(auth_app_config, verbosity=0) - - # add/change/delete permission by default + custom permission - self.assertEqual(models.Permission.objects.filter( - content_type=permission_content_type, - ).count(), 4) - - models.Permission.objects.filter(content_type=permission_content_type).delete() - models.Permission._meta.default_permissions = [] - create_permissions(auth_app_config, verbosity=0) - - # custom permission only since default permissions is empty - self.assertEqual(models.Permission.objects.filter( - content_type=permission_content_type, - ).count(), 1) - - def test_verbose_name_length(self): - auth_app_config = apps.get_app_config('auth') - - permission_content_type = ContentType.objects.get_by_natural_key('auth', 'permission') - models.Permission.objects.filter(content_type=permission_content_type).delete() - models.Permission._meta.verbose_name = "some ridiculously long verbose name that is out of control" * 5 - - six.assertRaisesRegex(self, exceptions.ValidationError, - "The verbose_name of auth.permission is longer than 244 characters", - create_permissions, auth_app_config, verbosity=0) diff --git a/django/contrib/auth/tests/test_middleware.py b/django/contrib/auth/tests/test_middleware.py deleted file mode 100644 index 44372bce01..0000000000 --- a/django/contrib/auth/tests/test_middleware.py +++ /dev/null @@ -1,49 +0,0 @@ -from django.contrib.auth.middleware import AuthenticationMiddleware -from django.contrib.auth.models import User -from django.http import HttpRequest -from django.test import TestCase - - -class TestSessionAuthenticationMiddleware(TestCase): - def setUp(self): - self.user_password = 'test_password' - self.user = User.objects.create_user('test_user', - 'test@example.com', - self.user_password) - - self.middleware = AuthenticationMiddleware() - self.assertTrue(self.client.login( - username=self.user.username, - password=self.user_password, - )) - self.request = HttpRequest() - self.request.session = self.client.session - - def test_changed_password_doesnt_invalidate_session(self): - """ - Changing a user's password shouldn't invalidate the session if session - verification isn't activated. - """ - session_key = self.request.session.session_key - self.middleware.process_request(self.request) - self.assertIsNotNone(self.request.user) - self.assertFalse(self.request.user.is_anonymous()) - - # After password change, user should remain logged in. - self.user.set_password('new_password') - self.user.save() - self.middleware.process_request(self.request) - self.assertIsNotNone(self.request.user) - self.assertFalse(self.request.user.is_anonymous()) - self.assertEqual(session_key, self.request.session.session_key) - - def test_changed_password_invalidates_session_with_middleware(self): - with self.modify_settings(MIDDLEWARE_CLASSES={'append': ['django.contrib.auth.middleware.SessionAuthenticationMiddleware']}): - # After password change, user should be anonymous - self.user.set_password('new_password') - self.user.save() - self.middleware.process_request(self.request) - self.assertIsNotNone(self.request.user) - self.assertTrue(self.request.user.is_anonymous()) - # session should be flushed - self.assertIsNone(self.request.session.session_key) diff --git a/django/contrib/auth/tests/test_models.py b/django/contrib/auth/tests/test_models.py deleted file mode 100644 index ee51b15a98..0000000000 --- a/django/contrib/auth/tests/test_models.py +++ /dev/null @@ -1,219 +0,0 @@ -from django.contrib.auth import get_user_model -from django.contrib.auth.models import ( - AbstractUser, Group, Permission, User, UserManager, -) -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.contrib.contenttypes.models import ContentType -from django.core import mail -from django.db.models.signals import post_save -from django.test import TestCase, override_settings - - -@skipIfCustomUser -@override_settings(USE_TZ=False) -class NaturalKeysTestCase(TestCase): - fixtures = ['authtestdata.json'] - - def test_user_natural_key(self): - staff_user = User.objects.get(username='staff') - self.assertEqual(User.objects.get_by_natural_key('staff'), staff_user) - self.assertEqual(staff_user.natural_key(), ('staff',)) - - def test_group_natural_key(self): - users_group = Group.objects.create(name='users') - self.assertEqual(Group.objects.get_by_natural_key('users'), users_group) - - -@skipIfCustomUser -@override_settings(USE_TZ=False) -class LoadDataWithoutNaturalKeysTestCase(TestCase): - fixtures = ['regular.json'] - - def test_user_is_created_and_added_to_group(self): - user = User.objects.get(username='my_username') - group = Group.objects.get(name='my_group') - self.assertEqual(group, user.groups.get()) - - -@skipIfCustomUser -@override_settings(USE_TZ=False) -class LoadDataWithNaturalKeysTestCase(TestCase): - fixtures = ['natural.json'] - - def test_user_is_created_and_added_to_group(self): - user = User.objects.get(username='my_username') - group = Group.objects.get(name='my_group') - self.assertEqual(group, user.groups.get()) - - -class LoadDataWithNaturalKeysAndMultipleDatabasesTestCase(TestCase): - multi_db = True - - def test_load_data_with_user_permissions(self): - # Create test contenttypes for both databases - default_objects = [ - ContentType.objects.db_manager('default').create( - model='examplemodela', - app_label='app_a', - ), - ContentType.objects.db_manager('default').create( - model='examplemodelb', - app_label='app_b', - ), - ] - other_objects = [ - ContentType.objects.db_manager('other').create( - model='examplemodelb', - app_label='app_b', - ), - ContentType.objects.db_manager('other').create( - model='examplemodela', - app_label='app_a', - ), - ] - - # Now we create the test UserPermission - Permission.objects.db_manager("default").create( - name="Can delete example model b", - codename="delete_examplemodelb", - content_type=default_objects[1], - ) - Permission.objects.db_manager("other").create( - name="Can delete example model b", - codename="delete_examplemodelb", - content_type=other_objects[0], - ) - - perm_default = Permission.objects.get_by_natural_key( - 'delete_examplemodelb', - 'app_b', - 'examplemodelb', - ) - - perm_other = Permission.objects.db_manager('other').get_by_natural_key( - 'delete_examplemodelb', - 'app_b', - 'examplemodelb', - ) - - self.assertEqual(perm_default.content_type_id, default_objects[1].id) - self.assertEqual(perm_other.content_type_id, other_objects[0].id) - - -@skipIfCustomUser -class UserManagerTestCase(TestCase): - - def test_create_user(self): - email_lowercase = 'normal@normal.com' - user = User.objects.create_user('user', email_lowercase) - self.assertEqual(user.email, email_lowercase) - self.assertEqual(user.username, 'user') - self.assertFalse(user.has_usable_password()) - - def test_create_user_email_domain_normalize_rfc3696(self): - # According to http://tools.ietf.org/html/rfc3696#section-3 - # the "@" symbol can be part of the local part of an email address - returned = UserManager.normalize_email(r'Abc\@DEF@EXAMPLE.com') - self.assertEqual(returned, r'Abc\@DEF@example.com') - - def test_create_user_email_domain_normalize(self): - returned = UserManager.normalize_email('normal@DOMAIN.COM') - self.assertEqual(returned, 'normal@domain.com') - - def test_create_user_email_domain_normalize_with_whitespace(self): - returned = UserManager.normalize_email('email\ with_whitespace@D.COM') - self.assertEqual(returned, 'email\ with_whitespace@d.com') - - def test_empty_username(self): - self.assertRaisesMessage( - ValueError, - 'The given username must be set', - User.objects.create_user, username='' - ) - - -class AbstractUserTestCase(TestCase): - def test_email_user(self): - # valid send_mail parameters - kwargs = { - "fail_silently": False, - "auth_user": None, - "auth_password": None, - "connection": None, - "html_message": None, - } - abstract_user = AbstractUser(email='foo@bar.com') - abstract_user.email_user(subject="Subject here", - message="This is a message", from_email="from@domain.com", **kwargs) - # Test that one message has been sent. - self.assertEqual(len(mail.outbox), 1) - # Verify that test email contains the correct attributes: - message = mail.outbox[0] - self.assertEqual(message.subject, "Subject here") - self.assertEqual(message.body, "This is a message") - self.assertEqual(message.from_email, "from@domain.com") - self.assertEqual(message.to, [abstract_user.email]) - - def test_last_login_default(self): - user1 = User.objects.create(username='user1') - self.assertIsNone(user1.last_login) - - user2 = User.objects.create_user(username='user2') - self.assertIsNone(user2.last_login) - - -class IsActiveTestCase(TestCase): - """ - Tests the behavior of the guaranteed is_active attribute - """ - - @skipIfCustomUser - def test_builtin_user_isactive(self): - user = User.objects.create(username='foo', email='foo@bar.com') - # is_active is true by default - self.assertEqual(user.is_active, True) - user.is_active = False - user.save() - user_fetched = User.objects.get(pk=user.pk) - # the is_active flag is saved - self.assertFalse(user_fetched.is_active) - - @override_settings(AUTH_USER_MODEL='auth.IsActiveTestUser1') - def test_is_active_field_default(self): - """ - tests that the default value for is_active is provided - """ - UserModel = get_user_model() - user = UserModel(username='foo') - self.assertEqual(user.is_active, True) - # you can set the attribute - but it will not save - user.is_active = False - # there should be no problem saving - but the attribute is not saved - user.save() - user_fetched = UserModel._default_manager.get(pk=user.pk) - # the attribute is always true for newly retrieved instance - self.assertEqual(user_fetched.is_active, True) - - -@skipIfCustomUser -class TestCreateSuperUserSignals(TestCase): - """ - Simple test case for ticket #20541 - """ - def post_save_listener(self, *args, **kwargs): - self.signals_count += 1 - - def setUp(self): - self.signals_count = 0 - post_save.connect(self.post_save_listener, sender=User) - - def tearDown(self): - post_save.disconnect(self.post_save_listener, sender=User) - - def test_create_user(self): - User.objects.create_user("JohnDoe") - self.assertEqual(self.signals_count, 1) - - def test_create_superuser(self): - User.objects.create_superuser("JohnDoe", "mail@example.com", "1") - self.assertEqual(self.signals_count, 1) diff --git a/django/contrib/auth/tests/test_remote_user.py b/django/contrib/auth/tests/test_remote_user.py deleted file mode 100644 index 6f7de6f2ef..0000000000 --- a/django/contrib/auth/tests/test_remote_user.py +++ /dev/null @@ -1,239 +0,0 @@ -from datetime import datetime - -from django.conf import settings -from django.contrib.auth import authenticate -from django.contrib.auth.backends import RemoteUserBackend -from django.contrib.auth.middleware import RemoteUserMiddleware -from django.contrib.auth.models import User -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.test import TestCase, modify_settings, override_settings -from django.utils import timezone - - -@skipIfCustomUser -@override_settings(ROOT_URLCONF='django.contrib.auth.tests.urls') -class RemoteUserTest(TestCase): - - middleware = 'django.contrib.auth.middleware.RemoteUserMiddleware' - backend = 'django.contrib.auth.backends.RemoteUserBackend' - header = 'REMOTE_USER' - - # Usernames to be passed in REMOTE_USER for the test_known_user test case. - known_user = 'knownuser' - known_user2 = 'knownuser2' - - def setUp(self): - self.patched_settings = modify_settings( - AUTHENTICATION_BACKENDS={'append': self.backend}, - MIDDLEWARE_CLASSES={'append': self.middleware}, - ) - self.patched_settings.enable() - - def tearDown(self): - self.patched_settings.disable() - - def test_no_remote_user(self): - """ - Tests requests where no remote user is specified and insures that no - users get created. - """ - num_users = User.objects.count() - - response = self.client.get('/remote_user/') - self.assertTrue(response.context['user'].is_anonymous()) - self.assertEqual(User.objects.count(), num_users) - - response = self.client.get('/remote_user/', **{self.header: None}) - self.assertTrue(response.context['user'].is_anonymous()) - self.assertEqual(User.objects.count(), num_users) - - response = self.client.get('/remote_user/', **{self.header: ''}) - self.assertTrue(response.context['user'].is_anonymous()) - self.assertEqual(User.objects.count(), num_users) - - def test_unknown_user(self): - """ - Tests the case where the username passed in the header does not exist - as a User. - """ - num_users = User.objects.count() - response = self.client.get('/remote_user/', **{self.header: 'newuser'}) - self.assertEqual(response.context['user'].username, 'newuser') - self.assertEqual(User.objects.count(), num_users + 1) - User.objects.get(username='newuser') - - # Another request with same user should not create any new users. - response = self.client.get('/remote_user/', **{self.header: 'newuser'}) - self.assertEqual(User.objects.count(), num_users + 1) - - def test_known_user(self): - """ - Tests the case where the username passed in the header is a valid User. - """ - User.objects.create(username='knownuser') - User.objects.create(username='knownuser2') - num_users = User.objects.count() - response = self.client.get('/remote_user/', - **{self.header: self.known_user}) - self.assertEqual(response.context['user'].username, 'knownuser') - self.assertEqual(User.objects.count(), num_users) - # Test that a different user passed in the headers causes the new user - # to be logged in. - response = self.client.get('/remote_user/', - **{self.header: self.known_user2}) - self.assertEqual(response.context['user'].username, 'knownuser2') - self.assertEqual(User.objects.count(), num_users) - - def test_last_login(self): - """ - Tests that a user's last_login is set the first time they make a - request but not updated in subsequent requests with the same session. - """ - user = User.objects.create(username='knownuser') - # Set last_login to something so we can determine if it changes. - default_login = datetime(2000, 1, 1) - if settings.USE_TZ: - default_login = default_login.replace(tzinfo=timezone.utc) - user.last_login = default_login - user.save() - - response = self.client.get('/remote_user/', - **{self.header: self.known_user}) - self.assertNotEqual(default_login, response.context['user'].last_login) - - user = User.objects.get(username='knownuser') - user.last_login = default_login - user.save() - response = self.client.get('/remote_user/', - **{self.header: self.known_user}) - self.assertEqual(default_login, response.context['user'].last_login) - - def test_header_disappears(self): - """ - Tests that a logged in user is logged out automatically when - the REMOTE_USER header disappears during the same browser session. - """ - User.objects.create(username='knownuser') - # Known user authenticates - response = self.client.get('/remote_user/', - **{self.header: self.known_user}) - self.assertEqual(response.context['user'].username, 'knownuser') - # During the session, the REMOTE_USER header disappears. Should trigger logout. - response = self.client.get('/remote_user/') - self.assertEqual(response.context['user'].is_anonymous(), True) - # verify the remoteuser middleware will not remove a user - # authenticated via another backend - User.objects.create_user(username='modeluser', password='foo') - self.client.login(username='modeluser', password='foo') - authenticate(username='modeluser', password='foo') - response = self.client.get('/remote_user/') - self.assertEqual(response.context['user'].username, 'modeluser') - - def test_user_switch_forces_new_login(self): - """ - Tests that if the username in the header changes between requests - that the original user is logged out - """ - User.objects.create(username='knownuser') - # Known user authenticates - response = self.client.get('/remote_user/', - **{self.header: self.known_user}) - self.assertEqual(response.context['user'].username, 'knownuser') - # During the session, the REMOTE_USER changes to a different user. - response = self.client.get('/remote_user/', - **{self.header: "newnewuser"}) - # Ensure that the current user is not the prior remote_user - # In backends that create a new user, username is "newnewuser" - # In backends that do not create new users, it is '' (anonymous user) - self.assertNotEqual(response.context['user'].username, 'knownuser') - - -class RemoteUserNoCreateBackend(RemoteUserBackend): - """Backend that doesn't create unknown users.""" - create_unknown_user = False - - -@skipIfCustomUser -class RemoteUserNoCreateTest(RemoteUserTest): - """ - Contains the same tests as RemoteUserTest, but using a custom auth backend - class that doesn't create unknown users. - """ - - backend = 'django.contrib.auth.tests.test_remote_user.RemoteUserNoCreateBackend' - - def test_unknown_user(self): - num_users = User.objects.count() - response = self.client.get('/remote_user/', **{self.header: 'newuser'}) - self.assertTrue(response.context['user'].is_anonymous()) - self.assertEqual(User.objects.count(), num_users) - - -class CustomRemoteUserBackend(RemoteUserBackend): - """ - Backend that overrides RemoteUserBackend methods. - """ - - def clean_username(self, username): - """ - Grabs username before the @ character. - """ - return username.split('@')[0] - - def configure_user(self, user): - """ - Sets user's email address. - """ - user.email = 'user@example.com' - user.save() - return user - - -@skipIfCustomUser -class RemoteUserCustomTest(RemoteUserTest): - """ - Tests a custom RemoteUserBackend subclass that overrides the clean_username - and configure_user methods. - """ - - backend = 'django.contrib.auth.tests.test_remote_user.CustomRemoteUserBackend' - # REMOTE_USER strings with email addresses for the custom backend to - # clean. - known_user = 'knownuser@example.com' - known_user2 = 'knownuser2@example.com' - - def test_known_user(self): - """ - The strings passed in REMOTE_USER should be cleaned and the known users - should not have been configured with an email address. - """ - super(RemoteUserCustomTest, self).test_known_user() - self.assertEqual(User.objects.get(username='knownuser').email, '') - self.assertEqual(User.objects.get(username='knownuser2').email, '') - - def test_unknown_user(self): - """ - The unknown user created should be configured with an email address. - """ - super(RemoteUserCustomTest, self).test_unknown_user() - newuser = User.objects.get(username='newuser') - self.assertEqual(newuser.email, 'user@example.com') - - -class CustomHeaderMiddleware(RemoteUserMiddleware): - """ - Middleware that overrides custom HTTP auth user header. - """ - header = 'HTTP_AUTHUSER' - - -@skipIfCustomUser -class CustomHeaderRemoteUserTest(RemoteUserTest): - """ - Tests a custom RemoteUserMiddleware subclass with custom HTTP auth user - header. - """ - middleware = ( - 'django.contrib.auth.tests.test_remote_user.CustomHeaderMiddleware' - ) - header = 'HTTP_AUTHUSER' diff --git a/django/contrib/auth/tests/test_signals.py b/django/contrib/auth/tests/test_signals.py deleted file mode 100644 index 909c28a36d..0000000000 --- a/django/contrib/auth/tests/test_signals.py +++ /dev/null @@ -1,80 +0,0 @@ -from django.contrib.auth import signals -from django.contrib.auth.models import User -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.test import TestCase, override_settings -from django.test.client import RequestFactory - - -@skipIfCustomUser -@override_settings(USE_TZ=False, - PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], - ROOT_URLCONF='django.contrib.auth.tests.urls') -class SignalTestCase(TestCase): - fixtures = ['authtestdata.json'] - - def listener_login(self, user, **kwargs): - self.logged_in.append(user) - - def listener_logout(self, user, **kwargs): - self.logged_out.append(user) - - def listener_login_failed(self, sender, credentials, **kwargs): - self.login_failed.append(credentials) - - def setUp(self): - """Set up the listeners and reset the logged in/logged out counters""" - self.logged_in = [] - self.logged_out = [] - self.login_failed = [] - signals.user_logged_in.connect(self.listener_login) - signals.user_logged_out.connect(self.listener_logout) - signals.user_login_failed.connect(self.listener_login_failed) - - def tearDown(self): - """Disconnect the listeners""" - signals.user_logged_in.disconnect(self.listener_login) - signals.user_logged_out.disconnect(self.listener_logout) - signals.user_login_failed.disconnect(self.listener_login_failed) - - def test_login(self): - # Only a successful login will trigger the success signal. - self.client.login(username='testclient', password='bad') - self.assertEqual(len(self.logged_in), 0) - self.assertEqual(len(self.login_failed), 1) - self.assertEqual(self.login_failed[0]['username'], 'testclient') - # verify the password is cleansed - self.assertIn('***', self.login_failed[0]['password']) - - # Like this: - self.client.login(username='testclient', password='password') - self.assertEqual(len(self.logged_in), 1) - self.assertEqual(self.logged_in[0].username, 'testclient') - - # Ensure there were no more failures. - self.assertEqual(len(self.login_failed), 1) - - def test_logout_anonymous(self): - # The log_out function will still trigger the signal for anonymous - # users. - self.client.get('/logout/next_page/') - self.assertEqual(len(self.logged_out), 1) - self.assertEqual(self.logged_out[0], None) - - def test_logout(self): - self.client.login(username='testclient', password='password') - self.client.get('/logout/next_page/') - self.assertEqual(len(self.logged_out), 1) - self.assertEqual(self.logged_out[0].username, 'testclient') - - def test_update_last_login(self): - """Ensure that only `last_login` is updated in `update_last_login`""" - user = User.objects.get(pk=3) - old_last_login = user.last_login - - user.username = "This username shouldn't get saved" - request = RequestFactory().get('/login') - signals.user_logged_in.send(sender=user.__class__, request=request, - user=user) - user = User.objects.get(pk=3) - self.assertEqual(user.username, 'staff') - self.assertNotEqual(user.last_login, old_last_login) diff --git a/django/contrib/auth/tests/test_templates.py b/django/contrib/auth/tests/test_templates.py deleted file mode 100644 index ab3aea42db..0000000000 --- a/django/contrib/auth/tests/test_templates.py +++ /dev/null @@ -1,59 +0,0 @@ -from django.contrib.auth import authenticate -from django.contrib.auth.models import User -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.contrib.auth.tokens import PasswordResetTokenGenerator -from django.contrib.auth.views import ( - password_change, password_change_done, password_reset, - password_reset_complete, password_reset_confirm, password_reset_done, -) -from django.test import RequestFactory, TestCase, override_settings -from django.utils.encoding import force_bytes, force_text -from django.utils.http import urlsafe_base64_encode - - -@skipIfCustomUser -@override_settings( - PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], - ROOT_URLCONF='django.contrib.auth.tests.urls', -) -class AuthTemplateTests(TestCase): - - def test_titles(self): - rf = RequestFactory() - user = User.objects.create_user('jsmith', 'jsmith@example.com', 'pass') - user = authenticate(username=user.username, password='pass') - request = rf.get('/somepath/') - request.user = user - - response = password_reset(request, post_reset_redirect='dummy/') - self.assertContains(response, '<title>Password reset</title>') - self.assertContains(response, '<h1>Password reset</h1>') - - response = password_reset_done(request) - self.assertContains(response, '<title>Password reset sent</title>') - self.assertContains(response, '<h1>Password reset sent</h1>') - - # password_reset_confirm invalid token - response = password_reset_confirm(request, uidb64='Bad', token='Bad', post_reset_redirect='dummy/') - self.assertContains(response, '<title>Password reset unsuccessful</title>') - self.assertContains(response, '<h1>Password reset unsuccessful</h1>') - - # password_reset_confirm valid token - default_token_generator = PasswordResetTokenGenerator() - token = default_token_generator.make_token(user) - uidb64 = force_text(urlsafe_base64_encode(force_bytes(user.pk))) - response = password_reset_confirm(request, uidb64, token, post_reset_redirect='dummy/') - self.assertContains(response, '<title>Enter new password</title>') - self.assertContains(response, '<h1>Enter new password</h1>') - - response = password_reset_complete(request) - self.assertContains(response, '<title>Password reset complete</title>') - self.assertContains(response, '<h1>Password reset complete</h1>') - - response = password_change(request, post_change_redirect='dummy/') - self.assertContains(response, '<title>Password change</title>') - self.assertContains(response, '<h1>Password change</h1>') - - response = password_change_done(request) - self.assertContains(response, '<title>Password change successful</title>') - self.assertContains(response, '<h1>Password change successful</h1>') diff --git a/django/contrib/auth/tests/test_tokens.py b/django/contrib/auth/tests/test_tokens.py deleted file mode 100644 index b9433bdcfa..0000000000 --- a/django/contrib/auth/tests/test_tokens.py +++ /dev/null @@ -1,70 +0,0 @@ -import sys -import unittest -from datetime import date, timedelta - -from django.conf import settings -from django.contrib.auth.models import User -from django.contrib.auth.tests.utils import skipIfCustomUser -from django.contrib.auth.tokens import PasswordResetTokenGenerator -from django.test import TestCase - - -@skipIfCustomUser -class TokenGeneratorTest(TestCase): - - def test_make_token(self): - """ - Ensure that we can make a token and that it is valid - """ - user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw') - p0 = PasswordResetTokenGenerator() - tk1 = p0.make_token(user) - self.assertTrue(p0.check_token(user, tk1)) - - def test_10265(self): - """ - Ensure that the token generated for a user created in the same request - will work correctly. - """ - # See ticket #10265 - user = User.objects.create_user('comebackkid', 'test3@example.com', 'testpw') - p0 = PasswordResetTokenGenerator() - tk1 = p0.make_token(user) - reload = User.objects.get(username='comebackkid') - tk2 = p0.make_token(reload) - self.assertEqual(tk1, tk2) - - def test_timeout(self): - """ - Ensure we can use the token after n days, but no greater. - """ - # Uses a mocked version of PasswordResetTokenGenerator so we can change - # the value of 'today' - class Mocked(PasswordResetTokenGenerator): - def __init__(self, today): - self._today_val = today - - def _today(self): - return self._today_val - - user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw') - p0 = PasswordResetTokenGenerator() - tk1 = p0.make_token(user) - p1 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS)) - self.assertTrue(p1.check_token(user, tk1)) - - p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1)) - self.assertFalse(p2.check_token(user, tk1)) - - @unittest.skipIf(sys.version_info[:2] >= (3, 0), "Unnecessary test with Python 3") - def test_date_length(self): - """ - Make sure we don't allow overly long dates, causing a potential DoS. - """ - user = User.objects.create_user('ima1337h4x0r', 'test4@example.com', 'p4ssw0rd') - p0 = PasswordResetTokenGenerator() - - # This will put a 14-digit base36 timestamp into the token, which is too large. - self.assertRaises(ValueError, - p0._make_token_with_timestamp, - user, 175455491841851871349) diff --git a/django/contrib/auth/tests/test_views.py b/django/contrib/auth/tests/test_views.py deleted file mode 100644 index f125c1799a..0000000000 --- a/django/contrib/auth/tests/test_views.py +++ /dev/null @@ -1,915 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -import itertools -import re -from importlib import import_module - -from django.apps import apps -from django.conf import settings -from django.contrib.admin.models import LogEntry -from django.contrib.auth import REDIRECT_FIELD_NAME, SESSION_KEY -from django.contrib.auth.forms import ( - AuthenticationForm, PasswordChangeForm, SetPasswordForm, -) -from django.contrib.auth.models import User -from django.contrib.auth.views import login as login_view, redirect_to_login -from django.contrib.sessions.middleware import SessionMiddleware -from django.contrib.sites.requests import RequestSite -from django.core import mail -from django.core.urlresolvers import NoReverseMatch, reverse, reverse_lazy -from django.http import HttpRequest, QueryDict -from django.middleware.csrf import CsrfViewMiddleware -from django.test import ( - TestCase, ignore_warnings, modify_settings, override_settings, -) -from django.test.utils import patch_logger -from django.utils.deprecation import RemovedInDjango20Warning -from django.utils.encoding import force_text -from django.utils.http import urlquote -from django.utils.six.moves.urllib.parse import ParseResult, urlparse -from django.utils.translation import LANGUAGE_SESSION_KEY - -# Needed so model is installed when tests are run independently: -from .custom_user import CustomUser # NOQA -from .settings import AUTH_TEMPLATES -from .utils import skipIfCustomUser - - -@override_settings( - LANGUAGES=[ - ('en', 'English'), - ], - LANGUAGE_CODE='en', - TEMPLATES=AUTH_TEMPLATES, - USE_TZ=False, - PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], - ROOT_URLCONF='django.contrib.auth.tests.urls', -) -class AuthViewsTestCase(TestCase): - """ - Helper base class for all the follow test cases. - """ - fixtures = ['authtestdata.json'] - - def login(self, username='testclient', password='password'): - response = self.client.post('/login/', { - 'username': username, - 'password': password, - }) - self.assertIn(SESSION_KEY, self.client.session) - return response - - def logout(self): - response = self.client.get('/admin/logout/') - self.assertEqual(response.status_code, 200) - self.assertNotIn(SESSION_KEY, self.client.session) - - def assertFormError(self, response, error): - """Assert that error is found in response.context['form'] errors""" - form_errors = list(itertools.chain(*response.context['form'].errors.values())) - self.assertIn(force_text(error), form_errors) - - def assertURLEqual(self, url, expected, parse_qs=False): - """ - Given two URLs, make sure all their components (the ones given by - urlparse) are equal, only comparing components that are present in both - URLs. - If `parse_qs` is True, then the querystrings are parsed with QueryDict. - This is useful if you don't want the order of parameters to matter. - Otherwise, the query strings are compared as-is. - """ - fields = ParseResult._fields - - for attr, x, y in zip(fields, urlparse(url), urlparse(expected)): - if parse_qs and attr == 'query': - x, y = QueryDict(x), QueryDict(y) - if x and y and x != y: - self.fail("%r != %r (%s doesn't match)" % (url, expected, attr)) - - -@skipIfCustomUser -@override_settings(ROOT_URLCONF='django.contrib.auth.urls') -class AuthViewNamedURLTests(AuthViewsTestCase): - - def test_named_urls(self): - "Named URLs should be reversible" - expected_named_urls = [ - ('login', [], {}), - ('logout', [], {}), - ('password_change', [], {}), - ('password_change_done', [], {}), - ('password_reset', [], {}), - ('password_reset_done', [], {}), - ('password_reset_confirm', [], { - 'uidb64': 'aaaaaaa', - 'token': '1111-aaaaa', - }), - ('password_reset_complete', [], {}), - ] - for name, args, kwargs in expected_named_urls: - try: - reverse(name, args=args, kwargs=kwargs) - except NoReverseMatch: - self.fail("Reversal of url named '%s' failed with NoReverseMatch" % name) - - -@skipIfCustomUser -class PasswordResetTest(AuthViewsTestCase): - - def test_email_not_found(self): - """If the provided email is not registered, don't raise any error but - also don't send any email.""" - response = self.client.get('/password_reset/') - self.assertEqual(response.status_code, 200) - response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'}) - self.assertEqual(response.status_code, 302) - self.assertEqual(len(mail.outbox), 0) - - def test_email_found(self): - "Email is sent if a valid email address is provided for password reset" - response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'}) - self.assertEqual(response.status_code, 302) - self.assertEqual(len(mail.outbox), 1) - self.assertIn("http://", mail.outbox[0].body) - self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email) - # optional multipart text/html email has been added. Make sure original, - # default functionality is 100% the same - self.assertFalse(mail.outbox[0].message().is_multipart()) - - def test_html_mail_template(self): - """ - A multipart email with text/plain and text/html is sent - if the html_email_template parameter is passed to the view - """ - response = self.client.post('/password_reset/html_email_template/', {'email': 'staffmember@example.com'}) - self.assertEqual(response.status_code, 302) - self.assertEqual(len(mail.outbox), 1) - message = mail.outbox[0].message() - 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.assertNotIn('<html>', message.get_payload(0).get_payload()) - self.assertIn('<html>', message.get_payload(1).get_payload()) - - def test_email_found_custom_from(self): - "Email is sent if a valid email address is provided for password reset when a custom from_email is provided." - response = self.client.post('/password_reset_from_email/', {'email': 'staffmember@example.com'}) - self.assertEqual(response.status_code, 302) - self.assertEqual(len(mail.outbox), 1) - self.assertEqual("staffmember@example.com", mail.outbox[0].from_email) - - @ignore_warnings(category=RemovedInDjango20Warning) - @override_settings(ALLOWED_HOSTS=['adminsite.com']) - def test_admin_reset(self): - "If the reset view is marked as being for admin, the HTTP_HOST header is used for a domain override." - response = self.client.post('/admin_password_reset/', - {'email': 'staffmember@example.com'}, - HTTP_HOST='adminsite.com' - ) - self.assertEqual(response.status_code, 302) - self.assertEqual(len(mail.outbox), 1) - self.assertIn("http://adminsite.com", mail.outbox[0].body) - self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email) - - # Skip any 500 handler action (like sending more mail...) - @override_settings(DEBUG_PROPAGATE_EXCEPTIONS=True) - def test_poisoned_http_host(self): - "Poisoned HTTP_HOST headers can't be used for reset emails" - # This attack is based on the way browsers handle URLs. The colon - # should be used to separate the port, but if the URL contains an @, - # the colon is interpreted as part of a username for login purposes, - # making 'evil.com' the request domain. Since HTTP_HOST is used to - # produce a meaningful reset URL, we need to be certain that the - # HTTP_HOST header isn't poisoned. This is done as a check when get_host() - # is invoked, but we check here as a practical consequence. - with patch_logger('django.security.DisallowedHost', 'error') as logger_calls: - response = self.client.post( - '/password_reset/', - {'email': 'staffmember@example.com'}, - HTTP_HOST='www.example:dr.frankenstein@evil.tld' - ) - self.assertEqual(response.status_code, 400) - self.assertEqual(len(mail.outbox), 0) - self.assertEqual(len(logger_calls), 1) - - # Skip any 500 handler action (like sending more mail...) - @override_settings(DEBUG_PROPAGATE_EXCEPTIONS=True) - def test_poisoned_http_host_admin_site(self): - "Poisoned HTTP_HOST headers can't be used for reset emails on admin views" - with patch_logger('django.security.DisallowedHost', 'error') as logger_calls: - response = self.client.post( - '/admin_password_reset/', - {'email': 'staffmember@example.com'}, - HTTP_HOST='www.example:dr.frankenstein@evil.tld' - ) - self.assertEqual(response.status_code, 400) - self.assertEqual(len(mail.outbox), 0) - self.assertEqual(len(logger_calls), 1) - - def _test_confirm_start(self): - # Start by creating the email - self.client.post('/password_reset/', {'email': 'staffmember@example.com'}) - self.assertEqual(len(mail.outbox), 1) - return self._read_signup_email(mail.outbox[0]) - - def _read_signup_email(self, email): - urlmatch = re.search(r"https?://[^/]*(/.*reset/\S*)", email.body) - self.assertIsNotNone(urlmatch, "No URL found in sent email") - return urlmatch.group(), urlmatch.groups()[0] - - def test_confirm_valid(self): - url, path = self._test_confirm_start() - response = self.client.get(path) - # redirect to a 'complete' page: - self.assertContains(response, "Please enter your new password") - - def test_confirm_invalid(self): - url, path = self._test_confirm_start() - # Let's munge the token in the path, but keep the same length, - # in case the URLconf will reject a different length. - path = path[:-5] + ("0" * 4) + path[-1] - - response = self.client.get(path) - self.assertContains(response, "The password reset link was invalid") - - def test_confirm_invalid_user(self): - # Ensure that we get a 200 response for a non-existent user, not a 404 - response = self.client.get('/reset/123456/1-1/') - self.assertContains(response, "The password reset link was invalid") - - def test_confirm_overflow_user(self): - # Ensure that we get a 200 response for a base36 user id that overflows int - response = self.client.get('/reset/zzzzzzzzzzzzz/1-1/') - self.assertContains(response, "The password reset link was invalid") - - def test_confirm_invalid_post(self): - # Same as test_confirm_invalid, but trying - # to do a POST instead. - url, path = self._test_confirm_start() - path = path[:-5] + ("0" * 4) + path[-1] - - self.client.post(path, { - 'new_password1': 'anewpassword', - 'new_password2': ' anewpassword', - }) - # Check the password has not been changed - u = User.objects.get(email='staffmember@example.com') - self.assertTrue(not u.check_password("anewpassword")) - - def test_confirm_complete(self): - url, path = self._test_confirm_start() - response = self.client.post(path, {'new_password1': 'anewpassword', - 'new_password2': 'anewpassword'}) - # Check the password has been changed - u = User.objects.get(email='staffmember@example.com') - self.assertTrue(u.check_password("anewpassword")) - - # Check we can't use the link again - response = self.client.get(path) - self.assertContains(response, "The password reset link was invalid") - - def test_confirm_different_passwords(self): - url, path = self._test_confirm_start() - response = self.client.post(path, {'new_password1': 'anewpassword', - 'new_password2': 'x'}) - self.assertFormError(response, SetPasswordForm.error_messages['password_mismatch']) - - def test_reset_redirect_default(self): - response = self.client.post('/password_reset/', - {'email': 'staffmember@example.com'}) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/password_reset/done/') - - def test_reset_custom_redirect(self): - response = self.client.post('/password_reset/custom_redirect/', - {'email': 'staffmember@example.com'}) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/custom/') - - def test_reset_custom_redirect_named(self): - response = self.client.post('/password_reset/custom_redirect/named/', - {'email': 'staffmember@example.com'}) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/password_reset/') - - def test_confirm_redirect_default(self): - url, path = self._test_confirm_start() - response = self.client.post(path, {'new_password1': 'anewpassword', - 'new_password2': 'anewpassword'}) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/reset/done/') - - def test_confirm_redirect_custom(self): - url, path = self._test_confirm_start() - path = path.replace('/reset/', '/reset/custom/') - response = self.client.post(path, {'new_password1': 'anewpassword', - 'new_password2': 'anewpassword'}) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/custom/') - - def test_confirm_redirect_custom_named(self): - url, path = self._test_confirm_start() - path = path.replace('/reset/', '/reset/custom/named/') - response = self.client.post(path, {'new_password1': 'anewpassword', - 'new_password2': 'anewpassword'}) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/password_reset/') - - def test_confirm_display_user_from_form(self): - url, path = self._test_confirm_start() - response = self.client.get(path) - - # #16919 -- The ``password_reset_confirm`` view should pass the user - # object to the ``SetPasswordForm``, even on GET requests. - # For this test, we render ``{{ form.user }}`` in the template - # ``registration/password_reset_confirm.html`` so that we can test this. - username = User.objects.get(email='staffmember@example.com').username - self.assertContains(response, "Hello, %s." % username) - - # However, the view should NOT pass any user object on a form if the - # password reset link was invalid. - response = self.client.get('/reset/zzzzzzzzzzzzz/1-1/') - self.assertContains(response, "Hello, .") - - -@override_settings(AUTH_USER_MODEL='auth.CustomUser') -class CustomUserPasswordResetTest(AuthViewsTestCase): - fixtures = ['custom_user.json'] - - def _test_confirm_start(self): - # Start by creating the email - response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'}) - self.assertEqual(response.status_code, 302) - self.assertEqual(len(mail.outbox), 1) - return self._read_signup_email(mail.outbox[0]) - - def _read_signup_email(self, email): - urlmatch = re.search(r"https?://[^/]*(/.*reset/\S*)", email.body) - self.assertIsNotNone(urlmatch, "No URL found in sent email") - return urlmatch.group(), urlmatch.groups()[0] - - def test_confirm_valid_custom_user(self): - url, path = self._test_confirm_start() - response = self.client.get(path) - # redirect to a 'complete' page: - self.assertContains(response, "Please enter your new password") - - -@skipIfCustomUser -class ChangePasswordTest(AuthViewsTestCase): - - def fail_login(self, password='password'): - response = self.client.post('/login/', { - 'username': 'testclient', - 'password': password, - }) - self.assertFormError(response, AuthenticationForm.error_messages['invalid_login'] % { - 'username': User._meta.get_field('username').verbose_name - }) - - def logout(self): - self.client.get('/logout/') - - def test_password_change_fails_with_invalid_old_password(self): - self.login() - response = self.client.post('/password_change/', { - 'old_password': 'donuts', - 'new_password1': 'password1', - 'new_password2': 'password1', - }) - self.assertFormError(response, PasswordChangeForm.error_messages['password_incorrect']) - - def test_password_change_fails_with_mismatched_passwords(self): - self.login() - response = self.client.post('/password_change/', { - 'old_password': 'password', - 'new_password1': 'password1', - 'new_password2': 'donuts', - }) - self.assertFormError(response, SetPasswordForm.error_messages['password_mismatch']) - - def test_password_change_succeeds(self): - self.login() - self.client.post('/password_change/', { - 'old_password': 'password', - 'new_password1': 'password1', - 'new_password2': 'password1', - }) - self.fail_login() - self.login(password='password1') - - def test_password_change_done_succeeds(self): - self.login() - response = self.client.post('/password_change/', { - 'old_password': 'password', - 'new_password1': 'password1', - 'new_password2': 'password1', - }) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/password_change/done/') - - @override_settings(LOGIN_URL='/login/') - def test_password_change_done_fails(self): - response = self.client.get('/password_change/done/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/login/?next=/password_change/done/') - - def test_password_change_redirect_default(self): - self.login() - response = self.client.post('/password_change/', { - 'old_password': 'password', - 'new_password1': 'password1', - 'new_password2': 'password1', - }) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/password_change/done/') - - def test_password_change_redirect_custom(self): - self.login() - response = self.client.post('/password_change/custom/', { - 'old_password': 'password', - 'new_password1': 'password1', - 'new_password2': 'password1', - }) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/custom/') - - def test_password_change_redirect_custom_named(self): - self.login() - response = self.client.post('/password_change/custom/named/', { - 'old_password': 'password', - 'new_password1': 'password1', - 'new_password2': 'password1', - }) - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/password_reset/') - - -@modify_settings(MIDDLEWARE_CLASSES={ - 'append': 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', -}) -class SessionAuthenticationTests(AuthViewsTestCase): - def test_user_password_change_updates_session(self): - """ - #21649 - Ensure contrib.auth.views.password_change updates the user's - session auth hash after a password change so the session isn't logged out. - """ - self.login() - response = self.client.post('/password_change/', { - 'old_password': 'password', - 'new_password1': 'password1', - 'new_password2': 'password1', - }) - # if the hash isn't updated, retrieving the redirection page will fail. - self.assertRedirects(response, '/password_change/done/') - - -@skipIfCustomUser -class LoginTest(AuthViewsTestCase): - - def test_current_site_in_context_after_login(self): - response = self.client.get(reverse('login')) - self.assertEqual(response.status_code, 200) - if apps.is_installed('django.contrib.sites'): - Site = apps.get_model('sites.Site') - site = Site.objects.get_current() - self.assertEqual(response.context['site'], site) - self.assertEqual(response.context['site_name'], site.name) - else: - self.assertIsInstance(response.context['site'], RequestSite) - self.assertIsInstance(response.context['form'], AuthenticationForm) - - def test_security_check(self, password='password'): - login_url = reverse('login') - - # Those URLs should not pass the security check - for bad_url in ('http://example.com', - 'http:///example.com', - 'https://example.com', - 'ftp://exampel.com', - '///example.com', - '//example.com', - 'javascript:alert("XSS")'): - - nasty_url = '%(url)s?%(next)s=%(bad_url)s' % { - 'url': login_url, - 'next': REDIRECT_FIELD_NAME, - 'bad_url': urlquote(bad_url), - } - response = self.client.post(nasty_url, { - 'username': 'testclient', - 'password': password, - }) - self.assertEqual(response.status_code, 302) - self.assertNotIn(bad_url, response.url, - "%s should be blocked" % bad_url) - - # These URLs *should* still pass the security check - for good_url in ('/view/?param=http://example.com', - '/view/?param=https://example.com', - '/view?param=ftp://exampel.com', - 'view/?param=//example.com', - 'https://testserver/', - 'HTTPS://testserver/', - '//testserver/', - '/url%20with%20spaces/'): # see ticket #12534 - safe_url = '%(url)s?%(next)s=%(good_url)s' % { - 'url': login_url, - 'next': REDIRECT_FIELD_NAME, - 'good_url': urlquote(good_url), - } - response = self.client.post(safe_url, { - 'username': 'testclient', - 'password': password, - }) - self.assertEqual(response.status_code, 302) - self.assertIn(good_url, response.url, "%s should be allowed" % good_url) - - def test_login_form_contains_request(self): - # 15198 - self.client.post('/custom_requestauth_login/', { - 'username': 'testclient', - 'password': 'password', - }, follow=True) - # the custom authentication form used by this login asserts - # that a request is passed to the form successfully. - - def test_login_csrf_rotate(self, password='password'): - """ - Makes sure that a login rotates the currently-used CSRF token. - """ - # Do a GET to establish a CSRF token - # TestClient isn't used here as we're testing middleware, essentially. - req = HttpRequest() - CsrfViewMiddleware().process_view(req, login_view, (), {}) - req.META["CSRF_COOKIE_USED"] = True - resp = login_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, None) - token1 = csrf_cookie.coded_value - - # Prepare the POST request - req = HttpRequest() - req.COOKIES[settings.CSRF_COOKIE_NAME] = token1 - req.method = "POST" - req.POST = {'username': 'testclient', 'password': password, 'csrfmiddlewaretoken': token1} - - # Use POST request to log in - SessionMiddleware().process_request(req) - CsrfViewMiddleware().process_view(req, login_view, (), {}) - req.META["SERVER_NAME"] = "testserver" # Required to have redirect work in login view - req.META["SERVER_PORT"] = 80 - resp = login_view(req) - resp2 = CsrfViewMiddleware().process_response(req, resp) - csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, None) - token2 = csrf_cookie.coded_value - - # Check the CSRF token switched - self.assertNotEqual(token1, token2) - - def test_session_key_flushed_on_login(self): - """ - To avoid reusing another user's session, ensure a new, empty session is - created if the existing session corresponds to a different authenticated - user. - """ - self.login() - original_session_key = self.client.session.session_key - - self.login(username='staff') - self.assertNotEqual(original_session_key, self.client.session.session_key) - - def test_session_key_flushed_on_login_after_password_change(self): - """ - As above, but same user logging in after a password change. - """ - self.login() - original_session_key = self.client.session.session_key - - # If no password change, session key should not be flushed. - self.login() - self.assertEqual(original_session_key, self.client.session.session_key) - - user = User.objects.get(username='testclient') - user.set_password('foobar') - user.save() - - self.login(password='foobar') - self.assertNotEqual(original_session_key, self.client.session.session_key) - - def test_login_session_without_hash_session_key(self): - """ - Session without django.contrib.auth.HASH_SESSION_KEY should login - without an exception. - """ - user = User.objects.get(username='testclient') - engine = import_module(settings.SESSION_ENGINE) - session = engine.SessionStore() - session[SESSION_KEY] = user.id - session.save() - original_session_key = session.session_key - self.client.cookies[settings.SESSION_COOKIE_NAME] = original_session_key - - self.login() - self.assertNotEqual(original_session_key, self.client.session.session_key) - - -@skipIfCustomUser -class LoginURLSettings(AuthViewsTestCase): - """Tests for settings.LOGIN_URL.""" - def assertLoginURLEquals(self, url, parse_qs=False): - response = self.client.get('/login_required/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, url, parse_qs=parse_qs) - - @override_settings(LOGIN_URL='/login/') - def test_standard_login_url(self): - self.assertLoginURLEquals('/login/?next=/login_required/') - - @override_settings(LOGIN_URL='login') - def test_named_login_url(self): - self.assertLoginURLEquals('/login/?next=/login_required/') - - @override_settings(LOGIN_URL='http://remote.example.com/login') - def test_remote_login_url(self): - quoted_next = urlquote('http://testserver/login_required/') - expected = 'http://remote.example.com/login?next=%s' % quoted_next - self.assertLoginURLEquals(expected) - - @override_settings(LOGIN_URL='https:///login/') - def test_https_login_url(self): - quoted_next = urlquote('http://testserver/login_required/') - expected = 'https:///login/?next=%s' % quoted_next - self.assertLoginURLEquals(expected) - - @override_settings(LOGIN_URL='/login/?pretty=1') - def test_login_url_with_querystring(self): - self.assertLoginURLEquals('/login/?pretty=1&next=/login_required/', parse_qs=True) - - @override_settings(LOGIN_URL='http://remote.example.com/login/?next=/default/') - def test_remote_login_url_with_next_querystring(self): - quoted_next = urlquote('http://testserver/login_required/') - expected = 'http://remote.example.com/login/?next=%s' % quoted_next - self.assertLoginURLEquals(expected) - - @override_settings(LOGIN_URL=reverse_lazy('login')) - def test_lazy_login_url(self): - self.assertLoginURLEquals('/login/?next=/login_required/') - - -@skipIfCustomUser -class LoginRedirectUrlTest(AuthViewsTestCase): - """Tests for settings.LOGIN_REDIRECT_URL.""" - def assertLoginRedirectURLEqual(self, url): - response = self.login() - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, url) - - def test_default(self): - self.assertLoginRedirectURLEqual('/accounts/profile/') - - @override_settings(LOGIN_REDIRECT_URL='/custom/') - def test_custom(self): - self.assertLoginRedirectURLEqual('/custom/') - - @override_settings(LOGIN_REDIRECT_URL='password_reset') - def test_named(self): - self.assertLoginRedirectURLEqual('/password_reset/') - - @override_settings(LOGIN_REDIRECT_URL='http://remote.example.com/welcome/') - def test_remote(self): - self.assertLoginRedirectURLEqual('http://remote.example.com/welcome/') - - -class RedirectToLoginTests(AuthViewsTestCase): - """Tests for the redirect_to_login view""" - @override_settings(LOGIN_URL=reverse_lazy('login')) - def test_redirect_to_login_with_lazy(self): - login_redirect_response = redirect_to_login(next='/else/where/') - expected = '/login/?next=/else/where/' - self.assertEqual(expected, login_redirect_response.url) - - @override_settings(LOGIN_URL=reverse_lazy('login')) - def test_redirect_to_login_with_lazy_and_unicode(self): - login_redirect_response = redirect_to_login(next='/else/where/झ/') - expected = '/login/?next=/else/where/%E0%A4%9D/' - self.assertEqual(expected, login_redirect_response.url) - - -@skipIfCustomUser -class LogoutTest(AuthViewsTestCase): - - def confirm_logged_out(self): - self.assertNotIn(SESSION_KEY, self.client.session) - - def test_logout_default(self): - "Logout without next_page option renders the default template" - self.login() - response = self.client.get('/logout/') - self.assertContains(response, 'Logged out') - self.confirm_logged_out() - - def test_14377(self): - # Bug 14377 - self.login() - response = self.client.get('/logout/') - self.assertIn('site', response.context) - - def test_logout_with_overridden_redirect_url(self): - # Bug 11223 - self.login() - response = self.client.get('/logout/next_page/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/somewhere/') - - response = self.client.get('/logout/next_page/?next=/login/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/login/') - - self.confirm_logged_out() - - def test_logout_with_next_page_specified(self): - "Logout with next_page option given redirects to specified resource" - self.login() - response = self.client.get('/logout/next_page/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/somewhere/') - self.confirm_logged_out() - - def test_logout_with_redirect_argument(self): - "Logout with query string redirects to specified resource" - self.login() - response = self.client.get('/logout/?next=/login/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/login/') - self.confirm_logged_out() - - def test_logout_with_custom_redirect_argument(self): - "Logout with custom query string redirects to specified resource" - self.login() - response = self.client.get('/logout/custom_query/?follow=/somewhere/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/somewhere/') - self.confirm_logged_out() - - def test_logout_with_named_redirect(self): - "Logout resolves names or URLs passed as next_page." - self.login() - response = self.client.get('/logout/next_page/named/') - self.assertEqual(response.status_code, 302) - self.assertURLEqual(response.url, '/password_reset/') - self.confirm_logged_out() - - def test_security_check(self, password='password'): - logout_url = reverse('logout') - - # Those URLs should not pass the security check - for bad_url in ('http://example.com', - 'http:///example.com', - 'https://example.com', - 'ftp://exampel.com', - '///example.com', - '//example.com', - 'javascript:alert("XSS")'): - nasty_url = '%(url)s?%(next)s=%(bad_url)s' % { - 'url': logout_url, - 'next': REDIRECT_FIELD_NAME, - 'bad_url': urlquote(bad_url), - } - self.login() - response = self.client.get(nasty_url) - self.assertEqual(response.status_code, 302) - self.assertNotIn(bad_url, response.url, - "%s should be blocked" % bad_url) - self.confirm_logged_out() - - # These URLs *should* still pass the security check - for good_url in ('/view/?param=http://example.com', - '/view/?param=https://example.com', - '/view?param=ftp://exampel.com', - 'view/?param=//example.com', - 'https://testserver/', - 'HTTPS://testserver/', - '//testserver/', - '/url%20with%20spaces/'): # see ticket #12534 - safe_url = '%(url)s?%(next)s=%(good_url)s' % { - 'url': logout_url, - 'next': REDIRECT_FIELD_NAME, - 'good_url': urlquote(good_url), - } - self.login() - response = self.client.get(safe_url) - self.assertEqual(response.status_code, 302) - self.assertIn(good_url, response.url, "%s should be allowed" % good_url) - self.confirm_logged_out() - - def test_logout_preserve_language(self): - """Check that language stored in session is preserved after logout""" - # Create a new session with language - engine = import_module(settings.SESSION_ENGINE) - session = engine.SessionStore() - session[LANGUAGE_SESSION_KEY] = 'pl' - session.save() - self.client.cookies[settings.SESSION_COOKIE_NAME] = session.session_key - - self.client.get('/logout/') - self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], 'pl') - - -# Redirect in test_user_change_password will fail if session auth hash -# isn't updated after password change (#21649) -@skipIfCustomUser -@modify_settings(MIDDLEWARE_CLASSES={ - 'append': 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', -}) -@override_settings( - PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'], - ROOT_URLCONF='django.contrib.auth.tests.urls_admin', -) -class ChangelistTests(AuthViewsTestCase): - - def setUp(self): - # Make me a superuser before logging in. - User.objects.filter(username='testclient').update(is_staff=True, is_superuser=True) - self.login() - self.admin = User.objects.get(pk=1) - - def get_user_data(self, user): - return { - 'username': user.username, - 'password': user.password, - 'email': user.email, - 'is_active': user.is_active, - 'is_staff': user.is_staff, - 'is_superuser': user.is_superuser, - 'last_login_0': user.last_login.strftime('%Y-%m-%d'), - 'last_login_1': user.last_login.strftime('%H:%M:%S'), - 'initial-last_login_0': user.last_login.strftime('%Y-%m-%d'), - 'initial-last_login_1': user.last_login.strftime('%H:%M:%S'), - 'date_joined_0': user.date_joined.strftime('%Y-%m-%d'), - 'date_joined_1': user.date_joined.strftime('%H:%M:%S'), - 'initial-date_joined_0': user.date_joined.strftime('%Y-%m-%d'), - 'initial-date_joined_1': user.date_joined.strftime('%H:%M:%S'), - 'first_name': user.first_name, - 'last_name': user.last_name, - } - - # #20078 - users shouldn't be allowed to guess password hashes via - # repeated password__startswith queries. - def test_changelist_disallows_password_lookups(self): - # A lookup that tries to filter on password isn't OK - with patch_logger('django.security.DisallowedModelAdminLookup', 'error') as logger_calls: - response = self.client.get(reverse('auth_test_admin:auth_user_changelist') + '?password__startswith=sha1$') - self.assertEqual(response.status_code, 400) - self.assertEqual(len(logger_calls), 1) - - def test_user_change_email(self): - data = self.get_user_data(self.admin) - data['email'] = 'new_' + data['email'] - response = self.client.post( - reverse('auth_test_admin:auth_user_change', args=(self.admin.pk,)), - data - ) - self.assertRedirects(response, reverse('auth_test_admin:auth_user_changelist')) - row = LogEntry.objects.latest('id') - self.assertEqual(row.change_message, 'Changed email.') - - def test_user_not_change(self): - response = self.client.post( - reverse('auth_test_admin:auth_user_change', args=(self.admin.pk,)), - self.get_user_data(self.admin) - ) - self.assertRedirects(response, reverse('auth_test_admin:auth_user_changelist')) - row = LogEntry.objects.latest('id') - self.assertEqual(row.change_message, 'No fields changed.') - - def test_user_change_password(self): - response = self.client.post( - reverse('auth_test_admin:auth_user_password_change', args=(self.admin.pk,)), - { - 'password1': 'password1', - 'password2': 'password1', - } - ) - self.assertRedirects(response, reverse('auth_test_admin:auth_user_change', args=(self.admin.pk,))) - row = LogEntry.objects.latest('id') - self.assertEqual(row.change_message, 'Changed password.') - self.logout() - self.login(password='password1') - - def test_user_change_different_user_password(self): - u = User.objects.get(email='staffmember@example.com') - response = self.client.post( - reverse('auth_test_admin:auth_user_password_change', args=(u.pk,)), - { - 'password1': 'password1', - 'password2': 'password1', - } - ) - self.assertRedirects(response, reverse('auth_test_admin:auth_user_change', args=(u.pk,))) - row = LogEntry.objects.latest('id') - self.assertEqual(row.user_id, self.admin.pk) - self.assertEqual(row.object_id, str(u.pk)) - self.assertEqual(row.change_message, 'Changed password.') diff --git a/django/contrib/auth/tests/urls.py b/django/contrib/auth/tests/urls.py deleted file mode 100644 index 6f83e0f420..0000000000 --- a/django/contrib/auth/tests/urls.py +++ /dev/null @@ -1,101 +0,0 @@ -from django.conf.urls import include, url -from django.contrib import admin -from django.contrib.auth import views -from django.contrib.auth.decorators import login_required -from django.contrib.auth.forms import AuthenticationForm -from django.contrib.auth.urls import urlpatterns -from django.contrib.messages.api import info -from django.http import HttpRequest, HttpResponse -from django.shortcuts import render -from django.template import RequestContext, Template -from django.views.decorators.cache import never_cache - - -class CustomRequestAuthenticationForm(AuthenticationForm): - def __init__(self, request, *args, **kwargs): - assert isinstance(request, HttpRequest) - super(CustomRequestAuthenticationForm, self).__init__(request, *args, **kwargs) - - -@never_cache -def remote_user_auth_view(request): - "Dummy view for remote user tests" - t = Template("Username is {{ user }}.") - c = RequestContext(request, {}) - return HttpResponse(t.render(c)) - - -def auth_processor_no_attr_access(request): - render(request, 'context_processors/auth_attrs_no_access.html') - # *After* rendering, we check whether the session was accessed - return render(request, - 'context_processors/auth_attrs_test_access.html', - {'session_accessed': request.session.accessed}) - - -def auth_processor_attr_access(request): - render(request, 'context_processors/auth_attrs_access.html') - return render(request, - 'context_processors/auth_attrs_test_access.html', - {'session_accessed': request.session.accessed}) - - -def auth_processor_user(request): - return render(request, 'context_processors/auth_attrs_user.html') - - -def auth_processor_perms(request): - return render(request, 'context_processors/auth_attrs_perms.html') - - -def auth_processor_perm_in_perms(request): - return render(request, 'context_processors/auth_attrs_perm_in_perms.html') - - -def auth_processor_messages(request): - info(request, "Message 1") - return render(request, 'context_processors/auth_attrs_messages.html') - - -def userpage(request): - pass - - -def custom_request_auth_login(request): - return views.login(request, authentication_form=CustomRequestAuthenticationForm) - -# special urls for auth test cases -urlpatterns += [ - url(r'^logout/custom_query/$', views.logout, dict(redirect_field_name='follow')), - url(r'^logout/next_page/$', views.logout, dict(next_page='/somewhere/')), - url(r'^logout/next_page/named/$', views.logout, dict(next_page='password_reset')), - url(r'^remote_user/$', remote_user_auth_view), - url(r'^password_reset_from_email/$', views.password_reset, dict(from_email='staffmember@example.com')), - url(r'^password_reset/custom_redirect/$', views.password_reset, dict(post_reset_redirect='/custom/')), - url(r'^password_reset/custom_redirect/named/$', views.password_reset, dict(post_reset_redirect='password_reset')), - url(r'^password_reset/html_email_template/$', views.password_reset, - dict(html_email_template_name='registration/html_password_reset_email.html')), - url(r'^reset/custom/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', - views.password_reset_confirm, - dict(post_reset_redirect='/custom/')), - url(r'^reset/custom/named/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', - views.password_reset_confirm, - dict(post_reset_redirect='password_reset')), - url(r'^password_change/custom/$', views.password_change, dict(post_change_redirect='/custom/')), - url(r'^password_change/custom/named/$', views.password_change, dict(post_change_redirect='password_reset')), - url(r'^admin_password_reset/$', views.password_reset, dict(is_admin_site=True)), - url(r'^login_required/$', login_required(views.password_reset)), - url(r'^login_required_login_url/$', login_required(views.password_reset, login_url='/somewhere/')), - - url(r'^auth_processor_no_attr_access/$', auth_processor_no_attr_access), - url(r'^auth_processor_attr_access/$', auth_processor_attr_access), - url(r'^auth_processor_user/$', auth_processor_user), - url(r'^auth_processor_perms/$', auth_processor_perms), - url(r'^auth_processor_perm_in_perms/$', auth_processor_perm_in_perms), - url(r'^auth_processor_messages/$', auth_processor_messages), - url(r'^custom_request_auth_login/$', custom_request_auth_login), - url(r'^userpage/(.+)/$', userpage, name="userpage"), - - # This line is only required to render the password reset with is_admin=True - url(r'^admin/', include(admin.site.urls)), -] diff --git a/django/contrib/auth/tests/urls_admin.py b/django/contrib/auth/tests/urls_admin.py deleted file mode 100644 index 8d2fe3fd10..0000000000 --- a/django/contrib/auth/tests/urls_admin.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -Test URLs for auth admins. -""" - -from django.conf.urls import include, url -from django.contrib import admin -from django.contrib.auth.admin import GroupAdmin, UserAdmin -from django.contrib.auth.models import Group, User -from django.contrib.auth.urls import urlpatterns - -# Create a silo'd admin site for just the user/group admins. -site = admin.AdminSite(name='auth_test_admin') -site.register(User, UserAdmin) -site.register(Group, GroupAdmin) - -urlpatterns += [ - url(r'^admin/', include(site.urls)), -] |
