From e0b50b620cad386a644cdb000598c54c8986d4d3 Mon Sep 17 00:00:00 2001 From: Andrea Papotti Date: Mon, 10 Dec 2012 16:19:37 +0100 Subject: [PATCH] autenticazione e controllo (elementare) dei permessi. NON funziona come singleton. --- controllers/admin.py | 16 +++++++++++++ controllers/demo/due.py | 2 +- controllers/forbidden.py | 17 ++++++++++++++ controllers/login.py | 40 ++++++++++++++++++++++++++++++++ controllers/logout.py | 19 +++++++++++++++ controllers/secret.py | 3 ++- decorators.py | 49 +++++++++++++++++++++++++++++++++------ dispatch_wsgi.py | 2 +- router.py | 5 +--- static/attack_dog.jpg | Bin 0 -> 48950 bytes static/index.html | 5 +++- 11 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 controllers/admin.py create mode 100644 controllers/forbidden.py create mode 100644 controllers/login.py create mode 100644 controllers/logout.py create mode 100644 static/attack_dog.jpg diff --git a/controllers/admin.py b/controllers/admin.py new file mode 100644 index 0000000..5de5268 --- /dev/null +++ b/controllers/admin.py @@ -0,0 +1,16 @@ +#!/usr/bin/python +# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*- + +from decorators import WSGISimpleAuth # decoratore ( singleton ) +auth = WSGISimpleAuth() + +@auth.require( 'admin superadmin hyperadmin' ) +def application( environ, start_response ): + storage = environ['auth.storage'] + + start_response( '200 OK', [('content-type', 'text/html; charset=utf-8')] ) + + return [ + "

GOSH BATMAN! HOW DID SHE DO THE IMPOSSIBLE?

", + "index" + ] diff --git a/controllers/demo/due.py b/controllers/demo/due.py index 7628023..82cda5b 100644 --- a/controllers/demo/due.py +++ b/controllers/demo/due.py @@ -18,4 +18,4 @@ def application( environ, start_response ): start_response( '200 OK', [('content-type', 'text/html; charset=utf-8')] ) - return [ html, '



', '
', pformat( environ, width=132 ), '
' ] # TODO: pformat..... ---> trasformarlo in un decoratore + return [ html, '



', '
', pformat( environ, width=132 ), '
' ] diff --git a/controllers/forbidden.py b/controllers/forbidden.py new file mode 100644 index 0000000..b00bbd4 --- /dev/null +++ b/controllers/forbidden.py @@ -0,0 +1,17 @@ +#!/usr/bin/python +# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*- + +from decorators import WSGISimpleAuth # decoratore ( singleton ) +auth = WSGISimpleAuth() + +def application( environ, start_response ): + start_response( '200 OK', [('content-type', 'text/html; charset=utf-8')] ) + + return [ + "
", + "

FORBIDDEN

", + "", + "


", + "Maybe you should go back to index", + "
" + ] diff --git a/controllers/login.py b/controllers/login.py new file mode 100644 index 0000000..ff84c46 --- /dev/null +++ b/controllers/login.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*- + +from decorators import WSGISimpleAuth # decoratore ( singleton ) +auth = WSGISimpleAuth() + +@auth.require() +def application( environ, start_response ): + storage = environ['auth.storage'] + + import cgi + post_environ = environ.copy() + post_environ['QUERY_STRING'] = '' + post = cgi.FieldStorage( + fp=environ['wsgi.input'], + environ=post_environ, + keep_blank_values=True + ) + + if 'password' in post: + password = post['password'].value + storage['permissions'] = [ 'auth' ] + html = [ + "You are logged in, now you can see the Secret page.", + ] + + else: + storage['timeout'] = -1 + html = [ + "
" + "Password: ", + "", + "
", + ] + + start_response( '200 OK', [('content-type', 'text/html; charset=utf-8')] ) + + return html + + diff --git a/controllers/logout.py b/controllers/logout.py new file mode 100644 index 0000000..f9f1c1d --- /dev/null +++ b/controllers/logout.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*- + +from decorators import WSGISimpleAuth # decoratore ( singleton ) +auth = WSGISimpleAuth() + +@auth.require() +def application( environ, start_response ): + storage = environ['auth.storage'] + + storage['timeout'] = -1 + + start_response( '200 OK', [('content-type', 'text/html; charset=utf-8')] ) + + return [ + "
Now you are logged out
", + "index" + ] + diff --git a/controllers/secret.py b/controllers/secret.py index d558f78..0b338f3 100644 --- a/controllers/secret.py +++ b/controllers/secret.py @@ -4,7 +4,7 @@ from decorators import WSGISimpleAuth # decoratore ( singleton ) auth = WSGISimpleAuth() -@auth.require() +@auth.require( 'auth' ) def application( environ, start_response ): storage = environ['auth.storage'] @@ -14,4 +14,5 @@ def application( environ, start_response ): "

The secret code is:

