##// END OF EJS Templates
acl: read correct index into url for username (issue298)...
Henrik Stuart -
r9018:5ed463d0 default
parent child Browse files
Show More
@@ -1,107 +1,107 b''
1 1 # acl.py - changeset access control for mercurial
2 2 #
3 3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2, incorporated herein by reference.
7 7 #
8 8
9 9 '''hooks for controlling repository access
10 10
11 11 This hook makes it possible to allow or deny write access to portions
12 12 of a repository when receiving incoming changesets.
13 13
14 14 The authorization is matched based on the local user name on the
15 15 system where the hook runs, and not the committer of the original
16 16 changeset (since the latter is merely informative).
17 17
18 18 The acl hook is best used along with a restricted shell like hgsh,
19 19 preventing authenticating users from doing anything other than
20 20 pushing or pulling. The hook is not safe to use if users have
21 21 interactive shell access, as they can then disable the hook.
22 22 Nor is it safe if remote users share an account, because then there
23 23 is no way to distinguish them.
24 24
25 25 To use this hook, configure the acl extension in your hgrc like this:
26 26
27 27 [extensions]
28 28 hgext.acl =
29 29
30 30 [hooks]
31 31 pretxnchangegroup.acl = python:hgext.acl.hook
32 32
33 33 [acl]
34 34 # Check whether the source of incoming changes is in this list
35 35 # ("serve" == ssh or http, "push", "pull", "bundle")
36 36 sources = serve
37 37
38 38 The allow and deny sections take a subtree pattern as key (with a
39 39 glob syntax by default), and a comma separated list of users as
40 40 the corresponding value. The deny list is checked before the allow
41 41 list is.
42 42
43 43 [acl.allow]
44 44 # If acl.allow is not present, all users are allowed by default.
45 45 # An empty acl.allow section means no users allowed.
46 46 docs/** = doc_writer
47 47 .hgtags = release_engineer
48 48
49 49 [acl.deny]
50 50 # If acl.deny is not present, no users are refused by default.
51 51 # An empty acl.deny section means all users allowed.
52 52 glob pattern = user4, user5
53 53 ** = user6
54 54 '''
55 55
56 56 from mercurial.i18n import _
57 57 from mercurial import util, match
58 58 import getpass, urllib
59 59
60 60 def buildmatch(ui, repo, user, key):
61 61 '''return tuple of (match function, list enabled).'''
62 62 if not ui.has_section(key):
63 63 ui.debug(_('acl: %s not enabled\n') % key)
64 64 return None
65 65
66 66 pats = [pat for pat, users in ui.configitems(key)
67 67 if user in users.replace(',', ' ').split()]
68 68 ui.debug(_('acl: %s enabled, %d entries for user %s\n') %
69 69 (key, len(pats), user))
70 70 if pats:
71 71 return match.match(repo.root, '', pats)
72 72 return match.exact(repo.root, '', [])
73 73
74 74
75 75 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
76 76 if hooktype != 'pretxnchangegroup':
77 77 raise util.Abort(_('config error - hook type "%s" cannot stop '
78 78 'incoming changesets') % hooktype)
79 79 if source not in ui.config('acl', 'sources', 'serve').split():
80 80 ui.debug(_('acl: changes have source "%s" - skipping\n') % source)
81 81 return
82 82
83 83 user = None
84 84 if source == 'serve' and 'url' in kwargs:
85 85 url = kwargs['url'].split(':')
86 86 if url[0] == 'remote' and url[1].startswith('http'):
87 user = urllib.unquote(url[2])
87 user = urllib.unquote(url[3])
88 88
89 89 if user is None:
90 90 user = getpass.getuser()
91 91
92 92 cfg = ui.config('acl', 'config')
93 93 if cfg:
94 94 ui.readconfig(cfg, sections = ['acl.allow', 'acl.deny'])
95 95 allow = buildmatch(ui, repo, user, 'acl.allow')
96 96 deny = buildmatch(ui, repo, user, 'acl.deny')
97 97
98 98 for rev in xrange(repo[node], len(repo)):
99 99 ctx = repo[rev]
100 100 for f in ctx.files():
101 101 if deny and deny(f):
102 102 ui.debug(_('acl: user %s denied on %s\n') % (user, f))
103 103 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
104 104 if allow and not allow(f):
105 105 ui.debug(_('acl: user %s not allowed on %s\n') % (user, f))
106 106 raise util.Abort(_('acl: access denied for changeset %s') % ctx)
107 107 ui.debug(_('acl: allowing changeset %s\n') % ctx)
General Comments 0
You need to be logged in to leave comments. Login now