Patchwork acl: add support for bookmarks [RFC]

login
register
mail settings
Submitter timeless@mozdev.org
Date March 4, 2016, 12:08 a.m.
Message ID <ffccdee9c9c6e3e86991.1457050126@waste.org>
Download mbox | patch
Permalink /patch/13587/
State Changes Requested
Delegated to: Yuya Nishihara
Headers show

Comments

timeless@mozdev.org - March 4, 2016, 12:08 a.m.
# HG changeset patch
# User timeless <timeless@mozdev.org>
# Date 1457047766 0
#      Thu Mar 03 23:29:26 2016 +0000
# Node ID ffccdee9c9c6e3e86991043c0d56d58f26e746f6
# Parent  e00e57d836535aadcb13337613d2f891492d8e04
acl: add support for bookmarks [RFC]

Someone asked about whether acl could support bookmarks.
Before this, it couldn't.

This code isn't particularly well tested, but it seems to work.

It's also a template for using acl to control `phases`.
Pierre-Yves David - March 9, 2016, 5:25 p.m.
On 03/04/2016 12:08 AM, timeless wrote:
> # HG changeset patch
> # User timeless <timeless@mozdev.org>
> # Date 1457047766 0
> #      Thu Mar 03 23:29:26 2016 +0000
> # Node ID ffccdee9c9c6e3e86991043c0d56d58f26e746f6
> # Parent  e00e57d836535aadcb13337613d2f891492d8e04
> acl: add support for bookmarks [RFC]
>
> Someone asked about whether acl could support bookmarks.
> Before this, it couldn't.
>
> This code isn't particularly well tested, but it seems to work.
>
> It's also a template for using acl to control `phases`.

This seems a good improvement (a bit fragile as I can foresee bookmark 
move without pushkey at some point, we should probably have this as the 
transaction level instead). I've some feedback on the doc

>
> diff --git a/hgext/acl.py b/hgext/acl.py
> --- a/hgext/acl.py
> +++ b/hgext/acl.py
> @@ -57,6 +57,27 @@
>   a glob syntax by default). The corresponding values follow the same
>   syntax as the other sections above.
>
> +Bookmark-based Access Control
> +-----------------------------
> +Use the ``acl.deny.bookmarks`` and ``acl.allow.bookmarks`` sections to
> +have bookmark-based access control. Keys in these sections can be
> +either:
> +
> +- a bookmark name, or
> +- an asterisk, to match any bookmark;
> +
> +The corresponding values can be either:
> +
> +- a comma-separated list containing users and groups, or
> +- an asterisk, to match anyone;
> +
> +You can add the "!" prefix to a user or group name to invert the sense
> +of the match.
> +
> +Note: for bundle2 requests, a rejection will reject the entire push,
> +for bundle1 requests, the commit transactions will already be accepted,
> +and only the bookmark moveent will be rejected.

bundle2 and bundle1 will be totally opaque to user. We need to be more 
helpful here. Maybe mention Mercurial version number that will use the 
legacy protocol.

Cheers,
timeless - March 9, 2016, 6:03 p.m.
Pierre-Yves David wrote:
> bundle2 and bundle1 will be totally opaque to user. We need to be more
> helpful here. Maybe mention Mercurial version number that will use the
> legacy protocol.

I don't think it's version level controlled. Since afaiu bitbucket was
using a new version of mercurial but w/ old repositories and I /think/
I was getting the bundle1 behavior. But perhaps I'm wrong.

It might be requirements controlled.
And it's probably possible to give the acl command a validator which
would be able to report which style it would use. But I'm not
volunteering to write that, and I'm definitely not claiming ownership
of the module.

I'm open to wording if someone can write it up. I'm not sure the
correct wording.
Pierre-Yves David - March 9, 2016, 6:06 p.m.
On 03/09/2016 06:03 PM, timeless wrote:
> Pierre-Yves David wrote:
>> bundle2 and bundle1 will be totally opaque to user. We need to be more
>> helpful here. Maybe mention Mercurial version number that will use the
>> legacy protocol.
>
> I don't think it's version level controlled. Since afaiu bitbucket was
> using a new version of mercurial but w/ old repositories and I /think/
> I was getting the bundle1 behavior. But perhaps I'm wrong.

bitbucket explicitly disabled bundle2 globally. all other people are 
silently getting bundle2 for over a year.

> It might be requirements controlled.
> And it's probably possible to give the acl command a validator which
> would be able to report which style it would use. But I'm not
> volunteering to write that, and I'm definitely not claiming ownership
> of the module.
>
> I'm open to wording if someone can write it up. I'm not sure the
> correct wording.

