# HG changeset patch # User Marcin Kuzminski # Date 1274549390 -7200 # Node ID da59b7e07e3ce13ca3c8c1b9622deafdbc7128f9 # Parent 568f95056716c5c70f9b19193d301e7c2489e9a4 Changed import to base. Removed action logging from auth to simplehg. Splited loggin and invalidation action to private methods inside simplehg. diff -r 568f95056716 -r da59b7e07e3c pylons_app/lib/auth.py --- a/pylons_app/lib/auth.py Sat May 22 19:18:09 2010 +0200 +++ b/pylons_app/lib/auth.py Sat May 22 19:29:50 2010 +0200 @@ -4,7 +4,7 @@ from pylons import session, url from pylons.controllers.util import abort, redirect from pylons_app.model import meta -from pylons_app.model.db import Users, UserLogs +from pylons_app.model.db import Users from sqlalchemy.exc import OperationalError from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound import crypt @@ -31,28 +31,6 @@ if user.active: if user.username == username and user.password == password_crypt: log.info('user %s authenticated correctly', username) - if environ: - http_accept = environ.get('HTTP_ACCEPT') - - if http_accept.startswith('application/mercurial') or \ - environ['PATH_INFO'].find('raw-file') != -1: - repo = environ['PATH_INFO'] - for qry in environ['QUERY_STRING'].split('&'): - if qry.startswith('cmd'): - - try: - user_log = UserLogs() - user_log.user_id = user.user_id - user_log.action = qry - user_log.repository = repo - user_log.action_date = datetime.now() - sa.add(user_log) - sa.commit() - log.info('Adding user %s, action %s', username, qry) - except Exception as e: - sa.rollback() - log.error(e) - return True else: log.error('user %s is disabled', username) diff -r 568f95056716 -r da59b7e07e3c pylons_app/lib/simplehg.py --- a/pylons_app/lib/simplehg.py Sat May 22 19:18:09 2010 +0200 +++ b/pylons_app/lib/simplehg.py Sat May 22 19:29:50 2010 +0200 @@ -10,16 +10,19 @@ 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.utils import is_mercurial from pylons_app.lib.auth import authfunc -from pylons_app.lib.utils import make_ui, invalidate_cache +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): @@ -58,21 +61,70 @@ .replace('*', '') self.repo_path = os.path.join(self.basepath, repo_name) try: - app = wsgiapplication(self._make_app) + app = wsgiapplication(self.__make_app) except Exception as e: return HTTPNotFound()(environ, start_response) - """we know that some change was made to repositories and we should - invalidate the cache to see the changes right away""" - invalidate_cache('full_changelog', repo_name) - invalidate_cache('cached_repo_list') + 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): + 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') - + def __get_action(self, environ): + """ + Maps mercurial request commands into a pull or push command. + @param environ: + """ + mapping = { + 'changegroup': 'pull', + 'changegroupsubset': 'pull', + 'unbundle': 'push', + 'stream_out': 'pull', + } + for qry in environ['QUERY_STRING'].split('&'): + if qry.startswith('cmd'): + cmd = qry.split('=')[-1] + if mapping.has_key(cmd): + return mapping[cmd] + + def __log_user_action(self, username, action, repo): + sa = meta.Session + try: + user = sa.query(Users)\ + .filter(Users.username == username).one() + user_log = UserLogs() + user_log.user_id = user.user_id + user_log.action = action + user_log.repository = repo.replace('/', '') + user_log.action_date = datetime.now() + sa.add(user_log) + sa.commit() + log.info('Adding user %s, action %s on %s', + username, action, repo) + except Exception as e: + sa.rollback() + log.error('could not log user action:%s', str(e)) + + 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) + + def load_web_settings(self, hgserve): repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False) #set the global ui for hgserve diff -r 568f95056716 -r da59b7e07e3c pylons_app/lib/utils.py --- a/pylons_app/lib/utils.py Sat May 22 19:18:09 2010 +0200 +++ b/pylons_app/lib/utils.py Sat May 22 19:29:50 2010 +0200 @@ -108,7 +108,7 @@ region_invalidate(_get_repos_cached, None, *args) if name == 'full_changelog': - from pylons_app.controllers.changelog import _full_changelog_cached + from pylons_app.lib.base import _full_changelog_cached region_invalidate(_full_changelog_cached, None, *args) from vcs.backends.base import BaseChangeset