WebStack

examples/Common/LoginRedirect/__init__.py

136:d475f56082c5
2004-05-29 paulb [project @ 2004-05-29 21:09:25 by paulb] Added encoding of redirect URL information. Fixed the case where cookie values can be None.
     1 #!/usr/bin/env python     2      3 "Login redirection."     4      5 import md5     6      7 class LoginRedirectResource:     8      9     "A resource redirecting to a login URL."    10     11     def __init__(self, login_url, app_url, resource, authenticator, anonymous_parameter_name=None):    12     13         """    14         Initialise the resource with a 'login_url', an 'app_url' where the 'resource' for    15         the application being protected should be reachable, and an 'authenticator'.    16     17         If the optional 'anonymous_parameter_name' is set, clients providing a parameter    18         of that name in the URL will not be authenticated, but then such clients will not    19         get a user identity associated with them.     20         """    21     22         self.login_url = login_url    23         self.app_url = app_url    24         self.resource = resource    25         self.authenticator = authenticator    26         self.anonymous_parameter_name = anonymous_parameter_name    27     28     def respond(self, trans):    29     30         # Check for the anonymous parameter, if appropriate.    31     32         fields = trans.get_fields_from_path()    33         if self.anonymous_parameter_name is not None and fields.has_key(self.anonymous_parameter_name):    34             is_anonymous = 1    35         else:    36             is_anonymous = 0    37     38         # Check the authentication details with the specified authenticator.    39     40         if is_anonymous or self.authenticator.authenticate(trans):    41             self.resource.respond(trans)    42         else:    43             # Redirect to the login URL.    44     45             trans.set_header_value("Location", "%s?redirect=%s%s" % (self.login_url, self.app_url, self._encode(trans.get_path())))    46             trans.set_response_code(307)    47     48     def _encode(self, url):    49     50         "Encode the given 'url' for redirection purposes."    51     52         return url.replace("?", "%3f").replace("&", "%26")    53     54 class LoginRedirectAuthenticator:    55     56     """    57     An authenticator which verifies the credentials provided in a special login cookie.    58     """    59     60     def __init__(self, secret_key, cookie_name=None):    61     62         "Initialise the authenticator with a 'secret_key' and an optional 'cookie_name'."    63     64         self.secret_key = secret_key    65         self.cookie_name = cookie_name or "LoginAuthenticator"    66     67     def authenticate(self, trans):    68     69         "Authenticate the originator of 'trans', updating the object if successful."    70     71         cookie = trans.get_cookie(self.cookie_name)    72         if cookie is None or cookie.value is None:    73             return 0    74     75         # Test the token from the cookie against a recreated token using the    76         # given information.    77         # NOTE: This should be moved into a common library.    78     79         username, code = cookie.value.split(":")    80         if code == md5.md5(username + self.secret_key).hexdigest():    81     82             # Update the transaction with the user details.    83     84             trans.set_user(username)    85             return 1    86         else:    87             return 0    88     89 # vim: tabstop=4 expandtab shiftwidth=4