Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 165 additions & 10 deletions google/cloud/storage/acl.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -84,8 +84,10 @@
when sending metadata for ACLs to the API.
"""

from google.cloud.storage._helpers import _add_generation_match_parameters
from google.cloud.storage.constants import _DEFAULT_TIMEOUT
from google.cloud.storage.retry import DEFAULT_RETRY
from google.cloud.storage.retry import DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED


class _ACLEntity(object):
Expand DownExpand Up@@ -465,7 +467,18 @@ def reload(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
for entry in found.get("items", ()):
self.add_entity(self.entity_from_dict(entry))

def _save(self, acl, predefined, client, timeout=_DEFAULT_TIMEOUT):
def _save(
self,
acl,
predefined,
client,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
if_metageneration_not_match=None,
timeout=_DEFAULT_TIMEOUT,
retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
):
"""Helper for :meth:`save` and :meth:`save_predefined`.

:type acl: :class:`google.cloud.storage.acl.ACL`, or a compatible list.
Expand All@@ -481,12 +494,28 @@ def _save(self, acl, predefined, client, timeout=_DEFAULT_TIMEOUT):
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the ACL's parent.

:type if_generation_match: long
:param if_generation_match:
(Optional) See :ref:`using-if-generation-match`

:type if_generation_not_match: long
:param if_generation_not_match:
(Optional) See :ref:`using-if-generation-not-match`

:type if_metageneration_match: long
:param if_metageneration_match:
(Optional) See :ref:`using-if-metageneration-match`

:type if_metageneration_not_match: long
:param if_metageneration_not_match:
(Optional) See :ref:`using-if-metageneration-not-match`

:type timeout: float or tuple
:param timeout:
(Optional) The amount of time, in seconds, to wait
for the server response. See: :ref:`configuring_timeouts`

:type retry: :class:`~google.api_core.retry.Retry`
:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
:param retry:
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
"""
Expand All@@ -500,14 +529,22 @@ def _save(self, acl, predefined, client, timeout=_DEFAULT_TIMEOUT):
if self.user_project is not None:
query_params["userProject"] = self.user_project

_add_generation_match_parameters(
query_params,
if_generation_match=if_generation_match,
if_generation_not_match=if_generation_not_match,
if_metageneration_match=if_metageneration_match,
if_metageneration_not_match=if_metageneration_not_match,
)

path = self.save_path

result = client._patch_resource(
path,
{self._URL_PATH_ELEM: list(acl)},
query_params=query_params,
timeout=timeout,
retry=None,
retry=retry,
)

self.entities.clear()
Expand All@@ -517,7 +554,17 @@ def _save(self, acl, predefined, client, timeout=_DEFAULT_TIMEOUT):

self.loaded = True

def save(self, acl=None, client=None, timeout=_DEFAULT_TIMEOUT):
def save(
self,
acl=None,
client=None,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
if_metageneration_not_match=None,
timeout=_DEFAULT_TIMEOUT,
retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
):
"""Save this ACL for the current bucket.

If :attr:`user_project` is set, bills the API request to that project.
Expand All@@ -531,10 +578,30 @@ def save(self, acl=None, client=None, timeout=_DEFAULT_TIMEOUT):
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the ACL's parent.

:type if_generation_match: long
:param if_generation_match:
(Optional) See :ref:`using-if-generation-match`

:type if_generation_not_match: long
:param if_generation_not_match:
(Optional) See :ref:`using-if-generation-not-match`

:type if_metageneration_match: long
:param if_metageneration_match:
(Optional) See :ref:`using-if-metageneration-match`

:type if_metageneration_not_match: long
:param if_metageneration_not_match:
(Optional) See :ref:`using-if-metageneration-not-match`

:type timeout: float or tuple
:param timeout:
(Optional) The amount of time, in seconds, to wait
for the server response. See: :ref:`configuring_timeouts`

:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
:param retry:
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
"""
if acl is None:
acl = self
Expand All@@ -543,9 +610,29 @@ def save(self, acl=None, client=None, timeout=_DEFAULT_TIMEOUT):
save_to_backend = True

if save_to_backend:
self._save(acl, None, client, timeout=timeout)

def save_predefined(self, predefined, client=None, timeout=_DEFAULT_TIMEOUT):
self._save(
acl,
None,
client,
if_generation_match=if_generation_match,
if_generation_not_match=if_generation_not_match,
if_metageneration_match=if_metageneration_match,
if_metageneration_not_match=if_metageneration_not_match,
timeout=timeout,
retry=retry,
)

def save_predefined(
self,
predefined,
client=None,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
if_metageneration_not_match=None,
timeout=_DEFAULT_TIMEOUT,
retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
):
"""Save this ACL for the current bucket using a predefined ACL.

If :attr:`user_project` is set, bills the API request to that project.
Expand All@@ -562,15 +649,54 @@ def save_predefined(self, predefined, client=None, timeout=_DEFAULT_TIMEOUT):
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the ACL's parent.

:type if_generation_match: long
:param if_generation_match:
(Optional) See :ref:`using-if-generation-match`

:type if_generation_not_match: long
:param if_generation_not_match:
(Optional) See :ref:`using-if-generation-not-match`

:type if_metageneration_match: long
:param if_metageneration_match:
(Optional) See :ref:`using-if-metageneration-match`

:type if_metageneration_not_match: long
:param if_metageneration_not_match:
(Optional) See :ref:`using-if-metageneration-not-match`

:type timeout: float or tuple
:param timeout:
(Optional) The amount of time, in seconds, to wait
for the server response. See: :ref:`configuring_timeouts`

:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
:param retry:
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
"""
predefined = self.validate_predefined(predefined)
self._save(None, predefined, client, timeout=timeout)
self._save(
None,
predefined,
client,
if_generation_match=if_generation_match,
if_generation_not_match=if_generation_not_match,
if_metageneration_match=if_metageneration_match,
if_metageneration_not_match=if_metageneration_not_match,
timeout=timeout,
retry=retry,
)

def clear(self, client=None, timeout=_DEFAULT_TIMEOUT):
def clear(
self,
client=None,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
if_metageneration_not_match=None,
timeout=_DEFAULT_TIMEOUT,
retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
):
"""Remove all ACL entries.

If :attr:`user_project` is set, bills the API request to that project.
Expand All@@ -585,12 +711,41 @@ def clear(self, client=None, timeout=_DEFAULT_TIMEOUT):
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the ACL's parent.

:type if_generation_match: long
:param if_generation_match:
(Optional) See :ref:`using-if-generation-match`

:type if_generation_not_match: long
:param if_generation_not_match:
(Optional) See :ref:`using-if-generation-not-match`

:type if_metageneration_match: long
:param if_metageneration_match:
(Optional) See :ref:`using-if-metageneration-match`

:type if_metageneration_not_match: long
:param if_metageneration_not_match:
(Optional) See :ref:`using-if-metageneration-not-match`

:type timeout: float or tuple
:param timeout:
(Optional) The amount of time, in seconds, to wait
for the server response. See: :ref:`configuring_timeouts`

:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
:param retry:
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
"""
self.save([], client=client, timeout=timeout)
self.save(
[],
client=client,
if_generation_match=if_generation_match,
if_generation_not_match=if_generation_not_match,
if_metageneration_match=if_metageneration_match,
if_metageneration_not_match=if_metageneration_not_match,
timeout=timeout,
retry=retry,
)


class BucketACL(ACL):
Expand Down
82 changes: 78 additions & 4 deletions google/cloud/storage/blob.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,6 +83,7 @@
from google.cloud.storage.retry import DEFAULT_RETRY
from google.cloud.storage.retry import DEFAULT_RETRY_IF_ETAG_IN_JSON
from google.cloud.storage.retry import DEFAULT_RETRY_IF_GENERATION_SPECIFIED
from google.cloud.storage.retry import DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED
from google.cloud.storage.fileio import BlobReader
from google.cloud.storage.fileio import BlobWriter

Expand DownExpand Up@@ -3226,7 +3227,16 @@ def test_iam_permissions(

return resp.get("permissions", [])

def make_public(self, client=None, timeout=_DEFAULT_TIMEOUT):
def make_public(
self,
client=None,
timeout=_DEFAULT_TIMEOUT,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
if_metageneration_not_match=None,
retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
):
"""Update blob's ACL, granting read access to anonymous users.

:type client: :class:`~google.cloud.storage.client.Client` or
Expand All@@ -3239,11 +3249,47 @@ def make_public(self, client=None, timeout=_DEFAULT_TIMEOUT):
(Optional) The amount of time, in seconds, to wait
for the server response. See: :ref:`configuring_timeouts`

:type if_generation_match: long
:param if_generation_match:
(Optional) See :ref:`using-if-generation-match`

:type if_generation_not_match: long
:param if_generation_not_match:
(Optional) See :ref:`using-if-generation-not-match`

:type if_metageneration_match: long
:param if_metageneration_match:
(Optional) See :ref:`using-if-metageneration-match`

:type if_metageneration_not_match: long
:param if_metageneration_not_match:
(Optional) See :ref:`using-if-metageneration-not-match`

:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
:param retry:
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
"""
self.acl.all().grant_read()
self.acl.save(client=client, timeout=timeout)
self.acl.save(
client=client,
timeout=timeout,
if_generation_match=if_generation_match,
if_generation_not_match=if_generation_not_match,
if_metageneration_match=if_metageneration_match,
if_metageneration_not_match=if_metageneration_not_match,
retry=retry,
)

def make_private(self, client=None, timeout=_DEFAULT_TIMEOUT):
def make_private(
self,
client=None,
timeout=_DEFAULT_TIMEOUT,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
if_metageneration_not_match=None,
retry=DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED,
):
"""Update blob's ACL, revoking read access for anonymous users.

:type client: :class:`~google.cloud.storage.client.Client` or
Expand All@@ -3255,9 +3301,37 @@ def make_private(self, client=None, timeout=_DEFAULT_TIMEOUT):
:param timeout:
(Optional) The amount of time, in seconds, to wait
for the server response. See: :ref:`configuring_timeouts`

:type if_generation_match: long
:param if_generation_match:
(Optional) See :ref:`using-if-generation-match`

:type if_generation_not_match: long
:param if_generation_not_match:
(Optional) See :ref:`using-if-generation-not-match`

:type if_metageneration_match: long
:param if_metageneration_match:
(Optional) See :ref:`using-if-metageneration-match`

:type if_metageneration_not_match: long
:param if_metageneration_not_match:
(Optional) See :ref:`using-if-metageneration-not-match`

:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
:param retry:
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
"""
self.acl.all().revoke_read()
self.acl.save(client=client, timeout=timeout)
self.acl.save(
client=client,
timeout=timeout,
if_generation_match=if_generation_match,
if_generation_not_match=if_generation_not_match,
if_metageneration_match=if_metageneration_match,
if_metageneration_not_match=if_metageneration_not_match,
retry=retry,
)

def compose(
self,
Expand Down
Loading