Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

fix: disable always_use_jwt_access #217

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion .coveragerc
Expand Up @@ -2,7 +2,6 @@
branch = True

[report]
fail_under = 100
show_missing = True
omit =
google/cloud/asset/__init__.py
Expand Down
14 changes: 8 additions & 6 deletions google/cloud/asset_v1/services/asset_service/async_client.py
Expand Up @@ -955,12 +955,11 @@ async def search_all_resources(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
core_exceptions.DeadlineExceeded,
core_exceptions.ServiceUnavailable,
),
deadline=15.0,
deadline=30.0,
),
default_timeout=15.0,
default_timeout=30.0,
client_info=DEFAULT_CLIENT_INFO,
)

Expand Down Expand Up @@ -1067,6 +1066,10 @@ async def search_all_iam_policies(
find IAM policy bindings that are set on resources
"instance1" or "instance2" and also specify user
"amy".
- ``roles:roles/compute.admin`` to find IAM policy
bindings that specify the Compute Admin role.
- ``memberTypes:user`` to find IAM policy bindings that
contain the "user" member type.

This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
Expand Down Expand Up @@ -1113,12 +1116,11 @@ async def search_all_iam_policies(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
core_exceptions.DeadlineExceeded,
core_exceptions.ServiceUnavailable,
),
deadline=15.0,
deadline=30.0,
),
default_timeout=15.0,
default_timeout=30.0,
client_info=DEFAULT_CLIENT_INFO,
)

