Changeset - be6d8aaddbd1
[Not reviewed]
default
0 2 0
Marcin Kuzminski - 15 years ago 2010-05-22 22:40:12
marcin@python-works.com
dirty fix for https working.
2 files changed with 2 insertions and 1 deletions:
0 comments (0 inline, 0 general)
pylons_app/config/middleware.py
Show inline comments
 
"""Pylons middleware initialization"""
 
from beaker.middleware import SessionMiddleware
 
from paste.cascade import Cascade
 
from paste.registry import RegistryManager
 
from paste.urlparser import StaticURLParser
 
from paste.deploy.converters import asbool
 
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.lib.simplehg import SimpleHg
 
from pylons_app.config.environment import load_environment
 

	
 
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
 
    """Create a Pylons WSGI application and return it
 

	
 
    ``global_conf``
 
        The inherited configuration for this application. Normally from
 
        the [DEFAULT] section of the Paste ini file.
 

	
 
    ``full_stack``
 
        Whether or not this application provides a full WSGI stack (by
 
        default, meaning it handles its own exceptions and errors).
 
        Disable full_stack when this application is "managed" by
 
        another WSGI middleware.
 

	
 
    ``app_conf``
 
        The application's local configuration. Normally specified in
 
        the [app:<name>] section of the Paste ini file (where <name>
 
        defaults to main).
 

	
 
    """
 
    # Configure the Pylons environment
 
    config = load_environment(global_conf, app_conf)
 

	
 

	
 
    # The Pylons WSGI app
 
    app = PylonsApp(config=config)
 

	
 
    
 
    # Routing/Session/Cache Middleware
 
    app = RoutesMiddleware(app, config['routes.map'])
 
    app = SessionMiddleware(app, config)
 
    
 
    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)    
 
    app = SimpleHg(app, config)
 
    
 
    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']):
 
            app = StatusCodeRedirect(app)
 
        else:
 
            app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
 
    
pylons_app/lib/simplehg.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
#
 
# Copyright (c) 2010 marcink.  All rights reserved.
 
#
 
"""
 
Created on 2010-04-28
 

	
 
@author: marcink
 
SimpleHG middleware for handling mercurial protocol request (push/clone etc.)
 
It's implemented with basic auth function
 
"""
 
from datetime import datetime
 
from mercurial.hgweb import hgweb
 
from mercurial.hgweb.request import wsgiapplication
 
from paste.auth.basic import AuthBasicAuthenticator
 
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
 
from pylons_app.lib.auth import authfunc
 
from pylons_app.lib.utils import is_mercurial, make_ui, invalidate_cache
 
from pylons_app.model import meta
 
from pylons_app.model.db import UserLogs, Users
 
from webob.exc import HTTPNotFound
 
import logging
 
import os
 
log = logging.getLogger(__name__)
 

	
 
class SimpleHg(object):
 

	
 
    def __init__(self, application, config):
 
        self.application = application
 
        self.config = config
 
        #authenticate this mercurial request using 
 
        realm = '%s %s' % (config['hg_app_name'], 'mercurial repository')
 
        self.authenticate = AuthBasicAuthenticator(realm, authfunc)
 
        
 
    def __call__(self, environ, start_response):
 
        #dirty fix for https
 
        environ['wsgi.url_scheme'] = 'https'
 
        if not is_mercurial(environ):
 
            return self.application(environ, start_response)
 
        else:
 
            #===================================================================
 
            # AUTHENTICATE THIS MERCURIAL REQUEST
 
            #===================================================================
 
            username = REMOTE_USER(environ)
 
            if not username:
 
                result = self.authenticate(environ)
 
                if isinstance(result, str):
 
                    AUTH_TYPE.update(environ, 'basic')
 
                    REMOTE_USER.update(environ, result)
 
                else:
 
                    return result.wsgi_application(environ, start_response)
 
            
 
            try:
 
                repo_name = environ['PATH_INFO'].split('/')[1]
 
            except:
 
                return HTTPNotFound()(environ, start_response)
 
            
 
            #since we wrap into hgweb, just reset the path
 
            environ['PATH_INFO'] = '/'
 
            self.baseui = make_ui()
 
            self.basepath = self.baseui.configitems('paths')[0][1]\
 
                                                            .replace('*', '')
 
            self.repo_path = os.path.join(self.basepath, repo_name)
 
            try:
 
                app = wsgiapplication(self.__make_app)
 
            except Exception as e:
 
                return HTTPNotFound()(environ, start_response)
 
            
 
            action = self.__get_action(environ)            
 
            #invalidate cache on push
 
            if action == 'push':
 
                self.__invalidate_cache(repo_name)
 
            
 
            if action:
 
                username = self.__get_environ_user(environ)
 
                self.__log_user_action(username, action, repo_name)            
 
            return app(environ, start_response)            
 

	
 
    def __make_app(self):
 
        hgserve = hgweb(self.repo_path)
 
        return  self.load_web_settings(hgserve)
 
    
 
    def __get_environ_user(self, environ):
 
        return environ.get('REMOTE_USER')
 
        
0 comments (0 inline, 0 general)