# HG changeset patch # User paulb # Date 1085939057 0 # Node ID 29f53ea6be11e3459856e7c23b45e747a96927f5 # Parent f2878dc56e5dd0919a9d9788a1fb6948eab92465 [project @ 2004-05-30 17:44:17 by paulb] Updated documentation in LoginRedirect. Moved Login from the examples to WebStack.Resources. diff -r f2878dc56e5d -r 29f53ea6be11 WebStack/Resources/Login.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebStack/Resources/Login.py Sun May 30 17:44:17 2004 +0000 @@ -0,0 +1,171 @@ +#!/usr/bin/env python + +"Login resources which redirect clients back to an application after a successful login." + +import WebStack.Generic +from WebStack.Helpers.Auth import get_token + +class LoginResource: + + "A resource providing a login screen." + + def __init__(self, authenticator, use_redirect=1): + + """ + Initialise the resource with an 'authenticator'. + + If the optional 'use_redirect' flag is set to 0, a confirmation screen is given + instead of redirecting the user back to the original application. + """ + + self.authenticator = authenticator + self.use_redirect = use_redirect + + def respond(self, trans): + + "Respond using the transaction 'trans'." + + fields_path = trans.get_fields_from_path() + fields_body = trans.get_fields_from_body() + + # NOTE: Handle missing redirects better. + + if fields_body.has_key("redirect"): + redirects = fields_body["redirect"] + redirect = redirects[0] + elif fields_path.has_key("redirect"): + redirects = fields_path["redirect"] + redirect = redirects[0] + else: + redirect = "" + + # Check for a submitted login form. + + if fields_body.has_key("login"): + if self.authenticator.authenticate(trans): + self._redirect(trans, redirect) + return + + # Otherwise, show the login form. + + self._show_login(trans, redirect) + + def _redirect(self, trans, redirect): + + "Redirect the client using 'trans' and the given 'redirect' URL." + + if self.use_redirect: + trans.set_header_value("Location", redirect) + trans.set_response_code(307) + + # Show the success page anyway. + + self._show_success(trans, redirect) + + def _show_login(self, trans, redirect): + + """ + Writes a login screen using the transaction 'trans', including details of the + 'redirect' URL which the client was attempting to access. + """ + + trans.set_content_type(WebStack.Generic.ContentType("text/html")) + out = trans.get_response_stream() + out.write(""" + + + Login Example + + +

Login

+
+

Username:

+

Password:

+

+ +
+ + +""" % redirect) + + def _show_success(self, trans, redirect): + + # When authentication fails or is yet to take place, show the login + # screen. + + trans.set_content_type(WebStack.Generic.ContentType("text/html")) + out = trans.get_response_stream() + out.write(""" + + + Login Example + + +

Login Successful

+

Please proceed to the application.

+ + +""" % redirect) + + def _decode(self, url): + + "Decode the given 'url' for redirection purposes." + + return url.replace("%3f", "?").replace("%26", "&") + +class LoginAuthenticator: + + def __init__(self, secret_key, credentials, cookie_name=None): + + """ + Initialise the authenticator with a 'secret_key', the authenticator's registry of + 'credentials' and an optional 'cookie_name'. + + The 'credentials' must be an object which supports tests of the form + '(username, password) in credentials'. + """ + + self.secret_key = secret_key + self.credentials = credentials + self.cookie_name = cookie_name or "LoginAuthenticator" + + def authenticate(self, trans): + + """ + Authenticate the sender of the transaction 'trans', returning 1 (true) if they are + recognised, 0 (false) otherwise. + """ + + # Process any supplied parameters. + + fields = trans.get_fields_from_body() + + if fields.has_key("username") and fields.has_key("password"): + usernames, passwords = fields["username"], fields["password"] + + # Insist on only one username and password. + + if len(usernames) == 1 and len(passwords) == 1: + username, password = usernames[0], passwords[0] + + # Check against the class's credentials. + + if (username, password) in self.credentials: + + # Make a special cookie token. + + self.set_token(trans, username) + return 1 + + return 0 + + def set_token(self, trans, username): + + "Set an authentication token in 'trans' with the given 'username'." + + trans.set_cookie_value( + self.cookie_name, + get_token(username, self.secret_key) + ) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r f2878dc56e5d -r 29f53ea6be11 WebStack/Resources/LoginRedirect.py --- a/WebStack/Resources/LoginRedirect.py Sun May 30 17:21:51 2004 +0000 +++ b/WebStack/Resources/LoginRedirect.py Sun May 30 17:44:17 2004 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env python -"Login redirection." +"Login redirection resources, sending unauthenticated users to a login screen URL." from WebStack.Helpers.Auth import get_token import WebStack.Generic @@ -134,7 +134,10 @@ def authenticate(self, trans): - "Authenticate the originator of 'trans', updating the object if successful." + """ + Authenticate the originator of 'trans', updating the object if successful and + returning 1 (true) if successful, 0 (false) otherwise. + """ cookie = trans.get_cookie(self.cookie_name) if cookie is None or cookie.value is None: