test_auth_backends.py 27 KB

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