1# -*- coding: utf-8 -*-
2# Copyright 2020 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16from collections import OrderedDict
17from distutils import util
18import os
19import re
20from typing import Dict, Optional, Sequence, Tuple, Type, Union
21import pkg_resources
22
23from google.api_core import client_options as client_options_lib  # type: ignore
24from google.api_core import exceptions as core_exceptions  # type: ignore
25from google.api_core import gapic_v1  # type: ignore
26from google.api_core import retry as retries  # type: ignore
27from google.auth import credentials as ga_credentials  # type: ignore
28from google.auth.transport import mtls  # type: ignore
29from google.auth.transport.grpc import SslCredentials  # type: ignore
30from google.auth.exceptions import MutualTLSChannelError  # type: ignore
31from google.oauth2 import service_account  # type: ignore
32
33OptionalRetry = Union[retries.Retry, object]
34
35from google.cloud.iam_credentials_v1.types import common
36from google.protobuf import duration_pb2  # type: ignore
37from google.protobuf import timestamp_pb2  # type: ignore
38from .transports.base import IAMCredentialsTransport, DEFAULT_CLIENT_INFO
39from .transports.grpc import IAMCredentialsGrpcTransport
40from .transports.grpc_asyncio import IAMCredentialsGrpcAsyncIOTransport
41
42
43class IAMCredentialsClientMeta(type):
44    """Metaclass for the IAMCredentials client.
45
46    This provides class-level methods for building and retrieving
47    support objects (e.g. transport) without polluting the client instance
48    objects.
49    """
50
51    _transport_registry = (
52        OrderedDict()
53    )  # type: Dict[str, Type[IAMCredentialsTransport]]
54    _transport_registry["grpc"] = IAMCredentialsGrpcTransport
55    _transport_registry["grpc_asyncio"] = IAMCredentialsGrpcAsyncIOTransport
56
57    def get_transport_class(cls, label: str = None,) -> Type[IAMCredentialsTransport]:
58        """Returns an appropriate transport class.
59
60        Args:
61            label: The name of the desired transport. If none is
62                provided, then the first transport in the registry is used.
63
64        Returns:
65            The transport class to use.
66        """
67        # If a specific transport is requested, return that one.
68        if label:
69            return cls._transport_registry[label]
70
71        # No transport is requested; return the default (that is, the first one
72        # in the dictionary).
73        return next(iter(cls._transport_registry.values()))
74
75
76class IAMCredentialsClient(metaclass=IAMCredentialsClientMeta):
77    """A service account is a special type of Google account that
78    belongs to your application or a virtual machine (VM), instead
79    of to an individual end user. Your application assumes the
80    identity of the service account to call Google APIs, so that the
81    users aren't directly involved.
82
83    Service account credentials are used to temporarily assume the
84    identity of the service account. Supported credential types
85    include OAuth 2.0 access tokens, OpenID Connect ID tokens, self-
86    signed JSON Web Tokens (JWTs), and more.
87    """
88
89    @staticmethod
90    def _get_default_mtls_endpoint(api_endpoint):
91        """Converts api endpoint to mTLS endpoint.
92
93        Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
94        "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
95        Args:
96            api_endpoint (Optional[str]): the api endpoint to convert.
97        Returns:
98            str: converted mTLS api endpoint.
99        """
100        if not api_endpoint:
101            return api_endpoint
102
103        mtls_endpoint_re = re.compile(
104            r"(?P<name>[^.]+)(?P<mtls>\.mtls)?(?P<sandbox>\.sandbox)?(?P<googledomain>\.googleapis\.com)?"
105        )
106
107        m = mtls_endpoint_re.match(api_endpoint)
108        name, mtls, sandbox, googledomain = m.groups()
109        if mtls or not googledomain:
110            return api_endpoint
111
112        if sandbox:
113            return api_endpoint.replace(
114                "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
115            )
116
117        return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
118
119    DEFAULT_ENDPOINT = "iamcredentials.googleapis.com"
120    DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__(  # type: ignore
121        DEFAULT_ENDPOINT
122    )
123
124    @classmethod
125    def from_service_account_info(cls, info: dict, *args, **kwargs):
126        """Creates an instance of this client using the provided credentials
127            info.
128
129        Args:
130            info (dict): The service account private key info.
131            args: Additional arguments to pass to the constructor.
132            kwargs: Additional arguments to pass to the constructor.
133
134        Returns:
135            IAMCredentialsClient: The constructed client.
136        """
137        credentials = service_account.Credentials.from_service_account_info(info)
138        kwargs["credentials"] = credentials
139        return cls(*args, **kwargs)
140
141    @classmethod
142    def from_service_account_file(cls, filename: str, *args, **kwargs):
143        """Creates an instance of this client using the provided credentials
144            file.
145
146        Args:
147            filename (str): The path to the service account private key json
148                file.
149            args: Additional arguments to pass to the constructor.
150            kwargs: Additional arguments to pass to the constructor.
151
152        Returns:
153            IAMCredentialsClient: The constructed client.
154        """
155        credentials = service_account.Credentials.from_service_account_file(filename)
156        kwargs["credentials"] = credentials
157        return cls(*args, **kwargs)
158
159    from_service_account_json = from_service_account_file
160
161    @property
162    def transport(self) -> IAMCredentialsTransport:
163        """Returns the transport used by the client instance.
164
165        Returns:
166            IAMCredentialsTransport: The transport used by the client
167                instance.
168        """
169        return self._transport
170
171    @staticmethod
172    def service_account_path(project: str, service_account: str,) -> str:
173        """Returns a fully-qualified service_account string."""
174        return "projects/{project}/serviceAccounts/{service_account}".format(
175            project=project, service_account=service_account,
176        )
177
178    @staticmethod
179    def parse_service_account_path(path: str) -> Dict[str, str]:
180        """Parses a service_account path into its component segments."""
181        m = re.match(
182            r"^projects/(?P<project>.+?)/serviceAccounts/(?P<service_account>.+?)$",
183            path,
184        )
185        return m.groupdict() if m else {}
186
187    @staticmethod
188    def common_billing_account_path(billing_account: str,) -> str:
189        """Returns a fully-qualified billing_account string."""
190        return "billingAccounts/{billing_account}".format(
191            billing_account=billing_account,
192        )
193
194    @staticmethod
195    def parse_common_billing_account_path(path: str) -> Dict[str, str]:
196        """Parse a billing_account path into its component segments."""
197        m = re.match(r"^billingAccounts/(?P<billing_account>.+?)$", path)
198        return m.groupdict() if m else {}
199
200    @staticmethod
201    def common_folder_path(folder: str,) -> str:
202        """Returns a fully-qualified folder string."""
203        return "folders/{folder}".format(folder=folder,)
204
205    @staticmethod
206    def parse_common_folder_path(path: str) -> Dict[str, str]:
207        """Parse a folder path into its component segments."""
208        m = re.match(r"^folders/(?P<folder>.+?)$", path)
209        return m.groupdict() if m else {}
210
211    @staticmethod
212    def common_organization_path(organization: str,) -> str:
213        """Returns a fully-qualified organization string."""
214        return "organizations/{organization}".format(organization=organization,)
215
216    @staticmethod
217    def parse_common_organization_path(path: str) -> Dict[str, str]:
218        """Parse a organization path into its component segments."""
219        m = re.match(r"^organizations/(?P<organization>.+?)$", path)
220        return m.groupdict() if m else {}
221
222    @staticmethod
223    def common_project_path(project: str,) -> str:
224        """Returns a fully-qualified project string."""
225        return "projects/{project}".format(project=project,)
226
227    @staticmethod
228    def parse_common_project_path(path: str) -> Dict[str, str]:
229        """Parse a project path into its component segments."""
230        m = re.match(r"^projects/(?P<project>.+?)$", path)
231        return m.groupdict() if m else {}
232
233    @staticmethod
234    def common_location_path(project: str, location: str,) -> str:
235        """Returns a fully-qualified location string."""
236        return "projects/{project}/locations/{location}".format(
237            project=project, location=location,
238        )
239
240    @staticmethod
241    def parse_common_location_path(path: str) -> Dict[str, str]:
242        """Parse a location path into its component segments."""
243        m = re.match(r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$", path)
244        return m.groupdict() if m else {}
245
246    def __init__(
247        self,
248        *,
249        credentials: Optional[ga_credentials.Credentials] = None,
250        transport: Union[str, IAMCredentialsTransport, None] = None,
251        client_options: Optional[client_options_lib.ClientOptions] = None,
252        client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
253    ) -> None:
254        """Instantiates the iam credentials client.
255
256        Args:
257            credentials (Optional[google.auth.credentials.Credentials]): The
258                authorization credentials to attach to requests. These
259                credentials identify the application to the service; if none
260                are specified, the client will attempt to ascertain the
261                credentials from the environment.
262            transport (Union[str, IAMCredentialsTransport]): The
263                transport to use. If set to None, a transport is chosen
264                automatically.
265            client_options (google.api_core.client_options.ClientOptions): Custom options for the
266                client. It won't take effect if a ``transport`` instance is provided.
267                (1) The ``api_endpoint`` property can be used to override the
268                default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
269                environment variable can also be used to override the endpoint:
270                "always" (always use the default mTLS endpoint), "never" (always
271                use the default regular endpoint) and "auto" (auto switch to the
272                default mTLS endpoint if client certificate is present, this is
273                the default value). However, the ``api_endpoint`` property takes
274                precedence if provided.
275                (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
276                is "true", then the ``client_cert_source`` property can be used
277                to provide client certificate for mutual TLS transport. If
278                not provided, the default SSL client certificate will be used if
279                present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
280                set, no client certificate will be used.
281            client_info (google.api_core.gapic_v1.client_info.ClientInfo):
282                The client info used to send a user-agent string along with
283                API requests. If ``None``, then default info will be used.
284                Generally, you only need to set this if you're developing
285                your own client library.
286
287        Raises:
288            google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
289                creation failed for any reason.
290        """
291        if isinstance(client_options, dict):
292            client_options = client_options_lib.from_dict(client_options)
293        if client_options is None:
294            client_options = client_options_lib.ClientOptions()
295
296        # Create SSL credentials for mutual TLS if needed.
297        use_client_cert = bool(
298            util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
299        )
300
301        client_cert_source_func = None
302        is_mtls = False
303        if use_client_cert:
304            if client_options.client_cert_source:
305                is_mtls = True
306                client_cert_source_func = client_options.client_cert_source
307            else:
308                is_mtls = mtls.has_default_client_cert_source()
309                if is_mtls:
310                    client_cert_source_func = mtls.default_client_cert_source()
311                else:
312                    client_cert_source_func = None
313
314        # Figure out which api endpoint to use.
315        if client_options.api_endpoint is not None:
316            api_endpoint = client_options.api_endpoint
317        else:
318            use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
319            if use_mtls_env == "never":
320                api_endpoint = self.DEFAULT_ENDPOINT
321            elif use_mtls_env == "always":
322                api_endpoint = self.DEFAULT_MTLS_ENDPOINT
323            elif use_mtls_env == "auto":
324                if is_mtls:
325                    api_endpoint = self.DEFAULT_MTLS_ENDPOINT
326                else:
327                    api_endpoint = self.DEFAULT_ENDPOINT
328            else:
329                raise MutualTLSChannelError(
330                    "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted "
331                    "values: never, auto, always"
332                )
333
334        # Save or instantiate the transport.
335        # Ordinarily, we provide the transport, but allowing a custom transport
336        # instance provides an extensibility point for unusual situations.
337        if isinstance(transport, IAMCredentialsTransport):
338            # transport is a IAMCredentialsTransport instance.
339            if credentials or client_options.credentials_file:
340                raise ValueError(
341                    "When providing a transport instance, "
342                    "provide its credentials directly."
343                )
344            if client_options.scopes:
345                raise ValueError(
346                    "When providing a transport instance, provide its scopes "
347                    "directly."
348                )
349            self._transport = transport
350        else:
351            Transport = type(self).get_transport_class(transport)
352            self._transport = Transport(
353                credentials=credentials,
354                credentials_file=client_options.credentials_file,
355                host=api_endpoint,
356                scopes=client_options.scopes,
357                client_cert_source_for_mtls=client_cert_source_func,
358                quota_project_id=client_options.quota_project_id,
359                client_info=client_info,
360                always_use_jwt_access=True,
361            )
362
363    def generate_access_token(
364        self,
365        request: Union[common.GenerateAccessTokenRequest, dict] = None,
366        *,
367        name: str = None,
368        delegates: Sequence[str] = None,
369        scope: Sequence[str] = None,
370        lifetime: duration_pb2.Duration = None,
371        retry: OptionalRetry = gapic_v1.method.DEFAULT,
372        timeout: float = None,
373        metadata: Sequence[Tuple[str, str]] = (),
374    ) -> common.GenerateAccessTokenResponse:
375        r"""Generates an OAuth 2.0 access token for a service
376        account.
377
378        Args:
379            request (Union[google.cloud.iam_credentials_v1.types.GenerateAccessTokenRequest, dict]):
380                The request object.
381            name (str):
382                Required. The resource name of the service account for
383                which the credentials are requested, in the following
384                format:
385                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
386                The ``-`` wildcard character is required; replacing it
387                with a project ID is invalid.
388
389                This corresponds to the ``name`` field
390                on the ``request`` instance; if ``request`` is provided, this
391                should not be set.
392            delegates (Sequence[str]):
393                The sequence of service accounts in a delegation chain.
394                Each service account must be granted the
395                ``roles/iam.serviceAccountTokenCreator`` role on its
396                next service account in the chain. The last service
397                account in the chain must be granted the
398                ``roles/iam.serviceAccountTokenCreator`` role on the
399                service account that is specified in the ``name`` field
400                of the request.
401
402                The delegates must have the following format:
403                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
404                The ``-`` wildcard character is required; replacing it
405                with a project ID is invalid.
406
407                This corresponds to the ``delegates`` field
408                on the ``request`` instance; if ``request`` is provided, this
409                should not be set.
410            scope (Sequence[str]):
411                Required. Code to identify the scopes
412                to be included in the OAuth 2.0 access
413                token. See
414                https://developers.google.com/identity/protocols/googlescopes
415                for more information.
416                At least one value required.
417
418                This corresponds to the ``scope`` field
419                on the ``request`` instance; if ``request`` is provided, this
420                should not be set.
421            lifetime (google.protobuf.duration_pb2.Duration):
422                The desired lifetime duration of the
423                access token in seconds. Must be set to
424                a value less than or equal to 3600 (1
425                hour). If a value is not specified, the
426                token's lifetime will be set to a
427                default value of one hour.
428
429                This corresponds to the ``lifetime`` field
430                on the ``request`` instance; if ``request`` is provided, this
431                should not be set.
432            retry (google.api_core.retry.Retry): Designation of what errors, if any,
433                should be retried.
434            timeout (float): The timeout for this request.
435            metadata (Sequence[Tuple[str, str]]): Strings which should be
436                sent along with the request as metadata.
437
438        Returns:
439            google.cloud.iam_credentials_v1.types.GenerateAccessTokenResponse:
440
441        """
442        # Create or coerce a protobuf request object.
443        # Sanity check: If we got a request object, we should *not* have
444        # gotten any keyword arguments that map to the request.
445        has_flattened_params = any([name, delegates, scope, lifetime])
446        if request is not None and has_flattened_params:
447            raise ValueError(
448                "If the `request` argument is set, then none of "
449                "the individual field arguments should be set."
450            )
451
452        # Minor optimization to avoid making a copy if the user passes
453        # in a common.GenerateAccessTokenRequest.
454        # There's no risk of modifying the input as we've already verified
455        # there are no flattened fields.
456        if not isinstance(request, common.GenerateAccessTokenRequest):
457            request = common.GenerateAccessTokenRequest(request)
458            # If we have keyword arguments corresponding to fields on the
459            # request, apply these.
460            if name is not None:
461                request.name = name
462            if delegates is not None:
463                request.delegates = delegates
464            if scope is not None:
465                request.scope = scope
466            if lifetime is not None:
467                request.lifetime = lifetime
468
469        # Wrap the RPC method; this adds retry and timeout information,
470        # and friendly error handling.
471        rpc = self._transport._wrapped_methods[self._transport.generate_access_token]
472
473        # Certain fields should be provided within the metadata header;
474        # add these here.
475        metadata = tuple(metadata) + (
476            gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
477        )
478
479        # Send the request.
480        response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
481
482        # Done; return the response.
483        return response
484
485    def generate_id_token(
486        self,
487        request: Union[common.GenerateIdTokenRequest, dict] = None,
488        *,
489        name: str = None,
490        delegates: Sequence[str] = None,
491        audience: str = None,
492        include_email: bool = None,
493        retry: OptionalRetry = gapic_v1.method.DEFAULT,
494        timeout: float = None,
495        metadata: Sequence[Tuple[str, str]] = (),
496    ) -> common.GenerateIdTokenResponse:
497        r"""Generates an OpenID Connect ID token for a service
498        account.
499
500        Args:
501            request (Union[google.cloud.iam_credentials_v1.types.GenerateIdTokenRequest, dict]):
502                The request object.
503            name (str):
504                Required. The resource name of the service account for
505                which the credentials are requested, in the following
506                format:
507                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
508                The ``-`` wildcard character is required; replacing it
509                with a project ID is invalid.
510
511                This corresponds to the ``name`` field
512                on the ``request`` instance; if ``request`` is provided, this
513                should not be set.
514            delegates (Sequence[str]):
515                The sequence of service accounts in a delegation chain.
516                Each service account must be granted the
517                ``roles/iam.serviceAccountTokenCreator`` role on its
518                next service account in the chain. The last service
519                account in the chain must be granted the
520                ``roles/iam.serviceAccountTokenCreator`` role on the
521                service account that is specified in the ``name`` field
522                of the request.
523
524                The delegates must have the following format:
525                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
526                The ``-`` wildcard character is required; replacing it
527                with a project ID is invalid.
528
529                This corresponds to the ``delegates`` field
530                on the ``request`` instance; if ``request`` is provided, this
531                should not be set.
532            audience (str):
533                Required. The audience for the token,
534                such as the API or account that this
535                token grants access to.
536
537                This corresponds to the ``audience`` field
538                on the ``request`` instance; if ``request`` is provided, this
539                should not be set.
540            include_email (bool):
541                Include the service account email in the token. If set
542                to ``true``, the token will contain ``email`` and
543                ``email_verified`` claims.
544
545                This corresponds to the ``include_email`` field
546                on the ``request`` instance; if ``request`` is provided, this
547                should not be set.
548            retry (google.api_core.retry.Retry): Designation of what errors, if any,
549                should be retried.
550            timeout (float): The timeout for this request.
551            metadata (Sequence[Tuple[str, str]]): Strings which should be
552                sent along with the request as metadata.
553
554        Returns:
555            google.cloud.iam_credentials_v1.types.GenerateIdTokenResponse:
556
557        """
558        # Create or coerce a protobuf request object.
559        # Sanity check: If we got a request object, we should *not* have
560        # gotten any keyword arguments that map to the request.
561        has_flattened_params = any([name, delegates, audience, include_email])
562        if request is not None and has_flattened_params:
563            raise ValueError(
564                "If the `request` argument is set, then none of "
565                "the individual field arguments should be set."
566            )
567
568        # Minor optimization to avoid making a copy if the user passes
569        # in a common.GenerateIdTokenRequest.
570        # There's no risk of modifying the input as we've already verified
571        # there are no flattened fields.
572        if not isinstance(request, common.GenerateIdTokenRequest):
573            request = common.GenerateIdTokenRequest(request)
574            # If we have keyword arguments corresponding to fields on the
575            # request, apply these.
576            if name is not None:
577                request.name = name
578            if delegates is not None:
579                request.delegates = delegates
580            if audience is not None:
581                request.audience = audience
582            if include_email is not None:
583                request.include_email = include_email
584
585        # Wrap the RPC method; this adds retry and timeout information,
586        # and friendly error handling.
587        rpc = self._transport._wrapped_methods[self._transport.generate_id_token]
588
589        # Certain fields should be provided within the metadata header;
590        # add these here.
591        metadata = tuple(metadata) + (
592            gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
593        )
594
595        # Send the request.
596        response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
597
598        # Done; return the response.
599        return response
600
601    def sign_blob(
602        self,
603        request: Union[common.SignBlobRequest, dict] = None,
604        *,
605        name: str = None,
606        delegates: Sequence[str] = None,
607        payload: bytes = None,
608        retry: OptionalRetry = gapic_v1.method.DEFAULT,
609        timeout: float = None,
610        metadata: Sequence[Tuple[str, str]] = (),
611    ) -> common.SignBlobResponse:
612        r"""Signs a blob using a service account's system-managed
613        private key.
614
615        Args:
616            request (Union[google.cloud.iam_credentials_v1.types.SignBlobRequest, dict]):
617                The request object.
618            name (str):
619                Required. The resource name of the service account for
620                which the credentials are requested, in the following
621                format:
622                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
623                The ``-`` wildcard character is required; replacing it
624                with a project ID is invalid.
625
626                This corresponds to the ``name`` field
627                on the ``request`` instance; if ``request`` is provided, this
628                should not be set.
629            delegates (Sequence[str]):
630                The sequence of service accounts in a delegation chain.
631                Each service account must be granted the
632                ``roles/iam.serviceAccountTokenCreator`` role on its
633                next service account in the chain. The last service
634                account in the chain must be granted the
635                ``roles/iam.serviceAccountTokenCreator`` role on the
636                service account that is specified in the ``name`` field
637                of the request.
638
639                The delegates must have the following format:
640                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
641                The ``-`` wildcard character is required; replacing it
642                with a project ID is invalid.
643
644                This corresponds to the ``delegates`` field
645                on the ``request`` instance; if ``request`` is provided, this
646                should not be set.
647            payload (bytes):
648                Required. The bytes to sign.
649                This corresponds to the ``payload`` field
650                on the ``request`` instance; if ``request`` is provided, this
651                should not be set.
652            retry (google.api_core.retry.Retry): Designation of what errors, if any,
653                should be retried.
654            timeout (float): The timeout for this request.
655            metadata (Sequence[Tuple[str, str]]): Strings which should be
656                sent along with the request as metadata.
657
658        Returns:
659            google.cloud.iam_credentials_v1.types.SignBlobResponse:
660
661        """
662        # Create or coerce a protobuf request object.
663        # Sanity check: If we got a request object, we should *not* have
664        # gotten any keyword arguments that map to the request.
665        has_flattened_params = any([name, delegates, payload])
666        if request is not None and has_flattened_params:
667            raise ValueError(
668                "If the `request` argument is set, then none of "
669                "the individual field arguments should be set."
670            )
671
672        # Minor optimization to avoid making a copy if the user passes
673        # in a common.SignBlobRequest.
674        # There's no risk of modifying the input as we've already verified
675        # there are no flattened fields.
676        if not isinstance(request, common.SignBlobRequest):
677            request = common.SignBlobRequest(request)
678            # If we have keyword arguments corresponding to fields on the
679            # request, apply these.
680            if name is not None:
681                request.name = name
682            if delegates is not None:
683                request.delegates = delegates
684            if payload is not None:
685                request.payload = payload
686
687        # Wrap the RPC method; this adds retry and timeout information,
688        # and friendly error handling.
689        rpc = self._transport._wrapped_methods[self._transport.sign_blob]
690
691        # Certain fields should be provided within the metadata header;
692        # add these here.
693        metadata = tuple(metadata) + (
694            gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
695        )
696
697        # Send the request.
698        response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
699
700        # Done; return the response.
701        return response
702
703    def sign_jwt(
704        self,
705        request: Union[common.SignJwtRequest, dict] = None,
706        *,
707        name: str = None,
708        delegates: Sequence[str] = None,
709        payload: str = None,
710        retry: OptionalRetry = gapic_v1.method.DEFAULT,
711        timeout: float = None,
712        metadata: Sequence[Tuple[str, str]] = (),
713    ) -> common.SignJwtResponse:
714        r"""Signs a JWT using a service account's system-managed
715        private key.
716
717        Args:
718            request (Union[google.cloud.iam_credentials_v1.types.SignJwtRequest, dict]):
719                The request object.
720            name (str):
721                Required. The resource name of the service account for
722                which the credentials are requested, in the following
723                format:
724                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
725                The ``-`` wildcard character is required; replacing it
726                with a project ID is invalid.
727
728                This corresponds to the ``name`` field
729                on the ``request`` instance; if ``request`` is provided, this
730                should not be set.
731            delegates (Sequence[str]):
732                The sequence of service accounts in a delegation chain.
733                Each service account must be granted the
734                ``roles/iam.serviceAccountTokenCreator`` role on its
735                next service account in the chain. The last service
736                account in the chain must be granted the
737                ``roles/iam.serviceAccountTokenCreator`` role on the
738                service account that is specified in the ``name`` field
739                of the request.
740
741                The delegates must have the following format:
742                ``projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}``.
743                The ``-`` wildcard character is required; replacing it
744                with a project ID is invalid.
745
746                This corresponds to the ``delegates`` field
747                on the ``request`` instance; if ``request`` is provided, this
748                should not be set.
749            payload (str):
750                Required. The JWT payload to sign: a
751                JSON object that contains a JWT Claims
752                Set.
753
754                This corresponds to the ``payload`` field
755                on the ``request`` instance; if ``request`` is provided, this
756                should not be set.
757            retry (google.api_core.retry.Retry): Designation of what errors, if any,
758                should be retried.
759            timeout (float): The timeout for this request.
760            metadata (Sequence[Tuple[str, str]]): Strings which should be
761                sent along with the request as metadata.
762
763        Returns:
764            google.cloud.iam_credentials_v1.types.SignJwtResponse:
765
766        """
767        # Create or coerce a protobuf request object.
768        # Sanity check: If we got a request object, we should *not* have
769        # gotten any keyword arguments that map to the request.
770        has_flattened_params = any([name, delegates, payload])
771        if request is not None and has_flattened_params:
772            raise ValueError(
773                "If the `request` argument is set, then none of "
774                "the individual field arguments should be set."
775            )
776
777        # Minor optimization to avoid making a copy if the user passes
778        # in a common.SignJwtRequest.
779        # There's no risk of modifying the input as we've already verified
780        # there are no flattened fields.
781        if not isinstance(request, common.SignJwtRequest):
782            request = common.SignJwtRequest(request)
783            # If we have keyword arguments corresponding to fields on the
784            # request, apply these.
785            if name is not None:
786                request.name = name
787            if delegates is not None:
788                request.delegates = delegates
789            if payload is not None:
790                request.payload = payload
791
792        # Wrap the RPC method; this adds retry and timeout information,
793        # and friendly error handling.
794        rpc = self._transport._wrapped_methods[self._transport.sign_jwt]
795
796        # Certain fields should be provided within the metadata header;
797        # add these here.
798        metadata = tuple(metadata) + (
799            gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
800        )
801
802        # Send the request.
803        response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
804
805        # Done; return the response.
806        return response
807
808    def __enter__(self):
809        return self
810
811    def __exit__(self, type, value, traceback):
812        """Releases underlying transport's resources.
813
814        .. warning::
815            ONLY use as a context manager if the transport is NOT shared
816            with other clients! Exiting the with block will CLOSE the transport
817            and may cause errors in other clients!
818        """
819        self.transport.close()
820
821
822try:
823    DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
824        gapic_version=pkg_resources.get_distribution("google-cloud-iam",).version,
825    )
826except pkg_resources.DistributionNotFound:
827    DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
828
829
830__all__ = ("IAMCredentialsClient",)
831