Revision d50ed8d4 snf-pithos-backend/pithos/backends/lib/sqlalchemy/permissions.py
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/permissions.py | ||
---|---|---|
1 | 1 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
2 |
#
|
|
2 |
# |
|
3 | 3 |
# Redistribution and use in source and binary forms, with or |
4 | 4 |
# without modification, are permitted provided that the following |
5 | 5 |
# conditions are met: |
6 |
#
|
|
6 |
# |
|
7 | 7 |
# 1. Redistributions of source code must retain the above |
8 | 8 |
# copyright notice, this list of conditions and the following |
9 | 9 |
# disclaimer. |
10 |
#
|
|
10 |
# |
|
11 | 11 |
# 2. Redistributions in binary form must reproduce the above |
12 | 12 |
# copyright notice, this list of conditions and the following |
13 | 13 |
# disclaimer in the documentation and/or other materials |
14 | 14 |
# provided with the distribution. |
15 |
#
|
|
15 |
# |
|
16 | 16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
17 | 17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | 18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
... | ... | |
25 | 25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
26 | 26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | 27 |
# POSSIBILITY OF SUCH DAMAGE. |
28 |
#
|
|
28 |
# |
|
29 | 29 |
# The views and conclusions contained in the software and |
30 | 30 |
# documentation are those of the authors and should not be |
31 | 31 |
# interpreted as representing official policies, either expressed |
... | ... | |
44 | 44 |
|
45 | 45 |
|
46 | 46 |
class Permissions(XFeatures, Groups, Public): |
47 |
|
|
47 |
|
|
48 | 48 |
def __init__(self, **params): |
49 | 49 |
XFeatures.__init__(self, **params) |
50 | 50 |
Groups.__init__(self, **params) |
51 | 51 |
Public.__init__(self, **params) |
52 |
|
|
52 |
|
|
53 | 53 |
def access_grant(self, path, access, members=()): |
54 | 54 |
"""Grant members with access to path. |
55 | 55 |
Members can also be '*' (all), |
56 | 56 |
or some group specified as 'owner:group'.""" |
57 |
|
|
57 |
|
|
58 | 58 |
if not members: |
59 | 59 |
return |
60 | 60 |
feature = self.xfeature_create(path) |
61 | 61 |
self.feature_setmany(feature, access, members) |
62 |
|
|
62 |
|
|
63 | 63 |
def access_set(self, path, permissions): |
64 | 64 |
"""Set permissions for path. The permissions dict |
65 | 65 |
maps 'read', 'write' keys to member lists.""" |
66 |
|
|
66 |
|
|
67 | 67 |
r = permissions.get('read', []) |
68 | 68 |
w = permissions.get('write', []) |
69 | 69 |
if not r and not w: |
... | ... | |
76 | 76 |
self.feature_setmany(feature, READ, r) |
77 | 77 |
if w: |
78 | 78 |
self.feature_setmany(feature, WRITE, w) |
79 |
|
|
79 |
|
|
80 | 80 |
def access_get(self, path): |
81 | 81 |
"""Get permissions for path.""" |
82 |
|
|
82 |
|
|
83 | 83 |
feature = self.xfeature_get(path) |
84 | 84 |
if not feature: |
85 | 85 |
return {} |
... | ... | |
91 | 91 |
permissions['write'] = permissions[WRITE] |
92 | 92 |
del(permissions[WRITE]) |
93 | 93 |
return permissions |
94 |
|
|
94 |
|
|
95 | 95 |
def access_members(self, path): |
96 | 96 |
feature = self.xfeature_get(path) |
97 | 97 |
if not feature: |
... | ... | |
108 | 108 |
members.remove(m) |
109 | 109 |
members.update(self.group_members(user, group)) |
110 | 110 |
return list(members) |
111 |
|
|
111 |
|
|
112 | 112 |
def access_clear(self, path): |
113 | 113 |
"""Revoke access to path (both permissions and public).""" |
114 |
|
|
114 |
|
|
115 | 115 |
self.xfeature_destroy(path) |
116 | 116 |
self.public_unset(path) |
117 |
|
|
117 |
|
|
118 | 118 |
def access_clear_bulk(self, paths): |
119 | 119 |
"""Revoke access to path (both permissions and public).""" |
120 |
|
|
120 |
|
|
121 | 121 |
self.xfeature_destroy_bulk(paths) |
122 | 122 |
self.public_unset_bulk(paths) |
123 |
|
|
123 |
|
|
124 | 124 |
def access_check(self, path, access, member): |
125 | 125 |
"""Return true if the member has this access to the path.""" |
126 |
|
|
126 |
|
|
127 | 127 |
feature = self.xfeature_get(path) |
128 | 128 |
if not feature: |
129 | 129 |
return False |
... | ... | |
134 | 134 |
if owner + ':' + group in members: |
135 | 135 |
return True |
136 | 136 |
return False |
137 |
|
|
137 |
|
|
138 | 138 |
def access_inherit(self, path): |
139 | 139 |
"""Return the paths influencing the access for path.""" |
140 |
|
|
140 |
|
|
141 | 141 |
# r = self.xfeature_inherit(path) |
142 | 142 |
# if not r: |
143 | 143 |
# return [] |
144 | 144 |
# # Compute valid. |
145 | 145 |
# return [x[0] for x in r if x[0] in valid] |
146 |
|
|
146 |
|
|
147 | 147 |
# Only keep path components. |
148 | 148 |
parts = path.rstrip('/').split('/') |
149 | 149 |
valid = [] |
... | ... | |
153 | 153 |
if subp != path: |
154 | 154 |
valid.append(subp + '/') |
155 | 155 |
return [x for x in valid if self.xfeature_get(x)] |
156 |
|
|
156 |
|
|
157 | 157 |
def access_list_paths(self, member, prefix=None): |
158 | 158 |
"""Return the list of paths granted to member.""" |
159 |
|
|
160 |
xfeatures_xfeaturevals = self.xfeatures.join(self.xfeaturevals)
|
|
161 |
|
|
159 |
|
|
160 |
xfeatures_xfeaturevals = self.xfeatures.join(self.xfeaturevals) |
|
161 |
|
|
162 | 162 |
selectable = (self.groups.c.owner + ':' + self.groups.c.name) |
163 | 163 |
member_groups = select([selectable.label('value')], |
164 |
self.groups.c.member == member) |
|
165 |
|
|
164 |
self.groups.c.member == member)
|
|
165 |
|
|
166 | 166 |
members = select([literal(member).label('value')]) |
167 | 167 |
any = select([literal('*').label('value')]) |
168 |
|
|
168 |
|
|
169 | 169 |
u = union(member_groups, members, any).alias() |
170 | 170 |
inner_join = join(xfeatures_xfeaturevals, u, |
171 |
self.xfeaturevals.c.value == u.c.value) |
|
171 |
self.xfeaturevals.c.value == u.c.value)
|
|
172 | 172 |
s = select([self.xfeatures.c.path], from_obj=[inner_join]).distinct() |
173 | 173 |
if prefix: |
174 |
s = s.where(self.xfeatures.c.path.like(self.escape_like(prefix) + '%', escape='\\')) |
|
174 |
s = s.where(self.xfeatures.c.path.like( |
|
175 |
self.escape_like(prefix) + '%', escape='\\')) |
|
175 | 176 |
r = self.conn.execute(s) |
176 | 177 |
l = [row[0] for row in r.fetchall()] |
177 | 178 |
r.close() |
178 | 179 |
return l |
179 |
|
|
180 |
|
|
180 | 181 |
def access_list_shared(self, prefix=''): |
181 | 182 |
"""Return the list of shared paths.""" |
182 |
|
|
183 |
|
|
183 | 184 |
s = select([self.xfeatures.c.path], |
184 |
self.xfeatures.c.path.like(self.escape_like(prefix) + '%', escape='\\')).order_by(self.xfeatures.c.path.asc()) |
|
185 |
self.xfeatures.c.path.like(self.escape_like(prefix) + '%', escape='\\')).order_by(self.xfeatures.c.path.asc())
|
|
185 | 186 |
r = self.conn.execute(s) |
186 | 187 |
l = [row[0] for row in r.fetchall()] |
187 | 188 |
r.close() |
Also available in: Unified diff