--- a/src/mercurialserver/ruleset.py Sun Dec 19 09:49:18 2010 +0000
+++ b/src/mercurialserver/ruleset.py Tue Sep 06 11:16:58 2011 +0100
@@ -13,63 +13,56 @@
# ** means "match recursively" ie "ignore directories"
return re.compile(p.replace("[^/]*[^/]*", ".*") + "$")
-# Returns True for a definite match
-# False for a definite non-match
-# None where we can't be sure because a key is None
+# Returns 1 for a definite match
+# -1 for a definite non-match
+# 0 where we can't be sure because a key is None
+def rmatch(k, m, kw):
+ if k not in kw:
+ return -1
+ kkw = kw[k]
+ if kkw is None:
+ return 0
+ elif m.match(kkw) is None:
+ return -1
+ else:
+ return 1
+
def rule(pairs):
matchers = [(k, globmatcher(v)) for k, v in pairs]
def c(kw):
- for k, m in matchers:
- if k not in kw:
- return False
- kkw = kw[k]
- if kkw is None:
- return None
- if m.match(kkw) is None:
- return False
- return True
+ return min(rmatch(k, m, kw) for k, m in matchers)
return c
class Ruleset(object):
'''Class representing the rules in a rule file'''
-
+
levels = ["init", "write", "read", "deny"]
def __init__(self):
self.rules = []
self.preset = {}
- def add(self, action, conditions):
- self.rules.append((action, conditions))
-
def set(self, **kw):
self.preset.update(kw)
-
+
def get(self, k):
return self.preset.get(k, None)
-
- def matchrules(self, kw):
+
+ def allow(self, level, **kw):
+ levelindex = self.levels.index(level)
d = self.preset.copy()
d.update(kw)
- res = set()
for a, c in self.rules:
m = c(d)
- if m is None:
- # "Maybe match" - add it and carry on
- res.add(a)
- elif m:
- # Definite match - add it and stop
- res.add(a)
- break
- return res
-
- def allow(self, level, **kw):
- for a in self.matchrules(kw):
- if a in self.levels:
- if self.levels.index(a) <= self.levels.index(level):
+ if m == 1:
+ # Definite match - what it says goes
+ return a <= levelindex
+ elif m == 0:
+ # "Maybe match" - allow if it says yes, ignore if no
+ if a <= levelindex:
return True
return False
-
+
def readfile(self, fn):
f = open(fn)
try:
@@ -78,9 +71,14 @@
if len(l) == 0 or l.startswith("#"):
continue
l = l.split()
- self.add(l[0], rule([c.split("=", 1) for c in l[1:]]))
+ # Unrecognized actions are off the high end
+ if l[0] in self.levels:
+ ix = self.levels.index(l[0])
+ else:
+ ix = len(self.levels)
+ self.rules.append((ix,
+ rule([c.split("=", 1) for c in l[1:]])))
finally:
f.close()
rules = Ruleset()
-