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}