1# Copyright 2014 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Manage access to objects and buckets."""
16
17from google.cloud.storage._helpers import _add_generation_match_parameters
18from google.cloud.storage._opentelemetry_tracing import create_trace_span
19from google.cloud.storage.constants import _DEFAULT_TIMEOUT
20from google.cloud.storage.retry import DEFAULT_RETRY
21from google.cloud.storage.retry import DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED
22
23
24class _ACLEntity(object):
25 """Class representing a set of roles for an entity.
26
27 This is a helper class that you likely won't ever construct
28 outside of using the factor methods on the :class:`ACL` object.
29
30 :type entity_type: str
31 :param entity_type: The type of entity (ie, 'group' or 'user').
32
33 :type identifier: str
34 :param identifier: (Optional) The ID or e-mail of the entity. For the special
35 entity types (like 'allUsers').
36 """
37
38 READER_ROLE = "READER"
39 WRITER_ROLE = "WRITER"
40 OWNER_ROLE = "OWNER"
41
42 def __init__(self, entity_type, identifier=None):
43 self.identifier = identifier
44 self.roles = set([])
45 self.type = entity_type
46
47 def __str__(self):
48 if not self.identifier:
49 return str(self.type)
50 else:
51 return "{acl.type}-{acl.identifier}".format(acl=self)
52
53 def __repr__(self):
54 return f"<ACL Entity: {self} ({', '.join(self.roles)})>"
55
56 def get_roles(self):
57 """Get the list of roles permitted by this entity.
58
59 :rtype: list of strings
60 :returns: The list of roles associated with this entity.
61 """
62 return self.roles
63
64 def grant(self, role):
65 """Add a role to the entity.
66
67 :type role: str
68 :param role: The role to add to the entity.
69 """
70 self.roles.add(role)
71
72 def revoke(self, role):
73 """Remove a role from the entity.
74
75 :type role: str
76 :param role: The role to remove from the entity.
77 """
78 if role in self.roles:
79 self.roles.remove(role)
80
81 def grant_read(self):
82 """Grant read access to the current entity."""
83 self.grant(_ACLEntity.READER_ROLE)
84
85 def grant_write(self):
86 """Grant write access to the current entity."""
87 self.grant(_ACLEntity.WRITER_ROLE)
88
89 def grant_owner(self):
90 """Grant owner access to the current entity."""
91 self.grant(_ACLEntity.OWNER_ROLE)
92
93 def revoke_read(self):
94 """Revoke read access from the current entity."""
95 self.revoke(_ACLEntity.READER_ROLE)
96
97 def revoke_write(self):
98 """Revoke write access from the current entity."""
99 self.revoke(_ACLEntity.WRITER_ROLE)
100
101 def revoke_owner(self):
102 """Revoke owner access from the current entity."""
103 self.revoke(_ACLEntity.OWNER_ROLE)
104
105
106class ACL(object):
107 """Container class representing a list of access controls."""
108
109 _URL_PATH_ELEM = "acl"
110 _PREDEFINED_QUERY_PARAM = "predefinedAcl"
111
112 PREDEFINED_XML_ACLS = {
113 # XML API name -> JSON API name
114 "project-private": "projectPrivate",
115 "public-read": "publicRead",
116 "public-read-write": "publicReadWrite",
117 "authenticated-read": "authenticatedRead",
118 "bucket-owner-read": "bucketOwnerRead",
119 "bucket-owner-full-control": "bucketOwnerFullControl",
120 }
121
122 PREDEFINED_JSON_ACLS = frozenset(
123 [
124 "private",
125 "projectPrivate",
126 "publicRead",
127 "publicReadWrite",
128 "authenticatedRead",
129 "bucketOwnerRead",
130 "bucketOwnerFullControl",
131 ]
132 )
133 """See
134 https://cloud.google.com/storage/docs/access-control/lists#predefined-acl
135 """
136
137 loaded = False
138
139 # Subclasses must override to provide these attributes (typically,
140 # as properties).
141 reload_path = None
142 save_path = None
143 user_project = None
144
145 def __init__(self):
146 self.entities = {}
147
148 def _ensure_loaded(self, timeout=_DEFAULT_TIMEOUT):
149 """Load if not already loaded.
150
151 :type timeout: float or tuple
152 :param timeout:
153 (Optional) The amount of time, in seconds, to wait
154 for the server response. See: :ref:`configuring_timeouts`
155 """
156 if not self.loaded:
157 self.reload(timeout=timeout)
158
159 @classmethod
160 def validate_predefined(cls, predefined):
161 """Ensures predefined is in list of predefined json values
162
163 :type predefined: str
164 :param predefined: name of a predefined acl
165
166 :type predefined: str
167 :param predefined: validated JSON name of predefined acl
168
169 :raises: :exc: `ValueError`: If predefined is not a valid acl
170 """
171 predefined = cls.PREDEFINED_XML_ACLS.get(predefined, predefined)
172 if predefined and predefined not in cls.PREDEFINED_JSON_ACLS:
173 raise ValueError(f"Invalid predefined ACL: {predefined}")
174 return predefined
175
176 def reset(self):
177 """Remove all entities from the ACL, and clear the ``loaded`` flag."""
178 self.entities.clear()
179 self.loaded = False
180
181 def __iter__(self):
182 self._ensure_loaded()
183
184 for entity in self.entities.values():
185 for role in entity.get_roles():
186 if role:
187 yield {"entity": str(entity), "role": role}
188
189 def entity_from_dict(self, entity_dict):
190 """Build an _ACLEntity object from a dictionary of data.
191
192 An entity is a mutable object that represents a list of roles
193 belonging to either a user or group or the special types for all
194 users and all authenticated users.
195
196 :type entity_dict: dict
197 :param entity_dict: Dictionary full of data from an ACL lookup.
198
199 :rtype: :class:`_ACLEntity`
200 :returns: An Entity constructed from the dictionary.
201 """
202 entity = entity_dict["entity"]
203 role = entity_dict["role"]
204
205 if entity == "allUsers":
206 entity = self.all()
207
208 elif entity == "allAuthenticatedUsers":
209 entity = self.all_authenticated()
210
211 elif "-" in entity:
212 entity_type, identifier = entity.split("-", 1)
213 entity = self.entity(entity_type=entity_type, identifier=identifier)
214
215 if not isinstance(entity, _ACLEntity):
216 raise ValueError(f"Invalid dictionary: {entity_dict}")
217
218 entity.grant(role)
219 return entity
220
221 def has_entity(self, entity):
222 """Returns whether or not this ACL has any entries for an entity.
223
224 :type entity: :class:`_ACLEntity`
225 :param entity: The entity to check for existence in this ACL.
226
227 :rtype: bool
228 :returns: True of the entity exists in the ACL.
229 """
230 self._ensure_loaded()
231 return str(entity) in self.entities
232
233 def get_entity(self, entity, default=None):
234 """Gets an entity object from the ACL.
235
236 :type entity: :class:`_ACLEntity` or string
237 :param entity: The entity to get lookup in the ACL.
238
239 :type default: anything
240 :param default: This value will be returned if the entity
241 doesn't exist.
242
243 :rtype: :class:`_ACLEntity`
244 :returns: The corresponding entity or the value provided
245 to ``default``.
246 """
247 self._ensure_loaded()
248 return self.entities.get(str(entity), default)
249
250 def add_entity(self, entity):
251 """Add an entity to the ACL.
252
253 :type entity: :class:`_ACLEntity`
254 :param entity: The entity to add to this ACL.
255 """
256 self._ensure_loaded()
257 self.entities[str(entity)] = entity
258
259 def entity(self, entity_type, identifier=None):
260 """Factory method for creating an Entity.
261
262 If an entity with the same type and identifier already exists,
263 this will return a reference to that entity. If not, it will
264 create a new one and add it to the list of known entities for
265 this ACL.
266
267 :type entity_type: str
268 :param entity_type: The type of entity to create
269 (ie, ``user``, ``group``, etc)
270
271 :type identifier: str
272 :param identifier: The ID of the entity (if applicable).
273 This can be either an ID or an e-mail address.
274
275 :rtype: :class:`_ACLEntity`
276 :returns: A new Entity or a reference to an existing identical entity.
277 """
278 entity = _ACLEntity(entity_type=entity_type, identifier=identifier)
279 if self.has_entity(entity):
280 entity = self.get_entity(entity)
281 else:
282 self.add_entity(entity)
283 return entity
284
285 def user(self, identifier):
286 """Factory method for a user Entity.
287
288 :type identifier: str
289 :param identifier: An id or e-mail for this particular user.
290
291 :rtype: :class:`_ACLEntity`
292 :returns: An Entity corresponding to this user.
293 """
294 return self.entity("user", identifier=identifier)
295
296 def group(self, identifier):
297 """Factory method for a group Entity.
298
299 :type identifier: str
300 :param identifier: An id or e-mail for this particular group.
301
302 :rtype: :class:`_ACLEntity`
303 :returns: An Entity corresponding to this group.
304 """
305 return self.entity("group", identifier=identifier)
306
307 def domain(self, domain):
308 """Factory method for a domain Entity.
309
310 :type domain: str
311 :param domain: The domain for this entity.
312
313 :rtype: :class:`_ACLEntity`
314 :returns: An entity corresponding to this domain.
315 """
316 return self.entity("domain", identifier=domain)
317
318 def all(self):
319 """Factory method for an Entity representing all users.
320
321 :rtype: :class:`_ACLEntity`
322 :returns: An entity representing all users.
323 """
324 return self.entity("allUsers")
325
326 def all_authenticated(self):
327 """Factory method for an Entity representing all authenticated users.
328
329 :rtype: :class:`_ACLEntity`
330 :returns: An entity representing all authenticated users.
331 """
332 return self.entity("allAuthenticatedUsers")
333
334 def get_entities(self):
335 """Get a list of all Entity objects.
336
337 :rtype: list of :class:`_ACLEntity` objects
338 :returns: A list of all Entity objects.
339 """
340 self._ensure_loaded()
341 return list(self.entities.values())
342
343 @property
344 def client(self):
345 """Abstract getter for the object client."""
346 raise NotImplementedError
347
348 def _require_client(self, client):
349 """Check client or verify over-ride.
350
351 :type client: :class:`~google.cloud.storage.client.Client` or
352 ``NoneType``
353 :param client: the client to use. If not passed, falls back to the
354 ``client`` stored on the current ACL.
355
356 :rtype: :class:`google.cloud.storage.client.Client`
357 :returns: The client passed in or the currently bound client.
358 """
359 if client is None:
360 client = self.client
361 return client
362
363 def reload(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
364 """Reload the ACL data from Cloud Storage.
365
366 If :attr:`user_project` is set, bills the API request to that project.
367
368 :type client: :class:`~google.cloud.storage.client.Client` or
369 ``NoneType``
370 :param client: (Optional) The client to use. If not passed, falls back
371 to the ``client`` stored on the ACL's parent.
372 :type timeout: float or tuple
373 :param timeout:
374 (Optional) The amount of time, in seconds, to wait
375 for the server response. See: :ref:`configuring_timeouts`
376
377 :type retry: :class:`~google.api_core.retry.Retry`
378 :param retry:
379 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
380 """
381 with create_trace_span(name="Storage.ACL.reload"):
382 path = self.reload_path
383 client = self._require_client(client)
384 query_params = {}
385
386 if self.user_project is not None:
387 query_params["userProject"] = self.user_project
388
389 self.entities.clear()
390
391 found = client._get_resource(
392 path,
393 query_params=query_params,
394 timeout=timeout,
395 retry=retry,
396 )
397 self.loaded = True
398
399 for entry in found.get("items", ()):
400 self.add_entity(self.entity_from_dict(entry))
401
402 def _save(
403 self,
404 acl,
405 predefined,
406 client,
407 if_generation_match=None,
408 if_generation_not_match=None,
409 if_metageneration_match=None,
410 if_metageneration_not_match=None,
411 timeout=_DEFAULT_TIMEOUT,
412 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
413 ):
414 """Helper for :meth:`save` and :meth:`save_predefined`.
415
416 :type acl: :class:`google.cloud.storage.acl.ACL`, or a compatible list.
417 :param acl: The ACL object to save. If left blank, this will save
418 current entries.
419
420 :type predefined: str
421 :param predefined: An identifier for a predefined ACL. Must be one of the
422 keys in :attr:`PREDEFINED_JSON_ACLS` If passed, `acl` must be None.
423
424 :type client: :class:`~google.cloud.storage.client.Client` or
425 ``NoneType``
426 :param client: (Optional) The client to use. If not passed, falls back
427 to the ``client`` stored on the ACL's parent.
428
429 :type if_generation_match: long
430 :param if_generation_match:
431 (Optional) See :ref:`using-if-generation-match`
432
433 :type if_generation_not_match: long
434 :param if_generation_not_match:
435 (Optional) See :ref:`using-if-generation-not-match`
436
437 :type if_metageneration_match: long
438 :param if_metageneration_match:
439 (Optional) See :ref:`using-if-metageneration-match`
440
441 :type if_metageneration_not_match: long
442 :param if_metageneration_not_match:
443 (Optional) See :ref:`using-if-metageneration-not-match`
444
445 :type timeout: float or tuple
446 :param timeout:
447 (Optional) The amount of time, in seconds, to wait
448 for the server response. See: :ref:`configuring_timeouts`
449
450 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
451 :param retry:
452 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
453 """
454 client = self._require_client(client)
455 query_params = {"projection": "full"}
456
457 if predefined is not None:
458 acl = []
459 query_params[self._PREDEFINED_QUERY_PARAM] = predefined
460
461 if self.user_project is not None:
462 query_params["userProject"] = self.user_project
463
464 _add_generation_match_parameters(
465 query_params,
466 if_generation_match=if_generation_match,
467 if_generation_not_match=if_generation_not_match,
468 if_metageneration_match=if_metageneration_match,
469 if_metageneration_not_match=if_metageneration_not_match,
470 )
471
472 path = self.save_path
473
474 result = client._patch_resource(
475 path,
476 {self._URL_PATH_ELEM: list(acl)},
477 query_params=query_params,
478 timeout=timeout,
479 retry=retry,
480 )
481
482 self.entities.clear()
483
484 for entry in result.get(self._URL_PATH_ELEM, ()):
485 self.add_entity(self.entity_from_dict(entry))
486
487 self.loaded = True
488
489 def save(
490 self,
491 acl=None,
492 client=None,
493 if_generation_match=None,
494 if_generation_not_match=None,
495 if_metageneration_match=None,
496 if_metageneration_not_match=None,
497 timeout=_DEFAULT_TIMEOUT,
498 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
499 ):
500 """Save this ACL for the current bucket.
501
502 If :attr:`user_project` is set, bills the API request to that project.
503
504 :type acl: :class:`google.cloud.storage.acl.ACL`, or a compatible list.
505 :param acl: The ACL object to save. If left blank, this will save
506 current entries.
507
508 :type client: :class:`~google.cloud.storage.client.Client` or
509 ``NoneType``
510 :param client: (Optional) The client to use. If not passed, falls back
511 to the ``client`` stored on the ACL's parent.
512
513 :type if_generation_match: long
514 :param if_generation_match:
515 (Optional) See :ref:`using-if-generation-match`
516
517 :type if_generation_not_match: long
518 :param if_generation_not_match:
519 (Optional) See :ref:`using-if-generation-not-match`
520
521 :type if_metageneration_match: long
522 :param if_metageneration_match:
523 (Optional) See :ref:`using-if-metageneration-match`
524
525 :type if_metageneration_not_match: long
526 :param if_metageneration_not_match:
527 (Optional) See :ref:`using-if-metageneration-not-match`
528
529 :type timeout: float or tuple
530 :param timeout:
531 (Optional) The amount of time, in seconds, to wait
532 for the server response. See: :ref:`configuring_timeouts`
533
534 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
535 :param retry:
536 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
537 """
538 with create_trace_span(name="Storage.ACL.save"):
539 if acl is None:
540 acl = self
541 save_to_backend = acl.loaded
542 else:
543 save_to_backend = True
544
545 if save_to_backend:
546 self._save(
547 acl,
548 None,
549 client,
550 if_generation_match=if_generation_match,
551 if_generation_not_match=if_generation_not_match,
552 if_metageneration_match=if_metageneration_match,
553 if_metageneration_not_match=if_metageneration_not_match,
554 timeout=timeout,
555 retry=retry,
556 )
557
558 def save_predefined(
559 self,
560 predefined,
561 client=None,
562 if_generation_match=None,
563 if_generation_not_match=None,
564 if_metageneration_match=None,
565 if_metageneration_not_match=None,
566 timeout=_DEFAULT_TIMEOUT,
567 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
568 ):
569 """Save this ACL for the current bucket using a predefined ACL.
570
571 If :attr:`user_project` is set, bills the API request to that project.
572
573 :type predefined: str
574 :param predefined: An identifier for a predefined ACL. Must be one
575 of the keys in :attr:`PREDEFINED_JSON_ACLS`
576 or :attr:`PREDEFINED_XML_ACLS` (which will be
577 aliased to the corresponding JSON name).
578 If passed, `acl` must be None.
579
580 :type client: :class:`~google.cloud.storage.client.Client` or
581 ``NoneType``
582 :param client: (Optional) The client to use. If not passed, falls back
583 to the ``client`` stored on the ACL's parent.
584
585 :type if_generation_match: long
586 :param if_generation_match:
587 (Optional) See :ref:`using-if-generation-match`
588
589 :type if_generation_not_match: long
590 :param if_generation_not_match:
591 (Optional) See :ref:`using-if-generation-not-match`
592
593 :type if_metageneration_match: long
594 :param if_metageneration_match:
595 (Optional) See :ref:`using-if-metageneration-match`
596
597 :type if_metageneration_not_match: long
598 :param if_metageneration_not_match:
599 (Optional) See :ref:`using-if-metageneration-not-match`
600
601 :type timeout: float or tuple
602 :param timeout:
603 (Optional) The amount of time, in seconds, to wait
604 for the server response. See: :ref:`configuring_timeouts`
605
606 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
607 :param retry:
608 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
609 """
610 with create_trace_span(name="Storage.ACL.savePredefined"):
611 predefined = self.validate_predefined(predefined)
612 self._save(
613 None,
614 predefined,
615 client,
616 if_generation_match=if_generation_match,
617 if_generation_not_match=if_generation_not_match,
618 if_metageneration_match=if_metageneration_match,
619 if_metageneration_not_match=if_metageneration_not_match,
620 timeout=timeout,
621 retry=retry,
622 )
623
624 def clear(
625 self,
626 client=None,
627 if_generation_match=None,
628 if_generation_not_match=None,
629 if_metageneration_match=None,
630 if_metageneration_not_match=None,
631 timeout=_DEFAULT_TIMEOUT,
632 retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
633 ):
634 """Remove all ACL entries.
635
636 If :attr:`user_project` is set, bills the API request to that project.
637
638 Note that this won't actually remove *ALL* the rules, but it
639 will remove all the non-default rules. In short, you'll still
640 have access to a bucket that you created even after you clear
641 ACL rules with this method.
642
643 :type client: :class:`~google.cloud.storage.client.Client` or
644 ``NoneType``
645 :param client: (Optional) The client to use. If not passed, falls back
646 to the ``client`` stored on the ACL's parent.
647
648 :type if_generation_match: long
649 :param if_generation_match:
650 (Optional) See :ref:`using-if-generation-match`
651
652 :type if_generation_not_match: long
653 :param if_generation_not_match:
654 (Optional) See :ref:`using-if-generation-not-match`
655
656 :type if_metageneration_match: long
657 :param if_metageneration_match:
658 (Optional) See :ref:`using-if-metageneration-match`
659
660 :type if_metageneration_not_match: long
661 :param if_metageneration_not_match:
662 (Optional) See :ref:`using-if-metageneration-not-match`
663
664 :type timeout: float or tuple
665 :param timeout:
666 (Optional) The amount of time, in seconds, to wait
667 for the server response. See: :ref:`configuring_timeouts`
668
669 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
670 :param retry:
671 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
672 """
673 with create_trace_span(name="Storage.ACL.clear"):
674 self.save(
675 [],
676 client=client,
677 if_generation_match=if_generation_match,
678 if_generation_not_match=if_generation_not_match,
679 if_metageneration_match=if_metageneration_match,
680 if_metageneration_not_match=if_metageneration_not_match,
681 timeout=timeout,
682 retry=retry,
683 )
684
685
686class BucketACL(ACL):
687 """An ACL specifically for a bucket.
688
689 :type bucket: :class:`google.cloud.storage.bucket.Bucket`
690 :param bucket: The bucket to which this ACL relates.
691 """
692
693 def __init__(self, bucket):
694 super(BucketACL, self).__init__()
695 self.bucket = bucket
696
697 @property
698 def client(self):
699 """The client bound to this ACL's bucket."""
700 return self.bucket.client
701
702 @property
703 def reload_path(self):
704 """Compute the path for GET API requests for this ACL."""
705 return f"{self.bucket.path}/{self._URL_PATH_ELEM}"
706
707 @property
708 def save_path(self):
709 """Compute the path for PATCH API requests for this ACL."""
710 return self.bucket.path
711
712 @property
713 def user_project(self):
714 """Compute the user project charged for API requests for this ACL."""
715 return self.bucket.user_project
716
717
718class DefaultObjectACL(BucketACL):
719 """A class representing the default object ACL for a bucket."""
720
721 _URL_PATH_ELEM = "defaultObjectAcl"
722 _PREDEFINED_QUERY_PARAM = "predefinedDefaultObjectAcl"
723
724
725class ObjectACL(ACL):
726 """An ACL specifically for a Cloud Storage object / blob.
727
728 :type blob: :class:`google.cloud.storage.blob.Blob`
729 :param blob: The blob that this ACL corresponds to.
730 """
731
732 def __init__(self, blob):
733 super(ObjectACL, self).__init__()
734 self.blob = blob
735
736 @property
737 def client(self):
738 """The client bound to this ACL's blob."""
739 return self.blob.client
740
741 @property
742 def reload_path(self):
743 """Compute the path for GET API requests for this ACL."""
744 return f"{self.blob.path}/acl"
745
746 @property
747 def save_path(self):
748 """Compute the path for PATCH API requests for this ACL."""
749 return self.blob.path
750
751 @property
752 def user_project(self):
753 """Compute the user project charged for API requests for this ACL."""
754 return self.blob.user_project
755
756 def save(
757 self,
758 acl=None,
759 client=None,
760 if_generation_match=None,
761 if_generation_not_match=None,
762 if_metageneration_match=None,
763 if_metageneration_not_match=None,
764 timeout=_DEFAULT_TIMEOUT,
765 retry=DEFAULT_RETRY,
766 ):
767 """Save this ACL for the current object.
768
769 If :attr:`user_project` is set, bills the API request to that project.
770
771 :type acl: :class:`google.cloud.storage.acl.ACL`, or a compatible list.
772 :param acl: The ACL object to save. If left blank, this will save
773 current entries.
774
775 :type client: :class:`~google.cloud.storage.client.Client` or
776 ``NoneType``
777 :param client: (Optional) The client to use. If not passed, falls back
778 to the ``client`` stored on the ACL's parent.
779
780 :type if_generation_match: long
781 :param if_generation_match:
782 (Optional) See :ref:`using-if-generation-match`
783
784 :type if_generation_not_match: long
785 :param if_generation_not_match:
786 (Optional) See :ref:`using-if-generation-not-match`
787
788 :type if_metageneration_match: long
789 :param if_metageneration_match:
790 (Optional) See :ref:`using-if-metageneration-match`
791
792 :type if_metageneration_not_match: long
793 :param if_metageneration_not_match:
794 (Optional) See :ref:`using-if-metageneration-not-match`
795
796 :type timeout: float or tuple
797 :param timeout:
798 (Optional) The amount of time, in seconds, to wait
799 for the server response. See: :ref:`configuring_timeouts`
800
801 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
802 :param retry:
803 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
804 """
805 super().save(
806 acl=acl,
807 client=client,
808 if_generation_match=if_generation_match,
809 if_generation_not_match=if_generation_not_match,
810 if_metageneration_match=if_metageneration_match,
811 if_metageneration_not_match=if_metageneration_not_match,
812 timeout=timeout,
813 retry=retry,
814 )
815
816 def save_predefined(
817 self,
818 predefined,
819 client=None,
820 if_generation_match=None,
821 if_generation_not_match=None,
822 if_metageneration_match=None,
823 if_metageneration_not_match=None,
824 timeout=_DEFAULT_TIMEOUT,
825 retry=DEFAULT_RETRY,
826 ):
827 """Save this ACL for the current object using a predefined ACL.
828
829 If :attr:`user_project` is set, bills the API request to that project.
830
831 :type predefined: str
832 :param predefined: An identifier for a predefined ACL. Must be one
833 of the keys in :attr:`PREDEFINED_JSON_ACLS`
834 or :attr:`PREDEFINED_XML_ACLS` (which will be
835 aliased to the corresponding JSON name).
836 If passed, `acl` must be None.
837
838 :type client: :class:`~google.cloud.storage.client.Client` or
839 ``NoneType``
840 :param client: (Optional) The client to use. If not passed, falls back
841 to the ``client`` stored on the ACL's parent.
842
843 :type if_generation_match: long
844 :param if_generation_match:
845 (Optional) See :ref:`using-if-generation-match`
846
847 :type if_generation_not_match: long
848 :param if_generation_not_match:
849 (Optional) See :ref:`using-if-generation-not-match`
850
851 :type if_metageneration_match: long
852 :param if_metageneration_match:
853 (Optional) See :ref:`using-if-metageneration-match`
854
855 :type if_metageneration_not_match: long
856 :param if_metageneration_not_match:
857 (Optional) See :ref:`using-if-metageneration-not-match`
858
859 :type timeout: float or tuple
860 :param timeout:
861 (Optional) The amount of time, in seconds, to wait
862 for the server response. See: :ref:`configuring_timeouts`
863
864 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
865 :param retry:
866 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
867 """
868 super().save_predefined(
869 predefined=predefined,
870 client=client,
871 if_generation_match=if_generation_match,
872 if_generation_not_match=if_generation_not_match,
873 if_metageneration_match=if_metageneration_match,
874 if_metageneration_not_match=if_metageneration_not_match,
875 timeout=timeout,
876 retry=retry,
877 )
878
879 def clear(
880 self,
881 client=None,
882 if_generation_match=None,
883 if_generation_not_match=None,
884 if_metageneration_match=None,
885 if_metageneration_not_match=None,
886 timeout=_DEFAULT_TIMEOUT,
887 retry=DEFAULT_RETRY,
888 ):
889 """Remove all ACL entries.
890
891 If :attr:`user_project` is set, bills the API request to that project.
892
893 Note that this won't actually remove *ALL* the rules, but it
894 will remove all the non-default rules. In short, you'll still
895 have access to a bucket that you created even after you clear
896 ACL rules with this method.
897
898 :type client: :class:`~google.cloud.storage.client.Client` or
899 ``NoneType``
900 :param client: (Optional) The client to use. If not passed, falls back
901 to the ``client`` stored on the ACL's parent.
902
903 :type if_generation_match: long
904 :param if_generation_match:
905 (Optional) See :ref:`using-if-generation-match`
906
907 :type if_generation_not_match: long
908 :param if_generation_not_match:
909 (Optional) See :ref:`using-if-generation-not-match`
910
911 :type if_metageneration_match: long
912 :param if_metageneration_match:
913 (Optional) See :ref:`using-if-metageneration-match`
914
915 :type if_metageneration_not_match: long
916 :param if_metageneration_not_match:
917 (Optional) See :ref:`using-if-metageneration-not-match`
918
919 :type timeout: float or tuple
920 :param timeout:
921 (Optional) The amount of time, in seconds, to wait
922 for the server response. See: :ref:`configuring_timeouts`
923
924 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
925 :param retry:
926 (Optional) How to retry the RPC. See: :ref:`configuring_retries`
927 """
928 super().clear(
929 client=client,
930 if_generation_match=if_generation_match,
931 if_generation_not_match=if_generation_not_match,
932 if_metageneration_match=if_metageneration_match,
933 if_metageneration_not_match=if_metageneration_not_match,
934 timeout=timeout,
935 retry=retry,
936 )