@@ -166,6 +166,21 @@ class ACL(object):
166
166
"""Container class representing a list of access controls."""
167
167
168
168
_URL_PATH_ELEM = 'acl'
169
+ _PREDEFINED_QUERY_PARAM = 'predefinedAcl'
170
+
171
+ _PREDEFINED_ACLS = frozenset ([
172
+ 'private' ,
173
+ 'project-private' ,
174
+ 'public-read' ,
175
+ 'public-read-write' ,
176
+ 'authenticated-read' ,
177
+ 'bucket-owner-read' ,
178
+ 'bucket-owner-full-control' ,
179
+ ])
180
+ """See:
181
+ https://cloud.google.com/storage/docs/access-control#predefined-acl
182
+ """
183
+
169
184
loaded = False
170
185
171
186
# Subclasses must override to provide these attributes (typically,
@@ -385,6 +400,39 @@ def reload(self, client=None):
385
400
for entry in found .get ('items' , ()):
386
401
self .add_entity (self .entity_from_dict (entry ))
387
402
403
+ def _save (self , acl , predefined , client ):
404
+ """Helper for :meth:`save` and :meth:`save_predefined`.
405
+
406
+ :type acl: :class:`gcloud.storage.acl.ACL`, or a compatible list.
407
+ :param acl: The ACL object to save. If left blank, this will save
408
+ current entries.
409
+
410
+ :type predefined: string or None
411
+ :param predefined: An identifier for a predefined ACL. Must be one
412
+ of the keys in :attr:`_PREDEFINED_ACLS`
413
+ If passed, `acl` must be None.
414
+
415
+ :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
416
+ :param client: Optional. The client to use. If not passed, falls back
417
+ to the ``client`` stored on the ACL's parent.
418
+ """
419
+ query_params = {'projection' : 'full' }
420
+ if predefined is not None :
421
+ acl = []
422
+ query_params [self ._PREDEFINED_QUERY_PARAM ] = predefined
423
+
424
+ path = self .save_path
425
+ client = self ._require_client (client )
426
+ result = client .connection .api_request (
427
+ method = 'PATCH' ,
428
+ path = path ,
429
+ data = {self ._URL_PATH_ELEM : list (acl )},
430
+ query_params = query_params )
431
+ self .entities .clear ()
432
+ for entry in result .get (self ._URL_PATH_ELEM , ()):
433
+ self .add_entity (self .entity_from_dict (entry ))
434
+ self .loaded = True
435
+
388
436
def save (self , acl = None , client = None ):
389
437
"""Save this ACL for the current bucket.
390
438
@@ -403,17 +451,24 @@ def save(self, acl=None, client=None):
403
451
save_to_backend = True
404
452
405
453
if save_to_backend :
406
- path = self .save_path
407
- client = self ._require_client (client )
408
- result = client .connection .api_request (
409
- method = 'PATCH' ,
410
- path = path ,
411
- data = {self ._URL_PATH_ELEM : list (acl )},
412
- query_params = {'projection' : 'full' })
413
- self .entities .clear ()
414
- for entry in result .get (self ._URL_PATH_ELEM , ()):
415
- self .add_entity (self .entity_from_dict (entry ))
416
- self .loaded = True
454
+ self ._save (acl , None , client )
455
+
456
+ def save_predefined (self , predefined , client = None ):
457
+ """Save this ACL for the current bucket using a predefined ACL.
458
+
459
+ :type predefined: string
460
+ :param predefined: An identifier for a predefined ACL. Must be one
461
+ of the keys in :attr:`_PREDEFINED_ACLS`
462
+ If passed, `acl` must be None.
463
+
464
+ :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
465
+ :param client: Optional. The client to use. If not passed, falls back
466
+ to the ``client`` stored on the ACL's parent.
467
+ """
468
+ if predefined not in self ._PREDEFINED_ACLS :
469
+ raise ValueError ("Invalid predefined ACL: %s" % (predefined ,))
470
+
471
+ self ._save (None , predefined , client )
417
472
418
473
def clear (self , client = None ):
419
474
"""Remove all ACL entries.
@@ -461,6 +516,7 @@ class DefaultObjectACL(BucketACL):
461
516
"""A class representing the default object ACL for a bucket."""
462
517
463
518
_URL_PATH_ELEM = 'defaultObjectAcl'
519
+ _PREDEFINED_QUERY_PARAM = 'predefinedDefaultObjectAcl'
464
520
465
521
466
522
class ObjectACL (ACL ):
0 commit comments