I've faith in you. ping me on IRC if you need more help.

Patch

diff --git a/hgext/acl.py b/hgext/acl.py
--- a/hgext/acl.py
+++ b/hgext/acl.py
@@ -57,6 +57,27 @@ 
 a glob syntax by default). The corresponding values follow the same
 syntax as the other sections above.
 
+Bookmark-based Access Control
+-----------------------------
+Use the ``acl.deny.bookmarks`` and ``acl.allow.bookmarks`` sections to
+have bookmark-based access control. Keys in these sections can be
+either:
+
+- a bookmark name, or
+- an asterisk, to match any bookmark;
+
+The corresponding values can be either:
+
+- a comma-separated list containing users and groups, or
+- an asterisk, to match anyone;
+
+You can add the "!" prefix to a user or group name to invert the sense
+of the match.
+
+Note: for bundle2 requests, a rejection will reject the entire push,
+for bundle1 requests, the commit transactions will already be accepted,
+and only the bookmark moveent will be rejected.
+
 Groups
 ------
 
@@ -275,9 +296,9 @@ 
     return util.never
 
 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
-    if hooktype not in ['pretxnchangegroup', 'pretxncommit']:
+    if hooktype not in ['pretxnchangegroup', 'pretxncommit', 'prepushkey']:
         raise error.Abort(_('config error - hook type "%s" cannot stop '
-                           'incoming changesets nor commits') % hooktype)
+                           'incoming changesets, commits, nor bookmarks') % hooktype)
     if (hooktype == 'pretxnchangegroup' and
         source not in ui.config('acl', 'sources', 'serve').split()):
         ui.debug('acl: changes have source "%s" - skipping\n' % source)
@@ -294,6 +315,30 @@ 
 
     ui.debug('acl: checking access for user "%s"\n' % user)
 
+    if hooktype == 'prepushkey':
+        _pkhook(ui, repo, hooktype, node, source, user, **kwargs)
+    else:
+        _txnhook(ui, repo, hooktype, node, source, user, **kwargs)
+
+def _pkhook(ui, repo, hooktype, node, source, user, **kwargs):
+    if kwargs['namespace'] == 'bookmarks':
+        bookmark = kwargs['key']
+        ctx = kwargs['new']
+        allowbookmarks = buildmatch(ui, None, user, 'acl.allow.bookmarks')
+        denybookmarks = buildmatch(ui, None, user, 'acl.deny.bookmarks')
+
+        if denybookmarks and denybookmarks(bookmark):
+            raise error.Abort(_('acl: user "%s" denied on bookmark "%s"'
+                               ' (changeset "%s")')
+                               % (user, bookmark, ctx))
+        if allowbookmarks and not allowbookmarks(bookmark):
+            raise error.Abort(_('acl: user "%s" not allowed on bookmark "%s"'
+                               ' (changeset "%s")')
+                               % (user, bookmark, ctx))
+        ui.debug('acl: bookmark access granted: "%s" on bookmark "%s"\n'
+                 % (ctx, bookmark))
+
+def _txnhook(ui, repo, hooktype, node, source, user, **kwargs):
     # deprecated config: acl.config
     cfg = ui.config('acl', 'config')
     if cfg:
diff --git a/tests/test-acl.t b/tests/test-acl.t
--- a/tests/test-acl.t
+++ b/tests/test-acl.t
@@ -15,7 +15,7 @@ 
   >     #  LOGNAME=$user hg --cws a --debug push ../b
   >     # fails with "This variable is read only."
   >     # Use env to work around this.
-  >     env LOGNAME=$user hg --cwd a --debug push ../b
+  >     env LOGNAME=$user hg --cwd a --debug push ../b $*
   >     hg --cwd b rollback
   >     hg --cwd b --quiet tip
   >     echo
@@ -37,6 +37,7 @@ 
   >     cat > $config <<EOF
   > [hooks]
   > pretxnchangegroup.acl = python:hgext.acl.hook
+  > prepushkey.acl = python:hgext.acl.hook
   > [acl]
   > sources = push
   > [extensions]
@@ -138,6 +139,7 @@ 
 
   $ echo '[hooks]' >> $config
   $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
+  $ echo 'prepushkey.acl = python:hgext.acl.hook' >> $config
 
 Extension disabled for lack of acl.sources
 
