changeset 41:71ffa932799d

Added app basic auth. Changed few deprecations for new pylons. added sqlite logging for user actions.
author Marcin Kuzminski <marcin@python-blog.com>
date Wed, 07 Apr 2010 00:51:55 +0200
parents cbc1624cb499
children b2bc08f2974b
files development.ini production.ini pylons_app/config/environment.py pylons_app/config/middleware.py pylons_app/controllers/hg.py pylons_app/lib/auth.py
diffstat 6 files changed, 122 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/development.ini	Tue Apr 06 22:21:23 2010 +0200
+++ b/development.ini	Wed Apr 07 00:51:55 2010 +0200
@@ -29,6 +29,7 @@
 static_files = true
 lang=en
 cache_dir = %(here)s/data
+repos_name = etelko
 
 ################################################################################
 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
--- a/production.ini	Tue Apr 06 22:21:23 2010 +0200
+++ b/production.ini	Wed Apr 07 00:51:55 2010 +0200
@@ -29,6 +29,7 @@
 static_files = false
 lang=en
 cache_dir = %(here)s/data
+repos_name = etelko
 
 ################################################################################
 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
--- a/pylons_app/config/environment.py	Tue Apr 06 22:21:23 2010 +0200
+++ b/pylons_app/config/environment.py	Wed Apr 07 00:51:55 2010 +0200
@@ -28,17 +28,16 @@
                     template_engine='mako', paths=paths)
 
     config['routes.map'] = make_map()
-    config['pylons.g'] = app_globals.Globals()
+    config['pylons.app_globals'] = app_globals.Globals()
     config['pylons.h'] = pylons_app.lib.helpers
 
     # Create the Mako TemplateLookup, with the default auto-escaping
-    config['pylons.g'].mako_lookup = TemplateLookup(
+    config['pylons.app_globals'].mako_lookup = TemplateLookup(
         directories=paths['templates'],
         error_handler=handle_mako_error,
         module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
-        output_encoding='utf-8',
-        imports=['from webhelpers.html import escape'],
-        default_filters=['escape'])
+        input_encoding='utf-8', default_filters=['escape'],
+        imports=['from webhelpers.html import escape'])
 
     # CONFIGURATION OPTIONS HERE (note: all config options will override
     # any Pylons config options)
--- a/pylons_app/config/middleware.py	Tue Apr 06 22:21:23 2010 +0200
+++ b/pylons_app/config/middleware.py	Wed Apr 07 00:51:55 2010 +0200
@@ -8,9 +8,9 @@
 from pylons.middleware import ErrorHandler, StatusCodeRedirect
 from pylons.wsgiapp import PylonsApp
 from routes.middleware import RoutesMiddleware
-
+from paste.auth.basic import AuthBasicHandler
 from pylons_app.config.environment import load_environment
