Browse Source

Fixed #19057 -- support custom user models in mod_wsgi auth handler

thanks @freakboy3742 for the catch and review
Preston Holmes 12 years ago
parent
commit
5f8b97f9fb

+ 19 - 6
django/contrib/auth/handlers/modwsgi.py

@@ -1,4 +1,4 @@
-from django.contrib.auth.models import User
+from django.contrib import auth
 from django import db
 from django.utils.encoding import force_bytes
 
@@ -11,14 +11,21 @@ def check_password(environ, username, password):
     on whether the user exists and authenticates.
     """
 
+    UserModel = auth.get_user_model()
     # db connection state is managed similarly to the wsgi handler
     # as mod_wsgi may call these functions outside of a request/response cycle
     db.reset_queries()
 
     try:
         try:
-            user = User.objects.get(username=username, is_active=True)
-        except User.DoesNotExist:
+            user = UserModel.objects.get_by_natural_key(username)
+        except UserModel.DoesNotExist:
+            return None
+        try:
+            if not user.is_active:
+                return None
+        except AttributeError as e:
+            # a custom user may not support is_active
             return None
         return user.check_password(password)
     finally:
@@ -30,14 +37,20 @@ def groups_for_user(environ, username):
     Authorizes a user based on groups
     """
 
+    UserModel = auth.get_user_model()
     db.reset_queries()
 
     try:
         try:
-            user = User.objects.get(username=username, is_active=True)
-        except User.DoesNotExist:
+            user = UserModel.objects.get_by_natural_key(username)
+        except UserModel.DoesNotExist:
+            return []
+        try:
+            if not user.is_active:
+                return []
+        except AttributeError as e:
+            # a custom user may not support is_active
             return []
-
         return [force_bytes(group.name) for group in user.groups.all()]
     finally:
         db.close_connection()

+ 6 - 1
django/contrib/auth/tests/handlers.py

@@ -2,6 +2,7 @@ from __future__ import unicode_literals
 
 from django.contrib.auth.handlers.modwsgi import check_password, groups_for_user
 from django.contrib.auth.models import User, Group
+from django.contrib.auth.tests.utils import skipIfCustomUser
 from django.test import TransactionTestCase
 
 
@@ -13,7 +14,6 @@ class ModWsgiHandlerTestCase(TransactionTestCase):
     def setUp(self):
         user1 = User.objects.create_user('test', 'test@example.com', 'test')
         User.objects.create_user('test1', 'test1@example.com', 'test1')
-
         group = Group.objects.create(name='test_group')
         user1.groups.add(group)
 
@@ -21,6 +21,10 @@ class ModWsgiHandlerTestCase(TransactionTestCase):
         """
         Verify that check_password returns the correct values as per
         http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms#Apache_Authentication_Provider
+
+        because the custom user available in the test framework does not
+        support the is_active attribute, we can't test this with a custom
+        user.
         """
 
         # User not in database
@@ -32,6 +36,7 @@ class ModWsgiHandlerTestCase(TransactionTestCase):
         # Valid user with incorrect password
         self.assertFalse(check_password({}, 'test', 'incorrect'))
 
+    @skipIfCustomUser
     def test_groups_for_user(self):
         """
         Check that groups_for_user returns correct values as per

+ 8 - 0
docs/howto/deployment/wsgi/apache-auth.txt

@@ -14,6 +14,14 @@ version >= 2.2 and mod_wsgi >= 2.0. For example, you could:
 
 * Allow certain users to connect to a WebDAV share created with mod_dav_.
 
+.. note::
+    If you have installed a :ref:`custom User model <auth-custom-user>` and
+    want to use this default auth handler, it must support an `is_active`
+    attribute. If you want to use group based authorization, your custom user
+    must have a relation named 'groups', referring to a related object that has
+    a 'name' field. You can also specify your own custom mod_wsgi
+    auth handler if your custom cannot conform to these requirements.
+
 .. _Subversion: http://subversion.tigris.org/
 .. _mod_dav: http://httpd.apache.org/docs/2.2/mod/mod_dav.html