Ticket #215: paste.diff
| File paste.diff, 9.8 KB (added by catlee, 4 years ago) |
|---|
-
paste/auth/auth_tkt.py
diff -urN -x '*.pyc' paste-1.5.1.orig/paste/auth/auth_tkt.py paste/paste/auth/auth_tkt.py
old new 216 216 The path under this middleware that should signify a logout. The 217 217 page will be shown as usual, but the user will also be logged out 218 218 when they visit this page. 219 220 ``timeout``: 221 How many seconds before the cookie is considered invalid. Default 222 is None (never timeout) 223 224 ``refresh``: 225 A number between 0 and 1 representing the number of seconds (as 226 a fraction of ``timeout``) after which a valid cookie is refreshed. 227 Set to 0 to never refresh (the default) 228 Set to 1 to always refresh 229 Set to 0.33 to refresh the cookie after 0.33 * ``timeout`` seconds 219 230 220 231 If used with mod_auth_tkt, then these settings (except logout_path) should 221 232 match the analogous Apache configuration settings. … … 234 245 """ 235 246 236 247 def __init__(self, app, secret, cookie_name='auth_tkt', secure=False, 237 include_ip=True, logout_path=None): 248 include_ip=True, logout_path=None, timeout=None, 249 refresh=0): 238 250 self.app = app 239 251 self.secret = secret 240 252 self.cookie_name = cookie_name 241 253 self.secure = secure 242 254 self.include_ip = include_ip 243 255 self.logout_path = logout_path 256 self.timeout = timeout 257 self.refresh = float(refresh) 244 258 245 259 def __call__(self, environ, start_response): 260 set_cookies = [] 261 def set_user(userid, tokens='', user_data=''): 262 set_cookies.extend(self.set_user_cookie( 263 environ, userid, tokens, user_data)) 264 def logout_user(): 265 set_cookies.extend(self.logout_user_cookie(environ)) 266 environ['paste.auth_tkt.set_user'] = set_user 267 environ['paste.auth_tkt.logout_user'] = logout_user 268 269 def cookie_setting_start_response(status, headers, exc_info=None): 270 headers.extend(set_cookies) 271 return start_response(status, headers, exc_info) 272 246 273 cookies = request.get_cookies(environ) 247 274 if cookies.has_key(self.cookie_name): 248 275 cookie_value = cookies[self.cookie_name].value 249 276 else: 250 277 cookie_value = '' 278 279 if self.logout_path and environ.get('PATH_INFO') == self.logout_path: 280 logout_user() 281 251 282 if cookie_value: 252 283 if self.include_ip: 253 284 remote_addr = environ['REMOTE_ADDR'] … … 256 287 # checked: 257 288 remote_addr = '0.0.0.0' 258 289 # @@: This should handle bad signatures better: 259 # Also, timeouts should cause cookie refresh260 290 timestamp, userid, tokens, user_data = parse_ticket( 261 291 self.secret, cookie_value, remote_addr) 262 tokens = ','.join(tokens) 263 environ['REMOTE_USER'] = userid 264 if environ.get('REMOTE_USER_TOKENS'): 265 # We want to add tokens/roles to what's there: 266 tokens = environ['REMOTE_USER_TOKENS'] + ',' + tokens 267 environ['REMOTE_USER_TOKENS'] = tokens 268 environ['REMOTE_USER_DATA'] = user_data 269 environ['AUTH_TYPE'] = 'cookie' 270 set_cookies = [] 271 def set_user(userid, tokens='', user_data=''): 272 set_cookies.extend(self.set_user_cookie( 273 environ, userid, tokens, user_data)) 274 def logout_user(): 275 set_cookies.extend(self.logout_user_cookie(environ)) 276 environ['paste.auth_tkt.set_user'] = set_user 277 environ['paste.auth_tkt.logout_user'] = logout_user 278 if self.logout_path and environ.get('PATH_INFO') == self.logout_path: 279 logout_user() 280 def cookie_setting_start_response(status, headers, exc_info=None): 281 headers.extend(set_cookies) 282 return start_response(status, headers, exc_info) 292 # Check the timestamp 293 now = time_mod.time() 294 if self.timeout is None or timestamp + self.timeout > now: 295 cookieTokens = ','.join(tokens) 296 environ['REMOTE_USER'] = userid 297 if environ.get('REMOTE_USER_TOKENS'): 298 # We want to add tokens/roles to what's there: 299 tokens = environ['REMOTE_USER_TOKENS'] + ',' + cookieTokens 300 environ['REMOTE_USER_TOKENS'] = tokens 301 environ['REMOTE_USER_DATA'] = user_data 302 environ['AUTH_TYPE'] = 'cookie' 303 # Refresh the cookie if necessary 304 if self.timeout is not None: 305 elapsed = now - timestamp 306 if elapsed > (self.refresh * self.timeout): 307 set_user(userid, cookieTokens, user_data) 308 else: 309 # The cookie expired 310 pass 311 283 312 return self.app(environ, cookie_setting_start_response) 284 313 285 314 def set_user_cookie(self, environ, userid, tokens, user_data): … … 323 352 cookie_name='auth_tkt', 324 353 secure=False, 325 354 include_ip=True, 326 logout_path=None): 355 logout_path=None, 356 timeout=None, 357 refresh=0): 327 358 """ 328 359 Creates the `AuthTKTMiddleware 329 360 <class-paste.auth.auth_tkt.AuthTKTMiddleware.html>`_. … … 339 370 raise ValueError( 340 371 "You must provide a 'secret' (in global or local configuration)") 341 372 return AuthTKTMiddleware( 342 app, secret, cookie_name, secure, include_ip, logout_path or None) 373 app, secret, cookie_name, secure, include_ip, logout_path or None, 374 timeout, refresh) -
tests/test_auth/test_auth_tkt.py
diff -urN -x '*.pyc' paste-1.5.1.orig/tests/test_auth/test_auth_tkt.py paste/tests/test_auth/test_auth_tkt.py
old new 1 # (c) 2007 Chris AtLee 2 # This module is part of the Python Paste Project and is released under 3 # the MIT License: http://www.opensource.org/licenses/mit-license.php 4 5 from paste.auth.auth_tkt import * 6 from paste.wsgilib import raw_interactive, dump_environ 7 from paste.response import header_value 8 from paste.httpexceptions import * 9 import os 10 11 import py.test 12 import time as time_mod 13 14 secret = "s3krit" 15 16 def test_noop(): 17 app = AuthTKTMiddleware(dump_environ, secret) 18 19 (status, headers, content, errors) = \ 20 raw_interactive(app) 21 22 value = header_value(headers, 'Set-Cookie') 23 assert value is None 24 25 def test_basic(): 26 app = AuthTKTMiddleware(dump_environ, secret) 27 28 tkt = AuthTicket(secret, 'catlee', '0.0.0.0') 29 30 cookie = "%s=%s" % ("auth_tkt", tkt.cookie_value()) 31 32 (status, headers, content, errors) = \ 33 raw_interactive(app, HTTP_COOKIE=cookie, REMOTE_ADDR="0.0.0.0") 34 35 assert "REMOTE_USER: catlee" in content 36 37 def test_ipcheck(): 38 app = AuthTKTMiddleware(dump_environ, secret) 39 40 tkt = AuthTicket(secret, 'catlee', '0.0.0.1') 41 42 cookie = "%s=%s" % ("auth_tkt", tkt.cookie_value()) 43 44 py.test.raises(BadTicket, 45 raw_interactive, app, HTTP_COOKIE=cookie, REMOTE_ADDR="0.0.0.0") 46 47 def test_cookiename(): 48 app = AuthTKTMiddleware(dump_environ, secret, cookie_name = "secret") 49 50 tkt = AuthTicket(secret, 'catlee', '0.0.0.0') 51 52 cookie = "%s=%s" % ("secret", tkt.cookie_value()) 53 54 (status, headers, content, errors) = \ 55 raw_interactive(app, HTTP_COOKIE=cookie, REMOTE_ADDR="0.0.0.0") 56 57 assert "REMOTE_USER: catlee" in content 58 59 def test_logout(): 60 app = AuthTKTMiddleware(dump_environ, secret, logout_path="/logout") 61 62 (status, headers, content, errors) = \ 63 raw_interactive(app, "/logout") 64 65 value = header_value(headers, 'Set-Cookie') 66 assert value is not None 67 68 def test_nologout(): 69 app = AuthTKTMiddleware(dump_environ, secret, logout_path="/logout") 70 71 (status, headers, content, errors) = \ 72 raw_interactive(app, "/dontlogout") 73 74 value = header_value(headers, 'Set-Cookie') 75 assert value is None 76 77 def test_notimeout(): 78 app = AuthTKTMiddleware(dump_environ, secret, timeout=60) 79 80 now = time_mod.time() 81 82 tkt = AuthTicket(secret, 'catlee', '0.0.0.0', time=now) 83 cookie = "%s=%s" % ("auth_tkt", tkt.cookie_value()) 84 85 (status, headers, content, errors) = \ 86 raw_interactive(app, HTTP_COOKIE=cookie, REMOTE_ADDR="0.0.0.0") 87 88 assert "REMOTE_USER: catlee" in content 89 90 def test_timeout(): 91 app = AuthTKTMiddleware(dump_environ, secret, timeout=60) 92 93 now = time_mod.time() 94 95 tkt = AuthTicket(secret, 'catlee', '0.0.0.0', time=now-120) 96 cookie = "%s=%s" % ("auth_tkt", tkt.cookie_value()) 97 98 (status, headers, content, errors) = \ 99 raw_interactive(app, HTTP_COOKIE=cookie, REMOTE_ADDR="0.0.0.0") 100 101 assert "REMOTE_USER: catlee" not in content 102 103 def test_refresh(): 104 app = AuthTKTMiddleware(dump_environ, secret, timeout=60, refresh=0.5) 105 106 now = time_mod.time() 107 108 tkt = AuthTicket(secret, 'catlee', '0.0.0.0', time=now-40) 109 cookie = "%s=%s" % ("auth_tkt", tkt.cookie_value()) 110 111 (status, headers, content, errors) = \ 112 raw_interactive(app, HTTP_COOKIE=cookie, REMOTE_ADDR="0.0.0.0") 113 114 value = header_value(headers, 'Set-Cookie') 115 assert value is not None 116 117 def test_norefresh(): 118 app = AuthTKTMiddleware(dump_environ, secret, timeout=60, refresh=0.5) 119 120 now = time_mod.time() 121 122 tkt = AuthTicket(secret, 'catlee', '0.0.0.0', time=now-20) 123 cookie = "%s=%s" % ("auth_tkt", tkt.cookie_value()) 124 125 (status, headers, content, errors) = \ 126 raw_interactive(app, HTTP_COOKIE=cookie, REMOTE_ADDR="0.0.0.0") 127 128 value = header_value(headers, 'Set-Cookie') 129 assert value is None