Expand Down
4 changes: 4 additions & 0 deletions google/cloud/asset_v1/services/asset_service/client.py
Expand Up @@ -1194,6 +1194,10 @@ def search_all_iam_policies(
find IAM policy bindings that are set on resources
"instance1" or "instance2" and also specify user
"amy".
- ``roles:roles/compute.admin`` to find IAM policy
bindings that specify the Compute Admin role.
- ``memberTypes:user`` to find IAM policy bindings that
contain the "user" member type.

This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
Expand Down
52 changes: 19 additions & 33 deletions google/cloud/asset_v1/services/asset_service/transports/base.py
Expand Up @@ -25,6 +25,7 @@
from google.api_core import retry as retries # type: ignore
from google.api_core import operations_v1 # type: ignore
from google.auth import credentials as ga_credentials # type: ignore
from google.oauth2 import service_account # type: ignore

from google.cloud.asset_v1.types import asset_service
from google.longrunning import operations_pb2 # type: ignore
Expand All @@ -46,8 +47,6 @@
except pkg_resources.DistributionNotFound: # pragma: NO COVER
_GOOGLE_AUTH_VERSION = None

_API_CORE_VERSION = google.api_core.__version__


class AssetServiceTransport(abc.ABC):
"""Abstract transport class for AssetService."""
Expand All @@ -65,6 +64,7 @@ def __init__(
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
**kwargs,
) -> None:
"""Instantiate the transport.
Expand All @@ -88,6 +88,8 @@ def __init__(
API requests. If ``None``, then default info will be used.
Generally, you only need to set this if you're developing
your own client library.
always_use_jwt_access (Optional[bool]): Whether self signed JWT should
be used for service account credentials.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
Expand All @@ -97,7 +99,7 @@ def __init__(
scopes_kwargs = self._get_scopes_kwargs(self._host, scopes)

# Save the scopes.
self._scopes = scopes or self.AUTH_SCOPES
self._scopes = scopes

# If no credentials are provided, then determine the appropriate
# defaults.
Expand All @@ -116,13 +118,20 @@ def __init__(
**scopes_kwargs, quota_project_id=quota_project_id
)

# If the credentials is service account credentials, then always try to use self signed JWT.
if (
always_use_jwt_access
and isinstance(credentials, service_account.Credentials)
and hasattr(service_account.Credentials, "with_always_use_jwt_access")
):
credentials = credentials.with_always_use_jwt_access(True)

# Save the credentials.
self._credentials = credentials

# TODO(busunkim): These two class methods are in the base transport
# TODO(busunkim): This method is in the base transport
# to avoid duplicating code across the transport classes. These functions
# should be deleted once the minimum required versions of google-api-core
# and google-auth are increased.
# should be deleted once the minimum required versions of google-auth is increased.

# TODO: Remove this function once google-auth >= 1.25.0 is required
@classmethod
Expand All @@ -143,27 +152,6 @@ def _get_scopes_kwargs(

return scopes_kwargs

# TODO: Remove this function once google-api-core >= 1.26.0 is required
@classmethod
def _get_self_signed_jwt_kwargs(
cls, host: str, scopes: Optional[Sequence[str]]
) -> Dict[str, Union[Optional[Sequence[str]], str]]:
"""Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version"""

self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {}

if _API_CORE_VERSION and (
packaging.version.parse(_API_CORE_VERSION)
>= packaging.version.parse("1.26.0")
):
self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES
self_signed_jwt_kwargs["scopes"] = scopes
self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST
else:
self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES

return self_signed_jwt_kwargs

def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
Expand Down Expand Up @@ -258,12 +246,11 @@ def _prep_wrapped_messages(self, client_info):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
core_exceptions.DeadlineExceeded,
core_exceptions.ServiceUnavailable,
),
deadline=15.0,
deadline=30.0,
),
default_timeout=15.0,
default_timeout=30.0,
client_info=client_info,
),
self.search_all_iam_policies: gapic_v1.method.wrap_method(
Expand All @@ -273,12 +260,11 @@ def _prep_wrapped_messages(self, client_info):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
core_exceptions.DeadlineExceeded,
core_exceptions.ServiceUnavailable,
),
deadline=15.0,
deadline=30.0,
),
default_timeout=15.0,
default_timeout=30.0,
client_info=client_info,
),
self.analyze_iam_policy: gapic_v1.method.wrap_method(
Expand Down
10 changes: 7 additions & 3 deletions google/cloud/asset_v1/services/asset_service/transports/grpc.py
Expand Up @@ -60,6 +60,7 @@ def __init__(
client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
) -> None:
"""Instantiate the transport.

Expand Down Expand Up @@ -100,6 +101,8 @@ def __init__(
API requests. If ``None``, then default info will be used.
Generally, you only need to set this if you're developing
your own client library.
always_use_jwt_access (Optional[bool]): Whether self signed JWT should
be used for service account credentials.

Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
Expand Down Expand Up @@ -153,6 +156,7 @@ def __init__(
scopes=scopes,
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
)

if not self._grpc_channel:
Expand Down Expand Up @@ -208,14 +212,14 @@ def create_channel(
and ``credentials_file`` are passed.
"""

self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes)

return grpc_helpers.create_channel(
host,
credentials=credentials,
credentials_file=credentials_file,
quota_project_id=quota_project_id,
**self_signed_jwt_kwargs,
default_scopes=cls.AUTH_SCOPES,
scopes=scopes,
default_host=cls.DEFAULT_HOST,
**kwargs,
)

Expand Down
Expand Up @@ -81,14 +81,14 @@ def create_channel(
aio.Channel: A gRPC AsyncIO channel object.
"""

self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes)

return grpc_helpers_async.create_channel(
host,
credentials=credentials,
credentials_file=credentials_file,
quota_project_id=quota_project_id,
**self_signed_jwt_kwargs,
default_scopes=cls.AUTH_SCOPES,
scopes=scopes,
default_host=cls.DEFAULT_HOST,
**kwargs,
)

Expand All @@ -106,6 +106,7 @@ def __init__(
client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
quota_project_id=None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
) -> None:
"""Instantiate the transport.

Expand Down Expand Up @@ -147,6 +148,8 @@ def __init__(
API requests. If ``None``, then default info will be used.
Generally, you only need to set this if you're developing
your own client library.
always_use_jwt_access (Optional[bool]): Whether self signed JWT should
be used for service account credentials.

Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
Expand Down Expand Up @@ -199,6 +202,7 @@ def __init__(
scopes=scopes,
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
)

if not self._grpc_channel:
Expand Down
39 changes: 39 additions & 0 deletions google/cloud/asset_v1/types/asset_service.py
Expand Up @@ -879,6 +879,10 @@ class SearchAllIamPoliciesRequest(proto.Message):
- ``resource:(instance1 OR instance2) policy:amy`` to find
IAM policy bindings that are set on resources "instance1"
or "instance2" and also specify user "amy".
- ``roles:roles/compute.admin`` to find IAM policy bindings
that specify the Compute Admin role.
- ``memberTypes:user`` to find IAM policy bindings that
contain the "user" member type.
page_size (int):
Optional. The page size for search result pagination. Page
size is capped at 500 even if a larger value is given. If
Expand All @@ -892,12 +896,47 @@ class SearchAllIamPoliciesRequest(proto.Message):
be the value of ``next_page_token`` from the previous
response. The values of all other method parameters must be
identical to those in the previous call.
asset_types (Sequence[str]):
Optional. A list of asset types that the IAM policies are
attached to. If empty, it will search the IAM policies that
are attached to all the `searchable asset
types <https://cloud.google.com/asset-inventory/docs/supported-asset-types#searchable_asset_types>`__.

Regular expressions are also supported. For example:

- "compute.googleapis.com.*" snapshots IAM policies
attached to asset type starts with
"compute.googleapis.com".
- ".*Instance" snapshots IAM policies attached to asset
type ends with "Instance".
- ".*Instance.*" snapshots IAM policies attached to asset
type contains "Instance".

See `RE2 <https://github.com/google/re2/wiki/Syntax>`__ for
all supported regular expression syntax. If the regular
expression does not match any supported asset type, an
INVALID_ARGUMENT error will be returned.
order_by (str):
Optional. A comma-separated list of fields specifying the
sorting order of the results. The default order is
ascending. Add " DESC" after the field name to indicate
descending order. Redundant space characters are ignored.
Example: "assetType DESC, resource". Only singular primitive
fields in the response are sortable:

- resource
- assetType
- project All the other fields such as repeated fields
(e.g., ``folders``) and non-primitive fields (e.g.,
``policy``) are not supported.
"""

scope = proto.Field(proto.STRING, number=1,)
query = proto.Field(proto.STRING, number=2,)
page_size = proto.Field(proto.INT32, number=3,)
page_token = proto.Field(proto.STRING, number=4,)
asset_types = proto.RepeatedField(proto.STRING, number=5,)
order_by = proto.Field(proto.STRING, number=7,)


class SearchAllIamPoliciesResponse(proto.Message):
Expand Down
32 changes: 32 additions & 0 deletions google/cloud/asset_v1/types/assets.py
Expand Up @@ -518,6 +518,13 @@ class IamPolicySearchResult(proto.Message):

- use a field query. Example:
``resource:organizations/123``
asset_type (str):
The type of the resource associated with this IAM policy.
Example: ``compute.googleapis.com/Disk``.

To search against the ``asset_type``:

- specify the ``asset_types`` field in your search request.
project (str):
The project that the associated GCP resource belongs to, in
the form of projects/{PROJECT_NUMBER}. If an IAM policy is
Expand All @@ -530,6 +537,28 @@ class IamPolicySearchResult(proto.Message):

- specify the ``scope`` field as this project in your
search request.
folders (Sequence[str]):
The folder(s) that the IAM policy belongs to, in the form of
folders/{FOLDER_NUMBER}. This field is available when the
IAM policy belongs to one or more folders.

To search against ``folders``:

- use a field query. Example: ``folders:(123 OR 456)``
- use a free text query. Example: ``123``
- specify the ``scope`` field as this folder in your search
request.
organization (str):
The organization that the IAM policy belongs to, in the form
of organizations/{ORGANIZATION_NUMBER}. This field is
available when the IAM policy belongs to an organization.

To search against ``organization``:

- use a field query. Example: ``organization:123``
- use a free text query. Example: ``123``
- specify the ``scope`` field as this organization in your
search request.
policy (google.iam.v1.policy_pb2.Policy):
The IAM policy directly set on the given resource. Note that
the original IAM policy can contain multiple bindings. This
Expand Down Expand Up @@ -588,7 +617,10 @@ class Permissions(proto.Message):
)

resource = proto.Field(proto.STRING, number=1,)
asset_type = proto.Field(proto.STRING, number=5,)
project = proto.Field(proto.STRING, number=2,)
folders = proto.RepeatedField(proto.STRING, number=6,)
organization = proto.Field(proto.STRING, number=7,)
policy = proto.Field(proto.MESSAGE, number=3, message=policy_pb2.Policy,)
explanation = proto.Field(proto.MESSAGE, number=4, message=Explanation,)

Expand Down