author | Paul Crowley <paul@ciphergoth.org> |
Mon, 21 Apr 2008 12:37:56 +0100 | |
changeset 17 | 4c98440de851 |
child 18 | 538d6b198f4a |
permissions | -rw-r--r-- |
17
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
1 |
# Copyright 2008 Paul Crowley <paul@lshift.net> |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
2 |
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
3 |
# |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
4 |
# This software may be used and distributed according to the terms |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
5 |
# of the GNU General Public License, incorporated herein by reference. |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
6 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
7 |
from mercurial.i18n import _ |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
8 |
from mercurial.node import * |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
9 |
from mercurial import util |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
10 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
11 |
import os |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
12 |
import re |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
13 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
14 |
allowedchars = "A-Za-z0-9_-" |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
15 |
goodglobre = re.compile("[*/%s]+$" % allowedchars) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
16 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
17 |
# Don't put anything except *A-Za-z0-9_- in rule globs or |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
18 |
# it will match nothing. No regexp metachars, not even . |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
19 |
# We may fix this later. |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
20 |
def globmatcher(pattern): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
21 |
if not goodglobre.match(pattern): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
22 |
#fail("Bad glob pattern in auth config: %s" % pattern) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
23 |
# FIXME: report it somehow |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
24 |
return lambda x: False |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
25 |
pattern = pattern.replace("*", "[]") |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
26 |
pattern = pattern.replace("[][]", "[/%s]*" % allowedchars) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
27 |
pattern = pattern.replace("[]", "[%s]*" % allowedchars) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
28 |
rex = re.compile(pattern + "$") |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
29 |
return lambda x: rex.match(x) is not None |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
30 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
31 |
def rule(pairs): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
32 |
matchers = [(k, globmatcher(v)) for k, v in pairs] |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
33 |
def c(**kw): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
34 |
for k, m in matchers: |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
35 |
if k not in kw or not m(kw[k]): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
36 |
return False |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
37 |
return True |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
38 |
return c |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
39 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
40 |
class Rulefile(object): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
41 |
'''Class representing the rules in a rule file''' |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
42 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
43 |
self.levels = ["init", "write", "read", "deny"] |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
44 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
45 |
def __init__(self): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
46 |
self.rules = [] |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
47 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
48 |
def add(self, action, conditions): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
49 |
self.rules.append((action, conditions)) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
50 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
51 |
def matchrule(self, **kw): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
52 |
for a, c in self.rules: |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
53 |
if c(**kw): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
54 |
return a |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
55 |
return None |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
56 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
57 |
def allow(self, level, **kw): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
58 |
a = matchrule(self, **kw) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
59 |
return a in self.levels and self.levels.index(a) <= self.levels.index(level) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
60 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
61 |
def read_rules(fn): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
62 |
res = Rulefile() |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
63 |
f = open(fn) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
64 |
try: |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
65 |
for l in f: |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
66 |
l = l.strip() |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
67 |
if len(l) == 0 or l.startswith["#"]: |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
68 |
continue |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
69 |
res.add(l[0], rule([c.split("=", 1) for c in l[1:]])) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
70 |
finally: |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
71 |
f.close() |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
72 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
73 |
class Checker(object): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
74 |
'''acl checker.''' |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
75 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
76 |
def getuser(self): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
77 |
'''return name of hg-ssh user''' |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
78 |
return os.environ['REMOTE_USER'] |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
79 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
80 |
def __init__(self, ui, repo): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
81 |
self.ui = ui |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
82 |
self.repo = repo |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
83 |
self.rules = read_rules(os.environ['HG_ACCESS_RULES_FILE']) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
84 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
85 |
def check(self, node): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
86 |
'''return if access allowed, raise exception if not.''' |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
87 |
files = self.repo.changectx(node).files() |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
88 |
for f in files: |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
89 |
if not self.rules.allow("write", user=self.user, ): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
90 |
self.ui.debug(_('%s: user %s not allowed on %s\n') % |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
91 |
(__name__, self.getuser(), f)) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
92 |
raise util.Abort(_('%s: access denied for changeset %s') % |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
93 |
(__name__, short(node))) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
94 |
self.ui.debug(_('%s: allowing changeset %s\n') % (__name__, short(node))) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
95 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
96 |
def hook(ui, repo, hooktype, node=None, source=None, **kwargs): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
97 |
if hooktype != 'pretxnchangegroup': |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
98 |
raise util.Abort(_('config error - hook type "%s" cannot stop ' |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
99 |
'incoming changesets') % hooktype) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
100 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
101 |
c = checker(ui, repo) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
102 |
|
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
103 |
start = repo.changelog.rev(bin(node)) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
104 |
end = repo.changelog.count() |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
105 |
for rev in xrange(start, end): |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
106 |
c.check(repo.changelog.node(rev)) |
4c98440de851
Started work on acl.py replacement - currently broken.
Paul Crowley <paul@ciphergoth.org>
parents:
diff
changeset
|
107 |