Details
Details
- Reviewers
- None
- Group Reviewers
hg-reviewers - Commits
- rHG6beb8347b709: acl: add bookmarks support
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Lint Skipped - Unit
Unit Tests Skipped
hg-reviewers |
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
M | hgext/acl.py (50 lines) | |||
M | tests/test-acl.t (204 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
Sandu Turcan | Jun 15 2018, 2:07 PM |
Path-based Access Control | Path-based Access Control | ||||
------------------------- | ------------------------- | ||||
Use the ``acl.deny`` and ``acl.allow`` sections to have path-based | Use the ``acl.deny`` and ``acl.allow`` sections to have path-based | ||||
access control. Keys in these sections accept a subtree pattern (with | access control. Keys in these sections accept a subtree pattern (with | ||||
a glob syntax by default). The corresponding values follow the same | a glob syntax by default). The corresponding values follow the same | ||||
syntax as the other sections above. | 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 interactions between clients and servers using Mercurial 3.6+ | |||||
a rejection will generally reject the entire push, for interactions | |||||
involving older clients, the commit transactions will already be accepted, | |||||
and only the bookmark movement will be rejected. | |||||
Groups | Groups | ||||
------ | ------ | ||||
Group names must be prefixed with an ``@`` symbol. Specifying a group | Group names must be prefixed with an ``@`` symbol. Specifying a group | ||||
name has the same effect as specifying all the users in that group. | name has the same effect as specifying all the users in that group. | ||||
You can define group members in the ``acl.groups`` section. | You can define group members in the ``acl.groups`` section. | ||||
If a group name is not defined there, and Mercurial is running under | If a group name is not defined there, and Mercurial is running under | ||||
return | return | ||||
ui.setconfig('extensions', 'acl', '', source='internal') | ui.setconfig('extensions', 'acl', '', source='internal') | ||||
extensions.loadall(ui, ['acl']) | extensions.loadall(ui, ['acl']) | ||||
def hook(ui, repo, hooktype, node=None, source=None, **kwargs): | def hook(ui, repo, hooktype, node=None, source=None, **kwargs): | ||||
ensureenabled(ui) | ensureenabled(ui) | ||||
if hooktype not in ['pretxnchangegroup', 'pretxncommit']: | if hooktype not in ['pretxnchangegroup', 'pretxncommit', 'prepushkey']: | ||||
raise error.Abort(_('config error - hook type "%s" cannot stop ' | 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 | if (hooktype == 'pretxnchangegroup' and | ||||
source not in ui.configlist('acl', 'sources')): | source not in ui.configlist('acl', 'sources')): | ||||
ui.debug('acl: changes have source "%s" - skipping\n' % source) | ui.debug('acl: changes have source "%s" - skipping\n' % source) | ||||
return | return | ||||
user = None | user = None | ||||
if source == 'serve' and r'url' in kwargs: | if source == 'serve' and r'url' in kwargs: | ||||
url = kwargs[r'url'].split(':') | url = kwargs[r'url'].split(':') | ||||
if url[0] == 'remote' and url[1].startswith('http'): | if url[0] == 'remote' and url[1].startswith('http'): | ||||
user = urlreq.unquote(url[3]) | user = urlreq.unquote(url[3]) | ||||
if user is None: | if user is None: | ||||
user = procutil.getuser() | user = procutil.getuser() | ||||
ui.debug('acl: checking access for user "%s"\n' % user) | 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 | # deprecated config: acl.config | ||||
cfg = ui.config('acl', 'config') | cfg = ui.config('acl', 'config') | ||||
if cfg: | if cfg: | ||||
ui.readconfig(cfg, sections=['acl.groups', 'acl.allow.branches', | ui.readconfig(cfg, sections=['acl.groups', 'acl.allow.branches', | ||||
'acl.deny.branches', 'acl.allow', 'acl.deny']) | 'acl.deny.branches', 'acl.allow', 'acl.deny']) | ||||
allowbranches = buildmatch(ui, None, user, 'acl.allow.branches') | allowbranches = buildmatch(ui, None, user, 'acl.allow.branches') | ||||
denybranches = buildmatch(ui, None, user, 'acl.deny.branches') | denybranches = buildmatch(ui, None, user, 'acl.deny.branches') |
> echo 'acl.config = """' | > echo 'acl.config = """' | ||||
> cat acl.config | > cat acl.config | ||||
> echo '"""' | > echo '"""' | ||||
> fi | > fi | ||||
> # On AIX /etc/profile sets LOGNAME read-only. So | > # On AIX /etc/profile sets LOGNAME read-only. So | ||||
> # LOGNAME=$user hg --cws a --debug push ../b | > # LOGNAME=$user hg --cws a --debug push ../b | ||||
> # fails with "This variable is read only." | > # fails with "This variable is read only." | ||||
> # Use env to work around this. | > # 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 rollback | ||||
> hg --cwd b --quiet tip | > hg --cwd b --quiet tip | ||||
> echo | > echo | ||||
> } | > } | ||||
> cat > posixgetuser.py <<'EOF' | > cat > posixgetuser.py <<'EOF' | ||||
> import getpass | > import getpass | ||||
> from mercurial import pycompat | > from mercurial import pycompat | ||||
> return ["fred", "betty"] | > return ["fred", "betty"] | ||||
> acl._getusersorig = acl._getusers | > acl._getusersorig = acl._getusers | ||||
> acl._getusers = fakegetusers | > acl._getusers = fakegetusers | ||||
> EOF | > EOF | ||||
> rm -f acl.config | > rm -f acl.config | ||||
> cat > $config <<EOF | > cat > $config <<EOF | ||||
> [hooks] | > [hooks] | ||||
> pretxnchangegroup.acl = python:hgext.acl.hook | > pretxnchangegroup.acl = python:hgext.acl.hook | ||||
> prepushkey.acl = python:hgext.acl.hook | |||||
> [acl] | > [acl] | ||||
> sources = push | > sources = push | ||||
> [extensions] | > [extensions] | ||||
> f=`pwd`/fakegroups.py | > f=`pwd`/fakegroups.py | ||||
> posixgetuser=$TESTTMP/posixgetuser.py | > posixgetuser=$TESTTMP/posixgetuser.py | ||||
> EOF | > EOF | ||||
> } | > } | ||||
bundle2-input-bundle: 0 parts total | bundle2-input-bundle: 0 parts total | ||||
listing keys for "phases" | listing keys for "phases" | ||||
repository tip rolled back to revision 0 (undo push) | repository tip rolled back to revision 0 (undo push) | ||||
0:6675d58eff77 | 0:6675d58eff77 | ||||
$ echo '[hooks]' >> $config | $ echo '[hooks]' >> $config | ||||
$ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config | $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config | ||||
$ echo 'prepushkey.acl = python:hgext.acl.hook' >> $config | |||||
Extension disabled for lack of acl.sources | Extension disabled for lack of acl.sources | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
query 1; heads | query 1; heads | ||||
searching for changes | searching for changes | ||||
all remote heads known locally | all remote heads known locally | ||||
listing keys for "phases" | listing keys for "phases" | ||||
checking for updated bookmarks | checking for updated bookmarks | ||||
listing keys for "bookmarks" | listing keys for "bookmarks" | ||||
$ echo '[acl]' >> $config | $ echo '[acl]' >> $config | ||||
$ echo 'sources = push' >> $config | $ echo 'sources = push' >> $config | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
query 1; heads | query 1; heads | ||||
searching for changes | searching for changes | ||||
all remote heads known locally | all remote heads known locally | ||||
listing keys for "phases" | listing keys for "phases" | ||||
Empty [acl.allow] | Empty [acl.allow] | ||||
$ echo '[acl.allow]' >> $config | $ echo '[acl.allow]' >> $config | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
query 1; heads | query 1; heads | ||||
searching for changes | searching for changes | ||||
all remote heads known locally | all remote heads known locally | ||||
fred is allowed inside foo/ | fred is allowed inside foo/ | ||||
$ echo 'foo/** = fred' >> $config | $ echo 'foo/** = fred' >> $config | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
query 1; heads | query 1; heads | ||||
searching for changes | searching for changes | ||||
Empty [acl.deny] | Empty [acl.deny] | ||||
$ echo '[acl.deny]' >> $config | $ echo '[acl.deny]' >> $config | ||||
$ do_push barney | $ do_push barney | ||||
Pushing as user barney | Pushing as user barney | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
query 1; heads | query 1; heads | ||||
fred is allowed inside foo/, but not foo/bar/ (case matters) | fred is allowed inside foo/, but not foo/bar/ (case matters) | ||||
$ echo 'foo/bar/** = fred' >> $config | $ echo 'foo/bar/** = fred' >> $config | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
fred is allowed inside foo/, but not foo/Bar/ | fred is allowed inside foo/, but not foo/Bar/ | ||||
$ echo 'foo/Bar/** = fred' >> $config | $ echo 'foo/Bar/** = fred' >> $config | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
foo/Bar/** = fred | foo/Bar/** = fred | ||||
""" | """ | ||||
$ echo 'barney is not mentioned => not allowed anywhere' | $ echo 'barney is not mentioned => not allowed anywhere' | ||||
barney is not mentioned => not allowed anywhere | barney is not mentioned => not allowed anywhere | ||||
$ do_push barney | $ do_push barney | ||||
Pushing as user barney | Pushing as user barney | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
foo/Bar/** = fred | foo/Bar/** = fred | ||||
""" | """ | ||||
bundle2-input-bundle: 4 parts total | bundle2-input-bundle: 4 parts total | ||||
transaction abort! | transaction abort! | ||||
rollback completed | rollback completed | ||||
abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374") | abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374") | ||||
no rollback information available | no rollback information available | ||||
0:6675d58eff77 | 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" | |||||
listing keys for "bookmarks" | |||||
1 changesets found | |||||
list of changesets: | |||||
ef1ea85a6374b77d6da9dcda9541f498f2d17df7 | |||||
bundle2-output-bundle: "HG20", 7 parts total | |||||
bundle2-output-part: "replycaps" 205 bytes payload | |||||
bundle2-output-part: "check:bookmarks" 37 bytes payload | |||||
bundle2-output-part: "check:phases" 24 bytes payload | |||||
bundle2-output-part: "check:heads" streamed payload | |||||
bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload | |||||
bundle2-output-part: "phase-heads" 24 bytes payload | |||||
bundle2-output-part: "bookmarks" 37 bytes payload | |||||
bundle2-input-bundle: with-transaction | |||||
bundle2-input-part: "replycaps" supported | |||||
bundle2-input-part: total payload size 205 | |||||
bundle2-input-part: "check:bookmarks" supported | |||||
bundle2-input-part: total payload size 37 | |||||
bundle2-input-part: "check:phases" supported | |||||
bundle2-input-part: total payload size 24 | |||||
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" | |||||
bundle2-input-part: total payload size 520 | |||||
bundle2-input-part: "phase-heads" supported | |||||
bundle2-input-part: total payload size 24 | |||||
bundle2-input-part: "bookmarks" supported | |||||
bundle2-input-part: total payload size 37 | |||||
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" | |||||
bundle2-input-bundle: 6 parts total | |||||
updating the branch cache | |||||
bundle2-output-bundle: "HG20", 1 parts total | |||||
bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload | |||||
bundle2-input-bundle: no-transaction | |||||
bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported | |||||
bundle2-input-bundle: 0 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" | |||||
listing keys for "bookmarks" | |||||
1 changesets found | |||||
list of changesets: | |||||
ef1ea85a6374b77d6da9dcda9541f498f2d17df7 | |||||
bundle2-output-bundle: "HG20", 7 parts total | |||||
bundle2-output-part: "replycaps" 205 bytes payload | |||||
bundle2-output-part: "check:bookmarks" 37 bytes payload | |||||
bundle2-output-part: "check:phases" 24 bytes payload | |||||
bundle2-output-part: "check:heads" streamed payload | |||||
bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload | |||||
bundle2-output-part: "phase-heads" 24 bytes payload | |||||
bundle2-output-part: "bookmarks" 37 bytes payload | |||||
bundle2-input-bundle: with-transaction | |||||
bundle2-input-part: "replycaps" supported | |||||
bundle2-input-part: total payload size 205 | |||||
bundle2-input-part: "check:bookmarks" supported | |||||
bundle2-input-part: total payload size 37 | |||||
bundle2-input-part: "check:phases" supported | |||||
bundle2-input-part: total payload size 24 | |||||
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" | |||||
bundle2-input-part: total payload size 520 | |||||
bundle2-input-part: "phase-heads" supported | |||||
bundle2-input-part: total payload size 24 | |||||
bundle2-input-part: "bookmarks" supported | |||||
bundle2-input-part: total payload size 37 | |||||
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: 6 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 | barney is allowed everywhere | ||||
$ echo '[acl.allow]' >> $config | $ echo '[acl.allow]' >> $config | ||||
$ echo '** = barney' >> $config | $ echo '** = barney' >> $config | ||||
$ do_push barney | $ do_push barney | ||||
Pushing as user barney | Pushing as user barney | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
foo/Bar/** = fred | foo/Bar/** = fred | ||||
[acl.allow] | [acl.allow] | ||||
wilma can change files with a .txt extension | wilma can change files with a .txt extension | ||||
$ echo '**/*.txt = wilma' >> $config | $ echo '**/*.txt = wilma' >> $config | ||||
$ do_push wilma | $ do_push wilma | ||||
Pushing as user wilma | Pushing as user wilma | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
foo/Bar/** = fred | foo/Bar/** = fred | ||||
[acl.allow] | [acl.allow] | ||||
$ echo '[acl]' >> $config | $ echo '[acl]' >> $config | ||||
$ echo 'config = ../acl.config' >> $config | $ echo 'config = ../acl.config' >> $config | ||||
$ do_push barney | $ do_push barney | ||||
Pushing as user barney | Pushing as user barney | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
foo/Bar/** = fred | foo/Bar/** = fred | ||||
[acl.allow] | [acl.allow] | ||||
$ echo '[acl.allow]' >> acl.config | $ echo '[acl.allow]' >> acl.config | ||||
$ echo 'foo/** = betty' >> acl.config | $ echo 'foo/** = betty' >> acl.config | ||||
$ do_push betty | $ do_push betty | ||||
Pushing as user betty | Pushing as user betty | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
foo/Bar/** = fred | foo/Bar/** = fred | ||||
[acl.allow] | [acl.allow] | ||||
$ echo '[hooks]' >> acl.config | $ echo '[hooks]' >> acl.config | ||||
$ echo 'changegroup.acl = false' >> acl.config | $ echo 'changegroup.acl = false' >> acl.config | ||||
$ do_push barney | $ do_push barney | ||||
Pushing as user barney | Pushing as user barney | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[acl.allow] | [acl.allow] | ||||
foo/** = fred | foo/** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/bar/** = fred | foo/bar/** = fred | ||||
foo/Bar/** = fred | foo/Bar/** = fred | ||||
[acl.allow] | [acl.allow] | ||||
fred is always allowed | fred is always allowed | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow] | [acl.allow] | ||||
** = fred | ** = fred | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
no one is allowed inside foo/Bar/ | no one is allowed inside foo/Bar/ | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow] | [acl.allow] | ||||
** = fred | ** = fred | ||||
[acl.deny] | [acl.deny] | ||||
foo/Bar/** = * | foo/Bar/** = * | ||||
@group1 is always allowed | @group1 is always allowed | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow] | [acl.allow] | ||||
** = @group1 | ** = @group1 | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
@group is allowed inside anything but foo/Bar/ | @group is allowed inside anything but foo/Bar/ | ||||
$ do_push fred | $ do_push fred | ||||
Pushing as user fred | Pushing as user fred | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow] | [acl.allow] | ||||
** = @group1 | ** = @group1 | ||||
[acl.deny] | [acl.deny] | ||||
foo/Bar/** = @group1 | foo/Bar/** = @group1 | ||||
No branch acls specified | No branch acls specified | ||||
$ do_push astro | $ do_push astro | ||||
Pushing as user astro | Pushing as user astro | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
query 1; heads | query 1; heads | ||||
searching for changes | searching for changes | ||||
$ echo "[acl.deny.branches]" >> $config | $ echo "[acl.deny.branches]" >> $config | ||||
$ echo "foobar = *" >> $config | $ echo "foobar = *" >> $config | ||||
$ do_push astro | $ do_push astro | ||||
Pushing as user astro | Pushing as user astro | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.deny.branches] | [acl.deny.branches] | ||||
foobar = * | foobar = * | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
$ init_config | $ init_config | ||||
$ echo "[acl.allow.branches]" >> $config | $ echo "[acl.allow.branches]" >> $config | ||||
$ do_push astro | $ do_push astro | ||||
Pushing as user astro | Pushing as user astro | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow.branches] | [acl.allow.branches] | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
query 1; heads | query 1; heads | ||||
$ init_config | $ init_config | ||||
$ echo "[acl.allow.branches]" >> $config | $ echo "[acl.allow.branches]" >> $config | ||||
$ echo "* = george" >> $config | $ echo "* = george" >> $config | ||||
$ do_push astro | $ do_push astro | ||||
Pushing as user astro | Pushing as user astro | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow.branches] | [acl.allow.branches] | ||||
* = george | * = george | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
no rollback information available | no rollback information available | ||||
2:fb35475503ef | 2:fb35475503ef | ||||
$ do_push george | $ do_push george | ||||
Pushing as user george | Pushing as user george | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow.branches] | [acl.allow.branches] | ||||
* = george | * = george | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
$ echo "[acl.allow.branches]" >> $config | $ echo "[acl.allow.branches]" >> $config | ||||
$ echo "foobar = astro" >> $config | $ echo "foobar = astro" >> $config | ||||
$ echo "* = george" >> $config | $ echo "* = george" >> $config | ||||
$ do_push george | $ do_push george | ||||
Pushing as user george | Pushing as user george | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.allow.branches] | [acl.allow.branches] | ||||
foobar = astro | foobar = astro | ||||
* = george | * = george | ||||
""" | """ | ||||
$ echo "foobar = astro" >> $config | $ echo "foobar = astro" >> $config | ||||
$ echo "default = astro" >> $config | $ echo "default = astro" >> $config | ||||
$ echo "* = george" >> $config | $ echo "* = george" >> $config | ||||
$ do_push george | $ do_push george | ||||
Pushing as user george | Pushing as user george | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.deny.branches] | [acl.deny.branches] | ||||
foobar = astro | foobar = astro | ||||
default = astro | default = astro | ||||
* = george | * = george | ||||
$ init_config | $ init_config | ||||
$ echo "[acl.deny.branches]" >> $config | $ echo "[acl.deny.branches]" >> $config | ||||
$ echo "default = !astro" >> $config | $ echo "default = !astro" >> $config | ||||
$ do_push astro | $ do_push astro | ||||
Pushing as user astro | Pushing as user astro | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.deny.branches] | [acl.deny.branches] | ||||
default = !astro | default = !astro | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b | ||||
Non-astro users must be denied | Non-astro users must be denied | ||||
$ do_push george | $ do_push george | ||||
Pushing as user george | Pushing as user george | ||||
hgrc = """ | hgrc = """ | ||||
[hooks] | [hooks] | ||||
pretxnchangegroup.acl = python:hgext.acl.hook | pretxnchangegroup.acl = python:hgext.acl.hook | ||||
prepushkey.acl = python:hgext.acl.hook | |||||
[acl] | [acl] | ||||
sources = push | sources = push | ||||
[extensions] | [extensions] | ||||
posixgetuser=$TESTTMP/posixgetuser.py | posixgetuser=$TESTTMP/posixgetuser.py | ||||
[acl.deny.branches] | [acl.deny.branches] | ||||
default = !astro | default = !astro | ||||
""" | """ | ||||
pushing to ../b | pushing to ../b |