--- a/access.py Tue Apr 22 10:27:43 2008 +0100
+++ b/access.py Tue Apr 22 13:03:17 2008 +0100
@@ -13,7 +13,7 @@
from mercurial import util
import os
-import rules
+import ruleset
class Checker(object):
'''acl checker.'''
@@ -21,7 +21,7 @@
def __init__(self, ui, repo):
self.ui = ui
self.repo = repo
- self.rules = rules.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
+ self.rules = ruleset.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
self.rules.set(user = os.environ['REMOTE_USER'])
self.rules.set(repo = os.environ['HG_REPO_PATH'])
--- a/hg-ssh Tue Apr 22 10:27:43 2008 +0100
+++ b/hg-ssh Tue Apr 22 13:03:17 2008 +0100
@@ -34,7 +34,7 @@
from mercurial import dispatch
import sys, os
-import rules
+import ruleset
def fail(message):
#logfile.write("Fail: %s\n" % message)
@@ -44,7 +44,7 @@
def getpath(path):
if path.endswith("/"):
path = path[:-1]
- if not rules.goodpath(path):
+ if not ruleset.goodpath(path):
fail("Disallowing path: %s" % path)
return path
@@ -68,7 +68,7 @@
fail("hg-ssh must have no arguments (%s)"
% sys.argv)
-rules = rules.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
+rules = ruleset.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
rules.set(remoteuser = getpath(os.environ['REMOTE_USER']))
rules.set(branch = None, file = None)
todispatch = get_cmd(rules,
--- a/rules.py Tue Apr 22 10:27:43 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-# Copyright 2008 LShift Ltd
-# Author(s):
-# Paul Crowley <paul@lshift.net>
-#
-# This software may be used and distributed according to the terms
-# of the GNU General Public License, incorporated herein by reference.
-
-import re
-
-allowedchars = "A-Za-z0-9_-"
-
-goodpathre = re.compile("([%s]+/)*[%s]+$" % (allowedchars, allowedchars))
-def goodpath(path):
- return goodpathre.match(path) is not None:
-
-goodglobre = re.compile("[*/%s]+$" % allowedchars)
-
-def goodglob(pattern):
- return goodglobre.match(pattern) is not None
-
-# Don't put anything except *A-Za-z0-9_- in rule globs or
-# it will match nothing. No regexp metachars, not even .
-# We may fix this later.
-def globmatcher(pattern):
- if not goodglob(pattern):
- #fail("Bad glob pattern in auth config: %s" % pattern)
- # FIXME: report it somehow
- return lambda x: False
- # Substitution cunning so ** can be different from *
- pattern = pattern.replace("*", "[]")
- pattern = pattern.replace("[][]", "[/%s]*" % allowedchars)
- pattern = pattern.replace("[]", "[%s]*" % allowedchars)
- rex = re.compile(pattern + "$")
- # None matches everything
- return lambda x: x is None or rex.match(x) is not None
-
-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 or not m(kw[k]):
- return False
- return True
- 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 matchrule(self, **kw):
- d = self.preset.copy()
- d.update(**kw)
- for a, c in self.rules:
- if c(**d):
- return a
- return None
-
- def allow(self, level, **kw):
- a = matchrule(self, **kw)
- return a in self.levels and self.levels.index(a) <= self.levels.index(level)
-
- @classmethod
- def read_rules(cls, fn):
- res = cls()
- f = open(fn)
- try:
- for l in f:
- l = l.strip()
- if len(l) == 0 or l.startswith["#"]:
- continue
- res.add(l[0], rule([c.split("=", 1) for c in l[1:]]))
- finally:
- f.close()
- return res
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ruleset.py Tue Apr 22 13:03:17 2008 +0100
@@ -0,0 +1,87 @@
+# Copyright 2008 LShift Ltd
+# Author(s):
+# Paul Crowley <paul@lshift.net>
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+
+import re
+
+allowedchars = "A-Za-z0-9_-"
+
+goodpathre = re.compile("([%s]+/)*[%s]+$" % (allowedchars, allowedchars))
+def goodpath(path):
+ return goodpathre.match(path) is not None
+
+goodglobre = re.compile("[*/%s]+$" % allowedchars)
+
+def goodglob(pattern):
+ return goodglobre.match(pattern) is not None
+
+# Don't put anything except *A-Za-z0-9_- in rule globs or
+# it will match nothing. No regexp metachars, not even .
+# We may fix this later.
+def globmatcher(pattern):
+ if not goodglob(pattern):
+ #fail("Bad glob pattern in auth config: %s" % pattern)
+ # FIXME: report it somehow
+ return lambda x: False
+ # Substitution cunning so ** can be different from *
+ pattern = pattern.replace("*", "[]")
+ pattern = pattern.replace("[][]", "[/%s]*" % allowedchars)
+ pattern = pattern.replace("[]", "[%s]*" % allowedchars)
+ rex = re.compile(pattern + "$")
+ # None matches everything
+ return lambda x: x is None or rex.match(x) is not None
+
+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 or not m(kw[k]):
+ return False
+ return True
+ 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 matchrule(self, **kw):
+ d = self.preset.copy()
+ d.update(**kw)
+ for a, c in self.rules:
+ if c(**d):
+ return a
+ return None
+
+ def allow(self, level, **kw):
+ a = self.matchrule(**kw)
+ return a in self.levels and self.levels.index(a) <= self.levels.index(level)
+
+ @classmethod
+ def readfile(cls, fn):
+ res = cls()
+ f = open(fn)
+ try:
+ for l in f:
+ l = l.strip()
+ if len(l) == 0 or l.startswith("#"):
+ continue
+ l = l.split()
+ res.add(l[0], rule([c.split("=", 1) for c in l[1:]]))
+ finally:
+ f.close()
+ return res