# HG changeset patch # User Marcin Kuzminski # Date 1323288492 -7200 # Node ID b265be1c6093b4a64e62cc1923e04a74becfc687 # Parent 9dda1146327c7ca0dbfd10dc35af6f5e19a4442f Wrapped calls for git and hg middleware in extra block that clears db Session. tries to fix #318 diff -r 9dda1146327c -r b265be1c6093 rhodecode/lib/base.py --- a/rhodecode/lib/base.py Wed Dec 07 20:43:16 2011 +0200 +++ b/rhodecode/lib/base.py Wed Dec 07 22:08:12 2011 +0200 @@ -4,6 +4,9 @@ """ import logging import time + +from paste.auth.basic import AuthBasicAuthenticator + from pylons import config, tmpl_context as c, request, session, url from pylons.controllers import WSGIController from pylons.controllers.util import redirect @@ -12,8 +15,9 @@ from rhodecode import __version__, BACKENDS from rhodecode.lib import str2bool -from rhodecode.lib.auth import AuthUser, get_container_username -from rhodecode.lib.utils import get_repo_slug +from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\ + HasPermissionAnyMiddleware +from rhodecode.lib.utils import get_repo_slug, invalidate_cache from rhodecode.model import meta from rhodecode.model.db import Repository @@ -22,6 +26,60 @@ log = logging.getLogger(__name__) +class BaseVCSController(object): + + def __init__(self, application, config): + self.application = application + self.config = config + # base path of repo locations + self.basepath = self.config['base_path'] + #authenticate this mercurial request using authfunc + self.authenticate = AuthBasicAuthenticator('', authfunc) + self.ipaddr = '0.0.0.0' + + def _invalidate_cache(self, repo_name): + """ + Set's cache for this repository for invalidation on next access + + :param repo_name: full repo name, also a cache key + """ + invalidate_cache('get_repo_cached_%s' % repo_name) + + def _check_permission(self, action, user, repo_name): + """ + Checks permissions using action (push/pull) user and repository + name + + :param action: push or pull action + :param user: user instance + :param repo_name: repository name + """ + if action == 'push': + if not HasPermissionAnyMiddleware('repository.write', + 'repository.admin')(user, + repo_name): + return False + + else: + #any other action need at least read permission + if not HasPermissionAnyMiddleware('repository.read', + 'repository.write', + 'repository.admin')(user, + repo_name): + return False + + return True + + def __call__(self, environ, start_response): + start = time.time() + try: + return self._handle_request(environ, start_response) + finally: + log = logging.getLogger(self.__class__.__name__) + log.debug('Request time: %.3fs' % (time.time() - start)) + meta.Session.remove() + + class BaseController(WSGIController): def __before__(self): diff -r 9dda1146327c -r b265be1c6093 rhodecode/lib/middleware/simplegit.py --- a/rhodecode/lib/middleware/simplegit.py Wed Dec 07 20:43:16 2011 +0200 +++ b/rhodecode/lib/middleware/simplegit.py Wed Dec 07 22:08:12 2011 +0200 @@ -30,7 +30,6 @@ from dulwich import server as dulserver - class SimpleGitUploadPackHandler(dulserver.UploadPackHandler): def handle(self): @@ -66,12 +65,12 @@ from dulwich.repo import Repo from dulwich.web import HTTPGitApplication -from paste.auth.basic import AuthBasicAuthenticator from paste.httpheaders import REMOTE_USER, AUTH_TYPE from rhodecode.lib import safe_str -from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, get_container_username -from rhodecode.lib.utils import invalidate_cache, is_valid_repo +from rhodecode.lib.base import BaseVCSController +from rhodecode.lib.auth import get_container_username +from rhodecode.lib.utils import is_valid_repo from rhodecode.model.db import User from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError @@ -91,17 +90,9 @@ return False -class SimpleGit(object): +class SimpleGit(BaseVCSController): - def __init__(self, application, config): - self.application = application - self.config = config - # base path of repo locations - self.basepath = self.config['base_path'] - #authenticate this mercurial request using authfunc - self.authenticate = AuthBasicAuthenticator('', authfunc) - - def __call__(self, environ, start_response): + def _handle_request(self, environ, start_response): if not is_git(environ): return self.application(environ, start_response) @@ -132,9 +123,8 @@ if action in ['pull', 'push']: anonymous_user = self.__get_user('default') username = anonymous_user.username - anonymous_perm = self.__check_permission(action, - anonymous_user, - repo_name) + anonymous_perm = self._check_permission(action,anonymous_user, + repo_name) if anonymous_perm is not True or anonymous_user.active is False: if anonymous_perm is not True: @@ -179,16 +169,11 @@ start_response) #check permissions for this repository - perm = self.__check_permission(action, user, + perm = self._check_permission(action, user, repo_name) if perm is not True: return HTTPForbidden()(environ, start_response) - extras = {'ip': ipaddr, - 'username': username, - 'action': action, - 'repository': repo_name} - #=================================================================== # GIT REQUEST HANDLING #=================================================================== @@ -203,7 +188,7 @@ try: #invalidate cache on push if action == 'push': - self.__invalidate_cache(repo_name) + self._invalidate_cache(repo_name) app = self.__make_app(repo_name, repo_path) return app(environ, start_response) @@ -225,31 +210,6 @@ return gitserve - def __check_permission(self, action, user, repo_name): - """ - Checks permissions using action (push/pull) user and repository - name - - :param action: push or pull action - :param user: user instance - :param repo_name: repository name - """ - if action == 'push': - if not HasPermissionAnyMiddleware('repository.write', - 'repository.admin')(user, - repo_name): - return False - - else: - #any other action need at least read permission - if not HasPermissionAnyMiddleware('repository.read', - 'repository.write', - 'repository.admin')(user, - repo_name): - return False - - return True - def __get_repository(self, environ): """ Get's repository name out of PATH_INFO header @@ -285,10 +245,3 @@ service_cmd if service_cmd else 'other') else: return 'other' - - 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('get_repo_cached_%s' % repo_name) - diff -r 9dda1146327c -r b265be1c6093 rhodecode/lib/middleware/simplehg.py --- a/rhodecode/lib/middleware/simplehg.py Wed Dec 07 20:43:16 2011 +0200 +++ b/rhodecode/lib/middleware/simplehg.py Wed Dec 07 22:08:12 2011 +0200 @@ -31,13 +31,12 @@ from mercurial.error import RepoError from mercurial.hgweb import hgweb_mod -from paste.auth.basic import AuthBasicAuthenticator from paste.httpheaders import REMOTE_USER, AUTH_TYPE from rhodecode.lib import safe_str -from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, get_container_username -from rhodecode.lib.utils import make_ui, invalidate_cache, \ - is_valid_repo, ui_sections +from rhodecode.lib.base import BaseVCSController +from rhodecode.lib.auth import get_container_username +from rhodecode.lib.utils import make_ui, is_valid_repo, ui_sections from rhodecode.model.db import User from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError @@ -55,18 +54,9 @@ return False -class SimpleHg(object): +class SimpleHg(BaseVCSController): - def __init__(self, application, config): - self.application = application - self.config = config - # base path of repo locations - self.basepath = self.config['base_path'] - #authenticate this mercurial request using authfunc - self.authenticate = AuthBasicAuthenticator('', authfunc) - self.ipaddr = '0.0.0.0' - - def __call__(self, environ, start_response): + def _handle_request(self, environ, start_response): if not is_mercurial(environ): return self.application(environ, start_response) @@ -98,9 +88,8 @@ anonymous_user = self.__get_user('default') username = anonymous_user.username - anonymous_perm = self.__check_permission(action, - anonymous_user, - repo_name) + anonymous_perm = self._check_permission(action,anonymous_user, + repo_name) if anonymous_perm is not True or anonymous_user.active is False: if anonymous_perm is not True: @@ -145,7 +134,7 @@ start_response) #check permissions for this repository - perm = self.__check_permission(action, user, + perm = self._check_permission(action, user, repo_name) if perm is not True: return HTTPForbidden()(environ, start_response) @@ -171,9 +160,9 @@ return HTTPNotFound()(environ, start_response) try: - #invalidate cache on push + # invalidate cache on push if action == 'push': - self.__invalidate_cache(repo_name) + self._invalidate_cache(repo_name) app = self.__make_app(repo_path, baseui, extras) return app(environ, start_response) @@ -192,31 +181,6 @@ return hgweb_mod.hgweb(repo_name, name=repo_name, baseui=baseui) - def __check_permission(self, action, user, repo_name): - """ - Checks permissions using action (push/pull) user and repository - name - - :param action: push or pull action - :param user: user instance - :param repo_name: repository name - """ - if action == 'push': - if not HasPermissionAnyMiddleware('repository.write', - 'repository.admin')(user, - repo_name): - return False - - else: - #any other action need at least read permission - if not HasPermissionAnyMiddleware('repository.read', - 'repository.write', - 'repository.admin')(user, - repo_name): - return False - - return True - def __get_repository(self, environ): """ Get's repository name out of PATH_INFO header @@ -257,11 +221,6 @@ else: return 'pull' - 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('get_repo_cached_%s' % repo_name) def __inject_extras(self, repo_path, baseui, extras={}): """