Revision e0f916bb

b/pithos/api/functions.py
45 45
    LengthRequired, PreconditionFailed, RangeNotSatisfiable, UnprocessableEntity)
46 46
from pithos.api.util import (format_header_key, printable_header_dict, get_account_headers,
47 47
    put_account_headers, get_container_headers, put_container_headers, get_object_headers, put_object_headers,
48
    update_manifest_meta, update_sharing_meta, validate_modification_preconditions,
48
    update_manifest_meta, update_sharing_meta, update_public_meta, validate_modification_preconditions,
49 49
    validate_matching_preconditions, split_container_object_string, copy_or_move_object,
50 50
    get_int_parameter, get_content_length, get_content_range, raw_input_socket,
51 51
    socket_read_iterator, object_data_response, put_object_block, hashmap_hash, api_method)
......
412 412
                meta = backend.get_object_meta(request.user, v_account, v_container, x[0], x[1])
413 413
                if until is None:
414 414
                    permissions = backend.get_object_permissions(request.user, v_account, v_container, x[0])
415
                    public = backend.get_object_public(request.user, v_account, v_container, x[0])
415 416
                else:
416 417
                    permissions = None
418
                    public = None
417 419
            except NotAllowedError:
418 420
                raise Unauthorized('Access denied')
419 421
            except NameError:
420 422
                pass
421 423
            update_sharing_meta(permissions, v_account, v_container, x[0], meta)
424
            update_public_meta(public, meta)
422 425
            object_meta.append(printable_header_dict(meta))
423 426
    if request.serialization == 'xml':
424 427
        data = render_to_string('objects.xml', {'container': v_container, 'objects': object_meta})
......
441 444
        meta = backend.get_object_meta(request.user, v_account, v_container, v_object, version)
442 445
        if version is None:
443 446
            permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
447
            public = backend.get_object_public(request.user, v_account, v_container, v_object)
444 448
        else:
445 449
            permissions = None
450
            public = None
446 451
    except NotAllowedError:
447 452
        raise Unauthorized('Access denied')
448 453
    except NameError:
......
452 457
    
453 458
    update_manifest_meta(request, v_account, meta)
454 459
    update_sharing_meta(permissions, v_account, v_container, v_object, meta)
460
    update_public_meta(public, meta)
455 461
    
456 462
    response = HttpResponse(status=200)
457 463
    put_object_headers(response, meta)
......
494 500
        meta = backend.get_object_meta(request.user, v_account, v_container, v_object, version)
495 501
        if version is None:
496 502
            permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
503
            public = backend.update_object_public(request.user, v_account, v_container, v_object)
497 504
        else:
498 505
            permissions = None
506
            public = None
499 507
    except NotAllowedError:
500 508
        raise Unauthorized('Access denied')
501 509
    except NameError:
......
505 513
    
506 514
    update_manifest_meta(request, v_account, meta)
507 515
    update_sharing_meta(permissions, v_account, v_container, v_object, meta)
516
    update_public_meta(public, meta)
508 517
    
509 518
    # Evaluate conditions.
510 519
    validate_modification_preconditions(request, meta)
......
656 665
        raise BadRequest('Invalid sharing header')
657 666
    except AttributeError:
658 667
        raise Conflict('Sharing already set above or below this path in the hierarchy')
668
    if public is not None:
669
        try:
670
            backend.update_object_public(request.user, v_account, v_container, v_object, public)
671
        except NotAllowedError:
672
            raise Unauthorized('Access denied')
673
        except NameError:
674
            raise ItemNotFound('Object does not exist')
659 675
    
660 676
    response = HttpResponse(content=payload, status=code)
661 677
    response['ETag'] = meta['hash']
......
740 756
                raise BadRequest('Invalid sharing header')
741 757
            except AttributeError:
742 758
                raise Conflict('Sharing already set above or below this path in the hierarchy')
759
        if public is not None:
760
            try:
761
                backend.update_object_public(request.user, v_account, v_container, v_object, public)
762
            except NotAllowedError:
763
                raise Unauthorized('Access denied')
764
            except NameError:
765
                raise ItemNotFound('Object does not exist')
743 766
        try:
744 767
            backend.update_object_meta(request.user, v_account, v_container, v_object, meta, replace)
745 768
        except NotAllowedError:
......
806 829
        raise BadRequest('Invalid sharing header')
807 830
    except AttributeError:
808 831
        raise Conflict('Sharing already set above or below this path in the hierarchy')
832
    if public is not None:
833
        try:
834
            backend.update_object_public(request.user, v_account, v_container, v_object, public)
835
        except NotAllowedError:
836
            raise Unauthorized('Access denied')
837
        except NameError:
838
            raise ItemNotFound('Object does not exist')
809 839
    
810 840
    response = HttpResponse(status=204)
811 841
    response['ETag'] = meta['hash']
b/pithos/api/util.py
148 148
        response['X-Object-Version-Timestamp'] = http_date(int(meta['version_timestamp']))
149 149
        for k in [x for x in meta.keys() if x.startswith('X-Object-Meta-')]:
150 150
            response[k.encode('utf-8')] = meta[k].encode('utf-8')
