Revision f6c97079 pithos/backends/simple.py

b/pithos/backends/simple.py
130 130
        self.mapper = Mapper(**params)
131 131
    
132 132
    @backend_method
133
    def list_accounts(self, user, marker=None, limit=10000):
134
        """Return a list of accounts the user can access."""
135
        
136
        allowed = self._allowed_accounts(user)
137
        start, limit = self._list_limits(allowed, marker, limit)
138
        return allowed[start:start + limit]
139
    
140
    @backend_method
133 141
    def get_account_meta(self, user, account, until=None):
134 142
        """Return a dictionary with the account metadata."""
135 143
        
136 144
        logger.debug("get_account_meta: %s %s", account, until)
137 145
        if user != account:
138
            raise NotAllowedError
146
            if until or account not in self._allowed_accounts(user):
147
                raise NotAllowedError
139 148
        try:
140 149
            version_id, mtime = self._get_accountinfo(account, until)
141 150
        except NameError:
......
158 167
        row = c.fetchone()
159 168
        count = row[0]
160 169
        
161
        meta = self._get_metadata(account, version_id)
162
        meta.update({'name': account, 'count': count, 'bytes': bytes})
170
        if user != account:
171
            meta = {'name': account}
172
        else:
173
            meta = self._get_metadata(account, version_id)
174
            meta.update({'name': account, 'count': count, 'bytes': bytes})
175
            if until is not None:
176
                meta.update({'until_timestamp': tstamp})
163 177
        if modified:
164 178
            meta.update({'modified': modified})
165
        if until is not None:
166
            meta.update({'until_timestamp': tstamp})
167 179
        return meta
168 180
    
169 181
    @backend_method
......
181 193
        
182 194
        logger.debug("get_account_groups: %s", account)
183 195
        if user != account:
184
            raise NotAllowedError
196
            if account not in self._allowed_accounts(user):
197
                raise NotAllowedError
198
            return {}
185 199
        return self._get_groups(account)
186 200
    
187 201
    @backend_method
......
229 243
        
230 244
        logger.debug("list_containers: %s %s %s %s", account, marker, limit, until)
231 245
        if user != account:
232
            if until:
246
            if until or account not in self._allowed_accounts(user):
233 247
                raise NotAllowedError
234
            containers = self._allowed_containers(user, account)
235
            start = 0
236
            if marker:
237
                try:
238
                    start = containers.index(marker) + 1
239
                except ValueError:
240
                    pass
241
            if not limit or limit > 10000:
242
                limit = 10000
243
            return containers[start:start + limit]
244
        return self._list_objects(account, '', '/', marker, limit, False, [], until)
248
            allowed = self._allowed_containers(user, account)
249
            start, limit = self._list_limits(allowed, marker, limit)
250
            return allowed[start:start + limit]
251
        return [x[0] for x in self._list_objects(account, '', '/', marker, limit, False, [], until)]
245 252
    
246 253
    @backend_method
247 254
    def get_container_meta(self, user, account, container, until=None):
......
249 256
        
250 257
        logger.debug("get_container_meta: %s %s %s", account, container, until)
251 258
        if user != account:
252
            raise NotAllowedError
259
            if until or container not in self._allowed_containers(user, account):
260
                raise NotAllowedError
253 261
        path, version_id, mtime = self._get_containerinfo(account, container, until)
254 262
        count, bytes, tstamp = self._get_pathstats(path, until)
255 263
        if mtime > tstamp:
......
261 269
            if mtime > modified:
262 270
                modified = mtime
263 271
        
264
        meta = self._get_metadata(path, version_id)
265
        meta.update({'name': container, 'count': count, 'bytes': bytes, 'modified': modified})
266
        if until is not None:
267
            meta.update({'until_timestamp': tstamp})
272
        if user != account:
273
            meta = {'name': container, 'modified': modified}
274
        else:
275
            meta = self._get_metadata(path, version_id)
276
            meta.update({'name': container, 'count': count, 'bytes': bytes, 'modified': modified})
277
            if until is not None:
278
                meta.update({'until_timestamp': tstamp})
268 279
        return meta
269 280
    
270 281
    @backend_method
......
283 294
        
284 295
        logger.debug("get_container_policy: %s %s", account, container)
285 296
        if user != account:
286
            raise NotAllowedError
297
            if container not in self._allowed_containers(user, account):
298
                raise NotAllowedError
299
            return {}
