[PATCH] acl: new option to prevent anyone except a given user or group to push changesets in a given branch

Elifarley Callado Coelho Cruz elifarley at gmail.com
Sun May 27 08:28:39 CDT 2012


This patch enables a use case suggested by a user (Julien Bonnet):
There's a branch that only a given user (or group) should be able to push
to, and you don't want to restrict access to any other branch that may be
created.

To achieve that, you simply deny branch access to "!givenuser" (or
"!@givengroup"). Configuration example below:

#=========================

[acl.deny.branches]
# only 'givenuser' can commit to branch 'default'; 'givenuser' and anyone
else can still use any other branch.
default = !givenuser

#=========================





# HG changeset patch
# User Elifarley Callado Coelho Cruz
# Date 1335990434 10800
# Node ID bd3ffd122b2be0d1fb0d1845b026d2a74f61cafc
# Parent  e9ae770eff1c5728eb397e0bd413af6b93e78a5f
acl: new option to prevent anyone except a given user or group to push
changesets in a given branch.

This patch enables a use case suggested by a user (Julien Bonnet):
There's a branch that only a given user (or group) should be able to push
to, and you don't want to restrict access to any other branch that may be
created.

To achieve that, you simply deny branch access to "!givenuser" (or
"!@givengroup"). Configuration example below:

#=========================

[acl.deny.branches]
# only 'givenuser' can commit to branch 'default'; 'givenuser' and anyone
else can still use any other branch.
default = !givenuser

#=========================

diff --git a/hgext/acl.py b/hgext/acl.py
--- a/hgext/acl.py
+++ b/hgext/acl.py
@@ -174,7 +174,19 @@
         return True

     for ug in usersorgroups.replace(',', ' ').split():
-        if user == ug or ug.startswith('@') and user in _getusers(ui,
ug[1:]):
+
+        if ug.startswith('!'):
+            # Test for excluded user or group. Format:
+            # if ug is a user  name: !username
+            # if ug is a group name: !@groupname
+            ug = ug[1:]
+            if not ug.startswith('@') and user != ug or ug.startswith('@')
and user not in _getusers(ui, ug[1:]):
+                return True
+
+        # Test for user or group. Format:
+        # if ug is a user  name: username
+        # if ug is a group name: @groupname
+        elif user == ug or ug.startswith('@') and user in _getusers(ui,
ug[1:]):
             return True

     return False
diff --git a/tests/test-acl.t b/tests/test-acl.t
--- a/tests/test-acl.t
+++ b/tests/test-acl.t
@@ -1922,3 +1922,153 @@
   no rollback information available
   2:fb35475503ef

+User 'astro' must not be denied
+
+  $ init_config
+  $ echo "[acl.deny.branches]" >> $config
+  $ echo "default = !astro" >> $config
+  $ do_push astro
+  Pushing as user astro
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.deny.branches]
+  default = !astro
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: checking access for user "astro"
+  acl: acl.allow.branches not enabled
+  acl: acl.deny.branches enabled, 0 entries for user astro
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  acl: branch access granted: "ef1ea85a6374" on branch "default"
+  acl: path access granted: "ef1ea85a6374"
+  acl: branch access granted: "f9cafe1212c8" on branch "default"
+  acl: path access granted: "f9cafe1212c8"
+  acl: branch access granted: "911600dab2ae" on branch "default"
+  acl: path access granted: "911600dab2ae"
+  acl: branch access granted: "e8fc755d4d82" on branch "foobar"
+  acl: path access granted: "e8fc755d4d82"
+  updating the branch cache
+  checking for updated bookmarks
+  repository tip rolled back to revision 2 (undo push)
+  2:fb35475503ef
+
+Non-astro users must be denied
+
+  $ do_push george
+  Pushing as user george
+  hgrc = """
+  [acl]
+  sources = push
+  [extensions]
+  [acl.deny.branches]
+  default = !astro
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  invalidating branch cache (tip differs)
+  4 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
+  911600dab2ae7a9baff75958b84fe606851ce955
+  e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
+  adding changesets
+  bundling: 1/4 changesets (25.00%)
+  bundling: 2/4 changesets (50.00%)
+  bundling: 3/4 changesets (75.00%)
+  bundling: 4/4 changesets (100.00%)
+  bundling: 1/4 manifests (25.00%)
+  bundling: 2/4 manifests (50.00%)
+  bundling: 3/4 manifests (75.00%)
+  bundling: 4/4 manifests (100.00%)
+  bundling: abc.txt 1/4 files (25.00%)
+  bundling: foo/Bar/file.txt 2/4 files (50.00%)
+  bundling: foo/file.txt 3/4 files (75.00%)
+  bundling: quux/file.py 4/4 files (100.00%)
+  changesets: 1 chunks
+  add changeset ef1ea85a6374
+  changesets: 2 chunks
+  add changeset f9cafe1212c8
+  changesets: 3 chunks
+  add changeset 911600dab2ae
+  changesets: 4 chunks
+  add changeset e8fc755d4d82
+  adding manifests
+  manifests: 1/4 chunks (25.00%)
+  manifests: 2/4 chunks (50.00%)
+  manifests: 3/4 chunks (75.00%)
+  manifests: 4/4 chunks (100.00%)
+  adding file changes
+  adding abc.txt revisions
+  files: 1/4 chunks (25.00%)
+  adding foo/Bar/file.txt revisions
+  files: 2/4 chunks (50.00%)
+  adding foo/file.txt revisions
+  files: 3/4 chunks (75.00%)
+  adding quux/file.py revisions
+  files: 4/4 chunks (100.00%)
+  added 4 changesets with 4 changes to 4 files (+1 heads)
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: checking access for user "george"
+  acl: acl.allow.branches not enabled
+  acl: acl.deny.branches enabled, 1 entries for user george
+  acl: acl.allow not enabled
+  acl: acl.deny not enabled
+  error: pretxnchangegroup.acl hook failed: acl: user "george" denied on
branch "default" (changeset "ef1ea85a6374")
+  transaction abort!
+  rollback completed
+  abort: acl: user "george" denied on branch "default" (changeset
"ef1ea85a6374")
+  no rollback information available
+  2:fb35475503ef
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20120527/da7d1c6e/attachment.html>


More information about the Mercurial-devel mailing list