151
        for k in ('Content-Encoding', 'Content-Disposition', 'X-Object-Manifest', 'X-Object-Sharing', 'X-Object-Shared-By'):
151
        for k in ('Content-Encoding', 'Content-Disposition', 'X-Object-Manifest', 'X-Object-Sharing', 'X-Object-Shared-By', 'X-Object-Public'):
152 152
            if k in meta:
153 153
                response[k] = meta[k]
154 154
    else:
......
194 194
    if '/'.join((v_account, v_container, v_object)) != perm_path:
195 195
        meta['X-Object-Shared-By'] = perm_path
196 196

  
197
def update_public_meta(public, meta):
198
    if not public:
199
        return
200
    meta['X-Object-Public'] = public
201

  
197 202
def validate_modification_preconditions(request, meta):
198 203
    """Check that the modified timestamp conforms with the preconditions set."""
199 204
    
......
255 260
        raise BadRequest('Invalid sharing header')
256 261
    except AttributeError:
257 262
        raise Conflict('Sharing already set above or below this path in the hierarchy')
263
    if public is not None:
264
        try:
265
            backend.update_object_public(request.user, v_account, v_container, v_object, public)
266
        except NotAllowedError:
267
            raise Unauthorized('Access denied')
268
        except NameError:
269
            raise ItemNotFound('Object does not exist')
258 270

  
259 271
def get_int_parameter(request, name):
260 272
    p = request.GET.get(name)
b/pithos/backends/simple.py
85 85
        sql = '''create table if not exists groups (
86 86
                    account text, name text, users text, primary key (account, name))'''
87 87
        self.con.execute(sql)
88
        sql = '''create table if not exists policy (
89
                    name text, key text, value text, primary key (name, key))'''
90
        self.con.execute(sql)
88 91
        sql = '''create table if not exists permissions (
89 92
                    name text, read text, write text, primary key (name))'''
90 93
        self.con.execute(sql)
91
        sql = '''create table if not exists policy (
92
                    name text, key text, value text, primary key (name, key))'''
94
        sql = '''create table if not exists public (
95
                    name text, primary key (name))'''
93 96
        self.con.execute(sql)
94 97
        self.con.commit()
95 98
    
......
351 354
        """Return the public URL of the object if applicable."""
352 355
        
353 356
        logger.debug("get_object_public: %s %s %s", account, container, name)
357
        self._can_read(user, account, container, name)
358
        path = self._get_objectinfo(account, container, name)[0]
359
        if self._get_public(path):
360
            return '/public/' + path
354 361
        return None
355 362
    
356 363
    def update_object_public(self, user, account, container, name, public):
357 364
        """Update the public status of the object."""
358 365
        
359 366
        logger.debug("update_object_public: %s %s %s %s", account, container, name, public)
360
        return
367
        self._can_write(user, account, container, name)
368
        path = self._get_objectinfo(account, container, name)[0]
369
        self._put_public(path, public)
361 370
    
362 371
    def get_object_hashmap(self, user, account, container, name, version=None):
363 372
        """Return the object's size and a list with partial hashes."""
......
649 658
        if user == account:
650 659
            return True
651 660
        path = os.path.join(account, container, name)
661
        if op == 'read' and self._get_public(path):
662
            return True
652 663
        perm_path, perms = self._get_permissions(path)
653 664
        
654 665
        # Expand groups.
......
723 734
            self.con.execute(sql, (path, r, w))
724 735
        self.con.commit()
725 736
    
737
    def _get_public(self, path):
738
        sql = 'select name from public where name = ?'
739
        c = self.con.execute(sql, (path,))
740
        row = c.fetchone()
741
        if not row:
742
            return False
743
        return True
744
    
745
    def _put_public(self, path, public):
746
        if not public:
747
            sql = 'delete from public where name = ?'
748
        else:
749
            sql = 'insert or replace into public (name) values (?)'
750
        self.con.execute(sql, (path,))
751
        self.con.commit()
752
    
726 753
    def _list_objects(self, path, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None):
727 754
        cont_prefix = path + '/'
728 755
        if keys and len(keys) > 0:
b/pithos/public/functions.py
65 65
    
66 66
    try:
67 67
        meta = backend.get_object_meta(request.user, v_account, v_container, v_object)
68
        permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
68
        public = backend.get_object_public(request.user, v_account, v_container, v_object)
69 69
    except:
70 70
        raise ItemNotFound('Object does not exist')
71 71
    
72
    # TODO: Fix public indicator.
73
    if 'public' not in permissions:
72
    if not public:
74 73
        raise ItemNotFound('Object does not exist')
75 74
    update_manifest_meta(request, v_account, meta)
76 75
    
......
91 90
    
92 91
    try:
93 92
        meta = backend.get_object_meta(request.user, v_account, v_container, v_object)
94
        permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
93
        public = backend.get_object_public(request.user, v_account, v_container, v_object)
95 94
    except:
96 95
        raise ItemNotFound('Object does not exist')
97 96
    
98
    # TODO: Fix public indicator.
99
    if 'public' not in permissions:
97
    if not public:
100 98
        raise ItemNotFound('Object does not exist')
101 99
    update_manifest_meta(request, v_account, meta)
102 100
    

Also available in: Unified diff