@@ -146,6 +148,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   """
   pushing to ../b
   query 1; heads
@@ -186,6 +189,8 @@ 
   acl: changes have source "push" - skipping
   bundle2-input-part: total payload size 1606
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-bundle: 3 parts total
   updating the branch cache
@@ -210,6 +215,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   """
@@ -262,6 +268,8 @@ 
   acl: path access granted: "911600dab2ae"
   bundle2-input-part: total payload size 1606
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-bundle: 3 parts total
   updating the branch cache
@@ -285,6 +293,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -349,6 +358,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -418,6 +428,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -484,6 +495,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -555,6 +567,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -624,6 +637,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -684,6 +698,175 @@ 
   0:6675d58eff77
   
 
+fred is not blocked from moving bookmarks
+
+  $ hg -R a book -q moving-bookmark -r 1
+  $ hg -R b book -q moving-bookmark -r 0
+  $ cp $config normalconfig
+  $ do_push fred -r 1
+  Pushing as user fred
+  hgrc = """
+  [hooks]
+  pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
+  [acl]
+  sources = push
+  [acl.allow]
+  foo/** = fred
+  [acl.deny]
+  foo/bar/** = fred
+  foo/Bar/** = fred
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  listing keys for "phases"
+  checking for updated bookmarks
+  listing keys for "bookmarks"
+  invalid branchheads cache (served): tip differs
+  listing keys for "bookmarks"
+  1 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  bundle2-output-bundle: "HG20", 5 parts total
+  bundle2-output-part: "replycaps" 155 bytes payload
+  bundle2-output-part: "check:heads" streamed payload
+  bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
+  bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
+  bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
+  bundle2-input-bundle: with-transaction
+  bundle2-input-part: "replycaps" supported
+  bundle2-input-part: total payload size 155
+  bundle2-input-part: "check:heads" supported
+  bundle2-input-part: total payload size 20
+  bundle2-input-part: "changegroup" (params: 1 mandatory) supported
+  adding changesets
+  add changeset ef1ea85a6374
+  adding manifests
+  adding file changes
+  adding foo/file.txt revisions
+  added 1 changesets with 1 changes to 1 files
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: checking access for user "fred"
+  acl: acl.allow.branches not enabled
+  acl: acl.deny.branches not enabled
+  acl: acl.allow enabled, 1 entries for user fred
+  acl: acl.deny enabled, 2 entries for user fred
+  acl: branch access granted: "ef1ea85a6374" on branch "default"
+  acl: path access granted: "ef1ea85a6374"
+  invalid branchheads cache (served): tip differs
+  bundle2-input-part: total payload size 537
+  bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
+  pushing key for "phases:ef1ea85a6374b77d6da9dcda9541f498f2d17df7"
+  bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
+  acl: acl.allow.bookmarks not enabled
+  acl: acl.deny.bookmarks not enabled
+  acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
+  pushing key for "bookmarks:moving-bookmark"
+  bundle2-input-bundle: 4 parts total
+  updating the branch cache
+  bundle2-output-bundle: "HG20", 3 parts total
+  bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
+  bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
+  bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
+  bundle2-input-bundle: with-transaction
+  bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
+  bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
+  bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
+  bundle2-input-bundle: 2 parts total
+  updating bookmark moving-bookmark
+  listing keys for "phases"
+  repository tip rolled back to revision 0 (undo push)
+  0:6675d58eff77
+  
+fred is not allowed to move bookmarks
+
+  $ echo '[acl.deny.bookmarks]' >> $config
+  $ echo '* = fred' >> $config
+  $ do_push fred -r 1
+  Pushing as user fred
+  hgrc = """
+  [hooks]
+  pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
+  [acl]
+  sources = push
+  [acl.allow]
+  foo/** = fred
+  [acl.deny]
+  foo/bar/** = fred
+  foo/Bar/** = fred
+  [acl.deny.bookmarks]
+  * = fred
+  """
+  pushing to ../b
+  query 1; heads
+  searching for changes
+  all remote heads known locally
+  listing keys for "phases"
+  checking for updated bookmarks
+  listing keys for "bookmarks"
+  invalid branchheads cache (served): tip differs
+  listing keys for "bookmarks"
+  1 changesets found
+  list of changesets:
+  ef1ea85a6374b77d6da9dcda9541f498f2d17df7
+  bundle2-output-bundle: "HG20", 5 parts total
+  bundle2-output-part: "replycaps" 155 bytes payload
+  bundle2-output-part: "check:heads" streamed payload
+  bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
+  bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
+  bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
+  bundle2-input-bundle: with-transaction
+  bundle2-input-part: "replycaps" supported
+  bundle2-input-part: total payload size 155
+  bundle2-input-part: "check:heads" supported
+  bundle2-input-part: total payload size 20
+  bundle2-input-part: "changegroup" (params: 1 mandatory) supported
+  adding changesets
+  add changeset ef1ea85a6374
+  adding manifests
+  adding file changes
+  adding foo/file.txt revisions
+  added 1 changesets with 1 changes to 1 files
+  calling hook pretxnchangegroup.acl: hgext.acl.hook
+  acl: checking access for user "fred"
+  acl: acl.allow.branches not enabled
+  acl: acl.deny.branches not enabled
+  acl: acl.allow enabled, 1 entries for user fred
+  acl: acl.deny enabled, 2 entries for user fred
+  acl: branch access granted: "ef1ea85a6374" on branch "default"
+  acl: path access granted: "ef1ea85a6374"
+  invalid branchheads cache (served): tip differs
+  bundle2-input-part: total payload size 537
+  bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
+  pushing key for "phases:ef1ea85a6374b77d6da9dcda9541f498f2d17df7"
+  bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
+  acl: acl.allow.bookmarks not enabled
+  acl: acl.deny.bookmarks enabled, 1 entries for user fred
+  error: prepushkey.acl hook failed: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
+  bundle2-input-bundle: 4 parts total
+  transaction abort!
+  rollback completed
+  abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
+  no rollback information available
+  0:6675d58eff77
+  
+cleanup bookmark stuff
+
+  $ hg book -R a -d moving-bookmark
+  $ hg book -R b -d moving-bookmark
+  $ cp normalconfig $config
+
 barney is allowed everywhere
 
   $ echo '[acl.allow]' >> $config
@@ -693,6 +876,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -711,6 +895,7 @@ 
   checking for updated bookmarks
   listing keys for "bookmarks"
   invalid branchheads cache (served): tip differs
+  invalid branchheads cache (base): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
@@ -752,6 +937,8 @@ 
   acl: path access granted: "911600dab2ae"
   bundle2-input-part: total payload size 1606
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "barney"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-bundle: 3 parts total
   updating the branch cache
@@ -775,6 +962,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -851,6 +1039,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -920,6 +1109,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -1002,6 +1192,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [acl.allow]
@@ -1070,6 +1261,8 @@ 
   acl: path access granted: "911600dab2ae"
   bundle2-input-part: total payload size 1606
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "barney"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-bundle: 3 parts total
   updating the branch cache
@@ -1101,6 +1294,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1156,6 +1350,8 @@ 
   acl: path access granted: "911600dab2ae"
   bundle2-input-part: total payload size 1606
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-bundle: 3 parts total
   updating the branch cache
@@ -1181,6 +1377,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1259,6 +1456,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1315,6 +1513,8 @@ 
   acl: path access granted: "911600dab2ae"
   bundle2-input-part: total payload size 1606
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "fred"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-bundle: 3 parts total
   updating the branch cache
@@ -1340,6 +1540,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1459,6 +1660,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1517,8 +1719,12 @@ 
   acl: path access granted: "e8fc755d4d82"
   bundle2-input-part: total payload size 2101
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "astro"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "astro"
   pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
   bundle2-input-bundle: 4 parts total
   updating the branch cache
@@ -1545,6 +1751,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1620,6 +1827,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1689,6 +1897,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1753,6 +1962,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1813,8 +2023,12 @@ 
   acl: path access granted: "e8fc755d4d82"
   bundle2-input-part: total payload size 2101
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "george"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "george"
   pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
   bundle2-input-bundle: 4 parts total
   updating the branch cache
@@ -1845,6 +2059,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -1906,8 +2121,12 @@ 
   acl: path access granted: "e8fc755d4d82"
   bundle2-input-part: total payload size 2101
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "george"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "george"
   pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
   bundle2-input-bundle: 4 parts total
   updating the branch cache
@@ -1936,6 +2155,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -2007,6 +2227,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]
@@ -2067,8 +2288,12 @@ 
   acl: path access granted: "e8fc755d4d82"
   bundle2-input-part: total payload size 2101
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "astro"
   pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
   bundle2-input-part: "pushkey" (params: 4 mandatory) supported
+  calling hook prepushkey.acl: hgext.acl.hook
+  acl: checking access for user "astro"
   pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
   bundle2-input-bundle: 4 parts total
   updating the branch cache
@@ -2093,6 +2318,7 @@ 
   hgrc = """
   [hooks]
   pretxnchangegroup.acl = python:hgext.acl.hook
+  prepushkey.acl = python:hgext.acl.hook
   [acl]
   sources = push
   [extensions]