Mercurial > public > mercurial-scm > hg
annotate hgext/acl.py @ 9052:1344e607180b
acl: wrapped docstrings at 78 characters
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Tue, 07 Jul 2009 23:54:42 +0200 |
parents | 5ed463d0ebdb |
children | 3d6c9659886b |
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 |
9052
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
11 This hook makes it possible to allow or deny write access to portions of a |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
12 repository when receiving incoming changesets. |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
13 |
9052
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
14 The authorization is matched based on the local user name on the system where |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
15 the hook runs, and not the committer of the original changeset (since the |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
16 latter is merely informative). |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
17 |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
18 The acl hook is best used along with a restricted shell like hgsh, preventing |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
19 authenticating users from doing anything other than pushing or pulling. The |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
20 hook is not safe to use if users have interactive shell access, as they can |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
21 then disable the hook. Nor is it safe if remote users share an account, |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
22 because then there 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 |
8893 | 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] |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
27 hgext.acl = |
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 |
9052
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
37 The allow and deny sections take a subtree pattern as key (with a glob syntax |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
38 by default), and a comma separated list of users as the corresponding value. |
1344e607180b
acl: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents:
9018
diff
changeset
|
39 The deny list is checked before the allow list is. |
8873
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
40 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
41 [acl.allow] |
8893 | 42 # If acl.allow is not present, all users are allowed by default. |
43 # 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
|
44 docs/** = doc_writer |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
45 .hgtags = release_engineer |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
46 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
47 [acl.deny] |
8893 | 48 # If acl.deny is not present, no users are refused by default. |
49 # 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
|
50 glob pattern = user4, user5 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
51 ** = user6 |
e872ef2e6758
help: add/fix docstrings for a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8846
diff
changeset
|
52 ''' |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
53 |
3891 | 54 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
|
55 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
|
56 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
|
57 |
6766 | 58 def buildmatch(ui, repo, user, key): |
59 '''return tuple of (match function, list enabled).''' | |
60 if not ui.has_section(key): | |
61 ui.debug(_('acl: %s not enabled\n') % key) | |
62 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
|
63 |
6766 | 64 pats = [pat for pat, users in ui.configitems(key) |
65 if user in users.replace(',', ' ').split()] | |
66 ui.debug(_('acl: %s enabled, %d entries for user %s\n') % | |
67 (key, len(pats), user)) | |
68 if pats: | |
8567
fea40a677d43
match: add some default args
Matt Mackall <mpm@selenic.com>
parents:
8566
diff
changeset
|
69 return match.match(repo.root, '', pats) |
8682 | 70 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
|
71 |
2344
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
72 |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
73 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
|
74 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
|
75 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
|
76 'incoming changesets') % hooktype) |
6766 | 77 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
|
78 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
|
79 return |
ae12e5a2c4a3
add acl extension, to limit who can push to subdirs of central repo.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
80 |
8846
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
81 user = None |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
82 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
|
83 url = kwargs['url'].split(':') |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
84 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
|
85 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
|
86 |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
87 if user is None: |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
88 user = getpass.getuser() |
b30775386d40
acl: support for getting authenticated user from web server (issue298)
Henrik Stuart <hg@hstuart.dk>
parents:
8682
diff
changeset
|
89 |
6766 | 90 cfg = ui.config('acl', 'config') |
91 if cfg: | |
8142
912bfef12ba6
ui: fold readsections into readconfig
Matt Mackall <mpm@selenic.com>
parents:
6766
diff
changeset
|
92 ui.readconfig(cfg, sections = ['acl.allow', 'acl.deny']) |
6766 | 93 allow = buildmatch(ui, repo, user, 'acl.allow') |
94 deny = buildmatch(ui, repo, user, 'acl.deny') | |
95 | |
96 for rev in xrange(repo[node], len(repo)): | |
97 ctx = repo[rev] | |
98 for f in ctx.files(): | |
99 if deny and deny(f): | |
100 ui.debug(_('acl: user %s denied on %s\n') % (user, f)) | |
101 raise util.Abort(_('acl: access denied for changeset %s') % ctx) | |
102 if allow and not allow(f): | |
103 ui.debug(_('acl: user %s not allowed on %s\n') % (user, f)) | |
104 raise util.Abort(_('acl: access denied for changeset %s') % ctx) | |
105 ui.debug(_('acl: allowing changeset %s\n') % ctx) |