ACL implementation. Current features:
[invirt/packages/python-afs.git] / afs / acl.py
diff --git a/afs/acl.py b/afs/acl.py
new file mode 100644 (file)
index 0000000..b5da255
--- /dev/null
@@ -0,0 +1,79 @@
+import _acl
+from _acl import READ, WRITE, INSERT, LOOKUP, DELETE, LOCK, ADMINISTER, \
+    USR0, USR1, USR2, USR3, USR4, USR5, USR6, USR7
+from _acl import getCallerAccess
+
+_canonical = {
+    "read":     "rl",
+    "write":    "rwlidwk",
+    "all":      "rwlidwka",
+    "mail":     "lik",
+    "none":     "",
+}
+_char2bit = {
+    'r': READ,
+    'w': WRITE,
+    'i': INSERT,
+    'l': LOOKUP,
+    'd': DELETE,
+    'k': LOCK,
+    'a': ADMINISTER,
+    'A': USR0,
+    'B': USR1,
+    'C': USR2,
+    'D': USR3,
+    'E': USR4,
+    'F': USR5,
+    'G': USR6,
+    'H': USR7,
+}
+
+_bit2char = dict([(v,k) for k,v in _char2bit.items()])
+
+def crights(s):
+    """Canonicalizes string rights to bitmask"""
+    if s in _canonical: s = _canonical[s]
+    return _parseRights(s)
+
+class ACL(object):
+    def __init__(self, pos, neg):
+        """
+        ``pos``
+            Dictionary of usernames to positive ACL bitmasks
+        ``neg``
+            Dictionary of usernames to negative ACL bitmasks
+        """
+        self.pos = pos
+        self.neg = neg
+    @staticmethod
+    def retrieve(dir):
+        """Retrieve the ACL for an AFS directory"""
+        pos, neg = _parseAcl(_acl.getAcl(dir))
+        return ACL(pos, neg)
+
+def _parseRights(s):
+    """Parses a rwlid... rights tring to bitmask"""
+    r = 0
+    try:
+        for c in s:
+            r = r | _char2bit[c]
+    except KeyError:
+        raise ValueError
+    return r
+
+def _parseAcl(inp):
+    lines = inp.split("\n")
+    npos = int(lines[0].split(" ")[0])
+    pos = {}
+    neg = {}
+    for l in lines[2:]:
+        if l == "": continue
+        name, acl = l.split()
+        if npos:
+            npos -= 1
+            pos[name] = int(acl)
+        else:
+            # negative acl
+            neg[name] = int(acl)
+    return (pos, neg)
+