Add size queries in backend object lists.
[pithos] / pithos / backends / lib / sqlite / permissions.py
1 # Copyright 2011 GRNET S.A. All rights reserved.
2
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34 from xfeatures import XFeatures
35 from groups import Groups
36 from public import Public
37
38
39 READ = 0
40 WRITE = 1
41
42
43 class Permissions(XFeatures, Groups, Public):
44     
45     def __init__(self, **params):
46         XFeatures.__init__(self, **params)
47         Groups.__init__(self, **params)
48         Public.__init__(self, **params)
49     
50     def access_grant(self, path, access, members=()):
51         """Grant members with access to path.
52            Members can also be '*' (all),
53            or some group specified as 'owner:group'."""
54         
55         if not members:
56             return
57         feature = self.xfeature_create(path)
58         if feature is None:
59             return
60         self.feature_setmany(feature, access, members)
61     
62     def access_set(self, path, permissions):
63         """Set permissions for path. The permissions dict
64            maps 'read', 'write' keys to member lists."""
65         
66         self.xfeature_destroy(path)
67         self.access_grant(path, READ, permissions.get('read', []))
68         self.access_grant(path, WRITE, permissions.get('write', []))
69     
70     def access_clear(self, path):
71         """Revoke access to path (both permissions and public)."""
72         
73         self.xfeature_destroy(path)
74         self.public_unset(path)
75     
76     def access_check(self, path, access, member):
77         """Return true if the member has this access to the path."""
78         
79         if access == READ and self.public_get(path) is not None:
80             return True
81         
82         r = self.xfeature_inherit(path)
83         if not r:
84             return False
85         fpath, feature = r
86         members = self.feature_get(feature, access)
87         if member in members or '*' in members:
88             return True
89         for owner, group in self.group_parents(member):
90             if owner + ':' + group in members:
91                 return True
92         return False
93     
94     def access_inherit(self, path):
95         """Return the inherited or assigned (path, permissions) pair for path."""
96         
97         r = self.xfeature_inherit(path)
98         if not r:
99             return (path, {})
100         fpath, feature = r
101         permissions = self.feature_dict(feature)
102         if READ in permissions:
103             permissions['read'] = permissions[READ]
104             del(permissions[READ])
105         if WRITE in permissions:
106             permissions['write'] = permissions[WRITE]
107             del(permissions[WRITE])
108         return (fpath, permissions)
109     
110     def access_list(self, path):
111         """List all permission paths inherited by or inheriting from path."""
112         
113         return [x[0] for x in self.xfeature_list(path) if x[0] != path]
114     
115     def access_list_paths(self, member, prefix=None):
116         """Return the list of paths granted to member."""
117         
118         q = ("select distinct path from xfeatures inner join "
119              "   (select distinct feature_id, key from xfeaturevals inner join "
120              "      (select owner || ':' || name as value from groups "
121              "       where member = ? union select ? union select '*') "
122              "    using (value)) "
123              "using (feature_id)")
124         p = (member, member)
125         if prefix:
126             q += " where path like ? escape '\\'"
127             p += (self.escape_like(prefix) + '%',)
128         self.execute(q, p)
129         return [r[0] for r in self.fetchall()]
130     
131     def access_list_shared(self, prefix=''):
132         """Return the list of shared paths."""
133         
134         q = "select path from xfeatures where path like ? escape '\\'"
135         self.execute(q, (self.escape_like(prefix) + '%',))
136         return [r[0] for r in self.fetchall()]