google_sts1/
api.rs

1#![allow(clippy::ptr_arg)]
2
3use std::collections::{BTreeSet, HashMap};
4
5use tokio::time::sleep;
6
7// ##############
8// UTILITIES ###
9// ############
10
11// ########
12// HUB ###
13// ######
14
15/// Central instance to access all CloudSecurityToken related resource activities
16///
17/// # Examples
18///
19/// Instantiate a new hub
20///
21/// ```test_harness,no_run
22/// extern crate hyper;
23/// extern crate hyper_rustls;
24/// extern crate google_sts1 as sts1;
25/// use sts1::api::GoogleIdentityStsV1ExchangeTokenRequest;
26/// use sts1::{Result, Error};
27/// # async fn dox() {
28/// use sts1::{CloudSecurityToken, FieldMask, hyper_rustls, hyper_util, yup_oauth2};
29///
30/// // Get an ApplicationSecret instance by some means. It contains the `client_id` and
31/// // `client_secret`, among other things.
32/// let secret: yup_oauth2::ApplicationSecret = Default::default();
33/// // Instantiate the authenticator. It will choose a suitable authentication flow for you,
34/// // unless you replace  `None` with the desired Flow.
35/// // Provide your own `AuthenticatorDelegate` to adjust the way it operates and get feedback about
36/// // what's going on. You probably want to bring in your own `TokenStorage` to persist tokens and
37/// // retrieve them from storage.
38/// let connector = hyper_rustls::HttpsConnectorBuilder::new()
39///     .with_native_roots()
40///     .unwrap()
41///     .https_only()
42///     .enable_http2()
43///     .build();
44///
45/// let executor = hyper_util::rt::TokioExecutor::new();
46/// let auth = yup_oauth2::InstalledFlowAuthenticator::with_client(
47///     secret,
48///     yup_oauth2::InstalledFlowReturnMethod::HTTPRedirect,
49///     yup_oauth2::client::CustomHyperClientBuilder::from(
50///         hyper_util::client::legacy::Client::builder(executor).build(connector),
51///     ),
52/// ).build().await.unwrap();
53///
54/// let client = hyper_util::client::legacy::Client::builder(
55///     hyper_util::rt::TokioExecutor::new()
56/// )
57/// .build(
58///     hyper_rustls::HttpsConnectorBuilder::new()
59///         .with_native_roots()
60///         .unwrap()
61///         .https_or_http()
62///         .enable_http2()
63///         .build()
64/// );
65/// let mut hub = CloudSecurityToken::new(client, auth);
66/// // As the method needs a request, you would usually fill it with the desired information
67/// // into the respective structure. Some of the parts shown here might not be applicable !
68/// // Values shown here are possibly random and not representative !
69/// let mut req = GoogleIdentityStsV1ExchangeTokenRequest::default();
70///
71/// // You can configure optional parameters by calling the respective setters at will, and
72/// // execute the final call using `doit()`.
73/// // Values shown here are possibly random and not representative !
74/// let result = hub.methods().token(req)
75///              .doit().await;
76///
77/// match result {
78///     Err(e) => match e {
79///         // The Error enum provides details about what exactly happened.
80///         // You can also just use its `Debug`, `Display` or `Error` traits
81///          Error::HttpError(_)
82///         |Error::Io(_)
83///         |Error::MissingAPIKey
84///         |Error::MissingToken(_)
85///         |Error::Cancelled
86///         |Error::UploadSizeLimitExceeded(_, _)
87///         |Error::Failure(_)
88///         |Error::BadRequest(_)
89///         |Error::FieldClash(_)
90///         |Error::JsonDecodeError(_, _) => println!("{}", e),
91///     },
92///     Ok(res) => println!("Success: {:?}", res),
93/// }
94/// # }
95/// ```
96#[derive(Clone)]
97pub struct CloudSecurityToken<C> {
98    pub client: common::Client<C>,
99    pub auth: Box<dyn common::GetToken>,
100    _user_agent: String,
101    _base_url: String,
102    _root_url: String,
103}
104
105impl<C> common::Hub for CloudSecurityToken<C> {}
106
107impl<'a, C> CloudSecurityToken<C> {
108    pub fn new<A: 'static + common::GetToken>(
109        client: common::Client<C>,
110        auth: A,
111    ) -> CloudSecurityToken<C> {
112        CloudSecurityToken {
113            client,
114            auth: Box::new(auth),
115            _user_agent: "google-api-rust-client/7.0.0".to_string(),
116            _base_url: "https://sts.googleapis.com/".to_string(),
117            _root_url: "https://sts.googleapis.com/".to_string(),
118        }
119    }
120
121    pub fn methods(&'a self) -> MethodMethods<'a, C> {
122        MethodMethods { hub: self }
123    }
124
125    /// Set the user-agent header field to use in all requests to the server.
126    /// It defaults to `google-api-rust-client/7.0.0`.
127    ///
128    /// Returns the previously set user-agent.
129    pub fn user_agent(&mut self, agent_name: String) -> String {
130        std::mem::replace(&mut self._user_agent, agent_name)
131    }
132
133    /// Set the base url to use in all requests to the server.
134    /// It defaults to `https://sts.googleapis.com/`.
135    ///
136    /// Returns the previously set base url.
137    pub fn base_url(&mut self, new_base_url: String) -> String {
138        std::mem::replace(&mut self._base_url, new_base_url)
139    }
140
141    /// Set the root url to use in all requests to the server.
142    /// It defaults to `https://sts.googleapis.com/`.
143    ///
144    /// Returns the previously set root url.
145    pub fn root_url(&mut self, new_root_url: String) -> String {
146        std::mem::replace(&mut self._root_url, new_root_url)
147    }
148}
149
150// ############
151// SCHEMAS ###
152// ##########
153/// Request message for ExchangeToken.
154///
155/// # Activities
156///
157/// This type is used in activities, which are methods you may call on this type or where this type is involved in.
158/// The list links the activity name, along with information about where it is used (one of *request* and *response*).
159///
160/// * [token](MethodTokenCall) (request)
161#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
162#[serde_with::serde_as]
163#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
164pub struct GoogleIdentityStsV1ExchangeTokenRequest {
165    /// The full resource name of the identity provider; for example: `//iam.googleapis.com/projects//locations/global/workloadIdentityPools//providers/` for workload identity pool providers, or `//iam.googleapis.com/locations/global/workforcePools//providers/` for workforce pool providers. Required when exchanging an external credential for a Google access token.
166    pub audience: Option<String>,
167    /// Required. The grant type. Must be `urn:ietf:params:oauth:grant-type:token-exchange`, which indicates a token exchange.
168    #[serde(rename = "grantType")]
169    pub grant_type: Option<String>,
170    /// A set of features that Security Token Service supports, in addition to the standard OAuth 2.0 token exchange, formatted as a serialized JSON object of Options. The size of the parameter value must not exceed 4 * 1024 * 1024 characters (4 MB).
171    pub options: Option<String>,
172    /// Required. An identifier for the type of requested security token. Can be `urn:ietf:params:oauth:token-type:access_token` or `urn:ietf:params:oauth:token-type:access_boundary_intermediary_token`.
173    #[serde(rename = "requestedTokenType")]
174    pub requested_token_type: Option<String>,
175    /// The OAuth 2.0 scopes to include on the resulting access token, formatted as a list of space-delimited, case-sensitive strings; for example, `https://www.googleapis.com/auth/cloud-platform`. Required when exchanging an external credential for a Google access token. For a list of OAuth 2.0 scopes, see [OAuth 2.0 Scopes for Google APIs](https://developers.google.com/identity/protocols/oauth2/scopes).
176    pub scope: Option<String>,
177    /// Required. The input token. This token is either an external credential issued by a workload identity pool provider, or a short-lived access token issued by Google. If the token is an OIDC JWT, it must use the JWT format defined in [RFC 7523](https://tools.ietf.org/html/rfc7523), and the `subject_token_type` must be either `urn:ietf:params:oauth:token-type:jwt` or `urn:ietf:params:oauth:token-type:id_token`. The following headers are required: - `kid`: The identifier of the signing key securing the JWT. - `alg`: The cryptographic algorithm securing the JWT. Must be `RS256` or `ES256`. The following payload fields are required. For more information, see [RFC 7523, Section 3](https://tools.ietf.org/html/rfc7523#section-3): - `iss`: The issuer of the token. The issuer must provide a discovery document at the URL `/.well-known/openid-configuration`, where `` is the value of this field. The document must be formatted according to section 4.2 of the [OIDC 1.0 Discovery specification](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse). - `iat`: The issue time, in seconds, since the Unix epoch. Must be in the past. - `exp`: The expiration time, in seconds, since the Unix epoch. Must be less than 48 hours after `iat`. Shorter expiration times are more secure. If possible, we recommend setting an expiration time less than 6 hours. - `sub`: The identity asserted in the JWT. - `aud`: For workload identity pools, this must be a value specified in the allowed audiences for the workload identity pool provider, or one of the audiences allowed by default if no audiences were specified. See https://cloud.google.com/iam/docs/reference/rest/v1/projects.locations.workloadIdentityPools.providers#oidc. For workforce pools, this must match the client ID specified in the provider configuration. See https://cloud.google.com/iam/docs/reference/rest/v1/locations.workforcePools.providers#oidc. Example header: ``` { "alg": "RS256", "kid": "us-east-11" } ``` Example payload: ``` { "iss": "https://accounts.google.com", "iat": 1517963104, "exp": 1517966704, "aud": "//iam.googleapis.com/projects/1234567890123/locations/global/workloadIdentityPools/my-pool/providers/my-provider", "sub": "113475438248934895348", "my_claims": { "additional_claim": "value" } } ``` If `subject_token` is for AWS, it must be a serialized `GetCallerIdentity` token. This token contains the same information as a request to the AWS [`GetCallerIdentity()`](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity) method, as well as the AWS [signature](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) for the request information. Use Signature Version 4. Format the request as URL-encoded JSON, and set the `subject_token_type` parameter to `urn:ietf:params:aws:token-type:aws4_request`. The following parameters are required: - `url`: The URL of the AWS STS endpoint for `GetCallerIdentity()`, such as `https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15`. Regional endpoints are also supported. - `method`: The HTTP request method: `POST`. - `headers`: The HTTP request headers, which must include: - `Authorization`: The request signature. - `x-amz-date`: The time you will send the request, formatted as an [ISO8601 Basic](https://docs.aws.amazon.com/general/latest/gr/sigv4_elements.html#sigv4_elements_date) string. This value is typically set to the current time and is used to help prevent replay attacks. - `host`: The hostname of the `url` field; for example, `sts.amazonaws.com`. - `x-goog-cloud-target-resource`: The full, canonical resource name of the workload identity pool provider, with or without an `https:` prefix. To help ensure data integrity, we recommend including this header in the `SignedHeaders` field of the signed request. For example: //iam.googleapis.com/projects//locations/global/workloadIdentityPools//providers/ https://iam.googleapis.com/projects//locations/global/workloadIdentityPools//providers/ If you are using temporary security credentials provided by AWS, you must also include the header `x-amz-security-token`, with the value set to the session token. The following example shows a `GetCallerIdentity` token: ``` { "headers": [ {"key": "x-amz-date", "value": "20200815T015049Z"}, {"key": "Authorization", "value": "AWS4-HMAC-SHA256+Credential=$credential,+SignedHeaders=host;x-amz-date;x-goog-cloud-target-resource,+Signature=$signature"}, {"key": "x-goog-cloud-target-resource", "value": "//iam.googleapis.com/projects//locations/global/workloadIdentityPools//providers/"}, {"key": "host", "value": "sts.amazonaws.com"} . ], "method": "POST", "url": "https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15" } ``` If the token is a SAML 2.0 assertion, it must use the format defined in [the SAML 2.0 spec](https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.pdf), and the `subject_token_type` must be `urn:ietf:params:oauth:token-type:saml2`. See [Verification of external credentials](https://cloud.google.com/iam/docs/using-workload-identity-federation#verification_of_external_credentials) for details on how SAML 2.0 assertions are validated during token exchanges. You can also use a Google-issued OAuth 2.0 access token with this field to obtain an access token with new security attributes applied, such as a Credential Access Boundary. In this case, set `subject_token_type` to `urn:ietf:params:oauth:token-type:access_token`. If an access token already contains security attributes, you cannot apply additional security attributes. If the request is for X.509 certificate-based authentication, the `subject_token` must be a JSON-formatted list of X.509 certificates in DER format, as defined in [RFC 7515](https://www.rfc-editor.org/rfc/rfc7515#section-4.1.6). `subject_token_type` must be `urn:ietf:params:oauth:token-type:mtls`. The following example shows a JSON-formatted list of X.509 certificate in DER format: ``` [\"MIIEYDCCA0i...\", \"MCIFFGAGTT0...\"] ```
178    #[serde(rename = "subjectToken")]
179    pub subject_token: Option<String>,
180    /// Required. An identifier that indicates the type of the security token in the `subject_token` parameter. Supported values are `urn:ietf:params:oauth:token-type:jwt`, `urn:ietf:params:oauth:token-type:id_token`, `urn:ietf:params:aws:token-type:aws4_request`, `urn:ietf:params:oauth:token-type:access_token`, `urn:ietf:params:oauth:token-type:mtls`, and `urn:ietf:params:oauth:token-type:saml2`.
181    #[serde(rename = "subjectTokenType")]
182    pub subject_token_type: Option<String>,
183}
184
185impl common::RequestValue for GoogleIdentityStsV1ExchangeTokenRequest {}
186
187/// Response message for ExchangeToken.
188///
189/// # Activities
190///
191/// This type is used in activities, which are methods you may call on this type or where this type is involved in.
192/// The list links the activity name, along with information about where it is used (one of *request* and *response*).
193///
194/// * [token](MethodTokenCall) (response)
195#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
196#[serde_with::serde_as]
197#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
198pub struct GoogleIdentityStsV1ExchangeTokenResponse {
199    /// The access boundary session key. This key is used along with the access boundary intermediary token to generate Credential Access Boundary tokens at client side. This field is absent when the `requested_token_type` from the request is not `urn:ietf:params:oauth:token-type:access_boundary_intermediary_token`.
200    #[serde_as(as = "Option<common::serde::standard_base64::Wrapper>")]
201    pub access_boundary_session_key: Option<Vec<u8>>,
202    /// An OAuth 2.0 security token, issued by Google, in response to the token exchange request. Tokens can vary in size, depending in part on the size of mapped claims, up to a maximum of 12288 bytes (12 KB). Google reserves the right to change the token size and the maximum length at any time.
203    pub access_token: Option<String>,
204    /// The amount of time, in seconds, between the time when the access token was issued and the time when the access token will expire. This field is absent when the `subject_token` in the request is a a short-lived access token for a Cloud Identity or Google Workspace user account. In this case, the access token has the same expiration time as the `subject_token`.
205    pub expires_in: Option<i32>,
206    /// The token type. Always matches the value of `requested_token_type` from the request.
207    pub issued_token_type: Option<String>,
208    /// The type of access token. Always has the value `Bearer`.
209    pub token_type: Option<String>,
210}
211
212impl common::ResponseResult for GoogleIdentityStsV1ExchangeTokenResponse {}
213
214// ###################
215// MethodBuilders ###
216// #################
217
218/// A builder providing access to all free methods, which are not associated with a particular resource.
219/// It is not used directly, but through the [`CloudSecurityToken`] hub.
220///
221/// # Example
222///
223/// Instantiate a resource builder
224///
225/// ```test_harness,no_run
226/// extern crate hyper;
227/// extern crate hyper_rustls;
228/// extern crate google_sts1 as sts1;
229///
230/// # async fn dox() {
231/// use sts1::{CloudSecurityToken, FieldMask, hyper_rustls, hyper_util, yup_oauth2};
232///
233/// let secret: yup_oauth2::ApplicationSecret = Default::default();
234/// let connector = hyper_rustls::HttpsConnectorBuilder::new()
235///     .with_native_roots()
236///     .unwrap()
237///     .https_only()
238///     .enable_http2()
239///     .build();
240///
241/// let executor = hyper_util::rt::TokioExecutor::new();
242/// let auth = yup_oauth2::InstalledFlowAuthenticator::with_client(
243///     secret,
244///     yup_oauth2::InstalledFlowReturnMethod::HTTPRedirect,
245///     yup_oauth2::client::CustomHyperClientBuilder::from(
246///         hyper_util::client::legacy::Client::builder(executor).build(connector),
247///     ),
248/// ).build().await.unwrap();
249///
250/// let client = hyper_util::client::legacy::Client::builder(
251///     hyper_util::rt::TokioExecutor::new()
252/// )
253/// .build(
254///     hyper_rustls::HttpsConnectorBuilder::new()
255///         .with_native_roots()
256///         .unwrap()
257///         .https_or_http()
258///         .enable_http2()
259///         .build()
260/// );
261/// let mut hub = CloudSecurityToken::new(client, auth);
262/// // Usually you wouldn't bind this to a variable, but keep calling *CallBuilders*
263/// // like `token(...)`
264/// // to build up your call.
265/// let rb = hub.methods();
266/// # }
267/// ```
268pub struct MethodMethods<'a, C>
269where
270    C: 'a,
271{
272    hub: &'a CloudSecurityToken<C>,
273}
274
275impl<'a, C> common::MethodsBuilder for MethodMethods<'a, C> {}
276
277impl<'a, C> MethodMethods<'a, C> {
278    /// Create a builder to help you perform the following task:
279    ///
280    /// Exchanges a credential for a Google OAuth 2.0 access token. The token asserts an external identity within an identity pool, or it applies a Credential Access Boundary to a Google access token. Note that workforce pools do not support Credential Access Boundaries. When you call this method, do not send the `Authorization` HTTP header in the request. This method does not require the `Authorization` header, and using the header can cause the request to fail.
281    ///
282    /// # Arguments
283    ///
284    /// * `request` - No description provided.
285    pub fn token(
286        &self,
287        request: GoogleIdentityStsV1ExchangeTokenRequest,
288    ) -> MethodTokenCall<'a, C> {
289        MethodTokenCall {
290            hub: self.hub,
291            _request: request,
292            _delegate: Default::default(),
293            _additional_params: Default::default(),
294        }
295    }
296}
297
298// ###################
299// CallBuilders   ###
300// #################
301
302/// Exchanges a credential for a Google OAuth 2.0 access token. The token asserts an external identity within an identity pool, or it applies a Credential Access Boundary to a Google access token. Note that workforce pools do not support Credential Access Boundaries. When you call this method, do not send the `Authorization` HTTP header in the request. This method does not require the `Authorization` header, and using the header can cause the request to fail.
303///
304/// A builder for the *token* method.
305/// It is not used directly, but through a [`MethodMethods`] instance.
306///
307/// # Example
308///
309/// Instantiate a resource method builder
310///
311/// ```test_harness,no_run
312/// # extern crate hyper;
313/// # extern crate hyper_rustls;
314/// # extern crate google_sts1 as sts1;
315/// use sts1::api::GoogleIdentityStsV1ExchangeTokenRequest;
316/// # async fn dox() {
317/// # use sts1::{CloudSecurityToken, FieldMask, hyper_rustls, hyper_util, yup_oauth2};
318///
319/// # let secret: yup_oauth2::ApplicationSecret = Default::default();
320/// # let connector = hyper_rustls::HttpsConnectorBuilder::new()
321/// #     .with_native_roots()
322/// #     .unwrap()
323/// #     .https_only()
324/// #     .enable_http2()
325/// #     .build();
326///
327/// # let executor = hyper_util::rt::TokioExecutor::new();
328/// # let auth = yup_oauth2::InstalledFlowAuthenticator::with_client(
329/// #     secret,
330/// #     yup_oauth2::InstalledFlowReturnMethod::HTTPRedirect,
331/// #     yup_oauth2::client::CustomHyperClientBuilder::from(
332/// #         hyper_util::client::legacy::Client::builder(executor).build(connector),
333/// #     ),
334/// # ).build().await.unwrap();
335///
336/// # let client = hyper_util::client::legacy::Client::builder(
337/// #     hyper_util::rt::TokioExecutor::new()
338/// # )
339/// # .build(
340/// #     hyper_rustls::HttpsConnectorBuilder::new()
341/// #         .with_native_roots()
342/// #         .unwrap()
343/// #         .https_or_http()
344/// #         .enable_http2()
345/// #         .build()
346/// # );
347/// # let mut hub = CloudSecurityToken::new(client, auth);
348/// // As the method needs a request, you would usually fill it with the desired information
349/// // into the respective structure. Some of the parts shown here might not be applicable !
350/// // Values shown here are possibly random and not representative !
351/// let mut req = GoogleIdentityStsV1ExchangeTokenRequest::default();
352///
353/// // You can configure optional parameters by calling the respective setters at will, and
354/// // execute the final call using `doit()`.
355/// // Values shown here are possibly random and not representative !
356/// let result = hub.methods().token(req)
357///              .doit().await;
358/// # }
359/// ```
360pub struct MethodTokenCall<'a, C>
361where
362    C: 'a,
363{
364    hub: &'a CloudSecurityToken<C>,
365    _request: GoogleIdentityStsV1ExchangeTokenRequest,
366    _delegate: Option<&'a mut dyn common::Delegate>,
367    _additional_params: HashMap<String, String>,
368}
369
370impl<'a, C> common::CallBuilder for MethodTokenCall<'a, C> {}
371
372impl<'a, C> MethodTokenCall<'a, C>
373where
374    C: common::Connector,
375{
376    /// Perform the operation you have build so far.
377    pub async fn doit(
378        mut self,
379    ) -> common::Result<(common::Response, GoogleIdentityStsV1ExchangeTokenResponse)> {
380        use std::borrow::Cow;
381        use std::io::{Read, Seek};
382
383        use common::{url::Params, ToParts};
384        use hyper::header::{AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE, LOCATION, USER_AGENT};
385
386        let mut dd = common::DefaultDelegate;
387        let mut dlg: &mut dyn common::Delegate = self._delegate.unwrap_or(&mut dd);
388        dlg.begin(common::MethodInfo {
389            id: "sts.token",
390            http_method: hyper::Method::POST,
391        });
392
393        for &field in ["alt"].iter() {
394            if self._additional_params.contains_key(field) {
395                dlg.finished(false);
396                return Err(common::Error::FieldClash(field));
397            }
398        }
399
400        let mut params = Params::with_capacity(3 + self._additional_params.len());
401
402        params.extend(self._additional_params.iter());
403
404        params.push("alt", "json");
405        let mut url = self.hub._base_url.clone() + "v1/token";
406
407        match dlg.api_key() {
408            Some(value) => params.push("key", value),
409            None => {
410                dlg.finished(false);
411                return Err(common::Error::MissingAPIKey);
412            }
413        }
414
415        let url = params.parse_with_url(&url);
416
417        let mut json_mime_type = mime::APPLICATION_JSON;
418        let mut request_value_reader = {
419            let mut value = serde_json::value::to_value(&self._request).expect("serde to work");
420            common::remove_json_null_values(&mut value);
421            let mut dst = std::io::Cursor::new(Vec::with_capacity(128));
422            serde_json::to_writer(&mut dst, &value).unwrap();
423            dst
424        };
425        let request_size = request_value_reader
426            .seek(std::io::SeekFrom::End(0))
427            .unwrap();
428        request_value_reader
429            .seek(std::io::SeekFrom::Start(0))
430            .unwrap();
431
432        loop {
433            request_value_reader
434                .seek(std::io::SeekFrom::Start(0))
435                .unwrap();
436            let mut req_result = {
437                let client = &self.hub.client;
438                dlg.pre_request();
439                let mut req_builder = hyper::Request::builder()
440                    .method(hyper::Method::POST)
441                    .uri(url.as_str())
442                    .header(USER_AGENT, self.hub._user_agent.clone());
443
444                let request = req_builder
445                    .header(CONTENT_TYPE, json_mime_type.to_string())
446                    .header(CONTENT_LENGTH, request_size as u64)
447                    .body(common::to_body(
448                        request_value_reader.get_ref().clone().into(),
449                    ));
450
451                client.request(request.unwrap()).await
452            };
453
454            match req_result {
455                Err(err) => {
456                    if let common::Retry::After(d) = dlg.http_error(&err) {
457                        sleep(d).await;
458                        continue;
459                    }
460                    dlg.finished(false);
461                    return Err(common::Error::HttpError(err));
462                }
463                Ok(res) => {
464                    let (mut parts, body) = res.into_parts();
465                    let mut body = common::Body::new(body);
466                    if !parts.status.is_success() {
467                        let bytes = common::to_bytes(body).await.unwrap_or_default();
468                        let error = serde_json::from_str(&common::to_string(&bytes));
469                        let response = common::to_response(parts, bytes.into());
470
471                        if let common::Retry::After(d) =
472                            dlg.http_failure(&response, error.as_ref().ok())
473                        {
474                            sleep(d).await;
475                            continue;
476                        }
477
478                        dlg.finished(false);
479
480                        return Err(match error {
481                            Ok(value) => common::Error::BadRequest(value),
482                            _ => common::Error::Failure(response),
483                        });
484                    }
485                    let response = {
486                        let bytes = common::to_bytes(body).await.unwrap_or_default();
487                        let encoded = common::to_string(&bytes);
488                        match serde_json::from_str(&encoded) {
489                            Ok(decoded) => (common::to_response(parts, bytes.into()), decoded),
490                            Err(error) => {
491                                dlg.response_json_decode_error(&encoded, &error);
492                                return Err(common::Error::JsonDecodeError(
493                                    encoded.to_string(),
494                                    error,
495                                ));
496                            }
497                        }
498                    };
499
500                    dlg.finished(true);
501                    return Ok(response);
502                }
503            }
504        }
505    }
506
507    ///
508    /// Sets the *request* property to the given value.
509    ///
510    /// Even though the property as already been set when instantiating this call,
511    /// we provide this method for API completeness.
512    pub fn request(
513        mut self,
514        new_value: GoogleIdentityStsV1ExchangeTokenRequest,
515    ) -> MethodTokenCall<'a, C> {
516        self._request = new_value;
517        self
518    }
519    /// The delegate implementation is consulted whenever there is an intermediate result, or if something goes wrong
520    /// while executing the actual API request.
521    ///
522    /// ````text
523    ///                   It should be used to handle progress information, and to implement a certain level of resilience.
524    /// ````
525    ///
526    /// Sets the *delegate* property to the given value.
527    pub fn delegate(mut self, new_value: &'a mut dyn common::Delegate) -> MethodTokenCall<'a, C> {
528        self._delegate = Some(new_value);
529        self
530    }
531
532    /// Set any additional parameter of the query string used in the request.
533    /// It should be used to set parameters which are not yet available through their own
534    /// setters.
535    ///
536    /// Please note that this method must not be used to set any of the known parameters
537    /// which have their own setter method. If done anyway, the request will fail.
538    ///
539    /// # Additional Parameters
540    ///
541    /// * *$.xgafv* (query-string) - V1 error format.
542    /// * *access_token* (query-string) - OAuth access token.
543    /// * *alt* (query-string) - Data format for response.
544    /// * *callback* (query-string) - JSONP
545    /// * *fields* (query-string) - Selector specifying which fields to include in a partial response.
546    /// * *key* (query-string) - API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.
547    /// * *oauth_token* (query-string) - OAuth 2.0 token for the current user.
548    /// * *prettyPrint* (query-boolean) - Returns response with indentations and line breaks.
549    /// * *quotaUser* (query-string) - Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.
550    /// * *uploadType* (query-string) - Legacy upload protocol for media (e.g. "media", "multipart").
551    /// * *upload_protocol* (query-string) - Upload protocol for media (e.g. "raw", "multipart").
552    pub fn param<T>(mut self, name: T, value: T) -> MethodTokenCall<'a, C>
553    where
554        T: AsRef<str>,
555    {
556        self._additional_params
557            .insert(name.as_ref().to_string(), value.as_ref().to_string());
558        self
559    }
560}