2
0

test_auth_backends.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. from __future__ import unicode_literals
  2. from datetime import date
  3. from django.contrib.auth import (
  4. BACKEND_SESSION_KEY, SESSION_KEY, authenticate, get_user,
  5. )
  6. from django.contrib.auth.backends import ModelBackend
  7. from django.contrib.auth.hashers import MD5PasswordHasher
  8. from django.contrib.auth.models import AnonymousUser, Group, Permission, User
  9. from django.contrib.auth.tests.custom_user import CustomUser, ExtensionUser
  10. from django.contrib.contenttypes.models import ContentType
  11. from django.core.exceptions import ImproperlyConfigured, PermissionDenied
  12. from django.http import HttpRequest
  13. from django.test import (
  14. SimpleTestCase, TestCase, modify_settings, override_settings,
  15. )
  16. from .models import CustomPermissionsUser, UUIDUser
  17. class CountingMD5PasswordHasher(MD5PasswordHasher):
  18. """Hasher that counts how many times it computes a hash."""
  19. calls = 0
  20. def encode(self, *args, **kwargs):
  21. type(self).calls += 1
  22. return super(CountingMD5PasswordHasher, self).encode(*args, **kwargs)
  23. class BaseModelBackendTest(object):
  24. """
  25. A base class for tests that need to validate the ModelBackend
  26. with different User models. Subclasses should define a class
  27. level UserModel attribute, and a create_users() method to
  28. construct two users for test purposes.
  29. """
  30. backend = 'django.contrib.auth.backends.ModelBackend'
  31. def setUp(self):
  32. self.patched_settings = modify_settings(
  33. AUTHENTICATION_BACKENDS={'append': self.backend},
  34. )
  35. self.patched_settings.enable()
  36. self.create_users()
  37. def tearDown(self):
  38. self.patched_settings.disable()
  39. # The custom_perms test messes with ContentTypes, which will
  40. # be cached; flush the cache to ensure there are no side effects
  41. # Refs #14975, #14925
  42. ContentType.objects.clear_cache()
  43. def test_has_perm(self):
  44. user = self.UserModel._default_manager.get(pk=self.user.pk)
  45. self.assertEqual(user.has_perm('auth.test'), False)
  46. user.is_staff = True
  47. user.save()
  48. self.assertEqual(user.has_perm('auth.test'), False)
  49. user.is_superuser = True
  50. user.save()
  51. self.assertEqual(user.has_perm('auth.test'), True)
  52. user.is_staff = True
  53. user.is_superuser = True
  54. user.is_active = False
  55. user.save()
  56. self.assertEqual(user.has_perm('auth.test'), False)
  57. def test_custom_perms(self):
  58. user = self.UserModel._default_manager.get(pk=self.user.pk)
  59. content_type = ContentType.objects.get_for_model(Group)
  60. perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
  61. user.user_permissions.add(perm)
  62. # reloading user to purge the _perm_cache
  63. user = self.UserModel._default_manager.get(pk=self.user.pk)
  64. self.assertEqual(user.get_all_permissions() == {'auth.test'}, True)
  65. self.assertEqual(user.get_group_permissions(), set())
  66. self.assertEqual(user.has_module_perms('Group'), False)
  67. self.assertEqual(user.has_module_perms('auth'), True)
  68. perm = Permission.objects.create(name='test2', content_type=content_type, codename='test2')
  69. user.user_permissions.add(perm)
  70. perm = Permission.objects.create(name='test3', content_type=content_type, codename='test3')
  71. user.user_permissions.add(perm)
  72. user = self.UserModel._default_manager.get(pk=self.user.pk)
  73. self.assertEqual(user.get_all_permissions(), {'auth.test2', 'auth.test', 'auth.test3'})
  74. self.assertEqual(user.has_perm('test'), False)
  75. self.assertEqual(user.has_perm('auth.test'), True)
  76. self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), True)
  77. perm = Permission.objects.create(name='test_group', content_type=content_type, codename='test_group')
  78. group = Group.objects.create(name='test_group')
  79. group.permissions.add(perm)
  80. user.groups.add(group)
  81. user = self.UserModel._default_manager.get(pk=self.user.pk)
  82. exp = {'auth.test2', 'auth.test', 'auth.test3', 'auth.test_group'}
  83. self.assertEqual(user.get_all_permissions(), exp)
  84. self.assertEqual(user.get_group_permissions(), {'auth.test_group'})
  85. self.assertEqual(user.has_perms(['auth.test3', 'auth.test_group']), True)
  86. user = AnonymousUser()
  87. self.assertEqual(user.has_perm('test'), False)
  88. self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), False)
  89. def test_has_no_object_perm(self):
  90. """Regressiontest for #12462"""
  91. user = self.UserModel._default_manager.get(pk=self.user.pk)
  92. content_type = ContentType.objects.get_for_model(Group)
  93. perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
  94. user.user_permissions.add(perm)
  95. self.assertEqual(user.has_perm('auth.test', 'object'), False)
  96. self.assertEqual(user.get_all_permissions('object'), set())
  97. self.assertEqual(user.has_perm('auth.test'), True)
  98. self.assertEqual(user.get_all_permissions(), {'auth.test'})
  99. def test_anonymous_has_no_permissions(self):
  100. """
  101. #17903 -- Anonymous users shouldn't have permissions in
  102. ModelBackend.get_(all|user|group)_permissions().
  103. """
  104. backend = ModelBackend()
  105. user = self.UserModel._default_manager.get(pk=self.user.pk)
  106. content_type = ContentType.objects.get_for_model(Group)
  107. user_perm = Permission.objects.create(name='test', content_type=content_type, codename='test_user')
  108. group_perm = Permission.objects.create(name='test2', content_type=content_type, codename='test_group')
  109. user.user_permissions.add(user_perm)
  110. group = Group.objects.create(name='test_group')
  111. user.groups.add(group)
  112. group.permissions.add(group_perm)
  113. self.assertEqual(backend.get_all_permissions(user), {'auth.test_user', 'auth.test_group'})
  114. self.assertEqual(backend.get_user_permissions(user), {'auth.test_user', 'auth.test_group'})
  115. self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'})
  116. user.is_anonymous = lambda: True
  117. self.assertEqual(backend.get_all_permissions(user), set())
  118. self.assertEqual(backend.get_user_permissions(user), set())
  119. self.assertEqual(backend.get_group_permissions(user), set())
  120. def test_inactive_has_no_permissions(self):
  121. """
  122. #17903 -- Inactive users shouldn't have permissions in
  123. ModelBackend.get_(all|user|group)_permissions().
  124. """
  125. backend = ModelBackend()
  126. user = self.UserModel._default_manager.get(pk=self.user.pk)
  127. content_type = ContentType.objects.get_for_model(Group)
  128. user_perm = Permission.objects.create(name='test', content_type=content_type, codename='test_user')
  129. group_perm = Permission.objects.create(name='test2', content_type=content_type, codename='test_group')
  130. user.user_permissions.add(user_perm)
  131. group = Group.objects.create(name='test_group')
  132. user.groups.add(group)
  133. group.permissions.add(group_perm)
  134. self.assertEqual(backend.get_all_permissions(user), {'auth.test_user', 'auth.test_group'})
  135. self.assertEqual(backend.get_user_permissions(user), {'auth.test_user', 'auth.test_group'})
  136. self.assertEqual(backend.get_group_permissions(user), {'auth.test_group'})
  137. user.is_active = False
  138. user.save()
  139. self.assertEqual(backend.get_all_permissions(user), set())
  140. self.assertEqual(backend.get_user_permissions(user), set())
  141. self.assertEqual(backend.get_group_permissions(user), set())
  142. def test_get_all_superuser_permissions(self):
  143. """A superuser has all permissions. Refs #14795."""
  144. user = self.UserModel._default_manager.get(pk=self.superuser.pk)
  145. self.assertEqual(len(user.get_all_permissions()), len(Permission.objects.all()))
  146. @override_settings(PASSWORD_HASHERS=['auth_tests.test_auth_backends.CountingMD5PasswordHasher'])
  147. def test_authentication_timing(self):
  148. """Hasher is run once regardless of whether the user exists. Refs #20760."""
  149. # Re-set the password, because this tests overrides PASSWORD_HASHERS
  150. self.user.set_password('test')
  151. self.user.save()
  152. CountingMD5PasswordHasher.calls = 0
  153. username = getattr(self.user, self.UserModel.USERNAME_FIELD)
  154. authenticate(username=username, password='test')
  155. self.assertEqual(CountingMD5PasswordHasher.calls, 1)
  156. CountingMD5PasswordHasher.calls = 0
  157. authenticate(username='no_such_user', password='test')
  158. self.assertEqual(CountingMD5PasswordHasher.calls, 1)
  159. class ModelBackendTest(BaseModelBackendTest, TestCase):
  160. """
  161. Tests for the ModelBackend using the default User model.
  162. """
  163. UserModel = User
  164. def create_users(self):
  165. self.user = User.objects.create_user(
  166. username='test',
  167. email='test@example.com',
  168. password='test',
  169. )
  170. self.superuser = User.objects.create_superuser(
  171. username='test2',
  172. email='test2@example.com',
  173. password='test',
  174. )
  175. @override_settings(AUTH_USER_MODEL='auth.ExtensionUser')
  176. class ExtensionUserModelBackendTest(BaseModelBackendTest, TestCase):
  177. """
  178. Tests for the ModelBackend using the custom ExtensionUser model.
  179. This isn't a perfect test, because both the User and ExtensionUser are
  180. synchronized to the database, which wouldn't ordinary happen in
  181. production. As a result, it doesn't catch errors caused by the non-
  182. existence of the User table.
  183. The specific problem is queries on .filter(groups__user) et al, which
  184. makes an implicit assumption that the user model is called 'User'. In
  185. production, the auth.User table won't exist, so the requested join
  186. won't exist either; in testing, the auth.User *does* exist, and
  187. so does the join. However, the join table won't contain any useful
  188. data; for testing, we check that the data we expect actually does exist.
  189. """
  190. UserModel = ExtensionUser
  191. def create_users(self):
  192. self.user = ExtensionUser._default_manager.create_user(
  193. username='test',
  194. email='test@example.com',
  195. password='test',
  196. date_of_birth=date(2006, 4, 25)
  197. )
  198. self.superuser = ExtensionUser._default_manager.create_superuser(
  199. username='test2',
  200. email='test2@example.com',
  201. password='test',
  202. date_of_birth=date(1976, 11, 8)
  203. )
  204. @override_settings(AUTH_USER_MODEL='auth_tests.CustomPermissionsUser')
  205. class CustomPermissionsUserModelBackendTest(BaseModelBackendTest, TestCase):
  206. """
  207. Tests for the ModelBackend using the CustomPermissionsUser model.
  208. As with the ExtensionUser test, this isn't a perfect test, because both
  209. the User and CustomPermissionsUser are synchronized to the database,
  210. which wouldn't ordinary happen in production.
  211. """
  212. UserModel = CustomPermissionsUser
  213. def create_users(self):
  214. self.user = CustomPermissionsUser._default_manager.create_user(
  215. email='test@example.com',
  216. password='test',
  217. date_of_birth=date(2006, 4, 25)
  218. )
  219. self.superuser = CustomPermissionsUser._default_manager.create_superuser(
  220. email='test2@example.com',
  221. password='test',
  222. date_of_birth=date(1976, 11, 8)
  223. )
  224. @override_settings(AUTH_USER_MODEL='auth.CustomUser')
  225. class CustomUserModelBackendAuthenticateTest(TestCase):
  226. """
  227. Tests that the model backend can accept a credentials kwarg labeled with
  228. custom user model's USERNAME_FIELD.
  229. """
  230. def test_authenticate(self):
  231. test_user = CustomUser._default_manager.create_user(
  232. email='test@example.com',
  233. password='test',
  234. date_of_birth=date(2006, 4, 25)
  235. )
  236. authenticated_user = authenticate(email='test@example.com', password='test')
  237. self.assertEqual(test_user, authenticated_user)
  238. @override_settings(AUTH_USER_MODEL='auth_tests.UUIDUser')
  239. class UUIDUserTests(TestCase):
  240. def test_login(self):
  241. """
  242. A custom user with a UUID primary key should be able to login.
  243. """
  244. user = UUIDUser.objects.create_user(username='uuid', password='test')
  245. self.assertTrue(self.client.login(username='uuid', password='test'))
  246. self.assertEqual(UUIDUser.objects.get(pk=self.client.session[SESSION_KEY]), user)
  247. class TestObj(object):
  248. pass
  249. class SimpleRowlevelBackend(object):
  250. def has_perm(self, user, perm, obj=None):
  251. if not obj:
  252. return # We only support row level perms
  253. if isinstance(obj, TestObj):
  254. if user.username == 'test2':
  255. return True
  256. elif user.is_anonymous() and perm == 'anon':
  257. return True
  258. elif not user.is_active and perm == 'inactive':
  259. return True
  260. return False
  261. def has_module_perms(self, user, app_label):
  262. if not user.is_anonymous() and not user.is_active:
  263. return False
  264. return app_label == "app1"
  265. def get_all_permissions(self, user, obj=None):
  266. if not obj:
  267. return [] # We only support row level perms
  268. if not isinstance(obj, TestObj):
  269. return ['none']
  270. if user.is_anonymous():
  271. return ['anon']
  272. if user.username == 'test2':
  273. return ['simple', 'advanced']
  274. else:
  275. return ['simple']
  276. def get_group_permissions(self, user, obj=None):
  277. if not obj:
  278. return # We only support row level perms
  279. if not isinstance(obj, TestObj):
  280. return ['none']
  281. if 'test_group' in [group.name for group in user.groups.all()]:
  282. return ['group_perm']
  283. else:
  284. return ['none']
  285. @modify_settings(AUTHENTICATION_BACKENDS={
  286. 'append': 'auth_tests.test_auth_backends.SimpleRowlevelBackend',
  287. })
  288. class RowlevelBackendTest(TestCase):
  289. """
  290. Tests for auth backend that supports object level permissions
  291. """
  292. def setUp(self):
  293. self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
  294. self.user2 = User.objects.create_user('test2', 'test2@example.com', 'test')
  295. self.user3 = User.objects.create_user('test3', 'test3@example.com', 'test')
  296. def tearDown(self):
  297. # The get_group_permissions test messes with ContentTypes, which will
  298. # be cached; flush the cache to ensure there are no side effects
  299. # Refs #14975, #14925
  300. ContentType.objects.clear_cache()
  301. def test_has_perm(self):
  302. self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
  303. self.assertEqual(self.user2.has_perm('perm', TestObj()), True)
  304. self.assertEqual(self.user2.has_perm('perm'), False)
  305. self.assertEqual(self.user2.has_perms(['simple', 'advanced'], TestObj()), True)
  306. self.assertEqual(self.user3.has_perm('perm', TestObj()), False)
  307. self.assertEqual(self.user3.has_perm('anon', TestObj()), False)
  308. self.assertEqual(self.user3.has_perms(['simple', 'advanced'], TestObj()), False)
  309. def test_get_all_permissions(self):
  310. self.assertEqual(self.user1.get_all_permissions(TestObj()), {'simple'})
  311. self.assertEqual(self.user2.get_all_permissions(TestObj()), {'simple', 'advanced'})
  312. self.assertEqual(self.user2.get_all_permissions(), set())
  313. def test_get_group_permissions(self):
  314. group = Group.objects.create(name='test_group')
  315. self.user3.groups.add(group)
  316. self.assertEqual(self.user3.get_group_permissions(TestObj()), {'group_perm'})
  317. @override_settings(
  318. AUTHENTICATION_BACKENDS=['auth_tests.test_auth_backends.SimpleRowlevelBackend'],
  319. )
  320. class AnonymousUserBackendTest(SimpleTestCase):
  321. """
  322. Tests for AnonymousUser delegating to backend.
  323. """
  324. def setUp(self):
  325. self.user1 = AnonymousUser()
  326. def test_has_perm(self):
  327. self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
  328. self.assertEqual(self.user1.has_perm('anon', TestObj()), True)
  329. def test_has_perms(self):
  330. self.assertEqual(self.user1.has_perms(['anon'], TestObj()), True)
  331. self.assertEqual(self.user1.has_perms(['anon', 'perm'], TestObj()), False)
  332. def test_has_module_perms(self):
  333. self.assertEqual(self.user1.has_module_perms("app1"), True)
  334. self.assertEqual(self.user1.has_module_perms("app2"), False)
  335. def test_get_all_permissions(self):
  336. self.assertEqual(self.user1.get_all_permissions(TestObj()), {'anon'})
  337. @override_settings(AUTHENTICATION_BACKENDS=[])
  338. class NoBackendsTest(TestCase):
  339. """
  340. Tests that an appropriate error is raised if no auth backends are provided.
  341. """
  342. def setUp(self):
  343. self.user = User.objects.create_user('test', 'test@example.com', 'test')
  344. def test_raises_exception(self):
  345. self.assertRaises(ImproperlyConfigured, self.user.has_perm, ('perm', TestObj(),))
  346. @override_settings(AUTHENTICATION_BACKENDS=['auth_tests.test_auth_backends.SimpleRowlevelBackend'])
  347. class InActiveUserBackendTest(TestCase):
  348. """
  349. Tests for an inactive user
  350. """
  351. def setUp(self):
  352. self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
  353. self.user1.is_active = False
  354. self.user1.save()
  355. def test_has_perm(self):
  356. self.assertEqual(self.user1.has_perm('perm', TestObj()), False)
  357. self.assertEqual(self.user1.has_perm('inactive', TestObj()), True)
  358. def test_has_module_perms(self):
  359. self.assertEqual(self.user1.has_module_perms("app1"), False)
  360. self.assertEqual(self.user1.has_module_perms("app2"), False)
  361. class PermissionDeniedBackend(object):
  362. """
  363. Always raises PermissionDenied in `authenticate`, `has_perm` and `has_module_perms`.
  364. """
  365. def authenticate(self, username=None, password=None):
  366. raise PermissionDenied
  367. def has_perm(self, user_obj, perm, obj=None):
  368. raise PermissionDenied
  369. def has_module_perms(self, user_obj, app_label):
  370. raise PermissionDenied
  371. class PermissionDeniedBackendTest(TestCase):
  372. """
  373. Tests that other backends are not checked once a backend raises PermissionDenied
  374. """
  375. backend = 'auth_tests.test_auth_backends.PermissionDeniedBackend'
  376. def setUp(self):
  377. self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
  378. self.user1.save()
  379. @modify_settings(AUTHENTICATION_BACKENDS={'prepend': backend})
  380. def test_permission_denied(self):
  381. "user is not authenticated after a backend raises permission denied #2550"
  382. self.assertEqual(authenticate(username='test', password='test'), None)
  383. @modify_settings(AUTHENTICATION_BACKENDS={'append': backend})
  384. def test_authenticates(self):
  385. self.assertEqual(authenticate(username='test', password='test'), self.user1)
  386. @modify_settings(AUTHENTICATION_BACKENDS={'prepend': backend})
  387. def test_has_perm_denied(self):
  388. content_type = ContentType.objects.get_for_model(Group)
  389. perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
  390. self.user1.user_permissions.add(perm)
  391. self.assertIs(self.user1.has_perm('auth.test'), False)
  392. self.assertIs(self.user1.has_module_perms('auth'), False)
  393. @modify_settings(AUTHENTICATION_BACKENDS={'append': backend})
  394. def test_has_perm(self):
  395. content_type = ContentType.objects.get_for_model(Group)
  396. perm = Permission.objects.create(name='test', content_type=content_type, codename='test')
  397. self.user1.user_permissions.add(perm)
  398. self.assertIs(self.user1.has_perm('auth.test'), True)
  399. self.assertIs(self.user1.has_module_perms('auth'), True)
  400. class NewModelBackend(ModelBackend):
  401. pass
  402. class ChangedBackendSettingsTest(TestCase):
  403. """
  404. Tests for changes in the settings.AUTHENTICATION_BACKENDS
  405. """
  406. backend = 'auth_tests.test_auth_backends.NewModelBackend'
  407. TEST_USERNAME = 'test_user'
  408. TEST_PASSWORD = 'test_password'
  409. TEST_EMAIL = 'test@example.com'
  410. def setUp(self):
  411. User.objects.create_user(self.TEST_USERNAME,
  412. self.TEST_EMAIL,
  413. self.TEST_PASSWORD)
  414. @override_settings(AUTHENTICATION_BACKENDS=[backend])
  415. def test_changed_backend_settings(self):
  416. """
  417. Tests that removing a backend configured in AUTHENTICATION_BACKENDS
  418. make already logged-in users disconnect.
  419. """
  420. # Get a session for the test user
  421. self.assertTrue(self.client.login(
  422. username=self.TEST_USERNAME,
  423. password=self.TEST_PASSWORD)
  424. )
  425. # Prepare a request object
  426. request = HttpRequest()
  427. request.session = self.client.session
  428. # Remove NewModelBackend
  429. with self.settings(AUTHENTICATION_BACKENDS=[
  430. 'django.contrib.auth.backends.ModelBackend']):
  431. # Get the user from the request
  432. user = get_user(request)
  433. # Assert that the user retrieval is successful and the user is
  434. # anonymous as the backend is not longer available.
  435. self.assertIsNotNone(user)
  436. self.assertTrue(user.is_anonymous())
  437. class TypeErrorBackend(object):
  438. """
  439. Always raises TypeError.
  440. """
  441. def authenticate(self, username=None, password=None):
  442. raise TypeError
  443. class TypeErrorBackendTest(TestCase):
  444. """
  445. Tests that a TypeError within a backend is propagated properly.
  446. Regression test for ticket #18171
  447. """
  448. backend = 'auth_tests.test_auth_backends.TypeErrorBackend'
  449. def setUp(self):
  450. self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
  451. @override_settings(AUTHENTICATION_BACKENDS=[backend])
  452. def test_type_error_raised(self):
  453. self.assertRaises(TypeError, authenticate, username='test', password='test')
  454. class ImproperlyConfiguredUserModelTest(TestCase):
  455. """
  456. Tests that an exception from within get_user_model is propagated and doesn't
  457. raise an UnboundLocalError.
  458. Regression test for ticket #21439
  459. """
  460. def setUp(self):
  461. self.user1 = User.objects.create_user('test', 'test@example.com', 'test')
  462. self.client.login(
  463. username='test',
  464. password='test'
  465. )
  466. @override_settings(AUTH_USER_MODEL='thismodel.doesntexist')
  467. def test_does_not_shadow_exception(self):
  468. # Prepare a request object
  469. request = HttpRequest()
  470. request.session = self.client.session
  471. self.assertRaises(ImproperlyConfigured, get_user, request)
  472. class ImportedModelBackend(ModelBackend):
  473. pass
  474. class CustomModelBackend(ModelBackend):
  475. pass
  476. class OtherModelBackend(ModelBackend):
  477. pass
  478. class ImportedBackendTests(TestCase):
  479. """
  480. #23925 - The backend path added to the session should be the same
  481. as the one defined in AUTHENTICATION_BACKENDS setting.
  482. """
  483. backend = 'auth_tests.backend_alias.ImportedModelBackend'
  484. @override_settings(AUTHENTICATION_BACKENDS=[backend])
  485. def test_backend_path(self):
  486. username = 'username'
  487. password = 'password'
  488. User.objects.create_user(username, 'email', password)
  489. self.assertTrue(self.client.login(username=username, password=password))
  490. request = HttpRequest()
  491. request.session = self.client.session
  492. self.assertEqual(request.session[BACKEND_SESSION_KEY], self.backend)
  493. class SelectingBackendTests(TestCase):
  494. backend = 'auth_tests.test_auth_backends.CustomModelBackend'
  495. other_backend = 'auth_tests.test_auth_backends.OtherModelBackend'
  496. username = 'username'
  497. password = 'password'
  498. def assertBackendInSession(self, backend):
  499. request = HttpRequest()
  500. request.session = self.client.session
  501. self.assertEqual(request.session[BACKEND_SESSION_KEY], backend)
  502. @override_settings(AUTHENTICATION_BACKENDS=[backend])
  503. def test_backend_path_login_without_authenticate_single_backend(self):
  504. user = User.objects.create_user(self.username, 'email', self.password)
  505. self.client._login(user)
  506. self.assertBackendInSession(self.backend)
  507. @override_settings(AUTHENTICATION_BACKENDS=[backend, other_backend])
  508. def test_backend_path_login_without_authenticate_multiple_backends(self):
  509. user = User.objects.create_user(self.username, 'email', self.password)
  510. expected_message = (
  511. 'You have multiple authentication backends configured and '
  512. 'therefore must provide the `backend` argument or set the '
  513. '`backend` attribute on the user.'
  514. )
  515. with self.assertRaisesMessage(ValueError, expected_message):
  516. self.client._login(user)
  517. @override_settings(AUTHENTICATION_BACKENDS=[backend, other_backend])
  518. def test_backend_path_login_with_explicit_backends(self):
  519. user = User.objects.create_user(self.username, 'email', self.password)
  520. self.client._login(user, self.other_backend)
  521. self.assertBackendInSession(self.other_backend)