##// END OF EJS Templates
Added tag v0.8.1 for changeset a9814a642e11
Added tag v0.8.1 for changeset a9814a642e11

File last commit:

r392:b27d32cb default
r394:42367607 default
Show More
simplehg.py
238 lines | 8.9 KiB | text/x-python | PythonLexer
Created middleware package. Crated special middleware to handle https requests redirections.
r204 #!/usr/bin/env python
# encoding: utf-8
licensing updates, code cleanups
r252 # middleware to handle mercurial api calls
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
fixes #20 hg middleware breaks ui() instance when repository has hgrc file....
r385 #
licensing updates, code cleanups
r252 # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License or (at your opinion) any later version of the license.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
Implemented hooks system,...
r392 """
Created on 2010-04-28
@author: marcink
SimpleHG middleware for handling mercurial protocol request (push/clone etc.)
It's implemented with basic auth function
"""
Created middleware package. Crated special middleware to handle https requests redirections.
r204 from datetime import datetime
rewritten simplehg middleware. Now permissions are checked for each repository/request/user
r317 from itertools import chain
implemented cache for repeated queries in simplehg mercurial requests
r343 from mercurial.error import RepoError
Created middleware package. Crated special middleware to handle https requests redirections.
r204 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
implemented cache for repeated queries in simplehg mercurial requests
r343 from pylons_app.lib.auth import authfunc, HasPermissionAnyMiddleware, \
get_user_cached
mercurial middleware now returns 500's instead of 404 on errors and 404 when repo not found, added tracebacks
r334 from pylons_app.lib.utils import is_mercurial, make_ui, invalidate_cache, \
fixes #20 hg middleware breaks ui() instance when repository has hgrc file....
r385 check_repo_fast, ui_sections
Created middleware package. Crated special middleware to handle https requests redirections.
r204 from pylons_app.model import meta
changed naming convention for db modules.
r234 from pylons_app.model.db import UserLog, User
mercurial middleware now returns 500's instead of 404 on errors and 404 when repo not found, added tracebacks
r334 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
Created middleware package. Crated special middleware to handle https requests redirections.
r204 import logging
import os
implemented cache for repeated queries in simplehg mercurial requests
r343 import pylons_app.lib.helpers as h
rewritten simplehg middleware. Now permissions are checked for each repository/request/user
r317 import traceback
implemented cache for repeated queries in simplehg mercurial requests
r343
Created middleware package. Crated special middleware to handle https requests redirections.
r204 log = logging.getLogger(__name__)
class SimpleHg(object):
def __init__(self, application, config):
self.application = application
self.config = config
#authenticate this mercurial request using
Added application settings, are now customizable from database...
r350 self.authenticate = AuthBasicAuthenticator('', authfunc)
Created middleware package. Crated special middleware to handle https requests redirections.
r204
def __call__(self, environ, start_response):
if not is_mercurial(environ):
return self.application(environ, start_response)
implemented cache for repeated queries in simplehg mercurial requests
r343
#===================================================================
# AUTHENTICATE THIS MERCURIAL REQUEST
#===================================================================
username = REMOTE_USER(environ)
if not username:
cleared global application settings....
r381 self.authenticate.realm = self.config['hg_app_realm']
implemented cache for repeated queries in simplehg mercurial requests
r343 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 = '/'.join(environ['PATH_INFO'].split('/')[1:])
except:
log.error(traceback.format_exc())
return HTTPInternalServerError()(environ, start_response)
#===================================================================
# CHECK PERMISSIONS FOR THIS REQUEST
#===================================================================
action = self.__get_action(environ)
if action:
username = self.__get_environ_user(environ)
Created middleware package. Crated special middleware to handle https requests redirections.
r204 try:
implemented cache for repeated queries in simplehg mercurial requests
r343 user = self.__get_user(username)
mercurial middleware now returns 500's instead of 404 on errors and 404 when repo not found, added tracebacks
r334 except:
rewritten simplehg middleware. Now permissions are checked for each repository/request/user
r317 log.error(traceback.format_exc())
mercurial middleware now returns 500's instead of 404 on errors and 404 when repo not found, added tracebacks
r334 return HTTPInternalServerError()(environ, start_response)
implemented cache for repeated queries in simplehg mercurial requests
r343 #check permissions for this repository
if action == 'pull':
if not HasPermissionAnyMiddleware('repository.read',
'repository.write',
'repository.admin')\
(user, repo_name):
return HTTPForbidden()(environ, start_response)
if action == 'push':
if not HasPermissionAnyMiddleware('repository.write',
'repository.admin')\
(user, repo_name):
return HTTPForbidden()(environ, start_response)
Created middleware package. Crated special middleware to handle https requests redirections.
r204
implemented cache for repeated queries in simplehg mercurial requests
r343 #log action
proxy_key = 'HTTP_X_REAL_IP'
def_key = 'REMOTE_ADDR'
ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
self.__log_user_action(user, action, repo_name, ipaddr)
#===================================================================
# MERCURIAL REQUEST HANDLING
#===================================================================
environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path
self.baseui = make_ui('db')
self.basepath = self.config['base_path']
self.repo_path = os.path.join(self.basepath, repo_name)
mercurial middleware now returns 500's instead of 404 on errors and 404 when repo not found, added tracebacks
r334
implemented cache for repeated queries in simplehg mercurial requests
r343 #quick check if that dir exists...
if check_repo_fast(repo_name, self.basepath):
return HTTPNotFound()(environ, start_response)
try:
app = wsgiapplication(self.__make_app)
except RepoError as e:
if str(e).find('not found') != -1:
mercurial middleware now returns 500's instead of 404 on errors and 404 when repo not found, added tracebacks
r334 return HTTPNotFound()(environ, start_response)
implemented cache for repeated queries in simplehg mercurial requests
r343 except Exception:
log.error(traceback.format_exc())
return HTTPInternalServerError()(environ, start_response)
#invalidate cache on push
if action == 'push':
self.__invalidate_cache(repo_name)
messages = []
messages.append('thank you for using hg-app')
return self.msg_wrapper(app, environ, start_response, messages)
else:
return app(environ, start_response)
added custom messages for remote responses.
r257
small fixes for hg middleware, messages are now propagated only on push
r340 def msg_wrapper(self, app, environ, start_response, messages=[]):
added custom messages for remote responses.
r257 """
Wrapper for custom messages that come out of mercurial respond messages
rewritten simplehg middleware. Now permissions are checked for each repository/request/user
r317 is a list of messages that the user will see at the end of response
from merurial protocol actions that involves remote answers
added custom messages for remote responses.
r257 @param app:
@param environ:
@param start_response:
"""
def custom_messages(msg_list):
for msg in msg_list:
yield msg + '\n'
org_response = app(environ, start_response)
return chain(org_response, custom_messages(messages))
Created middleware package. Crated special middleware to handle https requests redirections.
r204
def __make_app(self):
Made config file free configuration based on database and capable of beeing manage via application settings + some code cleanups
r341 hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
version bump. Made changesets work as should, but vcs had to be fixed for that.
r218 return self.__load_web_settings(hgserve)
Created middleware package. Crated special middleware to handle https requests redirections.
r204
def __get_environ_user(self, environ):
return environ.get('REMOTE_USER')
small fixes for hg middleware, messages are now propagated only on push
r340
implemented cache for repeated queries in simplehg mercurial requests
r343 def __get_user(self, username):
return get_user_cached(username)
Created middleware package. Crated special middleware to handle https requests redirections.
r204 def __get_action(self, environ):
"""
Maps mercurial request commands into a pull or push command.
@param environ:
"""
added new command mappings for mercurial 1.6
r330 mapping = {'changegroup': 'pull',
'changegroupsubset': 'pull',
'stream_out': 'pull',
'listkeys': 'pull',
'unbundle': 'push',
'pushkey': 'push', }
Created middleware package. Crated special middleware to handle https requests redirections.
r204 for qry in environ['QUERY_STRING'].split('&'):
if qry.startswith('cmd'):
cmd = qry.split('=')[-1]
if mapping.has_key(cmd):
return mapping[cmd]
added ip loggin into mercurial middleware
r331 def __log_user_action(self, user, action, repo, ipaddr):
Created middleware package. Crated special middleware to handle https requests redirections.
r204 sa = meta.Session
try:
changed naming convention for db modules.
r234 user_log = UserLog()
Created middleware package. Crated special middleware to handle https requests redirections.
r204 user_log.user_id = user.user_id
user_log.action = action
user_log.repository = repo.replace('/', '')
user_log.action_date = datetime.now()
added ip loggin into mercurial middleware
r331 user_log.user_ip = ipaddr
Created middleware package. Crated special middleware to handle https requests redirections.
r204 sa.add(user_log)
sa.commit()
log.info('Adding user %s, action %s on %s',
rewritten simplehg middleware. Now permissions are checked for each repository/request/user
r317 user.username, action, repo)
Created middleware package. Crated special middleware to handle https requests redirections.
r204 except Exception as e:
sa.rollback()
log.error('could not log user action:%s', str(e))
Added application settings, are now customizable from database...
r350 finally:
meta.Session.remove()
Created middleware package. Crated special middleware to handle https requests redirections.
r204 def __invalidate_cache(self, repo_name):
"""we know that some change was made to repositories and we should
invalidate the cache to see the changes right away but only for
push requests"""
invalidate_cache('cached_repo_list')
invalidate_cache('full_changelog', repo_name)
version bump. Made changesets work as should, but vcs had to be fixed for that.
r218 def __load_web_settings(self, hgserve):
Created middleware package. Crated special middleware to handle https requests redirections.
r204 #set the global ui for hgserve
hgserve.repo.ui = self.baseui
Made config file free configuration based on database and capable of beeing manage via application settings + some code cleanups
r341 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
repoui = make_ui('file', hgrc, False)
fixes #20 hg middleware breaks ui() instance when repository has hgrc file....
r385
Created middleware package. Crated special middleware to handle https requests redirections.
r204 if repoui:
fixes #20 hg middleware breaks ui() instance when repository has hgrc file....
r385 #overwrite our ui instance with the section from hgrc file
for section in ui_sections:
for k, v in repoui.configitems(section):
hgserve.repo.ui.setconfig(section, k, v)
Created middleware package. Crated special middleware to handle https requests redirections.
r204
return hgserve
fixes #20 hg middleware breaks ui() instance when repository has hgrc file....
r385