1.1 --- a/examples/Common/LoginRedirect/__init__.py Sun May 30 16:41:22 2004 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,168 +0,0 @@
1.4 -#!/usr/bin/env python
1.5 -
1.6 -"Login redirection."
1.7 -
1.8 -from WebStack.Helpers.Auth import get_token
1.9 -import WebStack.Generic
1.10 -
1.11 -class LoginRedirectResource:
1.12 -
1.13 - "A resource redirecting to a login URL."
1.14 -
1.15 - def __init__(self, login_url, app_url, resource, authenticator, anonymous_parameter_name=None,
1.16 - anonymous_username="anonymous", logout_parameter_name=None, logout_url="/",
1.17 - use_logout_redirect=1):
1.18 -
1.19 - """
1.20 - Initialise the resource with a 'login_url', an 'app_url' where the 'resource' for
1.21 - the application being protected should be reachable, and an 'authenticator'.
1.22 -
1.23 - If the optional 'anonymous_parameter_name' is set, clients providing a parameter
1.24 - of that name in the URL will not be authenticated, but then such clients will get
1.25 - a predefined user identity associated with them, configurable using the optional
1.26 - 'anonymous_username'.
1.27 -
1.28 - If the optional 'logout_parameter_name' is set, clients providing a parameter of
1.29 - that name in the URL will become logged out. After logging out, clients are
1.30 - redirected to a location which can be configured by the optional 'logout_url'.
1.31 -
1.32 - If the optional 'use_logout_redirect' flag is set to 0, a confirmation screen is
1.33 - given instead of redirecting the user to the 'logout_url'.
1.34 - """
1.35 -
1.36 - self.login_url = login_url
1.37 - self.app_url = app_url
1.38 - self.resource = resource
1.39 - self.authenticator = authenticator
1.40 - self.anonymous_parameter_name = anonymous_parameter_name
1.41 - self.anonymous_username = anonymous_username
1.42 - self.logout_parameter_name = logout_parameter_name
1.43 - self.logout_url = logout_url
1.44 - self.use_logout_redirect = use_logout_redirect
1.45 -
1.46 - def respond(self, trans):
1.47 -
1.48 - fields_path = trans.get_fields_from_path()
1.49 -
1.50 - # Check for the logout parameter, if appropriate.
1.51 -
1.52 - if self.logout_parameter_name is not None and fields_path.has_key(self.logout_parameter_name):
1.53 -
1.54 - # Remove the special cookie token, then pass on the transaction.
1.55 -
1.56 - self.authenticator.unset_token(trans)
1.57 -
1.58 - # Redirect to the logout URL.
1.59 -
1.60 - if self.use_logout_redirect:
1.61 - trans.set_header_value("Location", self.logout_url)
1.62 - trans.set_response_code(307)
1.63 -
1.64 - # Show the logout confirmation anyway.
1.65 -
1.66 - self._show_logout(trans, self.logout_url)
1.67 -
1.68 - # Check the authentication details with the specified authenticator.
1.69 -
1.70 - elif self.authenticator.authenticate(trans):
1.71 -
1.72 - # If successful, pass on the transaction.
1.73 -
1.74 - self.resource.respond(trans)
1.75 -
1.76 - # Check for the anonymous parameter, if appropriate.
1.77 -
1.78 - elif self.anonymous_parameter_name is not None and fields_path.has_key(self.anonymous_parameter_name):
1.79 -
1.80 - # Make a special cookie token, then pass on the transaction.
1.81 -
1.82 - self.authenticator.set_token(trans, self.anonymous_username)
1.83 - self.resource.respond(trans)
1.84 -
1.85 - else:
1.86 -
1.87 - # Redirect to the login URL.
1.88 -
1.89 - trans.set_header_value("Location", "%s?redirect=%s%s" % (
1.90 - self.login_url, self.app_url, self._encode(trans.get_path()))
1.91 - )
1.92 - trans.set_response_code(307)
1.93 -
1.94 - def _encode(self, url):
1.95 -
1.96 - "Encode the given 'url' for redirection purposes."
1.97 -
1.98 - return url.replace("?", "%3f").replace("&", "%26")
1.99 -
1.100 - def _show_logout(self, trans, redirect):
1.101 -
1.102 - # When logout takes place, show the login screen.
1.103 -
1.104 - trans.set_content_type(WebStack.Generic.ContentType("text/html"))
1.105 - out = trans.get_response_stream()
1.106 - out.write("""
1.107 -<html>
1.108 - <head>
1.109 - <title>Logout</title>
1.110 - </head>
1.111 - <body>
1.112 - <h1>Logout Successful</h1>
1.113 - <p>Please proceed <a href="%s">to the application</a>.</p>
1.114 - </body>
1.115 -</html>
1.116 -""" % redirect)
1.117 -
1.118 -class LoginRedirectAuthenticator:
1.119 -
1.120 - """
1.121 - An authenticator which verifies the credentials provided in a special login cookie.
1.122 - """
1.123 -
1.124 - def __init__(self, secret_key, cookie_name=None):
1.125 -
1.126 - "Initialise the authenticator with a 'secret_key' and an optional 'cookie_name'."
1.127 -
1.128 - self.secret_key = secret_key
1.129 - self.cookie_name = cookie_name or "LoginAuthenticator"
1.130 -
1.131 - def authenticate(self, trans):
1.132 -
1.133 - "Authenticate the originator of 'trans', updating the object if successful."
1.134 -
1.135 - cookie = trans.get_cookie(self.cookie_name)
1.136 - if cookie is None or cookie.value is None:
1.137 - return 0
1.138 -
1.139 - # Test the token from the cookie against a recreated token using the
1.140 - # given information.
1.141 -
1.142 - username, code = cookie.value.split(":")
1.143 - if cookie.value == get_token(username, self.secret_key):
1.144 -
1.145 - # Update the transaction with the user details.
1.146 -
1.147 - trans.set_user(username)
1.148 - return 1
1.149 - else:
1.150 - return 0
1.151 -
1.152 - def set_token(self, trans, username):
1.153 -
1.154 - "Set an authentication token in 'trans' with the given 'username'."
1.155 -
1.156 - trans.set_cookie_value(
1.157 - self.cookie_name,
1.158 - get_token(username, self.secret_key)
1.159 - )
1.160 -
1.161 - # Update the transaction with the user details.
1.162 -
1.163 - trans.set_user(username)
1.164 -
1.165 - def unset_token(self, trans):
1.166 -
1.167 - "Unset the authentication token in 'trans'."
1.168 -
1.169 - trans.delete_cookie(self.cookie_name)
1.170 -
1.171 -# vim: tabstop=4 expandtab shiftwidth=4