Django

Code

Ticket #3583: modpython.2.py

File modpython.2.py, 4.4 kB (added by TomFreudenberg, 3 years ago)

This is an update to apache_auth.2.patch. First: error of wrong "self" is fixed, second: The check was splitted to check if user is authenticated (if not raise UNAUTHORIZED) and the validate user for permissions (if not raise FORBIDDEN)

Line 
1 from mod_python import apache
2 import os
3 from django.core import signals
4 from django.dispatch import dispatcher
5 from django.core.handlers.base import BaseHandler
6 from django.core.handlers.modpython import ModPythonRequest
7 from django.contrib.auth import authenticate
8
9 _str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes')
10
11 class ModPythonAuthOptions:
12     def __init__(self, req):
13         options = req.get_options()
14         self.permission_name = options.get('DjangoPermissionName', None)
15         self.staff_only = _str_to_bool(options.get('DjangoRequireStaffStatus', "on"))
16         self.superuser_only = _str_to_bool(options.get('DjangoRequireSuperuserStatus', "off"))
17         self.settings_module = options.get('DJANGO_SETTINGS_MODULE', None)
18
19 def setup_environment(req, options):
20     """
21     mod_python fakes the environ, and thus doesn't process SetEnv. This ensures
22     any future imports relying on settings will work.
23     """
24     os.environ.update(req.subprocess_env)
25     if options.settings_module:
26         os.environ['DJANGO_SETTINGS_MODULE'] = options.settings_module
27
28 def authenticate_user(user, options):
29     if not user:
30         return False
31     # Require an is_authenticated property and check it
32     if not hasattr(user, 'is_authenticated') or not user.is_authenticated():
33         return False
34     return True
35
36 def validate_user(user, options):
37     # Don't require an is_active property, but if it's there then check it
38     if hasattr(user, 'is_active') and not user.is_active:
39         return False
40     if options.staff_only and not getattr(user, 'is_staff', None):
41         return False
42     if options.superuser_only and not getattr(user, 'is_superuser', None):
43         return False
44     # If a permission is required then user must have a has_perm function to validate
45     if options.permission_name and (not hasattr(user, 'has_perm') or not user.has_perm(options.permission_name)):
46         return False
47     return True
48
49 def authenhandler(req, **kwargs):
50     """
51     mod_python authentication handler that checks against Django's auth
52     database.
53     """
54     options = ModPythonAuthOptions(req)
55     setup_environment(req, options)
56
57     dispatcher.send(signal=signals.request_started)
58     try:
59         # This populates req.user too, so it's important to do first
60         password = req.get_basic_auth_pw()
61
62         # Get the user from any of the installed backends
63         user = authenticate(username=req.user, password=password)
64
65         # Raise unauthorized if the user wasn't authenticated to bring up
66         # a password dialog box to allow the user to authenticate.
67
68         # Check authentification of the user
69         if not authenticate_user(user, options):
70             return apache.HTTP_UNAUTHORIZED
71
72         # Validate and check permission of the user
73         if validate_user(user, options):
74             return apache.OK
75         else:
76             # mod_python docs say that HTTP_FORBIDDEN should be raised if the
77             # user authenticates but doesn't validate.
78             return apache.HTTP_FORBIDDEN
79     finally:
80         dispatcher.send(signal=signals.request_finished)
81
82 def accesshandler(req):
83     """
84     mod_python access handler that uses the contrib.auth framework (with
85     sessions and therefore requiring a session cookie).
86     """
87     options = ModPythonAuthOptions(req)
88     setup_environment(req, options)
89
90     # Set up middleware, now that settings works we can do it now.
91     base_handler = BaseHandler()
92     base_handler.load_middleware()
93
94     dispatcher.send(signal=signals.request_started)
95     try:
96         request = ModPythonRequest(req)
97
98         # Apply request middleware
99         for middleware_method in base_handler._request_middleware:
100             response = middleware_method(request)
101             if response:
102                 # If we get a response, we should probably stop processing any
103                 # remaining request middleware.
104                 break
105
106         # get user object
107         user = getattr(request, 'user', None)
108
109         # Check authentification of the user
110         if not authenticate_user(user, options):
111             return apache.HTTP_UNAUTHORIZED
112
113         # Validate and check permission of the user
114         if validate_user(user, options):
115             return apache.OK
116         else:
117             # mod_python docs say that HTTP_FORBIDDEN should be raised if the
118             # user authenticates but doesn't validate.
119             return apache.HTTP_FORBIDDEN
120
121     finally:
122         dispatcher.send(signal=signals.request_finished)