Progress II: update sqlalchemy pithos backend lib
[pithos] / snf-pithos-backend / pithos / backends / lib / sqlalchemy / permissions.py
index 2f54aaa..9644e85 100644 (file)
@@ -58,17 +58,56 @@ class Permissions(XFeatures, Groups, Public):
         if not members:
             return
         feature = self.xfeature_create(path)
-        if feature is None:
-            return
         self.feature_setmany(feature, access, members)
     
     def access_set(self, path, permissions):
         """Set permissions for path. The permissions dict
            maps 'read', 'write' keys to member lists."""
         
-        self.xfeature_destroy(path)
-        self.access_grant(path, READ, permissions.get('read', []))
-        self.access_grant(path, WRITE, permissions.get('write', []))
+        r = permissions.get('read', [])
+        w = permissions.get('write', [])
+        if not r and not w:
+            self.xfeature_destroy(path)
+            return
+        feature = self.xfeature_create(path)
+        self.feature_clear(feature, READ)
+        self.feature_clear(feature, WRITE)
+        if r:
+            self.feature_setmany(feature, READ, r)
+        if w:
+            self.feature_setmany(feature, WRITE, w)
+    
+    def access_get(self, path):
+        """Get permissions for path."""
+        
+        feature = self.xfeature_get(path)
+        if not feature:
+            return {}
+        permissions = self.feature_dict(feature)
+        if READ in permissions:
+            permissions['read'] = permissions[READ]
+            del(permissions[READ])
+        if WRITE in permissions:
+            permissions['write'] = permissions[WRITE]
+            del(permissions[WRITE])
+        return permissions
+    
+    def access_members(self, path):
+        feature = self.xfeature_get(path)
+        if not feature:
+            return []
+        permissions = self.feature_dict(feature)
+        members = set()
+        members.update(permissions.get(READ, []))
+        members.update(permissions.get(WRITE, []))
+        for m in set(members):
+            parts = m.split(':', 1)
+            if len(parts) != 2:
+                continue
+            user, group = parts
+            members.remove(m)
+            members.update(self.group_members(user, group))
+        return list(members)
     
     def access_clear(self, path):
         """Revoke access to path (both permissions and public)."""
@@ -76,16 +115,18 @@ class Permissions(XFeatures, Groups, Public):
         self.xfeature_destroy(path)
         self.public_unset(path)
     
+    def access_clear_bulk(self, paths):
+        """Revoke access to path (both permissions and public)."""
+        
+        self.xfeature_destroy_bulk(paths)
+        self.public_unset_bulk(paths)
+    
     def access_check(self, path, access, member):
         """Return true if the member has this access to the path."""
         
-        if access == READ and self.public_get(path) is not None:
-            return True
-        
-        r = self.xfeature_inherit(path)
-        if not r:
+        feature = self.xfeature_get(path)
+        if not feature:
             return False
-        fpath, feature = r
         members = self.feature_get(feature, access)
         if member in members or '*' in members:
             return True
@@ -95,25 +136,23 @@ class Permissions(XFeatures, Groups, Public):
         return False
     
     def access_inherit(self, path):
-        """Return the inherited or assigned (path, permissions) pair for path."""
+        """Return the paths influencing the access for path."""
         
-        r = self.xfeature_inherit(path)
-        if not r:
-            return (path, {})
-        fpath, feature = r
-        permissions = self.feature_dict(feature)
-        if READ in permissions:
-            permissions['read'] = permissions[READ]
-            del(permissions[READ])
-        if WRITE in permissions:
-            permissions['write'] = permissions[WRITE]
-            del(permissions[WRITE])
-        return (fpath, permissions)
-    
-    def access_list(self, path):
-        """List all permission paths inherited by or inheriting from path."""
+#         r = self.xfeature_inherit(path)
+#         if not r:
+#             return []
+#         # Compute valid.
+#         return [x[0] for x in r if x[0] in valid]
         
-        return [x[0] for x in self.xfeature_list(path) if x[0] != path]
+        # Only keep path components.
+        parts = path.rstrip('/').split('/')
+        valid = []
+        for i in range(1, len(parts)):
+            subp = '/'.join(parts[:i + 1])
+            valid.append(subp)
+            if subp != path:
+                valid.append(subp + '/')
+        return [x for x in valid if self.xfeature_get(x)]
     
     def access_list_paths(self, member, prefix=None):
         """Return the list of paths granted to member."""