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, trans.get_path())) 46 trans.set_response_code(307) 47 48 class LoginRedirectAuthenticator: 49 50 """ 51 An authenticator which verifies the credentials provided in a special login cookie. 52 """ 53 54 def __init__(self, secret_key, cookie_name=None): 55 56 "Initialise the authenticator with a 'secret_key' and an optional 'cookie_name'." 57 58 self.secret_key = secret_key 59 self.cookie_name = cookie_name or "LoginAuthenticator" 60 61 def authenticate(self, trans): 62 63 "Authenticate the originator of 'trans', updating the object if successful." 64 65 cookie = trans.get_cookie(self.cookie_name) 66 if cookie is None: 67 return 0 68 69 # Test the token from the cookie against a recreated token using the 70 # given information. 71 # NOTE: This should be moved into a common library. 72 73 username, code = cookie.value.split(":") 74 print "*", username, code 75 if code == md5.md5(username + self.secret_key).hexdigest(): 76 77 # Update the transaction with the user details. 78 79 trans.set_user(username) 80 return 1 81 else: 82 return 0 83 84 # vim: tabstop=4 expandtab shiftwidth=4