src/mercurialserver/ruleset.py
author Paul Crowley <paul@lshift.net>
Mon, 12 Oct 2009 17:04:26 +0100
changeset 109 72100d3ed1bd
parent 106 0519745e7a57
child 237 d30f3f312ece
permissions -rw-r--r--
Don't mix exceptions and sys.exit based failures
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50
77d97aa18f29 update dates and copyright notices
Paul Crowley <paul@lshift.net>
parents: 48
diff changeset
     1
# Copyright 2008-2009 LShift Ltd
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     2
# Author(s):
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     3
# Paul Crowley <paul@lshift.net>
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     4
#
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     7
32
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
     8
import sys
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     9
import re
39
f5055ce263c7 New system. No breaking in, just putting files in /etc/mercurial-server
Paul Crowley <paul@lshift.net>
parents: 33
diff changeset
    10
import os
f5055ce263c7 New system. No breaking in, just putting files in /etc/mercurial-server
Paul Crowley <paul@lshift.net>
parents: 33
diff changeset
    11
import os.path
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    12
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    13
allowedchars = "A-Za-z0-9_-"
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    14
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    15
def globmatcher(pattern):
106
0519745e7a57 Much less strict about most things
Paul Crowley <paul@lshift.net>
parents: 78
diff changeset
    16
    p = "[^/]*".join(re.escape(c) for c in pattern.split("*"))
0519745e7a57 Much less strict about most things
Paul Crowley <paul@lshift.net>
parents: 78
diff changeset
    17
    # ** means "match recursively" ie "ignore directories"
0519745e7a57 Much less strict about most things
Paul Crowley <paul@lshift.net>
parents: 78
diff changeset
    18
    rex = re.compile(p.replace("[^/]*[^/]*", ".*") + "$")
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    19
    # None matches everything
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    20
    return lambda x: x is None or rex.match(x) is not None
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    21
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    22
def rule(pairs):
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    23
    matchers = [(k, globmatcher(v)) for k, v in pairs]
48
f0cb7ad9e4ab Don't use keyword arguments everywhere
Paul Crowley <paul@lshift.net>
parents: 45
diff changeset
    24
    def c(kw):
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    25
        for k, m in matchers:
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    26
            if k not in kw or not m(kw[k]):
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    27
                return False
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    28
        return True
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    29
    return c
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    30
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    31
class Ruleset(object):
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    32
    '''Class representing the rules in a rule file'''
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    33
    
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    34
    levels = ["init", "write", "read", "deny"]
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    35
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    36
    def __init__(self):
48
f0cb7ad9e4ab Don't use keyword arguments everywhere
Paul Crowley <paul@lshift.net>
parents: 45
diff changeset
    37
        self.rules = []
21
59540181a4bb simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents: 18
diff changeset
    38
        self.preset = {}
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    39
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    40
    def add(self, action, conditions):
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    41
        self.rules.append((action, conditions))
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    42
21
59540181a4bb simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents: 18
diff changeset
    43
    def set(self, **kw):
59540181a4bb simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents: 18
diff changeset
    44
        self.preset.update(kw)
59540181a4bb simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents: 18
diff changeset
    45
        
78
2a3407a14654 Replaced env vars with Python globals
Paul Crowley <paul@lshift.net>
parents: 77
diff changeset
    46
    def get(self, k):
2a3407a14654 Replaced env vars with Python globals
Paul Crowley <paul@lshift.net>
parents: 77
diff changeset
    47
        return self.preset.get(k, None)
2a3407a14654 Replaced env vars with Python globals
Paul Crowley <paul@lshift.net>
parents: 77
diff changeset
    48
        
48
f0cb7ad9e4ab Don't use keyword arguments everywhere
Paul Crowley <paul@lshift.net>
parents: 45
diff changeset
    49
    def matchrule(self, kw):
21
59540181a4bb simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents: 18
diff changeset
    50
        d = self.preset.copy()
48
f0cb7ad9e4ab Don't use keyword arguments everywhere
Paul Crowley <paul@lshift.net>
parents: 45
diff changeset
    51
        d.update(kw)
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    52
        for a, c in self.rules:
48
f0cb7ad9e4ab Don't use keyword arguments everywhere
Paul Crowley <paul@lshift.net>
parents: 45
diff changeset
    53
            if c(d):
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    54
                return a
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    55
        return None
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    56
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    57
    def allow(self, level, **kw):
48
f0cb7ad9e4ab Don't use keyword arguments everywhere
Paul Crowley <paul@lshift.net>
parents: 45
diff changeset
    58
        a = self.matchrule(kw)
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    59
        return a in self.levels and self.levels.index(a) <= self.levels.index(level)
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    60
    
39
f5055ce263c7 New system. No breaking in, just putting files in /etc/mercurial-server
Paul Crowley <paul@lshift.net>
parents: 33
diff changeset
    61
    def readfile(self, fn):
18
538d6b198f4a Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    62
        try:
32
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    63
            f = open(fn)
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    64
            try:
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    65
                for l in f:
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    66
                    l = l.strip()
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    67
                    if len(l) == 0 or l.startswith("#"):
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    68
                        continue
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    69
                    l = l.split()
39
f5055ce263c7 New system. No breaking in, just putting files in /etc/mercurial-server
Paul Crowley <paul@lshift.net>
parents: 33
diff changeset
    70
                    self.add(l[0], rule([c.split("=", 1) for c in l[1:]]))
32
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    71
            finally:
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    72
                f.close()
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    73
        except Exception, e:
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    74
            print >> sys.stderr, "Failure reading rules file:", e
4059dbe9f26a new break-in system
Paul Crowley <paul@lshift.net>
parents: 23
diff changeset
    75
77
8d14aac93b5d Most of the way through abolishing env vars
Paul Crowley <paul@lshift.net>
parents: 67
diff changeset
    76
rules = Ruleset()
8d14aac93b5d Most of the way through abolishing env vars
Paul Crowley <paul@lshift.net>
parents: 67
diff changeset
    77