FW: Extension to ACL extension

Ralf Leibold Ralf.Leibold at nuance.com
Mon Jul 30 09:54:45 CDT 2007


Once again with patch attached...

Ralf

-----Original Message-----
From: Ralf Leibold 
Sent: Monday, July 30, 2007 4:12 PM
To: 'mercurial-devel at selenic.com'
Subject: Extension to ACL extension

Hi,

here is my second patch. I extended the ACL extension slightly:

1) You can use this extension also for commits. Therefore you need to
enable 
pretxncommit.acl = python:hgext.acl.hook

in your .hgrc-file and additionally there is a new "sources"-field named
"commit". 

2) The ACL-hook can be limited to special branches only. Those branches
are specified with usual regular expressions inside the "[acl]"-part of
the .hgrc-file. So e.g.
[acl]
sources = serve push pull commit
tracked_branches = development.*

(In this example the ACL is limited to all branches starting with
"development".) The default value for "tracked_branches" is ".*" for
backward compatibility.


Background info:
================
The idea is the following development process: We use mercurial on a
large fileserver. Some repositories are quite large in size and we don't
want them to be cloned dozens of times. So instead of "hg clone" we just
(soft-)link the ".hg"-directory and call "hg update". That means that
everyone directly changes the repository with each commit. To restrict
the main branches to certain people you can now restrict changes on
those branches to special people. But everyone is allowed (and enforced)
to add his private branch for his development and the "repo-admins"
merge those changes back into the main branch.


I hope this is of use
Ralf



The patch ("hg export" versus version "5026:48ebd6a83994" of
http://selenic.com/repo/hg)

# HG changeset patch
# User leibold at AC-Fairway.eu.scansoft.com
# Date 1185802074 -7200
# Branch ExtendACL
# Node ID 8f13db4d611d7b43aca34ce61ffde5f0f60d69fd
# Parent  48ebd6a8399480a889410a130d98e6bf342bc3ca
ACL-extension: Add ACLs for commits and ACLs for special branches only.

diff -r 48ebd6a83994 -r 8f13db4d611d hgext/acl.py
--- a/hgext/acl.py      Sat Jul 28 20:15:54 2007 +0200
+++ b/hgext/acl.py      Mon Jul 30 15:27:54 2007 +0200
@@ -49,6 +49,7 @@ from mercurial.node import *
 from mercurial.node import *
 from mercurial import util
 import getpass
+import re
 
 class checker(object):
     '''acl checker.'''
@@ -83,6 +84,11 @@ class checker(object):
             self.ui.readsections(cfg, 'acl.allow', 'acl.deny')
         self.allow, self.allowable = self.buildmatch('acl.allow')
         self.deny, self.deniable = self.buildmatch('acl.deny')
+        # Tracked branches
+        pats = self.ui.config('acl', 'tracked_branches',
'.*').replace(',', ' ').split()
+        pat = '(?:%s)$' % '|'.join([p for p in pats])
+        self.ui.debug(_('acl: branch pattern: "%s"\n' % pat))
+        self.tracked_branches = re.compile(pat)
 
     def skipsource(self, source):
         '''true if incoming changes from this source should be
skipped.'''
@@ -92,24 +98,32 @@ class checker(object):
     def check(self, node):
         '''return if access allowed, raise exception if not.'''
         files = self.repo.changectx(node).files()
-        if self.deniable:
-            for f in files:
-                if self.deny(f):
-                    self.ui.debug(_('acl: user %s denied on %s\n') %
-                                  (self.getuser(), f))
-                    raise util.Abort(_('acl: access denied for
changeset %s') %
-                                     short(node))
-        if self.allowable:
-            for f in files:
-                if not self.allow(f):
-                    self.ui.debug(_('acl: user %s not allowed on %s\n')
%
-                                  (self.getuser(), f))
-                    raise util.Abort(_('acl: access denied for
changeset %s') %
-                                     short(node))
+        branch = self.repo.changectx(node).branch()
+        matched_branch = self.tracked_branches.match(branch)
+        if matched_branch:
+            self.ui.debug(_('acl: branch "%s" tracked...\n' % branch))
+            if self.deniable:
+                for f in files:
+                    if self.deny(f):
+                        self.ui.debug(_('acl: user %s denied on %s\n')
%
+                                      (self.getuser(), f))
+                        raise util.Abort(_('acl: access denied for
changeset %s') %
+                                         short(node))
+            if self.allowable:
+                for f in files:
+                    if not self.allow(f):
+                        self.ui.debug(_('acl: user %s not allowed on
%s\n') %
+                                      (self.getuser(), f))
+                        raise util.Abort(_('acl: access denied for
changeset %s') %
+                                         short(node))
+        else:
+            self.ui.debug(_('acl: branch "%s" not tracked...\n' %
branch))
         self.ui.debug(_('acl: allowing changeset %s\n') % short(node))
 
 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
-    if hooktype != 'pretxnchangegroup':
+    if hooktype == 'pretxncommit':
+        source = 'commit'
+    elif hooktype != 'pretxnchangegroup':
         raise util.Abort(_('config error - hook type "%s" cannot stop '
                            'incoming changesets') % hooktype)
 
@@ -120,5 +134,6 @@ def hook(ui, repo, hooktype, node=None, 
 
     start = repo.changelog.rev(bin(node))
     end = repo.changelog.count()
+    ui.debug(_('acl: changes have source "%s": %s - %s.\n') % (source,
start, end))
     for rev in xrange(start, end):
         c.check(repo.changelog.node(rev))
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: export.txt
Url: http://selenic.com/pipermail/mercurial-devel/attachments/20070730/d1126158/attachment.txt 


More information about the Mercurial-devel mailing list