Ticket #3583: modpython.2.py

File modpython.2.py, 4.4 KB (added by TomFreudenberg, 17 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 
1from mod_python import apache
2import os
3from django.core import signals
4from django.dispatch import dispatcher
5from django.core.handlers.base import BaseHandler
6from django.core.handlers.modpython import ModPythonRequest
7from django.contrib.auth import authenticate
8
9_str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes')
10
11class 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
19def 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
28def 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
36def 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
49def 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
82def 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)
Back to Top