1.1 --- a/examples/Common/Login/__init__.py Sun May 30 17:44:17 2004 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,162 +0,0 @@
1.4 -#!/usr/bin/env python
1.5 -
1.6 -"An example login screen."
1.7 -
1.8 -import WebStack.Generic
1.9 -from WebStack.Helpers.Auth import get_token
1.10 -
1.11 -class LoginResource:
1.12 -
1.13 - "A resource providing a login screen."
1.14 -
1.15 - def __init__(self, authenticator, use_redirect=1):
1.16 -
1.17 - """
1.18 - Initialise the resource with an 'authenticator'.
1.19 -
1.20 - If the optional 'use_redirect' flag is set to 0, a confirmation screen is given
1.21 - instead of redirecting the user back to the original application.
1.22 - """
1.23 -
1.24 - self.authenticator = authenticator
1.25 - self.use_redirect = use_redirect
1.26 -
1.27 - def respond(self, trans):
1.28 -
1.29 - fields_path = trans.get_fields_from_path()
1.30 - fields_body = trans.get_fields_from_body()
1.31 -
1.32 - # NOTE: Handle missing redirects better.
1.33 -
1.34 - if fields_body.has_key("redirect"):
1.35 - redirects = fields_body["redirect"]
1.36 - redirect = redirects[0]
1.37 - elif fields_path.has_key("redirect"):
1.38 - redirects = fields_path["redirect"]
1.39 - redirect = redirects[0]
1.40 - else:
1.41 - redirect = ""
1.42 -
1.43 - # Check for a submitted login form.
1.44 -
1.45 - if fields_body.has_key("login"):
1.46 - if self.authenticator.authenticate(trans):
1.47 - self._redirect(trans, redirect)
1.48 - return
1.49 -
1.50 - # Otherwise, show the login form.
1.51 -
1.52 - self._show_login(trans, redirect)
1.53 -
1.54 - def _redirect(self, trans, redirect):
1.55 -
1.56 - "Redirect the client using 'trans' and the given 'redirect' URL."
1.57 -
1.58 - if self.use_redirect:
1.59 - trans.set_header_value("Location", redirect)
1.60 - trans.set_response_code(307)
1.61 -
1.62 - # Show the success page anyway.
1.63 -
1.64 - self._show_success(trans, redirect)
1.65 -
1.66 - def _show_login(self, trans, redirect):
1.67 -
1.68 - # When authentication fails or is yet to take place, show the login
1.69 - # screen.
1.70 -
1.71 - trans.set_content_type(WebStack.Generic.ContentType("text/html"))
1.72 - out = trans.get_response_stream()
1.73 - out.write("""
1.74 -<html>
1.75 - <head>
1.76 - <title>Login Example</title>
1.77 - </head>
1.78 - <body>
1.79 - <h1>Login</h1>
1.80 - <form method="POST">
1.81 - <p>Username: <input name="username" type="text" size="12"/></p>
1.82 - <p>Password: <input name="password" type="text" size="12"/></p>
1.83 - <p><input name="login" type="submit" value="Login"/></p>
1.84 - <input name="redirect" type="hidden" value="%s"/>
1.85 - </form>
1.86 - </body>
1.87 -</html>
1.88 -""" % redirect)
1.89 -
1.90 - def _show_success(self, trans, redirect):
1.91 -
1.92 - # When authentication fails or is yet to take place, show the login
1.93 - # screen.
1.94 -
1.95 - trans.set_content_type(WebStack.Generic.ContentType("text/html"))
1.96 - out = trans.get_response_stream()
1.97 - out.write("""
1.98 -<html>
1.99 - <head>
1.100 - <title>Login Example</title>
1.101 - </head>
1.102 - <body>
1.103 - <h1>Login Successful</h1>
1.104 - <p>Please proceed <a href="%s">to the application</a>.</p>
1.105 - </body>
1.106 -</html>
1.107 -""" % redirect)
1.108 -
1.109 - def _decode(self, url):
1.110 -
1.111 - "Decode the given 'url' for redirection purposes."
1.112 -
1.113 - return url.replace("%3f", "?").replace("%26", "&")
1.114 -
1.115 -class LoginAuthenticator:
1.116 -
1.117 - def __init__(self, secret_key, credentials, cookie_name=None):
1.118 -
1.119 - """
1.120 - Initialise the authenticator with a 'secret_key', the authenticator's registry of
1.121 - 'credentials' and an optional 'cookie_name'.
1.122 -
1.123 - The 'credentials' must be an object which supports tests of the form
1.124 - '(username, password) in credentials'.
1.125 - """
1.126 -
1.127 - self.secret_key = secret_key
1.128 - self.credentials = credentials
1.129 - self.cookie_name = cookie_name or "LoginAuthenticator"
1.130 -
1.131 - def authenticate(self, trans):
1.132 -
1.133 - # Process any supplied parameters.
1.134 -
1.135 - fields = trans.get_fields_from_body()
1.136 -
1.137 - if fields.has_key("username") and fields.has_key("password"):
1.138 - usernames, passwords = fields["username"], fields["password"]
1.139 -
1.140 - # Insist on only one username and password.
1.141 -
1.142 - if len(usernames) == 1 and len(passwords) == 1:
1.143 - username, password = usernames[0], passwords[0]
1.144 -
1.145 - # Check against the class's credentials.
1.146 -
1.147 - if (username, password) in self.credentials:
1.148 -
1.149 - # Make a special cookie token.
1.150 -
1.151 - self.set_token(trans, username)
1.152 - return 1
1.153 -
1.154 - return 0
1.155 -
1.156 - def set_token(self, trans, username):
1.157 -
1.158 - "Set an authentication token in 'trans' with the given 'username'."
1.159 -
1.160 - trans.set_cookie_value(
1.161 - self.cookie_name,
1.162 - get_token(username, self.secret_key)
1.163 - )
1.164 -
1.165 -# vim: tabstop=4 expandtab shiftwidth=4