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 SimpleTestCase, TestCase, override_settings from .settings import AUTH_MIDDLEWARE, AUTH_TEMPLATES class MockUser: def __repr__(self): return "MockUser()" def has_module_perms(self, perm): return perm == "mockapp" def has_perm(self, perm, obj=None): return perm == "mockapp.someperm" class PermWrapperTests(SimpleTestCase): """ Test some details of the PermWrapper implementation. """ class EQLimiterObject: """ 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_repr(self): perms = PermWrapper(MockUser()) self.assertEqual(repr(perms), "PermWrapper(MockUser())") def test_permwrapper_in(self): """ 'something' in PermWrapper works as expected. """ perms = PermWrapper(MockUser()) # Works for modules and full permissions. self.assertIn("mockapp", perms) self.assertNotIn("nonexistent", perms) self.assertIn("mockapp.someperm", perms) self.assertNotIn("mockapp.nonexistent", 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 def test_iter(self): with self.assertRaisesMessage(TypeError, "PermWrapper is not iterable."): iter(PermWrapper(MockUser())) @override_settings(ROOT_URLCONF="auth_tests.urls", TEMPLATES=AUTH_TEMPLATES) class AuthContextProcessorTests(TestCase): """ Tests for the ``django.contrib.auth.context_processors.auth`` processor """ @classmethod def setUpTestData(cls): cls.superuser = User.objects.create_superuser( username="super", password="secret", email="super@example.com" ) @override_settings(MIDDLEWARE=AUTH_MIDDLEWARE) def test_session_not_accessed(self): """ 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=AUTH_MIDDLEWARE) def test_session_is_accessed(self): """ 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.force_login(u) response = self.client.get("/auth_processor_perms/") self.assertContains(response, "Has auth permissions") self.assertContains(response, "Has auth.add_permission permissions") self.assertNotContains(response, "nonexistent") 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, "nonexistent") def test_message_attrs(self): self.client.force_login(self.superuser) response = self.client.get("/auth_processor_messages/") self.assertContains(response, "Message 1") def test_user_attrs(self): """ 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: %d" % self.superuser.pk) self.assertContains(response, "username: super") # bug #12037 is tested by the {% url %} in the template: self.assertContains(response, "url: /userpage/super/") # A Q() comparing a user and with another Q() (in an AND or OR fashion). 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"])