src/mercurialserver/access.py
author Paul Crowley <paul@lshift.net>
Tue, 15 Dec 2009 14:28:45 +0000
changeset 236 38cea4b518c1
parent 77 8d14aac93b5d
child 241 4af1e1ccf75b
permissions -rw-r--r--
Aargh, ConfigParser smashes case, breaking security

# Copyright 2008-2009 LShift Ltd
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
#
# Authors:
# Paul Crowley <paul@lshift.net>
# Vadim Gelfer <vadim.gelfer@gmail.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

from mercurial.i18n import _
import mercurial.util
import mercurial.node

import os
from mercurialserver import ruleset
from mercurialserver import changes

class Checker(object):
    '''acl checker.'''

    def __init__(self, ui, repo):
        self.ui = ui
        self.repo = repo
        
    def allow(self, ctx):
        branch = ctx.branch()
        if not ruleset.rules.allow("write", branch=branch, file=None):
            return False
        for f in ctx.files():
            if not ruleset.rules.allow("write", branch=branch, file=f):
                return False
        return True

    def check(self, ctx):
        '''return if access allowed, raise exception if not.'''
        if not self.allow(ctx):
            raise mercurial.util.Abort(_('%s: access denied for changeset %s') %
                (__name__, mercurial.node.short(ctx.node())))

def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
    if hooktype != 'pretxnchangegroup':
        raise mercurial.util.Abort(_('config error - hook type "%s" cannot stop '
                           'incoming changesets') % hooktype)
    c = Checker(ui, repo)
    for ctx in changes.changes(repo, node):
        c.check(ctx)