Mercurial > hg
annotate hgext/acl.py @ 10445:8b45102934e2
commands: support verbose help
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Sat, 13 Feb 2010 18:36:24 +0100 |
parents | 25e572394f5c |
children | fcfe2e50faab |
rev | line source |
---|---|
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
1 # acl.py - changeset access control for mercurial |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
2 # |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8142
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
7 |
8935
f4f0e902b750
extensions: change descriptions for hook-providing extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8894
diff
changeset
|
8 '''hooks for controlling repository access |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
9 |
9250
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
10 This hook makes it possible to allow or deny write access to portions |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
11 of a repository when receiving incoming changesets. |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
12 |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
13 The authorization is matched based on the local user name on the |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
14 system where the hook runs, and not the committer of the original |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
15 changeset (since the latter is merely informative). |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
16 |
9250
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
17 The acl hook is best used along with a restricted shell like hgsh, |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
18 preventing authenticating users from doing anything other than |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
19 pushing or pulling. The hook is not safe to use if users have |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
20 interactive shell access, as they can then disable the hook. |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
21 Nor is it safe if remote users share an account, because then there |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
22 is no way to distinguish them. |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
23 |
9201
3d6c9659886b
acl: use reST syntax for literal blocks
Martin Geisler <mg@lazybytes.net>
parents:
9052
diff
changeset
|
24 To use this hook, configure the acl extension in your hgrc like this:: |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
25 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
26 [extensions] |
10112
703db37d186b
hgext: enable extensions without "hgext." prefix in help texts
Martin Geisler <mg@lazybytes.net>
parents:
9467
diff
changeset
|
27 acl = |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
28 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
29 [hooks] |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
30 pretxnchangegroup.acl = python:hgext.acl.hook |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
31 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
32 [acl] |
8893 | 33 # Check whether the source of incoming changes is in this list |
34 # ("serve" == ssh or http, "push", "pull", "bundle") | |
35 sources = serve | |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
36 |
9250
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
37 The allow and deny sections take a subtree pattern as key (with a glob |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
38 syntax by default), and a comma separated list of users as the |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
39 corresponding value. The deny list is checked before the allow list |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
40 is. :: |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
41 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
42 [acl.allow] |
8893 | 43 # If acl.allow is not present, all users are allowed by default. |
44 # An empty acl.allow section means no users allowed. | |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
45 docs/** = doc_writer |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
46 .hgtags = release_engineer |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
47 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
48 [acl.deny] |
8893 | 49 # If acl.deny is not present, no users are refused by default. |
50 # An empty acl.deny section means all users allowed. | |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
51 glob pattern = user4, user5 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
52 ** = user6 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
53 ''' |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
54 |
3891 | 55 from mercurial.i18n import _ |
8566
744d6322b05b
match: change all users of util.matcher to match.match
Matt Mackall <mpm@selenic.com>
parents:
8225
diff
changeset
|
56 from mercurial import util, match |
8846
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
57 import getpass, urllib |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
58 |
6766 | 59 def buildmatch(ui, repo, user, key): |
60 '''return tuple of (match function, list enabled).''' | |
61 if not ui.has_section(key): | |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9250
diff
changeset
|
62 ui.debug('acl: %s not enabled\n' % key) |
6766 | 63 return None |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
64 |
6766 | 65 pats = [pat for pat, users in ui.configitems(key) |
66 if user in users.replace(',', ' ').split()] | |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9250
diff
changeset
|
67 ui.debug('acl: %s enabled, %d entries for user %s\n' % |
6766 | 68 (key, len(pats), user)) |
69 if pats: | |
8567
fea40a677d43
match: add some default args
Matt Mackall <mpm@selenic.com>
parents:
8566
diff
changeset
|
70 return match.match(repo.root, '', pats) |
8682 | 71 return match.exact(repo.root, '', []) |
8566
744d6322b05b
match: change all users of util.matcher to match.match
Matt Mackall <mpm@selenic.com>
parents:
8225
diff
changeset
|
72 |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
73 |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
74 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
75 if hooktype != 'pretxnchangegroup': |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
76 raise util.Abort(_('config error - hook type "%s" cannot stop ' |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
77 'incoming changesets') % hooktype) |
6766 | 78 if source not in ui.config('acl', 'sources', 'serve').split(): |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9250
diff
changeset
|
79 ui.debug('acl: changes have source "%s" - skipping\n' % source) |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
80 return |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
81 |
8846
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
82 user = None |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
83 if source == 'serve' and 'url' in kwargs: |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
84 url = kwargs['url'].split(':') |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
85 if url[0] == 'remote' and url[1].startswith('http'): |
9018
5ed463d0ebdb
acl: read correct index into url for username (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8935
diff
changeset
|
86 user = urllib.unquote(url[3]) |
8846
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
87 |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
88 if user is None: |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
89 user = getpass.getuser() |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
90 |
6766 | 91 cfg = ui.config('acl', 'config') |
92 if cfg: | |
8142
912bfef12ba6
ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents:
6766
diff
changeset
|
93 ui.readconfig(cfg, sections = ['acl.allow', 'acl.deny']) |
6766 | 94 allow = buildmatch(ui, repo, user, 'acl.allow') |
95 deny = buildmatch(ui, repo, user, 'acl.deny') | |
96 | |
97 for rev in xrange(repo[node], len(repo)): | |
98 ctx = repo[rev] | |
99 for f in ctx.files(): | |
100 if deny and deny(f): | |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9250
diff
changeset
|
101 ui.debug('acl: user %s denied on %s\n' % (user, f)) |
6766 | 102 raise util.Abort(_('acl: access denied for changeset %s') % ctx) |
103 if allow and not allow(f): | |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9250
diff
changeset
|
104 ui.debug('acl: user %s not allowed on %s\n' % (user, f)) |
6766 | 105 raise util.Abort(_('acl: access denied for changeset %s') % ctx) |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9250
diff
changeset
|
106 ui.debug('acl: allowing changeset %s\n' % ctx) |