test_context_processors.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. from django.contrib.auth import authenticate
  2. from django.contrib.auth.context_processors import PermLookupDict, PermWrapper
  3. from django.contrib.auth.models import Permission, User
  4. from django.contrib.contenttypes.models import ContentType
  5. from django.db.models import Q
  6. from django.test import TestCase, override_settings
  7. from .settings import AUTH_MIDDLEWARE_CLASSES, AUTH_TEMPLATES
  8. class MockUser(object):
  9. def has_module_perms(self, perm):
  10. if perm == 'mockapp':
  11. return True
  12. return False
  13. def has_perm(self, perm):
  14. if perm == 'mockapp.someperm':
  15. return True
  16. return False
  17. class PermWrapperTests(TestCase):
  18. """
  19. Test some details of the PermWrapper implementation.
  20. """
  21. class EQLimiterObject(object):
  22. """
  23. This object makes sure __eq__ will not be called endlessly.
  24. """
  25. def __init__(self):
  26. self.eq_calls = 0
  27. def __eq__(self, other):
  28. if self.eq_calls > 0:
  29. return True
  30. self.eq_calls += 1
  31. return False
  32. def test_permwrapper_in(self):
  33. """
  34. Test that 'something' in PermWrapper works as expected.
  35. """
  36. perms = PermWrapper(MockUser())
  37. # Works for modules and full permissions.
  38. self.assertIn('mockapp', perms)
  39. self.assertNotIn('nonexisting', perms)
  40. self.assertIn('mockapp.someperm', perms)
  41. self.assertNotIn('mockapp.nonexisting', perms)
  42. def test_permlookupdict_in(self):
  43. """
  44. No endless loops if accessed with 'in' - refs #18979.
  45. """
  46. pldict = PermLookupDict(MockUser(), 'mockapp')
  47. with self.assertRaises(TypeError):
  48. self.EQLimiterObject() in pldict
  49. @override_settings(
  50. PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
  51. ROOT_URLCONF='auth_tests.urls',
  52. TEMPLATES=AUTH_TEMPLATES,
  53. USE_TZ=False, # required for loading the fixture
  54. )
  55. class AuthContextProcessorTests(TestCase):
  56. """
  57. Tests for the ``django.contrib.auth.context_processors.auth`` processor
  58. """
  59. fixtures = ['context-processors-users.xml']
  60. @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
  61. def test_session_not_accessed(self):
  62. """
  63. Tests that the session is not accessed simply by including
  64. the auth context processor
  65. """
  66. response = self.client.get('/auth_processor_no_attr_access/')
  67. self.assertContains(response, "Session not accessed")
  68. @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
  69. def test_session_is_accessed(self):
  70. """
  71. Tests that the session is accessed if the auth context processor
  72. is used and relevant attributes accessed.
  73. """
  74. response = self.client.get('/auth_processor_attr_access/')
  75. self.assertContains(response, "Session accessed")
  76. def test_perms_attrs(self):
  77. u = User.objects.create_user(username='normal', password='secret')
  78. u.user_permissions.add(
  79. Permission.objects.get(
  80. content_type=ContentType.objects.get_for_model(Permission),
  81. codename='add_permission'))
  82. self.client.login(username='normal', password='secret')
  83. response = self.client.get('/auth_processor_perms/')
  84. self.assertContains(response, "Has auth permissions")
  85. self.assertContains(response, "Has auth.add_permission permissions")
  86. self.assertNotContains(response, "nonexisting")
  87. def test_perm_in_perms_attrs(self):
  88. u = User.objects.create_user(username='normal', password='secret')
  89. u.user_permissions.add(
  90. Permission.objects.get(
  91. content_type=ContentType.objects.get_for_model(Permission),
  92. codename='add_permission'))
  93. self.client.login(username='normal', password='secret')
  94. response = self.client.get('/auth_processor_perm_in_perms/')
  95. self.assertContains(response, "Has auth permissions")
  96. self.assertContains(response, "Has auth.add_permission permissions")
  97. self.assertNotContains(response, "nonexisting")
  98. def test_message_attrs(self):
  99. self.client.login(username='super', password='secret')
  100. response = self.client.get('/auth_processor_messages/')
  101. self.assertContains(response, "Message 1")
  102. def test_user_attrs(self):
  103. """
  104. Test that the lazy objects returned behave just like the wrapped objects.
  105. """
  106. # These are 'functional' level tests for common use cases. Direct
  107. # testing of the implementation (SimpleLazyObject) is in the 'utils'
  108. # tests.
  109. self.client.login(username='super', password='secret')
  110. user = authenticate(username='super', password='secret')
  111. response = self.client.get('/auth_processor_user/')
  112. self.assertContains(response, "unicode: super")
  113. self.assertContains(response, "id: 100")
  114. self.assertContains(response, "username: super")
  115. # bug #12037 is tested by the {% url %} in the template:
  116. self.assertContains(response, "url: /userpage/super/")
  117. # See if this object can be used for queries where a Q() comparing
  118. # a user can be used with another Q() (in an AND or OR fashion).
  119. # This simulates what a template tag might do with the user from the
  120. # context. Note that we don't need to execute a query, just build it.
  121. #
  122. # The failure case (bug #12049) on Python 2.4 with a LazyObject-wrapped
  123. # User is a fatal TypeError: "function() takes at least 2 arguments
  124. # (0 given)" deep inside deepcopy().
  125. #
  126. # Python 2.5 and 2.6 succeeded, but logged internally caught exception
  127. # spew:
  128. #
  129. # Exception RuntimeError: 'maximum recursion depth exceeded while
  130. # calling a Python object' in <type 'exceptions.AttributeError'>
  131. # ignored"
  132. Q(user=response.context['user']) & Q(someflag=True)
  133. # Tests for user equality. This is hard because User defines
  134. # equality in a non-duck-typing way
  135. # See bug #12060
  136. self.assertEqual(response.context['user'], user)
  137. self.assertEqual(user, response.context['user'])