changeset 190:d8eb7ee27b4c

Added LoginRequired decorator, empty User data container, hash functions
author Marcin Kuzminski <marcin@python-works.com>
date Sat, 22 May 2010 01:43:42 +0200
parents 410101210923
children b68b2246e5a6
files pylons_app/lib/auth.py
diffstat 1 files changed, 46 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/pylons_app/lib/auth.py	Sat May 22 01:42:03 2010 +0200
+++ b/pylons_app/lib/auth.py	Sat May 22 01:43:42 2010 +0200
@@ -1,38 +1,23 @@
-import logging
 from datetime import datetime
-import crypt
+from decorator import decorator
+from functools import wraps
 from pylons import session, url
 from pylons.controllers.util import abort, redirect
-from decorator import decorator
-from sqlalchemy.exc import OperationalError
-log = logging.getLogger(__name__)
 from pylons_app.model import meta
 from pylons_app.model.db import Users, UserLogs
+from sqlalchemy.exc import OperationalError
 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
+import crypt
+import logging
+log = logging.getLogger(__name__)
 
 def get_crypt_password(password):
+    """
+    Cryptographic function used for password hashing
+    @param password: password to hash
+    """
     return crypt.crypt(password, '6a')
 
-def admin_auth(username, password):
-    sa = meta.Session
-    password_crypt = get_crypt_password(password)
-
-    try:
-        user = sa.query(Users).filter(Users.username == username).one()
-    except (NoResultFound, MultipleResultsFound, OperationalError) as e:
-        log.error(e)
-        user = None
-        
-    if user:
-        if user.active:
-            if user.username == username and user.password == password_crypt and user.admin:
-                log.info('user %s authenticated correctly', username)
-                return True
-        else:
-            log.error('user %s is disabled', username)
-            
-    return False
-
 def authfunc(environ, username, password):
     sa = meta.Session
     password_crypt = get_crypt_password(password)
@@ -74,10 +59,40 @@
             
     return False
 
+class  AuthUser(object):
+    """
+    A simple object that handles a mercurial username for authentication
+    """
+    username = 'Empty'
+    is_authenticated = False
+    is_admin = False
+    permissions = set()
+    group = set()
+    
+    def __init__(self):
+        pass
+    
+#===============================================================================
+# DECORATORS
+#===============================================================================
+class LoginRequired(object):
+    """
+    Must be logged in to execute this function else redirect to login page
+    """
+    def __init__(self):
+        pass
+    
+    def __call__(self, func):
+        log.info('Checking login required')
+        
+        @wraps(func)
+        def _wrapper(*fargs, **fkwargs):
+            user = session.get('hg_app_user', AuthUser())
+            if user.is_authenticated:
+                    log.info('user %s is authenticated', user.username)
+                    func(*fargs)
+            else:
+                logging.info('user %s not authenticated', user.username)
+                return redirect(url('login_home'))
 
-@decorator
-def authenticate(fn, *args, **kwargs):
-    if not session.get('admin_user', False):
-        redirect(url('admin_home'), 301)
-    return fn(*args, **kwargs)
-
+        return _wrapper