-
+from pylons_app.lib.auth import authfunc 
 
 def make_app(global_conf, full_stack=True, **app_conf):
     """Create a Pylons WSGI application and return it
@@ -43,7 +43,8 @@
     app = RoutesMiddleware(app, config['routes.map'])
     app = SessionMiddleware(app, config)
     app = CacheMiddleware(app, config)
-
+    app = AuthBasicHandler(app, config['repos_name'] + ' mercurial repository', authfunc)
+    
     if asbool(full_stack):
         # Handle Python exceptions
         app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
@@ -55,7 +56,7 @@
             app = StatusCodeRedirect(app, [400, 401, 403, 500])
         else:
             app = StatusCodeRedirect(app, [400, 401, 403, 500])
-
+    
     # Establish the Registry for this application
     app = RegistryManager(app)
 
--- a/pylons_app/controllers/hg.py	Tue Apr 06 22:21:23 2010 +0200
+++ b/pylons_app/controllers/hg.py	Wed Apr 07 00:51:55 2010 +0200
@@ -1,23 +1,22 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 import logging
+import os
 from pylons_app.lib.base import BaseController, render
-from pylons import c, g, session, request
+from pylons import tmpl_context as c, app_globals as g, session, request, config
 from pylons_app.lib import helpers as h
 from mako.template import Template
-from pprint import pprint
-import os
 from mercurial import ui, hg
 from mercurial.error import RepoError
 from ConfigParser import ConfigParser
-import encodings
 from pylons.controllers.util import abort
+
 log = logging.getLogger(__name__)
 
 class HgController(BaseController):
 
     def __before__(self):
-        c.repos_prefix = 'etelko'
+        c.repos_prefix = config['repos_name']
 
     def view(self, *args, **kwargs):
         response = g.hgapp(request.environ, self.start_response)
@@ -33,14 +32,14 @@
         try:
             tmpl = u''.join(response)
             template = Template(tmpl, lookup=request.environ['pylons.pylons']\
-                            .config['pylons.g'].mako_lookup)
+                            .config['pylons.app_globals'].mako_lookup)
                         
         except (RuntimeError, UnicodeDecodeError):
             log.info('disabling unicode due to encoding error')
             response = g.hgapp(request.environ, self.start_response)
             tmpl = ''.join(response)
             template = Template(tmpl, lookup=request.environ['pylons.pylons']\
-                            .config['pylons.g'].mako_lookup, disable_unicode=True)
+                            .config['pylons.app_globals'].mako_lookup, disable_unicode=True)
 
 
         return template.render(g=g, c=c, session=session, h=h)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pylons_app/lib/auth.py	Wed Apr 07 00:51:55 2010 +0200
@@ -0,0 +1,105 @@
+import sqlite3
+import os
+import logging
+from os.path import dirname as dn
+from datetime import datetime
+import crypt
+
+log = logging.getLogger(__name__)
+ROOT = dn(dn(dn(os.path.realpath(__file__))))
+
+def get_sqlite_cur_conn():
+    conn = sqlite3.connect(os.path.join(ROOT, 'auth.sqlite'))
+    cur = conn.cursor()
+    return conn, cur
+
+def authfunc(environ, username, password):
+    conn, cur = get_sqlite_cur_conn()
+    password_crypt = crypt.crypt(password, '6a')
+
+    cur.execute("SELECT * FROM users WHERE username=?", (username,))
+    data = cur.fetchone()
+
+    if data:
+        if data[3]:
+            if data[1] == username and data[2] == password_crypt:
+                log.info('user %s authenticated correctly', username)
+                
+                http_accept = environ.get('HTTP_ACCEPT')
+        
+                if http_accept.startswith('application/mercurial') or \
+                    environ['PATH_INFO'].find('raw-file') != -1:
+                    cmd = environ['PATH_INFO']
+                    for qry in environ['QUERY_STRING'].split('&'):
+                        if qry.startswith('cmd'):
+                            cmd += "|" + qry
+                            
+                            try:
+                                cur.execute('''INSERT INTO 
+                                                    user_logs 
+                                               VALUES(?,?,?,?)''',
+                                                (None, data[0], cmd, datetime.now()))
+                                conn.commit()
+                            except Exception as e:
+                                conn.rollback()
+                                log.error(e)
+                            
+                                
+                return True
+        else:
+            log.error('user %s is disabled', username)
+            
+    return False
+
+def create_user_table():
+    '''
+    Create a auth database
+    '''
+    conn, cur = get_sqlite_cur_conn()
+    try:
+        log.info('creating table %s', 'users')
+        cur.execute('''DROP TABLE IF EXISTS users ''')
+        cur.execute('''CREATE TABLE users
+                        (id INTEGER PRIMARY KEY AUTOINCREMENT, 
+                         username TEXT, 
+                         password TEXT,
+                         active INTEGER)''')
+        log.info('creating table %s', 'user_logs')
+        cur.execute('''DROP TABLE IF EXISTS user_logs ''')
+        cur.execute('''CREATE TABLE user_logs
+                        (id INTEGER PRIMARY KEY AUTOINCREMENT,
+                            user_id INTEGER,
+                            last_action TEXT, 
+                            last_action_date DATETIME)''')
+        conn.commit()
+    except:
+        conn.rollback()
+        raise
+    
+    cur.close()
+    
+def create_user(username, password):
+    conn, cur = get_sqlite_cur_conn()    
+    password_crypt = crypt.crypt(password, '6a')
+    cur_date = datetime.now()
+    log.info('creating user %s', username)
+    try:
+        cur.execute('''INSERT INTO users values (?,?,?,?) ''',
+                    (None, username, password_crypt, 1,))     
+        conn.commit()
+    except:
+        conn.rollback()
+        raise
+    
+if __name__ == "__main__":
+    create_user_table()
+    create_user('marcink', 'qweqwe')
+    create_user('lukaszd', 'qweqwe')
+    create_user('adriand', 'qweqwe')
+    create_user('radek', 'qweqwe')
+    create_user('skrzeka', 'qweqwe')
+    create_user('bart', 'qweqwe')
+    create_user('maho', 'qweqwe')
+    create_user('michalg', 'qweqwe')
+    
+    #authfunc('', 'marcink', 'qweqwe')