changeset 16956:c49cf339b5bb

acl: use of "!" prefix in user or group names The "!" prefix allows you to prevent anyone except a given user or group to push changesets in a given branch or path. 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. With the "!" prefix, you simply deny access to "!givenuser" (or "!@givengroup").
author Elifarley Callado Coelho Cruz
date Mon, 28 May 2012 19:45:15 -0300
parents 92e1c64ba0d4
children d7b608149f6c
files hgext/acl.py tests/test-acl.t
diffstat 2 files changed, 167 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/acl.py	Wed May 30 12:55:33 2012 -0700
+++ b/hgext/acl.py	Mon May 28 19:45:15 2012 -0300
@@ -174,7 +174,21 @@
         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
--- a/tests/test-acl.t	Wed May 30 12:55:33 2012 -0700
+++ b/tests/test-acl.t	Mon May 28 19:45:15 2012 -0300
@@ -1919,3 +1919,155 @@
   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
+  
+