Skip to main content

qcs_api_client_openapi/apis/
authentication_api.rs

1// Copyright 2022 Rigetti Computing
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16 * Rigetti QCS API
17 *
18 * # Introduction  This is the documentation for the Rigetti QCS HTTP API.  You can find out more about Rigetti at [https://rigetti.com](https://rigetti.com), and also interact with QCS via the web at [https://qcs.rigetti.com](https://qcs.rigetti.com).  This API is documented in **OpenAPI format** and so is compatible with the dozens of language-specific client generators available [here](https://github.com/OpenAPITools/openapi-generator) and elsewhere on the web.  # Principles  This API follows REST design principles where appropriate, and otherwise an HTTP RPC paradigm. We adhere to the Google [API Improvement Proposals](https://google.aip.dev/general) where reasonable to provide a consistent, intuitive developer experience. HTTP response codes match their specifications, and error messages fit a common format.  # Authentication  All access to the QCS API requires OAuth2 authentication provided by Okta. You can request access [here](https://www.rigetti.com/get-quantum). Once you have a user account, you can download your access token from QCS [here](https://qcs.rigetti.com/auth/token).   That access token is valid for 24 hours after issuance. The value of `access_token` within the JSON file is the token used for authentication (don't use the entire JSON file).  Authenticate requests using the `Authorization` header and a `Bearer` prefix:  ``` curl --header \"Authorization: Bearer eyJraW...Iow\" ```  # Quantum Processor Access  Access to the quantum processors themselves is not yet provided directly by this HTTP API, but is instead performed over ZeroMQ/[rpcq](https://github.com/rigetti/rpcq). Until that changes, we suggest using [pyquil](https://github.com/rigetti/pyquil) to build and execute quantum programs via the Legacy API.  # Legacy API  Our legacy HTTP API remains accessible at https://forest-server.qcs.rigetti.com, and it shares a source of truth with this API's services. You can use either service with the same user account and means of authentication. We strongly recommend using the API documented here, as the legacy API is on the path to deprecation.
19 *
20 * The version of the OpenAPI document: 2020-07-31
21 * Contact: support@rigetti.com
22 * Generated by: https://openapi-generator.tech
23 */
24
25use super::{configuration, ContentType, Error};
26use crate::{apis::ResponseContent, models};
27use ::qcs_api_client_common::backoff::{
28    duration_from_io_error, duration_from_reqwest_error, duration_from_response, ExponentialBackoff,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::tokens::TokenRefresher;
32use reqwest::StatusCode;
33use serde::{Deserialize, Serialize};
34
35#[cfg(feature = "clap")]
36#[allow(unused, reason = "not used in all templates, but required in some")]
37use ::{miette::IntoDiagnostic as _, qcs_api_client_common::clap_utils::JsonMaybeStdin};
38
39/// Serialize command-line arguments for [`auth_email_password_reset_token`]
40#[cfg(feature = "clap")]
41#[derive(Debug, clap::Args)]
42pub struct AuthEmailPasswordResetTokenClapParams {
43    pub auth_email_password_reset_token_request:
44        Option<JsonMaybeStdin<crate::models::AuthEmailPasswordResetTokenRequest>>,
45}
46
47#[cfg(feature = "clap")]
48impl AuthEmailPasswordResetTokenClapParams {
49    pub async fn execute(
50        self,
51        configuration: &configuration::Configuration,
52    ) -> Result<(), miette::Error> {
53        let request = self
54            .auth_email_password_reset_token_request
55            .map(|body| body.into_inner().into_inner());
56
57        auth_email_password_reset_token(configuration, request)
58            .await
59            .into_diagnostic()
60    }
61}
62
63/// Serialize command-line arguments for [`auth_get_user`]
64#[cfg(feature = "clap")]
65#[derive(Debug, clap::Args)]
66pub struct AuthGetUserClapParams {}
67
68#[cfg(feature = "clap")]
69impl AuthGetUserClapParams {
70    pub async fn execute(
71        self,
72        configuration: &configuration::Configuration,
73    ) -> Result<models::User, miette::Error> {
74        auth_get_user(configuration).await.into_diagnostic()
75    }
76}
77
78/// Serialize command-line arguments for [`auth_reset_password`]
79#[cfg(feature = "clap")]
80#[derive(Debug, clap::Args)]
81pub struct AuthResetPasswordClapParams {
82    pub auth_reset_password_request: JsonMaybeStdin<crate::models::AuthResetPasswordRequest>,
83}
84
85#[cfg(feature = "clap")]
86impl AuthResetPasswordClapParams {
87    pub async fn execute(
88        self,
89        configuration: &configuration::Configuration,
90    ) -> Result<(), miette::Error> {
91        let request = self.auth_reset_password_request.into_inner().into_inner();
92
93        auth_reset_password(configuration, request)
94            .await
95            .into_diagnostic()
96    }
97}
98
99/// Serialize command-line arguments for [`auth_reset_password_with_token`]
100#[cfg(feature = "clap")]
101#[derive(Debug, clap::Args)]
102pub struct AuthResetPasswordWithTokenClapParams {
103    pub auth_reset_password_with_token_request:
104        JsonMaybeStdin<crate::models::AuthResetPasswordWithTokenRequest>,
105}
106
107#[cfg(feature = "clap")]
108impl AuthResetPasswordWithTokenClapParams {
109    pub async fn execute(
110        self,
111        configuration: &configuration::Configuration,
112    ) -> Result<(), miette::Error> {
113        let request = self
114            .auth_reset_password_with_token_request
115            .into_inner()
116            .into_inner();
117
118        auth_reset_password_with_token(configuration, request)
119            .await
120            .into_diagnostic()
121    }
122}
123
124/// struct for typed errors of method [`auth_email_password_reset_token`]
125#[derive(Debug, Clone, Serialize, Deserialize)]
126#[serde(untagged)]
127pub enum AuthEmailPasswordResetTokenError {
128    Status422(models::Error),
129    UnknownValue(serde_json::Value),
130}
131
132/// struct for typed errors of method [`auth_get_user`]
133#[derive(Debug, Clone, Serialize, Deserialize)]
134#[serde(untagged)]
135pub enum AuthGetUserError {
136    Status401(models::Error),
137    Status404(models::Error),
138    UnknownValue(serde_json::Value),
139}
140
141/// struct for typed errors of method [`auth_reset_password`]
142#[derive(Debug, Clone, Serialize, Deserialize)]
143#[serde(untagged)]
144pub enum AuthResetPasswordError {
145    Status401(models::Error),
146    Status422(models::Error),
147    UnknownValue(serde_json::Value),
148}
149
150/// struct for typed errors of method [`auth_reset_password_with_token`]
151#[derive(Debug, Clone, Serialize, Deserialize)]
152#[serde(untagged)]
153pub enum AuthResetPasswordWithTokenError {
154    Status404(models::Error),
155    Status422(models::Error),
156    UnknownValue(serde_json::Value),
157}
158
159async fn auth_email_password_reset_token_inner(
160    configuration: &configuration::Configuration,
161    backoff: &mut ExponentialBackoff,
162    auth_email_password_reset_token_request: Option<
163        crate::models::AuthEmailPasswordResetTokenRequest,
164    >,
165) -> Result<(), Error<AuthEmailPasswordResetTokenError>> {
166    let local_var_configuration = configuration;
167    // add a prefix to parameters to efficiently prevent name collisions
168    let p_body_auth_email_password_reset_token_request = auth_email_password_reset_token_request;
169
170    let local_var_client = &local_var_configuration.client;
171
172    let local_var_uri_str = format!(
173        "{}/v1/auth:emailPasswordResetToken",
174        local_var_configuration.qcs_config.api_url()
175    );
176    let mut local_var_req_builder =
177        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
178
179    #[cfg(feature = "tracing")]
180    {
181        // Ignore parsing errors if the URL is invalid for some reason.
182        // If it is invalid, it will turn up as an error later when actually making the request.
183        let local_var_do_tracing = local_var_uri_str
184            .parse::<::url::Url>()
185            .ok()
186            .is_none_or(|url| {
187                configuration
188                    .qcs_config
189                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
190            });
191
192        if local_var_do_tracing {
193            ::tracing::debug!(
194                url=%local_var_uri_str,
195                method="POST",
196                "making auth_email_password_reset_token request",
197            );
198        }
199    }
200
201    // Use the QCS Bearer token if a client OAuthSession is present,
202    // but do not require one when the security schema says it is optional.
203    {
204        use qcs_api_client_common::configuration::TokenError;
205
206        #[allow(
207            clippy::nonminimal_bool,
208            clippy::eq_op,
209            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
210        )]
211        let is_jwt_bearer_optional: bool = false;
212
213        let token = local_var_configuration
214            .qcs_config
215            .get_bearer_access_token()
216            .await;
217
218        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
219            // the client is configured without any OAuthSession, but this call does not require one.
220            #[cfg(feature = "tracing")]
221            tracing::debug!(
222                "No client credentials found, but this call does not require authentication."
223            );
224        } else {
225            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
226        }
227    }
228
229    local_var_req_builder =
230        local_var_req_builder.json(&p_body_auth_email_password_reset_token_request);
231
232    let local_var_req = local_var_req_builder.build()?;
233    let local_var_resp = local_var_client.execute(local_var_req).await?;
234
235    let local_var_status = local_var_resp.status();
236
237    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
238        Ok(())
239    } else {
240        let local_var_retry_delay =
241            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
242        let local_var_content = local_var_resp.text().await?;
243        let local_var_entity: Option<AuthEmailPasswordResetTokenError> =
244            serde_json::from_str(&local_var_content).ok();
245        let local_var_error = ResponseContent {
246            status: local_var_status,
247            content: local_var_content,
248            entity: local_var_entity,
249            retry_delay: local_var_retry_delay,
250        };
251        Err(Error::ResponseError(local_var_error))
252    }
253}
254
255/// Send a password reset link to the provided email address, if that email matches a registered user.
256pub async fn auth_email_password_reset_token(
257    configuration: &configuration::Configuration,
258    auth_email_password_reset_token_request: Option<
259        crate::models::AuthEmailPasswordResetTokenRequest,
260    >,
261) -> Result<(), Error<AuthEmailPasswordResetTokenError>> {
262    let mut backoff = configuration.backoff.clone();
263    let mut refreshed_credentials = false;
264    let method = reqwest::Method::POST;
265    loop {
266        let result = auth_email_password_reset_token_inner(
267            configuration,
268            &mut backoff,
269            auth_email_password_reset_token_request.clone(),
270        )
271        .await;
272
273        match result {
274            Ok(result) => return Ok(result),
275            Err(Error::ResponseError(response)) => {
276                if !refreshed_credentials
277                    && matches!(
278                        response.status,
279                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
280                    )
281                {
282                    configuration.qcs_config.refresh().await?;
283                    refreshed_credentials = true;
284                    continue;
285                } else if let Some(duration) = response.retry_delay {
286                    tokio::time::sleep(duration).await;
287                    continue;
288                }
289
290                return Err(Error::ResponseError(response));
291            }
292            Err(Error::Reqwest(error)) => {
293                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
294                    tokio::time::sleep(duration).await;
295                    continue;
296                }
297
298                return Err(Error::Reqwest(error));
299            }
300            Err(Error::Io(error)) => {
301                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
302                    tokio::time::sleep(duration).await;
303                    continue;
304                }
305
306                return Err(Error::Io(error));
307            }
308            Err(error) => return Err(error),
309        }
310    }
311}
312async fn auth_get_user_inner(
313    configuration: &configuration::Configuration,
314    backoff: &mut ExponentialBackoff,
315) -> Result<models::User, Error<AuthGetUserError>> {
316    let local_var_configuration = configuration;
317
318    let local_var_client = &local_var_configuration.client;
319
320    let local_var_uri_str = format!(
321        "{}/v1/auth:getUser",
322        local_var_configuration.qcs_config.api_url()
323    );
324    let mut local_var_req_builder =
325        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
326
327    #[cfg(feature = "tracing")]
328    {
329        // Ignore parsing errors if the URL is invalid for some reason.
330        // If it is invalid, it will turn up as an error later when actually making the request.
331        let local_var_do_tracing = local_var_uri_str
332            .parse::<::url::Url>()
333            .ok()
334            .is_none_or(|url| {
335                configuration
336                    .qcs_config
337                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
338            });
339
340        if local_var_do_tracing {
341            ::tracing::debug!(
342                url=%local_var_uri_str,
343                method="GET",
344                "making auth_get_user request",
345            );
346        }
347    }
348
349    // Use the QCS Bearer token if a client OAuthSession is present,
350    // but do not require one when the security schema says it is optional.
351    {
352        use qcs_api_client_common::configuration::TokenError;
353
354        #[allow(
355            clippy::nonminimal_bool,
356            clippy::eq_op,
357            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
358        )]
359        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
360
361        let token = local_var_configuration
362            .qcs_config
363            .get_bearer_access_token()
364            .await;
365
366        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
367            // the client is configured without any OAuthSession, but this call does not require one.
368            #[cfg(feature = "tracing")]
369            tracing::debug!(
370                "No client credentials found, but this call does not require authentication."
371            );
372        } else {
373            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
374        }
375    }
376
377    let local_var_req = local_var_req_builder.build()?;
378    let local_var_resp = local_var_client.execute(local_var_req).await?;
379
380    let local_var_status = local_var_resp.status();
381    let local_var_raw_content_type = local_var_resp
382        .headers()
383        .get("content-type")
384        .and_then(|v| v.to_str().ok())
385        .unwrap_or("application/octet-stream")
386        .to_string();
387    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
388
389    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
390        let local_var_content = local_var_resp.text().await?;
391        match local_var_content_type {
392            ContentType::Json => serde_path_to_error::deserialize(
393                &mut serde_json::Deserializer::from_str(&local_var_content),
394            )
395            .map_err(Error::from),
396            ContentType::Text => Err(Error::InvalidContentType {
397                content_type: local_var_raw_content_type,
398                return_type: "models::User",
399            }),
400            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
401                content_type: unknown_type,
402                return_type: "models::User",
403            }),
404        }
405    } else {
406        let local_var_retry_delay =
407            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
408        let local_var_content = local_var_resp.text().await?;
409        let local_var_entity: Option<AuthGetUserError> =
410            serde_json::from_str(&local_var_content).ok();
411        let local_var_error = ResponseContent {
412            status: local_var_status,
413            content: local_var_content,
414            entity: local_var_entity,
415            retry_delay: local_var_retry_delay,
416        };
417        Err(Error::ResponseError(local_var_error))
418    }
419}
420
421/// Retrieve the profile of the authenticated user.
422pub async fn auth_get_user(
423    configuration: &configuration::Configuration,
424) -> Result<models::User, Error<AuthGetUserError>> {
425    let mut backoff = configuration.backoff.clone();
426    let mut refreshed_credentials = false;
427    let method = reqwest::Method::GET;
428    loop {
429        let result = auth_get_user_inner(configuration, &mut backoff).await;
430
431        match result {
432            Ok(result) => return Ok(result),
433            Err(Error::ResponseError(response)) => {
434                if !refreshed_credentials
435                    && matches!(
436                        response.status,
437                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
438                    )
439                {
440                    configuration.qcs_config.refresh().await?;
441                    refreshed_credentials = true;
442                    continue;
443                } else if let Some(duration) = response.retry_delay {
444                    tokio::time::sleep(duration).await;
445                    continue;
446                }
447
448                return Err(Error::ResponseError(response));
449            }
450            Err(Error::Reqwest(error)) => {
451                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
452                    tokio::time::sleep(duration).await;
453                    continue;
454                }
455
456                return Err(Error::Reqwest(error));
457            }
458            Err(Error::Io(error)) => {
459                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
460                    tokio::time::sleep(duration).await;
461                    continue;
462                }
463
464                return Err(Error::Io(error));
465            }
466            Err(error) => return Err(error),
467        }
468    }
469}
470async fn auth_reset_password_inner(
471    configuration: &configuration::Configuration,
472    backoff: &mut ExponentialBackoff,
473    auth_reset_password_request: crate::models::AuthResetPasswordRequest,
474) -> Result<(), Error<AuthResetPasswordError>> {
475    let local_var_configuration = configuration;
476    // add a prefix to parameters to efficiently prevent name collisions
477    let p_body_auth_reset_password_request = auth_reset_password_request;
478
479    let local_var_client = &local_var_configuration.client;
480
481    let local_var_uri_str = format!(
482        "{}/v1/auth:resetPassword",
483        local_var_configuration.qcs_config.api_url()
484    );
485    let mut local_var_req_builder =
486        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
487
488    #[cfg(feature = "tracing")]
489    {
490        // Ignore parsing errors if the URL is invalid for some reason.
491        // If it is invalid, it will turn up as an error later when actually making the request.
492        let local_var_do_tracing = local_var_uri_str
493            .parse::<::url::Url>()
494            .ok()
495            .is_none_or(|url| {
496                configuration
497                    .qcs_config
498                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
499            });
500
501        if local_var_do_tracing {
502            ::tracing::debug!(
503                url=%local_var_uri_str,
504                method="POST",
505                "making auth_reset_password request",
506            );
507        }
508    }
509
510    // Use the QCS Bearer token if a client OAuthSession is present,
511    // but do not require one when the security schema says it is optional.
512    {
513        use qcs_api_client_common::configuration::TokenError;
514
515        #[allow(
516            clippy::nonminimal_bool,
517            clippy::eq_op,
518            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
519        )]
520        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
521
522        let token = local_var_configuration
523            .qcs_config
524            .get_bearer_access_token()
525            .await;
526
527        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
528            // the client is configured without any OAuthSession, but this call does not require one.
529            #[cfg(feature = "tracing")]
530            tracing::debug!(
531                "No client credentials found, but this call does not require authentication."
532            );
533        } else {
534            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
535        }
536    }
537
538    local_var_req_builder = local_var_req_builder.json(&p_body_auth_reset_password_request);
539
540    let local_var_req = local_var_req_builder.build()?;
541    let local_var_resp = local_var_client.execute(local_var_req).await?;
542
543    let local_var_status = local_var_resp.status();
544
545    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
546        Ok(())
547    } else {
548        let local_var_retry_delay =
549            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
550        let local_var_content = local_var_resp.text().await?;
551        let local_var_entity: Option<AuthResetPasswordError> =
552            serde_json::from_str(&local_var_content).ok();
553        let local_var_error = ResponseContent {
554            status: local_var_status,
555            content: local_var_content,
556            entity: local_var_entity,
557            retry_delay: local_var_retry_delay,
558        };
559        Err(Error::ResponseError(local_var_error))
560    }
561}
562
563/// Reset the password using the user's existing password. Note, this is an authenticated route.
564pub async fn auth_reset_password(
565    configuration: &configuration::Configuration,
566    auth_reset_password_request: crate::models::AuthResetPasswordRequest,
567) -> Result<(), Error<AuthResetPasswordError>> {
568    let mut backoff = configuration.backoff.clone();
569    let mut refreshed_credentials = false;
570    let method = reqwest::Method::POST;
571    loop {
572        let result = auth_reset_password_inner(
573            configuration,
574            &mut backoff,
575            auth_reset_password_request.clone(),
576        )
577        .await;
578
579        match result {
580            Ok(result) => return Ok(result),
581            Err(Error::ResponseError(response)) => {
582                if !refreshed_credentials
583                    && matches!(
584                        response.status,
585                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
586                    )
587                {
588                    configuration.qcs_config.refresh().await?;
589                    refreshed_credentials = true;
590                    continue;
591                } else if let Some(duration) = response.retry_delay {
592                    tokio::time::sleep(duration).await;
593                    continue;
594                }
595
596                return Err(Error::ResponseError(response));
597            }
598            Err(Error::Reqwest(error)) => {
599                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
600                    tokio::time::sleep(duration).await;
601                    continue;
602                }
603
604                return Err(Error::Reqwest(error));
605            }
606            Err(Error::Io(error)) => {
607                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
608                    tokio::time::sleep(duration).await;
609                    continue;
610                }
611
612                return Err(Error::Io(error));
613            }
614            Err(error) => return Err(error),
615        }
616    }
617}
618async fn auth_reset_password_with_token_inner(
619    configuration: &configuration::Configuration,
620    backoff: &mut ExponentialBackoff,
621    auth_reset_password_with_token_request: crate::models::AuthResetPasswordWithTokenRequest,
622) -> Result<(), Error<AuthResetPasswordWithTokenError>> {
623    let local_var_configuration = configuration;
624    // add a prefix to parameters to efficiently prevent name collisions
625    let p_body_auth_reset_password_with_token_request = auth_reset_password_with_token_request;
626
627    let local_var_client = &local_var_configuration.client;
628
629    let local_var_uri_str = format!(
630        "{}/v1/auth:resetPasswordWithToken",
631        local_var_configuration.qcs_config.api_url()
632    );
633    let mut local_var_req_builder =
634        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
635
636    #[cfg(feature = "tracing")]
637    {
638        // Ignore parsing errors if the URL is invalid for some reason.
639        // If it is invalid, it will turn up as an error later when actually making the request.
640        let local_var_do_tracing = local_var_uri_str
641            .parse::<::url::Url>()
642            .ok()
643            .is_none_or(|url| {
644                configuration
645                    .qcs_config
646                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
647            });
648
649        if local_var_do_tracing {
650            ::tracing::debug!(
651                url=%local_var_uri_str,
652                method="POST",
653                "making auth_reset_password_with_token request",
654            );
655        }
656    }
657
658    // Use the QCS Bearer token if a client OAuthSession is present,
659    // but do not require one when the security schema says it is optional.
660    {
661        use qcs_api_client_common::configuration::TokenError;
662
663        #[allow(
664            clippy::nonminimal_bool,
665            clippy::eq_op,
666            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
667        )]
668        let is_jwt_bearer_optional: bool = false;
669
670        let token = local_var_configuration
671            .qcs_config
672            .get_bearer_access_token()
673            .await;
674
675        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
676            // the client is configured without any OAuthSession, but this call does not require one.
677            #[cfg(feature = "tracing")]
678            tracing::debug!(
679                "No client credentials found, but this call does not require authentication."
680            );
681        } else {
682            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
683        }
684    }
685
686    local_var_req_builder =
687        local_var_req_builder.json(&p_body_auth_reset_password_with_token_request);
688
689    let local_var_req = local_var_req_builder.build()?;
690    let local_var_resp = local_var_client.execute(local_var_req).await?;
691
692    let local_var_status = local_var_resp.status();
693
694    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
695        Ok(())
696    } else {
697        let local_var_retry_delay =
698            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
699        let local_var_content = local_var_resp.text().await?;
700        let local_var_entity: Option<AuthResetPasswordWithTokenError> =
701            serde_json::from_str(&local_var_content).ok();
702        let local_var_error = ResponseContent {
703            status: local_var_status,
704            content: local_var_content,
705            entity: local_var_entity,
706            retry_delay: local_var_retry_delay,
707        };
708        Err(Error::ResponseError(local_var_error))
709    }
710}
711
712/// Complete the forgot password flow, resetting the new password in exchange for an emailed token.
713pub async fn auth_reset_password_with_token(
714    configuration: &configuration::Configuration,
715    auth_reset_password_with_token_request: crate::models::AuthResetPasswordWithTokenRequest,
716) -> Result<(), Error<AuthResetPasswordWithTokenError>> {
717    let mut backoff = configuration.backoff.clone();
718    let mut refreshed_credentials = false;
719    let method = reqwest::Method::POST;
720    loop {
721        let result = auth_reset_password_with_token_inner(
722            configuration,
723            &mut backoff,
724            auth_reset_password_with_token_request.clone(),
725        )
726        .await;
727
728        match result {
729            Ok(result) => return Ok(result),
730            Err(Error::ResponseError(response)) => {
731                if !refreshed_credentials
732                    && matches!(
733                        response.status,
734                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
735                    )
736                {
737                    configuration.qcs_config.refresh().await?;
738                    refreshed_credentials = true;
739                    continue;
740                } else if let Some(duration) = response.retry_delay {
741                    tokio::time::sleep(duration).await;
742                    continue;
743                }
744
745                return Err(Error::ResponseError(response));
746            }
747            Err(Error::Reqwest(error)) => {
748                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
749                    tokio::time::sleep(duration).await;
750                    continue;
751                }
752
753                return Err(Error::Reqwest(error));
754            }
755            Err(Error::Io(error)) => {
756                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
757                    tokio::time::sleep(duration).await;
758                    continue;
759                }
760
761                return Err(Error::Io(error));
762            }
763            Err(error) => return Err(error),
764        }
765    }
766}