287 300
        path = self._get_containerinfo(account, container)[0]
288 301
        return self._get_policy(path)
289 302
    
......
360 373
        """Return a list of objects existing under a container."""
361 374
        
362 375
        logger.debug("list_objects: %s %s %s %s %s %s %s %s %s", account, container, prefix, delimiter, marker, limit, virtual, keys, until)
376
        allowed = []
363 377
        if user != account:
364
            raise NotAllowedError
378
            if until:
379
                raise NotAllowedError
380
            allowed = self._allowed_paths(user, os.path.join(account, container))
381
            if not allowed:
382
                raise NotAllowedError
365 383
        path, version_id, mtime = self._get_containerinfo(account, container, until)
366
        return self._list_objects(path, prefix, delimiter, marker, limit, virtual, keys, until)
384
        return self._list_objects(path, prefix, delimiter, marker, limit, virtual, keys, until, allowed)
367 385
    
368 386
    @backend_method
369 387
    def list_object_meta(self, user, account, container, until=None):
370 388
        """Return a list with all the container's object meta keys."""
371 389
        
372 390
        logger.debug("list_object_meta: %s %s %s", account, container, until)
391
        allowed = []
373 392
        if user != account:
374
            raise NotAllowedError
393
            if until:
394
                raise NotAllowedError
395
            allowed = self._allowed_paths(user, os.path.join(account, container))
396
            if not allowed:
397
                raise NotAllowedError
375 398
        path, version_id, mtime = self._get_containerinfo(account, container, until)
376 399
        sql = '''select distinct m.key from (%s) o, metadata m
377 400
                    where m.version_id = o.version_id and o.name like ?'''
378 401
        sql = sql % self._sql_until(until)
379
        c = self.con.execute(sql, (path + '/%',))
402
        param = (path + '/%',)
403
        if allowed:
404
            for x in allowed:
405
                sql += ' and o.name like ?'
406
                param += (x,)
407
        c = self.con.execute(sql, param)
380 408
        return [x[0] for x in c.fetchall()]
381 409
    
382 410
    @backend_method
......
723 751
        c = self.con.execute(sql, (path,))
724 752
        return dict(c.fetchall())
725 753
    
726
    def _list_objects(self, path, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None):
754
    
755
    def _list_limits(self, listing, marker, limit):
756
        start = 0
757
        if marker:
758
            try:
759
                start = listing.index(marker) + 1
760
            except ValueError:
761
                pass
762
        if not limit or limit > 10000:
763
            limit = 10000
764
        return start, limit
765
    
766
    def _list_objects(self, path, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None, allowed=[]):
727 767
        cont_prefix = path + '/'
728 768
        if keys and len(keys) > 0:
729 769
            sql = '''select distinct o.name, o.version_id from (%s) o, metadata m where o.name like ? and
730
                        m.version_id = o.version_id and m.key in (%s) order by o.name'''
770
                        m.version_id = o.version_id and m.key in (%s)'''
731 771
            sql = sql % (self._sql_until(until), ', '.join('?' * len(keys)))
732 772
            param = (cont_prefix + prefix + '%',) + tuple(keys)
773
            if allowed:
774
                for x in allowed:
775
                    sql += ' and o.name like ?'
776
                    param += (x,)
777
            sql += ' order by o.name'
733 778
        else:
734
            sql = 'select name, version_id from (%s) where name like ? order by name'
779
            sql = 'select name, version_id from (%s) where name like ?'
735 780
            sql = sql % self._sql_until(until)
736 781
            param = (cont_prefix + prefix + '%',)
782
            if allowed:
783
                for x in allowed:
784
                    sql += ' and name like ?'
785
                    param += (x,)
786
            sql += ' order by name'
737 787
        c = self.con.execute(sql, param)
738 788
        objects = [(x[0][len(cont_prefix):], x[1]) for x in c.fetchall()]
739 789
        if delimiter:
......
757 807
                            pseudo_objects.append((pseudo_name, None))
758 808
            objects = pseudo_objects
759 809
        
760
        start = 0
761
        if marker:
762
            try:
763
                start = [x[0] for x in objects].index(marker) + 1
764
            except ValueError:
765
                pass
766
        if not limit or limit > 10000:
767
            limit = 10000
810
        start, limit = self._list_limits([x[0] for x in objects], marker, limit)
768 811
        return objects[start:start + limit]
769 812
    
770 813
    def _del_version(self, version):

Also available in: Unified diff