Changeset - 71ffa932799d
[Not reviewed]
default
0 5 1
Marcin Kuzminski - 16 years ago 2010-04-07 00:51:55
marcin@python-blog.com
Added app basic auth.
Changed few deprecations for new pylons.
added sqlite logging for user actions.
6 files changed with 122 insertions and 16 deletions:
0 comments (0 inline, 0 general)
development.ini
Show inline comments
 
@@ -29,6 +29,7 @@ full_stack = true
 
static_files = true
 
lang=en
 
cache_dir = %(here)s/data
 
repos_name = etelko
 

	
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
production.ini
Show inline comments
 
@@ -29,6 +29,7 @@ full_stack = true
 
static_files = false
 
lang=en
 
cache_dir = %(here)s/data
 
repos_name = etelko
 

	
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
pylons_app/config/environment.py
Show inline comments
 
@@ -28,17 +28,16 @@ def load_environment(global_conf, app_co
 
                    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)
pylons_app/config/middleware.py
Show inline comments
 
@@ -8,9 +8,9 @@ from pylons import config
 
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 @@ def make_app(global_conf, full_stack=Tru
 
    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 @@ def make_app(global_conf, full_stack=Tru
 
            app = StatusCodeRedirect(app, [400, 401, 403, 500])
 
        else:
 
            app = StatusCodeRedirect(app, [400, 401, 403, 500])
 

	
 
    
 
    # Establish the Registry for this application
 
    app = RegistryManager(app)
 

	
pylons_app/controllers/hg.py
Show inline comments
 
#!/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 @@ class HgController(BaseController):
 
        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)
pylons_app/lib/auth.py
Show inline comments
 
new file 100644
 
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')
0 comments (0 inline, 0 general)