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
 
@@ -26,12 +26,13 @@ port = 5000
 
[app:main]
 
use = egg:pylons_app
 
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*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
production.ini
Show inline comments
 
@@ -26,12 +26,13 @@ port = 8001
 
[app:main]
 
use = egg:pylons_app
 
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*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
pylons_app/config/environment.py
Show inline comments
 
@@ -25,20 +25,19 @@ def load_environment(global_conf, app_co
 

	
 
    # Initialize config with the basic options
 
    config.init_app(global_conf, app_conf, package='pylons_app',
 
                    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
 
@@ -5,15 +5,15 @@ from paste.registry import RegistryManag
 
from paste.urlparser import StaticURLParser
 
from paste.deploy.converters import asbool
 
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
 

	
 
    ``global_conf``
 
        The inherited configuration for this application. Normally from
 
@@ -40,25 +40,26 @@ def make_app(global_conf, full_stack=Tru
 
    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
 

	
 
    # Routing/Session/Cache Middleware
 
    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'])
 

	
 
        # Display error documents for 401, 403, 404 status codes (and
 
        # 500 when debug is disabled)
 
        if asbool(config['debug']):
 
            #don't handle 404, since mercurial does it for us.
 
            app = StatusCodeRedirect(app, [400, 401, 403, 500])
 
        else:
 
            app = StatusCodeRedirect(app, [400, 401, 403, 500])
 

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

	
 
    # Static files (If running in production, and Apache or another web
 
    # server is handling this static content, remove the following 3 lines)
 
    static_app = StaticURLParser(config['pylons.paths']['static_files'])
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)
 
        
 
        http_accept = request.environ.get('HTTP_ACCEPT', False)
 
        if not http_accept:
 
@@ -30,20 +29,20 @@ class HgController(BaseController):
 
        if http_accept.find("mercurial") != -1 or \
 
        request.environ['PATH_INFO'].find('raw-file') != -1:
 
                    return response
 
        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)
 

	
 

	
 
    def manage_hgrc(self):
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)