Revision 6e0f3e65

b/snf-pithos-app/pithos/api/functions.py
198 198
    return response
199 199

  
200 200

  
201
@api_method('GET', format_allowed=True, user_required=True, logger=logger)
201
@api_method('GET', format_allowed=True, user_required=True, logger=logger,
202
            serializations=["text", "xml", "json"])
202 203
def account_list(request):
203 204
    # Normal Response Codes: 200, 204
204 205
    # Error Response Codes: internalServerError (500),
b/snf-pithos-app/pithos/api/test/__init__.py
174 174
    def head(self, url, user='user', data={}, follow=False, **extra):
175 175
        with astakos_user(user):
176 176
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
177
            extra.setdefault('HTTP_X_AUTH_TOKEN', 'token')
177 178
            response = self.client.head(url, data, follow, **extra)
178 179
        return response
179 180

  
180 181
    def get(self, url, user='user', data={}, follow=False, **extra):
181 182
        with astakos_user(user):
182 183
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
184
            extra.setdefault('HTTP_X_AUTH_TOKEN', 'token')
183 185
            response = self.client.get(url, data, follow, **extra)
184 186
        return response
185 187

  
186 188
    def delete(self, url, user='user', data={}, follow=False, **extra):
187 189
        with astakos_user(user):
188 190
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
191
            extra.setdefault('HTTP_X_AUTH_TOKEN', 'token')
189 192
            response = self.client.delete(url, data, follow, **extra)
190 193
        return response
191 194

  
......
193 196
             content_type='application/octet-stream', follow=False, **extra):
194 197
        with astakos_user(user):
195 198
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
199
            extra.setdefault('HTTP_X_AUTH_TOKEN', 'token')
196 200
            response = self.client.post(url, data, content_type, follow,
197 201
                                        **extra)
198 202
        return response
......
201 205
            content_type='application/octet-stream', follow=False, **extra):
202 206
        with astakos_user(user):
203 207
            extra = dict((quote(k), quote(v)) for k, v in extra.items())
208
            extra.setdefault('HTTP_X_AUTH_TOKEN', 'token')
204 209
            response = self.client.put(url, data, content_type, follow,
205 210
                                       **extra)
206 211
        return response
......
218 223

  
219 224
    def delete_account_meta(self, meta, user=None):
220 225
        user = user or self.user
221
        transform = lambda k: 'HTTP_X_ACCOUNT_META_%s' % k.replace('-', '_').upper()
226
        transform = (lambda k: 'HTTP_X_ACCOUNT_META_%s' %
227
                     k.replace('-', '_').upper())
222 228
        kwargs = dict((transform(k), '') for k, v in meta.items())
223 229
        url = join_urls(self.pithos_path, user)
224 230
        r = self.post('%s?update=' % url, user=user, **kwargs)
......
230 236
    def delete_account_groups(self, groups, user=None):
231 237
        user = user or self.user
232 238
        url = join_urls(self.pithos_path, user)
233
        transform = lambda k: 'HTTP_X_ACCOUNT_GROUP_%s' % k.replace('-', '_').upper()
239
        transform = (lambda k: 'HTTP_X_ACCOUNT_GROUP_%s' %
240
                     k.replace('-', '_').upper())
234 241
        kwargs = dict((transform(k), '') for k, v in groups.items())
235 242
        r = self.post('%s?update=' % url, user=user, **kwargs)
236 243
        self.assertEqual(r.status_code, 202)
......
289 296
        url = join_urls(self.pithos_path, user, container)
290 297
        r = self.post('%s?update=' % url, user=user, **kwargs)
291 298
        self.assertEqual(r.status_code, 202)
292
        container_meta = self.get_container_meta(container)
299
        container_meta = self.get_container_meta(container, user=user)
293 300
        (self.assertTrue('X-Container-Meta-%s' % k in container_meta) for
294 301
            k in meta.keys())
