| | 75 | |
|---|
| | 76 | |
|---|
| | 77 | Bad Cookie Support |
|---|
| | 78 | ================== |
|---|
| | 79 | |
|---|
| | 80 | If a cookie has expired or because there is an error parsing the ticket, it |
|---|
| | 81 | is known as a bad cookie. By default, a simple HTML page is displayed with |
|---|
| | 82 | the title "Bad Cookie" and a brief message. The headers sent with this page |
|---|
| | 83 | remove the cookie. |
|---|
| | 84 | |
|---|
| | 85 | You may want to disable this functionality and let your application handle |
|---|
| | 86 | the error condition. You can do so with this option:: |
|---|
| | 87 | |
|---|
| | 88 | authkit.cookie.badcookie.page = false |
|---|
| | 89 | |
|---|
| | 90 | When a bad cookie is found the variable ``authkit.cookie.error`` is set in |
|---|
| | 91 | the environment with a value ``True``. If the error was due to cookie |
|---|
| | 92 | expiration the value ``authkit.cookie.timeout`` is also set to ``True``. It |
|---|
| | 93 | is then up to your application to set an appropriate cookie or restrict |
|---|
| | 94 | access to resources. AuthKit will also remove any ``REMOTE_USER`` present. |
|---|
| | 95 | |
|---|
| | 96 | Rather than handling the bad cookie in your application you may just want |
|---|
| | 97 | to change the template used by AuthKit. You do so like this:: |
|---|
| | 98 | |
|---|
| | 99 | authkit.cookie.badcookie.page = false |
|---|
| | 100 | authkit.cookie.badcookie.template.string = <html>Bad Cookie</html> |
|---|
| | 101 | |
|---|
| | 102 | You can use any of the template options you use to customise a form so |
|---|
| | 103 | you can also specify a function to render the template:: |
|---|
| | 104 | |
|---|
| | 105 | authkit.cookie.badcookie.page = false |
|---|
| | 106 | authkit.cookie.badcookie.template.obj = mymodule.auth:render_badcookie |
|---|
| | 107 | |
|---|
| | 108 | The render function can also take optional ``environ`` and ``state`` |
|---|
| | 109 | arguments which are passed in by AuthKit if the function takes them as named |
|---|
| | 110 | arguments. |
|---|
| | 111 | |
|---|
| | 112 | One thing to be aware of when using this functionality is that because the |
|---|
| | 113 | render function gets called as the request is first passed along the middleware |
|---|
| | 114 | chain, many of the tools your application relies on are not yet set up so |
|---|
| | 115 | you may not be able to use all the tools you usually do. This is unlike |
|---|
| | 116 | thr forms situation where the form render function is called on the response |
|---|
| | 117 | after all your usual application infrastructure is in place. |
|---|
| | 118 | |
|---|
| 88 | | from authkit.authenticate import strip_base, swap_underscore, AuthKitConfigError, AuthKitUserSetter |
|---|
| | 134 | from authkit.authenticate import strip_base, swap_underscore |
|---|
| | 135 | from authkit.authenticate import AuthKitConfigError |
|---|
| | 136 | from authkit.authenticate import get_template, AuthKitUserSetter |
|---|
| | 137 | |
|---|
| | 138 | |
|---|
| | 139 | def template(): |
|---|
| | 140 | t = '''\ |
|---|
| | 141 | <html><head><title></title></head> |
|---|
| | 142 | <body><h1>Bad Cookie</h1> |
|---|
| | 143 | <p>You have been signed out. If this problem persists |
|---|
| | 144 | please clear your browser's cookies.</p> |
|---|
| | 145 | </body></html> |
|---|
| | 146 | ''' |
|---|
| | 147 | return t |
|---|
| 327 | | # @@: This should handle bad signatures better: |
|---|
| 328 | | # Also, timeouts should cause cookie refresh |
|---|
| 329 | | |
|---|
| 330 | | # |
|---|
| 331 | | # Start changes from the default |
|---|
| 332 | | # |
|---|
| 333 | | def bad_ticket_app(environ, start_response, msg=None): |
|---|
| 334 | | # Remove the session username |
|---|
| 335 | | if self.nouserincookie: |
|---|
| 336 | | environ[self.session_middleware]['authkit.cookie.user'] = None |
|---|
| 337 | | del environ[self.session_middleware]['authkit.cookie.user'] |
|---|
| 338 | | environ[self.session_middleware].save() |
|---|
| 339 | | |
|---|
| 340 | | headers = self.logout_user_cookie(environ) |
|---|
| 341 | | headers.append(('Content-type','text/plain')) |
|---|
| 342 | | start_response('200 OK', headers) |
|---|
| 343 | | if not msg: |
|---|
| 344 | | msg = 'Bad cookie, you have been signed out.\n If this' |
|---|
| 345 | | msg += 'problem persists please clear your browser\'s ' |
|---|
| 346 | | msg += 'cookies.' |
|---|
| 347 | | return [msg] |
|---|
| 373 | | environ['REMOTE_USER'] = userid |
|---|
| 374 | | if environ.get('REMOTE_USER_TOKENS'): |
|---|
| 375 | | # We want to add tokens/roles to what's there: |
|---|
| 376 | | tokens = str(environ['REMOTE_USER_TOKENS']) + ',' + str(tokens) |
|---|
| 377 | | environ['REMOTE_USER_TOKENS'] = tokens |
|---|
| 378 | | environ['REMOTE_USER_DATA'] = user_data |
|---|
| 379 | | environ['AUTH_TYPE'] = 'cookie' |
|---|
| | 419 | if environ.get('authkit.cookie.error', False) and self.badcookiepage: |
|---|
| | 420 | def bad_cookie_app(environ, start_response): |
|---|
| | 421 | # If we are using optional session support remove the user from the session: |
|---|
| | 422 | if self.nouserincookie: |
|---|
| | 423 | environ[self.session_middleware]['authkit.cookie.user'] = None |
|---|
| | 424 | del environ[self.session_middleware]['authkit.cookie.user'] |
|---|
| | 425 | environ[self.session_middleware].save() |
|---|
| | 426 | # Now show the bad cookie screen: |
|---|
| | 427 | headers = self.logout_user_cookie(environ) |
|---|
| | 428 | headers.append(('Content-type','text/html')) |
|---|
| | 429 | start_response('200 OK', headers) |
|---|
| | 430 | # Inspect the function to see if we can pass it anything useful: |
|---|
| | 431 | args = {} |
|---|
| | 432 | kargs = {'environ':environ} |
|---|
| | 433 | if environ.has_key('gi.state'): |
|---|
| | 434 | kargs['state'] = environ['gi.state'] |
|---|
| | 435 | for name in inspect.getargspec(self.badcookietemplate)[0]: |
|---|
| | 436 | if kargs.has_key(name): |
|---|
| | 437 | args[name] = kargs[name] |
|---|
| | 438 | response = self.badcookietemplate(**args) |
|---|
| | 439 | return [response] |
|---|
| | 440 | return bad_cookie_app(environ, start_response) |
|---|
| | 441 | elif not environ.get('authkit.cookie.error', False): |
|---|
| | 442 | environ['REMOTE_USER'] = userid |
|---|
| | 443 | if environ.get('REMOTE_USER_TOKENS'): |
|---|
| | 444 | # We want to add tokens/roles to what's there: |
|---|
| | 445 | tokens = environ['REMOTE_USER_TOKENS'] + tokens |
|---|
| | 446 | environ['REMOTE_USER_TOKENS'] = tokens |
|---|
| | 447 | environ['REMOTE_USER_DATA'] = user_data |
|---|
| | 448 | environ['AUTH_TYPE'] = 'cookie' |
|---|
| | 449 | # Remove REMOTE_USER set by any other application. |
|---|
| | 450 | elif environ.has_key('REMOTE_USER'): |
|---|
| | 451 | log.warning('Removing the existing REMOTE_USER key because of a bad cookie') |
|---|
| | 452 | del environ['REMOTE_USER'] |
|---|