", "
''keep calm and carry on''
" "
uuid:%s
" % environ['auth.uuid'], + "index" ] diff --git a/decorators.py b/decorators.py index d7cccce..be9c8cd 100644 --- a/decorators.py +++ b/decorators.py @@ -158,7 +158,7 @@ class WSGISimpleAuth( object ): """Generate a unique session ID""" return hashlib.sha256( str(os.getpid()) - + str(time()) + + str(time.time()) + str(random.random()) ).hexdigest() @@ -169,7 +169,7 @@ class WSGISimpleAuth( object ): self._lock.release() - def require( self, permission='', group='', p_g_mode='AND', p_mode='OR', g_mode='OR' ): + def require( self, permissions=[], groups=[], p_g_mode='AND', p_mode='OR', g_mode='OR' ): def real_decorator( wsgi_application ): def wrapper( environ, start_response ): #-------------------------------------------------------------- @@ -185,6 +185,8 @@ class WSGISimpleAuth( object ): # # salva le informazioni legate al cookie # + timeout = storage.get( 'timeout', self.__timeout ) + storage['epoch_timeout'] = time.time() + timeout storage['epoch_write'] = time.time() self.acquire_lock() ## LOCK @@ -203,6 +205,7 @@ class WSGISimpleAuth( object ): start_response( status, response_headers ); #-------------------------------------------------------------- + # # recupera UUID dal cookie # @@ -218,24 +221,56 @@ class WSGISimpleAuth( object ): self.acquire_lock() ## LOCK - f = open( path, 'r' ) - try: + f = open( path, 'r' ) storage = cPickle.load( f ) + f.close() + + if storage['epoch_timeout'] < time.time(): + # dati scaduti rimuove il file dei permessi.. + os.unlink( path ) + + # ... e finge di non everlo mai trovato + raise Exception + + logged_in = True + except: # UUID assente, crea una nuova struttura dati storage = { 'epoch_created': time.time(), 'permissions': [], 'groups': [], + 'timeout': self.__timeout } - f.close() + logged_in = False self.release_lock() ## RELEASE storage['epoch_read'] = time.time() + if permissions: + if isinstance( permissions, str ): + p = permissions.split() + else: + p = permissions + + if not logged_in: + # non autenticato -> redirect to 'login_url' + start_response( '302 Found', [('Location', '/login'),] ) + yield 'Please login first.' % '/login' + return + + for perm in p: + if perm in storage['permissions']: + break + else: + # permessi insufficienti -> redirect to 'forbidden_url' + start_response( '302 Found', [('Location', '/forbidden'),] ) + yield 'This page is not for your eyes.' + return + # # popola environ # @@ -258,7 +293,7 @@ class WSGISimpleAuth( object ): """ { uuid: jkfghkjgdhfgkjlsk, - permission=[], + permissions=[], groups=[], timeout=3600 } @@ -267,7 +302,7 @@ class WSGISimpleAuth( object ): { uuid: jkfghkjgdhfgkjlsk, - permission=[], + permissions=[], groups=[], timeout=3600 } diff --git a/dispatch_wsgi.py b/dispatch_wsgi.py index 0367835..ec6716e 100755 --- a/dispatch_wsgi.py +++ b/dispatch_wsgi.py @@ -52,7 +52,7 @@ from router import WSGIRouter, WSGISmartRouter # def index( environ, start_response ): start_response( '200 OK', [('content-type', 'text/html')] ) - return [ 'Index was here' ] + return [ 'Index was here' ] # # hello: esempio minimo di applicazione WSGI diff --git a/router.py b/router.py index 4263180..503ea9a 100644 --- a/router.py +++ b/router.py @@ -78,8 +78,7 @@ class WSGISmartRouter(object): tokens = [ token for token in environ['SCRIPT_URL'].split('/') if token ] #for idx in range( 1, len( tokens ) + 1 ): # from shortest path to longest one - # from longest path to shortest one - for idx in range( len( tokens ) , 0, -1 ): + for idx in range( len( tokens ) , 0, -1 ): # from longest path to shortest one module = os.path.normpath( self.cont_dir + '/'.join( tokens[:idx] ) + '.py' ) args = tokens[idx:] @@ -88,8 +87,6 @@ class WSGISmartRouter(object): environ['router.args'] = args if environ['REQUEST_METHOD'] == 'GET' and hasattr( handler, 'get' ): - # FIXME: forse รจ meglio eseguire QUI la start_response - # e compilare il template (solo per GET e POST) return handler.get( environ, start_response ) elif environ['REQUEST_METHOD'] == 'POST' and hasattr( handler, 'post' ): diff --git a/static/attack_dog.jpg b/static/attack_dog.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0fdd63a04bba5c5404cc1e97bbd098c52e27921e GIT binary patch literal 48950 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 bpxau+QYaNP&9z3ArXGK!5@RqR% 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 literal 0 HcmV?d00001 diff --git a/static/index.html b/static/index.html index 84e1ecd..0362da4 100644 --- a/static/index.html +++ b/static/index.html @@ -12,7 +12,10 @@
  • test autorouting
  • test autorouting (longest path possible)
  • test sql access
  • -
  • test authenticated
  • +
  • login
  • +
  • secret page
  • +
  • admin page (you have no permissions)
  • +
  • logout
  • Creative Commons License