summaryrefslogtreecommitdiff
path: root/tests/auth_tests/test_models.py
diff options
context:
space:
mode:
authorBerker Peksag <berker.peksag@gmail.com>2016-08-25 19:26:18 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-08-29 19:32:12 +0200
commit400ec5125ec32e3b18d267bbb4f3aab09d741ce4 (patch)
tree96ef0b85d3dc5b7ea132307ab7fc1f6683201905 /tests/auth_tests/test_models.py
parentfa7ffc6cb3b143fb8566cbf6a387d0f032377dc7 (diff)
Fixed #18763 -- Added ModelBackend/UserManager.with_perm() methods.
Co-authored-by: Nick Pope <nick.pope@flightdataservices.com>
Diffstat (limited to 'tests/auth_tests/test_models.py')
-rw-r--r--tests/auth_tests/test_models.py137
1 files changed, 137 insertions, 0 deletions
diff --git a/tests/auth_tests/test_models.py b/tests/auth_tests/test_models.py
index a3502a224f..c60b66c993 100644
--- a/tests/auth_tests/test_models.py
+++ b/tests/auth_tests/test_models.py
@@ -2,6 +2,7 @@ from unittest import mock
from django.conf.global_settings import PASSWORD_HASHERS
from django.contrib.auth import get_user_model
+from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.hashers import get_hasher
from django.contrib.auth.models import (
@@ -261,6 +262,142 @@ class AbstractUserTestCase(TestCase):
hasher.iterations = old_iterations
+class CustomModelBackend(ModelBackend):
+ def with_perm(self, perm, is_active=True, include_superusers=True, backend=None, obj=None):
+ if obj is not None and obj.username == 'charliebrown':
+ return User.objects.filter(pk=obj.pk)
+ return User.objects.filter(username__startswith='charlie')
+
+
+class UserWithPermTestCase(TestCase):
+
+ @classmethod
+ def setUpTestData(cls):
+ content_type = ContentType.objects.get_for_model(Group)
+ cls.permission = Permission.objects.create(
+ name='test', content_type=content_type, codename='test',
+ )
+ # User with permission.
+ cls.user1 = User.objects.create_user('user 1', 'foo@example.com')
+ cls.user1.user_permissions.add(cls.permission)
+ # User with group permission.
+ group1 = Group.objects.create(name='group 1')
+ group1.permissions.add(cls.permission)
+ group2 = Group.objects.create(name='group 2')
+ group2.permissions.add(cls.permission)
+ cls.user2 = User.objects.create_user('user 2', 'bar@example.com')
+ cls.user2.groups.add(group1, group2)
+ # Users without permissions.
+ cls.user_charlie = User.objects.create_user('charlie', 'charlie@example.com')
+ cls.user_charlie_b = User.objects.create_user('charliebrown', 'charlie@brown.com')
+ # Superuser.
+ cls.superuser = User.objects.create_superuser(
+ 'superuser', 'superuser@example.com', 'superpassword',
+ )
+ # Inactive user with permission.
+ cls.inactive_user = User.objects.create_user(
+ 'inactive_user', 'baz@example.com', is_active=False,
+ )
+ cls.inactive_user.user_permissions.add(cls.permission)
+
+ def test_invalid_permission_name(self):
+ msg = 'Permission name should be in the form app_label.permission_codename.'
+ for perm in ('nodots', 'too.many.dots', '...', ''):
+ with self.subTest(perm), self.assertRaisesMessage(ValueError, msg):
+ User.objects.with_perm(perm)
+
+ def test_invalid_permission_type(self):
+ msg = 'The `perm` argument must be a string or a permission instance.'
+ for perm in (b'auth.test', object(), None):
+ with self.subTest(perm), self.assertRaisesMessage(TypeError, msg):
+ User.objects.with_perm(perm)
+
+ def test_invalid_backend_type(self):
+ msg = 'backend must be a dotted import path string (got %r).'
+ for backend in (b'auth_tests.CustomModelBackend', object()):
+ with self.subTest(backend):
+ with self.assertRaisesMessage(TypeError, msg % backend):
+ User.objects.with_perm('auth.test', backend=backend)
+
+ def test_basic(self):
+ active_users = [self.user1, self.user2]
+ tests = [
+ ({}, [*active_users, self.superuser]),
+ ({'obj': self.user1}, []),
+ # Only inactive users.
+ ({'is_active': False}, [self.inactive_user]),
+ # All users.
+ ({'is_active': None}, [*active_users, self.superuser, self.inactive_user]),
+ # Exclude superusers.
+ ({'include_superusers': False}, active_users),
+ (
+ {'include_superusers': False, 'is_active': False},
+ [self.inactive_user],
+ ),
+ (
+ {'include_superusers': False, 'is_active': None},
+ [*active_users, self.inactive_user],
+ ),
+ ]
+ for kwargs, expected_users in tests:
+ for perm in ('auth.test', self.permission):
+ with self.subTest(perm=perm, **kwargs):
+ self.assertCountEqual(
+ User.objects.with_perm(perm, **kwargs),
+ expected_users,
+ )
+
+ @override_settings(AUTHENTICATION_BACKENDS=['django.contrib.auth.backends.BaseBackend'])
+ def test_backend_without_with_perm(self):
+ self.assertSequenceEqual(User.objects.with_perm('auth.test'), [])
+
+ def test_nonexistent_permission(self):
+ self.assertSequenceEqual(User.objects.with_perm('auth.perm'), [self.superuser])
+
+ def test_nonexistent_backend(self):
+ with self.assertRaises(ImportError):
+ User.objects.with_perm(
+ 'auth.test',
+ backend='invalid.backend.CustomModelBackend',
+ )
+
+ @override_settings(AUTHENTICATION_BACKENDS=['auth_tests.test_models.CustomModelBackend'])
+ def test_custom_backend(self):
+ for perm in ('auth.test', self.permission):
+ with self.subTest(perm):
+ self.assertCountEqual(
+ User.objects.with_perm(perm),
+ [self.user_charlie, self.user_charlie_b],
+ )
+
+ @override_settings(AUTHENTICATION_BACKENDS=['auth_tests.test_models.CustomModelBackend'])
+ def test_custom_backend_pass_obj(self):
+ for perm in ('auth.test', self.permission):
+ with self.subTest(perm):
+ self.assertSequenceEqual(
+ User.objects.with_perm(perm, obj=self.user_charlie_b),
+ [self.user_charlie_b],
+ )
+
+ @override_settings(AUTHENTICATION_BACKENDS=[
+ 'auth_tests.test_models.CustomModelBackend',
+ 'django.contrib.auth.backends.ModelBackend',
+ ])
+ def test_multiple_backends(self):
+ msg = (
+ 'You have multiple authentication backends configured and '
+ 'therefore must provide the `backend` argument.'
+ )
+ with self.assertRaisesMessage(ValueError, msg):
+ User.objects.with_perm('auth.test')
+
+ backend = 'auth_tests.test_models.CustomModelBackend'
+ self.assertCountEqual(
+ User.objects.with_perm('auth.test', backend=backend),
+ [self.user_charlie, self.user_charlie_b],
+ )
+
+
class IsActiveTestCase(TestCase):
"""
Tests the behavior of the guaranteed is_active attribute