Mercurial > hg
annotate hgext/acl.py @ 9333:4e7149ed98e8
Merge with crew-stable.
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Mon, 10 Aug 2009 23:27:08 +0200 |
parents | 00986b9ed649 |
children | 4c041f1ee1b4 |
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 |
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8142
diff
changeset
|
6 # GNU General Public License version 2, incorporated herein by reference. |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
7 # |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
8 |
8935
f4f0e902b750
extensions: change descriptions for hook-providing extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8894
diff
changeset
|
9 '''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
|
10 |
9250
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
11 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
|
12 of a repository when receiving incoming changesets. |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
13 |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
14 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
|
15 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
|
16 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
|
17 |
9250
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
18 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
|
19 preventing authenticating users from doing anything other than |
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
20 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
|
21 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
|
22 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
|
23 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
|
24 |
9201
3d6c9659886b
acl: use reST syntax for literal blocks
Martin Geisler <mg@lazybytes.net>
parents:
9052
diff
changeset
|
25 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
|
26 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
27 [extensions] |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
28 hgext.acl = |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
29 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
30 [hooks] |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
31 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
|
32 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
33 [acl] |
8893 | 34 # Check whether the source of incoming changes is in this list |
35 # ("serve" == ssh or http, "push", "pull", "bundle") | |
36 sources = serve | |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
37 |
9250
00986b9ed649
acl: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents:
9201
diff
changeset
|
38 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
|
39 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
|
40 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
|
41 is. :: |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
42 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
43 [acl.allow] |
8893 | 44 # If acl.allow is not present, all users are allowed by default. |
45 # 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
|
46 docs/** = doc_writer |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
47 .hgtags = release_engineer |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
48 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
49 [acl.deny] |
8893 | 50 # If acl.deny is not present, no users are refused by default. |
51 # 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
|
52 glob pattern = user4, user5 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
53 ** = user6 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
54 ''' |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
55 |
3891 | 56 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
|
57 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
|
58 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
|
59 |
6766 | 60 def buildmatch(ui, repo, user, key): |
61 '''return tuple of (match function, list enabled).''' | |
62 if not ui.has_section(key): | |
63 ui.debug(_('acl: %s not enabled\n') % key) | |
64 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
|
65 |
6766 | 66 pats = [pat for pat, users in ui.configitems(key) |
67 if user in users.replace(',', ' ').split()] | |
68 ui.debug(_('acl: %s enabled, %d entries for user %s\n') % | |
69 (key, len(pats), user)) | |
70 if pats: | |
8567
fea40a677d43
match: add some default args
Matt Mackall <mpm@selenic.com>
parents:
8566
diff
changeset
|
71 return match.match(repo.root, '', pats) |
8682 | 72 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
|
73 |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
74 |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
75 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
|
76 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
|
77 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
|
78 'incoming changesets') % hooktype) |
6766 | 79 if source not in ui.config('acl', 'sources', 'serve').split(): |
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 ui.debug(_('acl: changes have source "%s" - skipping\n') % source) |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
81 return |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
82 |
8846
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
83 user = None |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
84 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
|
85 url = kwargs['url'].split(':') |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
86 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
|
87 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
|
88 |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
89 if user is None: |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
90 user = getpass.getuser() |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
91 |
6766 | 92 cfg = ui.config('acl', 'config') |
93 if cfg: | |
8142
912bfef12ba6
ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents:
6766
diff
changeset
|
94 ui.readconfig(cfg, sections = ['acl.allow', 'acl.deny']) |
6766 | 95 allow = buildmatch(ui, repo, user, 'acl.allow') |
96 deny = buildmatch(ui, repo, user, 'acl.deny') | |
97 | |
98 for rev in xrange(repo[node], len(repo)): | |
99 ctx = repo[rev] | |
100 for f in ctx.files(): | |
101 if deny and deny(f): | |
102 ui.debug(_('acl: user %s denied on %s\n') % (user, f)) | |
103 raise util.Abort(_('acl: access denied for changeset %s') % ctx) | |
104 if allow and not allow(f): | |
105 ui.debug(_('acl: user %s not allowed on %s\n') % (user, f)) | |
106 raise util.Abort(_('acl: access denied for changeset %s') % ctx) | |
107 ui.debug(_('acl: allowing changeset %s\n') % ctx) |