src/access.py
changeset 33 18e93dbdaf12
parent 24 9f8e11ede780
child 39 f5055ce263c7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/access.py	Mon Jun 16 17:12:20 2008 +0100
@@ -0,0 +1,55 @@
+# Copyright 2008 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 _
+from mercurial.node import *
+from mercurial import util
+
+import os
+import ruleset
+
+class Checker(object):
+    '''acl checker.'''
+
+    def __init__(self, ui, repo):
+        self.ui = ui
+        self.repo = repo
+        self.rules = ruleset.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
+        self.rules.set(user = os.environ['REMOTE_USER'])
+        self.rules.set(repo = os.environ['HG_REPO_PATH'])
+
+    def allow(self, node):
+        '''return if access allowed, raise exception if not.'''
+        ctx = self.repo.changectx(node)
+        branch = ctx.branch()
+        if not self.rules.allow("write", branch=branch, file=None):
+            return False
+        for f in ctx.files():
+            if not self.rules.allow("write", branch=branch, file=f):
+                return False
+        self.ui.debug(_('%s: allowing changeset %s\n') % (__name__, short(node)))
+        return True
+
+    def check(self, node):
+        if not self.allow(node):
+            raise util.Abort(_('%s: access denied for changeset %s') %
+                (__name__, short(node)))
+
+        
+def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
+    if hooktype != 'pretxnchangegroup':
+        raise util.Abort(_('config error - hook type "%s" cannot stop '
+                           'incoming changesets') % hooktype)
+    c = Checker(ui, repo)
+    start = repo.changelog.rev(bin(node))
+    end = repo.changelog.count()
+    for rev in xrange(start, end):
+        c.check(repo.changelog.node(rev))
+