ACL implementation. Current features:
[invirt/packages/python-afs.git] / afs / acl.py
1 import _acl
2 from _acl import READ, WRITE, INSERT, LOOKUP, DELETE, LOCK, ADMINISTER, \
3     USR0, USR1, USR2, USR3, USR4, USR5, USR6, USR7
4 from _acl import getCallerAccess
5
6 _canonical = {
7     "read":     "rl",
8     "write":    "rwlidwk",
9     "all":      "rwlidwka",
10     "mail":     "lik",
11     "none":     "",
12 }
13 _char2bit = {
14     'r': READ,
15     'w': WRITE,
16     'i': INSERT,
17     'l': LOOKUP,
18     'd': DELETE,
19     'k': LOCK,
20     'a': ADMINISTER,
21     'A': USR0,
22     'B': USR1,
23     'C': USR2,
24     'D': USR3,
25     'E': USR4,
26     'F': USR5,
27     'G': USR6,
28     'H': USR7,
29 }
30
31 _bit2char = dict([(v,k) for k,v in _char2bit.items()])
32
33 def crights(s):
34     """Canonicalizes string rights to bitmask"""
35     if s in _canonical: s = _canonical[s]
36     return _parseRights(s)
37
38 class ACL(object):
39     def __init__(self, pos, neg):
40         """
41         ``pos``
42             Dictionary of usernames to positive ACL bitmasks
43         ``neg``
44             Dictionary of usernames to negative ACL bitmasks
45         """
46         self.pos = pos
47         self.neg = neg
48     @staticmethod
49     def retrieve(dir):
50         """Retrieve the ACL for an AFS directory"""
51         pos, neg = _parseAcl(_acl.getAcl(dir))
52         return ACL(pos, neg)
53
54 def _parseRights(s):
55     """Parses a rwlid... rights tring to bitmask"""
56     r = 0
57     try:
58         for c in s:
59             r = r | _char2bit[c]
60     except KeyError:
61         raise ValueError
62     return r
63
64 def _parseAcl(inp):
65     lines = inp.split("\n")
66     npos = int(lines[0].split(" ")[0])
67     pos = {}
68     neg = {}
69     for l in lines[2:]:
70         if l == "": continue
71         name, acl = l.split()
72         if npos:
73             npos -= 1
74             pos[name] = int(acl)
75         else:
76             # negative acl
77             neg[name] = int(acl)
78     return (pos, neg)
79