| 4 |   | def authenhandler(req, **kwargs): | 
          
          
            |   | 12 | _str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes') | 
          
          
            |   | 13 |  | 
          
          
            |   | 14 | class ModPythonAuthOptions: | 
          
          
            |   | 15 |     def __init__(self, req): | 
          
          
            |   | 16 |         options = req.get_options() | 
          
          
            |   | 17 |         self.permission_name = options.get('DjangoPermissionName', None) | 
          
          
            |   | 18 |         self.staff_only = _str_to_bool(options.get('DjangoRequireStaffStatus', "on")) | 
          
          
            |   | 19 |         self.superuser_only = _str_to_bool(options.get('DjangoRequireSuperuserStatus', "off")) | 
          
          
            |   | 20 |         self.raise_forbidden = _str_to_bool(options.get('DjangoRaiseForbidden', "off")) | 
          
          
            |   | 21 |         self.settings_module = options.get('DJANGO_SETTINGS_MODULE', None) | 
          
          
            |   | 22 |  | 
          
          
            |   | 23 | def setup_environment(req, options): | 
          
        
        
          
            | 16 |   |     options = req.get_options() | 
          
          
            | 17 |   |     permission_name = options.get('DjangoPermissionName', None) | 
          
          
            | 18 |   |     staff_only = _str_to_bool(options.get('DjangoRequireStaffStatus', "on")) | 
          
          
            | 19 |   |     superuser_only = _str_to_bool(options.get('DjangoRequireSuperuserStatus', "off")) | 
          
          
            | 20 |   |     settings_module = options.get('DJANGO_SETTINGS_MODULE', None) | 
          
          
            | 21 |   |     if settings_module: | 
          
          
            | 22 |   |         os.environ['DJANGO_SETTINGS_MODULE'] = settings_module | 
          
          
            |   | 39 | def validate_user(user, options): | 
          
          
            |   | 40 |     if hasattr(user, 'is_active') and not user.is_active: | 
          
          
            |   | 41 |         return False | 
          
          
            |   | 42 |     if options.staff_only and not getattr(user, 'is_staff', None): | 
          
          
            |   | 43 |         return False | 
          
          
            |   | 44 |     if options.superuser_only and not getattr(user, 'is_superuser', None): | 
          
          
            |   | 45 |         return False | 
          
          
            |   | 46 |     # If a permission is required then user must have a has_perm function to | 
          
          
            |   | 47 |     # validate. | 
          
          
            |   | 48 |     if options.permission_name and (not hasattr(user, 'has_perm') or | 
          
          
            |   | 49 |                                     not user.has_perm(options.permission_name)): | 
          
          
            |   | 50 |         return False | 
          
          
            |   | 51 |     return True | 
          
        
        
          
            | 24 |   |     from django.contrib.auth.models import User | 
          
          
            | 25 |   |     from django import db | 
          
          
            | 26 |   |     db.reset_queries() | 
          
          
            |   | 53 | def redirect_to_login(req): | 
          
          
            |   | 54 |     path = quote(req.uri) | 
          
          
            |   | 55 |     if req.args: | 
          
          
            |   | 56 |         path = '%s?%s' % (path, req.args) | 
          
          
            |   | 57 |     path = quote(path) | 
          
          
            |   | 58 |     iri = '%s?%s=%s' % (settings.LOGIN_URL, REDIRECT_FIELD_NAME, path) | 
          
          
            |   | 59 |     uri = iri_to_uri(iri) | 
          
          
            |   | 60 |     req.err_headers_out.add('Location', uri) | 
          
          
            |   | 61 |     if req.proto_num >= 1001: | 
          
          
            |   | 62 |         # Use HTTP Error 303 (see other) for HTTP/1.1 browsers. | 
          
          
            |   | 63 |         raise apache.SERVER_RETURN, apache.HTTP_SEE_OTHER | 
          
          
            |   | 64 |     else: | 
          
          
            |   | 65 |         # Otherwise use HTTP Error 302 (moved temporarily). | 
          
          
            |   | 66 |         raise apache.SERVER_RETURN, apache.HTTP_MOVED_TEMPORARILY | 
          
        
        
          
            | 28 |   |     # check that the username is valid | 
          
          
            | 29 |   |     kwargs = {'username': req.user, 'is_active': True} | 
          
          
            | 30 |   |     if staff_only: | 
          
          
            | 31 |   |         kwargs['is_staff'] = True | 
          
          
            | 32 |   |     if superuser_only: | 
          
          
            | 33 |   |         kwargs['is_superuser'] = True | 
          
          
            |   | 68 | def authenhandler(req, **kwargs): | 
          
          
            |   | 69 |     """ | 
          
          
            |   | 70 |     mod_python authentication handler that checks against Django's auth | 
          
          
            |   | 71 |     database. | 
          
          
            |   | 72 |     """ | 
          
          
            |   | 73 |     options = ModPythonAuthOptions(req) | 
          
          
            |   | 74 |     setup_environment(req, options) | 
          
          
            |   | 75 |  | 
          
          
            |   | 76 |     dispatcher.send(signal=signals.request_started) | 
          
        
        
          
            | 35 |   |         try: | 
          
          
            | 36 |   |             user = User.objects.get(**kwargs) | 
          
          
            | 37 |   |         except User.DoesNotExist: | 
          
          
            |   | 78 |         # This populates req.user too, so it's important to do first. | 
          
          
            |   | 79 |         password = req.get_basic_auth_pw() | 
          
          
            |   | 80 |  | 
          
          
            |   | 81 |         # Get the user from any of the installed backends. | 
          
          
            |   | 82 |         user = authenticate(username=req.user, password=password) | 
          
          
            |   | 83 |  | 
          
          
            |   | 84 |         if not authenticate_user(user): | 
          
          
            |   | 85 |             # Raise unauthorized if the user doesn't authenticate to bring up a | 
          
          
            |   | 86 |             # password dialog box to allow the user to authenticate. | 
          
        
        
          
            | 39 |   |      | 
          
          
            | 40 |   |         # check the password and any permission given | 
          
          
            | 41 |   |         if user.check_password(req.get_basic_auth_pw()): | 
          
          
            | 42 |   |             if permission_name: | 
          
          
            | 43 |   |                 if user.has_perm(permission_name): | 
          
          
            | 44 |   |                     return apache.OK | 
          
          
            | 45 |   |                 else: | 
          
          
            | 46 |   |                     return apache.HTTP_UNAUTHORIZED | 
          
          
            | 47 |   |             else: | 
          
          
            | 48 |   |                 return apache.OK | 
          
          
            |   | 88 |  | 
          
          
            |   | 89 |         # Validate the user | 
          
          
            |   | 90 |         if validate_user(user, options): | 
          
          
            |   | 91 |             return apache.OK | 
          
          
            |   | 92 |  | 
          
          
            |   | 93 |         # mod_python docs say that HTTP_FORBIDDEN should be raised if the user | 
          
          
            |   | 94 |         # authenticates but doesn't validate but Django provides it as an | 
          
          
            |   | 95 |         # option, alternately raising HTTP_UNAUTHORIZED again to provide the | 
          
          
            |   | 96 |         # option of logging in as an alternate user. | 
          
          
            |   | 97 |         if options.raise_forbidden: | 
          
          
            |   | 98 |             return apache.HTTP_FORBIDDEN | 
          
        
        
          
            | 52 |   |         db.connection.close() | 
          
          
            |   | 102 |         dispatcher.send(signal=signals.request_finished) | 
          
          
            |   | 103 |  | 
          
          
            |   | 104 | def accesshandler(req): | 
          
          
            |   | 105 |     """ | 
          
          
            |   | 106 |     mod_python access handler that uses the contrib.auth framework (with | 
          
          
            |   | 107 |     sessions, therefore requiring a session cookie). | 
          
          
            |   | 108 |     """ | 
          
          
            |   | 109 |     options = ModPythonAuthOptions(req) | 
          
          
            |   | 110 |     setup_environment(req, options) | 
          
          
            |   | 111 |  | 
          
          
            |   | 112 |     # Set up middleware, now that settings works we can do it now. | 
          
          
            |   | 113 |     base_handler = BaseHandler() | 
          
          
            |   | 114 |     base_handler.load_middleware() | 
          
          
            |   | 115 |  | 
          
          
            |   | 116 |     dispatcher.send(signal=signals.request_started) | 
          
          
            |   | 117 |     try: | 
          
          
            |   | 118 |         request = ModPythonRequest(req) | 
          
          
            |   | 119 |  | 
          
          
            |   | 120 |         # Apply request middleware | 
          
          
            |   | 121 |         for middleware_method in base_handler._request_middleware: | 
          
          
            |   | 122 |             response = middleware_method(request) | 
          
          
            |   | 123 |             if response: | 
          
          
            |   | 124 |                 # If we get a response then there's no need to keep processing | 
          
          
            |   | 125 |                 # any remaining request middleware. | 
          
          
            |   | 126 |                 break | 
          
          
            |   | 127 |  | 
          
          
            |   | 128 |         user = getattr(request, 'user', None) | 
          
          
            |   | 129 |         if not authenticate_user(user): | 
          
          
            |   | 130 |             # Rather than raising HTTP_UNAUTHORIZED (which the browser won't be | 
          
          
            |   | 131 |             # able to handle since this isn't basic HTTP authentication), write | 
          
          
            |   | 132 |             # a response which redirects to settings.LOGIN_URL | 
          
          
            |   | 133 |             redirect_to_login(req) | 
          
          
            |   | 134 |  | 
          
          
            |   | 135 |         if validate_user(user, options): | 
          
          
            |   | 136 |             return apache.OK | 
          
          
            |   | 137 |  | 
          
          
            |   | 138 |         # mod_python docs say that HTTP_FORBIDDEN should be raised if the user | 
          
          
            |   | 139 |         # authenticates but doesn't validate but Django provides it as an | 
          
          
            |   | 140 |         # option, alternately redirecting to login to provide the option of | 
          
          
            |   | 141 |         # logging in as an alternate user. | 
          
          
            |   | 142 |         if options.raise_forbidden: | 
          
          
            |   | 143 |             return apache.HTTP_FORBIDDEN | 
          
          
            |   | 144 |         else: | 
          
          
            |   | 145 |             redirect_to_login(req) | 
          
          
            |   | 146 |  | 
          
          
            |   | 147 |     finally: | 
          
          
            |   | 148 |         dispatcher.send(signal=signals.request_finished) |