295 302
        (self.assertEqual(container_meta['X-Container-Meta-%s' % k], v) for
......
437 444
        url = join_urls(self.pithos_path, user, container, object)
438 445
        r = self.post('%s?update=' % url, user=user, content_type='', **kwargs)
439 446
        self.assertEqual(r.status_code, 202)
440
        object_meta = self.get_object_meta(container, object)
447
        object_meta = self.get_object_meta(container, object, user=user)
441 448
        (self.assertTrue('X-Objecr-Meta-%s' % k in object_meta) for
442 449
            k in meta.keys())
443 450
        (self.assertEqual(object_meta['X-Object-Meta-%s' % k], v) for
b/snf-pithos-app/pithos/api/test/listing.py
1
# Copyright 2011-2012 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 pithos.api.test import PithosAPITest
35

  
36
from synnefo.lib import join_urls
37

  
38
import django.utils.simplejson as json
39

  
40
class ListSharing(PithosAPITest):
41
    def _build_structure(self, user=None):
42
        user = user or self.user
43
        for i in range(2):
44
            cname = 'c%d' % i
45
            self.create_container(cname, user=user)
46
            self.upload_object(cname, 'obj', user=user)
47
            self.create_folder(cname, 'f1', user=user)
48
            self.create_folder(cname, 'f1/f2', user=user)
49
            self.upload_object(cname, 'f1/f2/obj', user=user)
50

  
51
        # share /c0/f1 path
52
        url = join_urls(self.pithos_path, user, 'c0', 'f1')
53
        r = self.post(url, user=user, content_type='',
54
                      HTTP_CONTENT_RANGE='bytes */*',
55
                      HTTP_X_OBJECT_SHARING='read=*')
56
        self.assertEqual(r.status_code, 202)
57
        r = self.get(url)
58

  
59
    def test_list_share_with_me(self):
60
        self._build_structure('alice')
61
        url = join_urls(self.pithos_path)
62
        r = self.get(url)
63
        self.assertEqual(r.status_code, 200)
64
        allowed_accounts = r.content.split('\n')
65
        if '' in allowed_accounts:
66
            allowed_accounts.remove('')
67
        self.assertEqual(allowed_accounts, ['alice'])
68

  
69
        r = self.get('%s?format=json' % url)
70
        self.assertEqual(r.status_code, 200)
71
        allowed_accounts = json.loads(r.content)
72
        self.assertEqual([i['name'] for i in allowed_accounts], ['alice'])
73

  
74
        url = join_urls(url, 'alice')
75
        r = self.get(url)
76
        self.assertEqual(r.status_code, 200)
77
        allowed_containers = r.content.split('\n')
78
        if '' in allowed_containers:
79
            allowed_containers.remove('')
80
        self.assertEqual(allowed_containers, ['c0'])
81

  
82
        r = self.get('%s?format=json' % url)
83
        self.assertEqual(r.status_code, 200)
84
        allowed_containers = json.loads(r.content)
85
        self.assertEqual([i['name'] for i in allowed_containers], ['c0'])
86

  
87
        url = join_urls(url, 'c0')
88
        r = self.get('%s?delimiter=/&shared=&format=json' % url)
89
        self.assertEqual(r.status_code, 200)
90
        shared_objects = [i.get('name', i.get('subdir')) for i in
91
                          json.loads(r.content)]
92
        self.assertEqual(shared_objects, ['f1', 'f1/'])
93

  
94
        r = self.get('%s?delimiter=/&prefix=f1&shared=&format=json' % url)
95
        self.assertEqual(r.status_code, 200)
96
        shared_objects = [i.get('name', i.get('subdir')) for i in
97
                          json.loads(r.content)]
98
        self.assertEqual(shared_objects, ['f1/f2', 'f1/f2/'])
99

  
100
        r = self.get('%s?delimiter=/&prefix=f1/f2&shared=&format=json' % url)
101
        self.assertEqual(r.status_code, 200)
102
        shared_objects = [i.get('name', i.get('subdir')) for i in
103
                          json.loads(r.content)]
104
        self.assertEqual(shared_objects, ['f1/f2/obj'])
105

  
106
    def test_list_shared_by_me(self):
107
        self._build_structure()
108
        url = join_urls(self.pithos_path, self.user)
109
        r = self.get('%s?shared=' % url)
110
        self.assertEqual(r.status_code, 200)
111
        shared_containers = r.content.split('\n')
112
        if '' in shared_containers:
113
            shared_containers.remove('')
114
        self.assertEqual(shared_containers, ['c0'])
115

  
116
        r = self.get('%s?shared=&format=json' % url)
117
        self.assertEqual(r.status_code, 200)
118
        shared_containers = json.loads(r.content)
119
        self.assertEqual([i['name'] for i in shared_containers], ['c0'])
120

  
121
        url = join_urls(url, 'c0')
122
        r = self.get('%s?delimiter=/&shared=&format=json' % url)
123
        self.assertEqual(r.status_code, 200)
124
        shared_objects = [i.get('name', i.get('subdir')) for i in
125
                          json.loads(r.content)]
126
        self.assertEqual(shared_objects, ['f1', 'f1/'])
127

  
128
        r = self.get('%s?delimiter=/&prefix=f1&shared=&format=json' % url)
129
        self.assertEqual(r.status_code, 200)
130
        shared_objects = [i.get('name', i.get('subdir')) for i in
131
                          json.loads(r.content)]
132
        self.assertEqual(shared_objects, ['f1/f2', 'f1/f2/'])
133

  
134
        r = self.get('%s?delimiter=/&prefix=f1/f2&shared=&format=json' % url)
135
        self.assertEqual(r.status_code, 200)
136
        shared_objects = [i.get('name', i.get('subdir')) for i in
137
                          json.loads(r.content)]
138
        self.assertEqual(shared_objects, ['f1/f2/obj'])
b/snf-pithos-app/pithos/api/tests.py
39 39
from pithos.api.test.public import *
40 40
from pithos.api.test.views import *
41 41
from pithos.api.test.unicode import *
42
from pithos.api.test.listing import *
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/permissions.py
184 184
                          self.xfeaturevals.c.value == u.c.value)
185 185
        s = select([self.xfeatures.c.path], from_obj=[inner_join]).distinct()
186 186
        if prefix:
187
            s = s.where(self.xfeatures.c.path.like(
188
                self.escape_like(prefix) + '%', escape=ESCAPE_CHAR
189
            ))
187
            like = lambda p: self.xfeatures.c.path.like(
188
                self.escape_like(p) + '%', escape=ESCAPE_CHAR)
189
            s = s.where(or_(*map(like,
190
                                 self.access_inherit(prefix) or [prefix])))
190 191
        r = self.conn.execute(s)
191 192
        l = [row[0] for row in r.fetchall()]
192 193
        r.close()
......
208 209
    def access_list_shared(self, prefix=''):
209 210
        """Return the list of shared paths."""
210 211

  
211
        s = select([self.xfeatures.c.path],
212
                   self.xfeatures.c.path.like(
213
                       self.escape_like(prefix) + '%',
214
                       escape=ESCAPE_CHAR)).order_by(
215
                           self.xfeatures.c.path.asc())
212
        s = select([self.xfeatures.c.path])
213
        like = lambda p: self.xfeatures.c.path.like(
214
            self.escape_like(p) + '%', escape=ESCAPE_CHAR)
215
        s = s.where(or_(*map(like, self.access_inherit(prefix) or [prefix])))
216
        s = s.order_by(self.xfeatures.c.path.asc())
216 217
        r = self.conn.execute(s)
217 218
        l = [row[0] for row in r.fetchall()]
218 219
        r.close()
b/snf-pithos-backend/pithos/backends/lib/sqlite/permissions.py
173 173
             "using (feature_id)")
174 174
        p = (member, member)
175 175
        if prefix:
176
            q += " where path like ? escape '\\'"
177
            p += (self.escape_like(prefix) + '%',)
176
            q += " where"
177
            for path in self.access_inherit(prefix) or [prefix]:
178
                q += " path like ? escape '\\'"
179
                p += (self.escape_like(path) + '%',)
178 180
        self.execute(q, p)
179 181

  
180 182
        l = [r[0] for r in self.fetchall()]
......
194 196
    def access_list_shared(self, prefix=''):
195 197
        """Return the list of shared paths."""
196 198

  
197
        q = "select path from xfeatures where path like ? escape '\\'"
198
        self.execute(q, (self.escape_like(prefix) + '%',))
199
        q = "select path from xfeatures where"
200
        p = []
201
        for path in self.access_inherit(prefix) or [prefix]:
202
            q += " path like ? escape '\\'"
203
            p += (self.escape_like(path) + '%',)
204
        self.execute(q, p)
199 205
        return [r[0] for r in self.fetchall()]

Also available in: Unified diff