From 2bc7d12a46b6cb8e75f989bc5ab354eac1b9accf Mon Sep 17 00:00:00 2001 From: PixelWeaver Date: Tue, 6 Aug 2024 12:59:26 +0200 Subject: [PATCH 1/2] feat: enable user to disable token exchange response body --- src/devicecode.rs | 6 +++--- src/endpoint.rs | 5 ++++- src/introspection.rs | 4 ++-- src/revocation.rs | 2 +- src/token/mod.rs | 37 +++++++++++++++++++++++++++++-------- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/devicecode.rs b/src/devicecode.rs index 53e9140..16f5e05 100644 --- a/src/devicecode.rs +++ b/src/devicecode.rs @@ -178,7 +178,7 @@ where C: SyncHttpClient, EF: ExtraDeviceAuthorizationFields, { - endpoint_response(http_client.call(self.prepare_request()?)?) + endpoint_response(http_client.call(self.prepare_request()?)?, true) } /// Asynchronously sends the request to the authorization server and returns a Future. @@ -196,7 +196,7 @@ where C: AsyncHttpClient<'c>, EF: ExtraDeviceAuthorizationFields, { - Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) }) + Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?, true) }) } } @@ -413,7 +413,7 @@ where }; // Explicitly process the response with a DeviceCodeErrorResponse - let res = endpoint_response::(http_response); + let res = endpoint_response::(http_response, true); match res { // On a ServerResponse error, the error needs inspecting as a DeviceCodeErrorResponse // to work out whether a retry needs to happen. diff --git a/src/endpoint.rs b/src/endpoint.rs index a46772f..739a1b1 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -156,6 +156,7 @@ pub(crate) fn endpoint_request<'a>( pub(crate) fn endpoint_response( http_response: HttpResponse, + check_body: bool ) -> Result> where RE: Error, @@ -164,7 +165,9 @@ where { check_response_status(&http_response)?; - check_response_body(&http_response)?; + if check_body { + check_response_body(&http_response)?; + } let response_body = http_response.body().as_slice(); serde_path_to_error::deserialize(&mut serde_json::Deserializer::from_slice(response_body)) diff --git a/src/introspection.rs b/src/introspection.rs index a40166f..2c8851d 100644 --- a/src/introspection.rs +++ b/src/introspection.rs @@ -168,7 +168,7 @@ where where C: SyncHttpClient, { - endpoint_response(http_client.call(self.prepare_request()?)?) + endpoint_response(http_client.call(self.prepare_request()?)?, true) } /// Asynchronously sends the request to the authorization server and returns a Future. @@ -180,7 +180,7 @@ where Self: 'c, C: AsyncHttpClient<'c>, { - Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) }) + Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?, true) }) } } diff --git a/src/revocation.rs b/src/revocation.rs index fcee130..762584b 100644 --- a/src/revocation.rs +++ b/src/revocation.rs @@ -303,7 +303,7 @@ where Self: 'c, C: AsyncHttpClient<'c>, { - Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) }) + Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?, true) }) } } diff --git a/src/token/mod.rs b/src/token/mod.rs index 97f8aac..8716482 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -84,6 +84,7 @@ where pkce_verifier: None, token_url, redirect_url: self.redirect_url.as_ref().map(Cow::Borrowed), + check_response_body: None, _phantom: PhantomData, } } @@ -142,6 +143,7 @@ where pub(crate) pkce_verifier: Option, pub(crate) token_url: &'a TokenUrl, pub(crate) redirect_url: Option>, + pub(crate) check_response_body: Option, pub(crate) _phantom: PhantomData<(TE, TR)>, } impl<'a, TE, TR> CodeTokenRequest<'a, TE, TR> @@ -187,6 +189,15 @@ where self } + /// + /// Disables body checks for exchange response. + /// Useful when APIs use a different Content-Type for instance. + /// + pub fn disable_check_response_body(mut self) -> Self { + self.check_response_body = Some(false); + self + } + fn prepare_request(self) -> Result> where RE: Error + 'static, @@ -212,6 +223,14 @@ where .map_err(|err| RequestTokenError::Other(format!("failed to prepare request: {err}"))) } + fn should_check_response_body(&self) -> bool { + if self.check_response_body.is_none() { + true + } else { + self.check_response_body.unwrap() + } + } + /// Synchronously sends the request to the authorization server and awaits a response. pub fn request( self, @@ -220,7 +239,8 @@ where where C: SyncHttpClient, { - endpoint_response(http_client.call(self.prepare_request()?)?) + let check_body = self.should_check_response_body(); + endpoint_response(http_client.call(self.prepare_request()?)?, check_body) } /// Asynchronously sends the request to the authorization server and returns a Future. @@ -232,7 +252,8 @@ where Self: 'c, C: AsyncHttpClient<'c>, { - Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) }) + let check_body = self.should_check_response_body(); + Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?, check_body) }) } } @@ -304,7 +325,7 @@ where where C: SyncHttpClient, { - endpoint_response(http_client.call(self.prepare_request()?)?) + endpoint_response(http_client.call(self.prepare_request()?)?, true) } /// Asynchronously sends the request to the authorization server and awaits a response. pub fn request_async<'c, C>( @@ -315,7 +336,7 @@ where Self: 'c, C: AsyncHttpClient<'c>, { - Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) }) + Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?, true) }) } fn prepare_request(&self) -> Result> @@ -408,7 +429,7 @@ where where C: SyncHttpClient, { - endpoint_response(http_client.call(self.prepare_request()?)?) + endpoint_response(http_client.call(self.prepare_request()?)?, true) } /// Asynchronously sends the request to the authorization server and awaits a response. @@ -420,7 +441,7 @@ where Self: 'c, C: AsyncHttpClient<'c>, { - Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) }) + Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?, true) }) } fn prepare_request(&self) -> Result> @@ -512,7 +533,7 @@ where where C: SyncHttpClient, { - endpoint_response(http_client.call(self.prepare_request()?)?) + endpoint_response(http_client.call(self.prepare_request()?)?, true) } /// Asynchronously sends the request to the authorization server and awaits a response. @@ -524,7 +545,7 @@ where Self: 'c, C: AsyncHttpClient<'c>, { - Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?) }) + Box::pin(async move { endpoint_response(http_client.call(self.prepare_request()?).await?, true) }) } fn prepare_request(&self) -> Result> From 071bd5b6e58455286b7c9400b49a9e80c9e0c31d Mon Sep 17 00:00:00 2001 From: PixelWeaver Date: Tue, 6 Aug 2024 13:12:23 +0200 Subject: [PATCH 2/2] chore: use match pattern --- src/token/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/token/mod.rs b/src/token/mod.rs index 8716482..4fa1774 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -224,10 +224,9 @@ where } fn should_check_response_body(&self) -> bool { - if self.check_response_body.is_none() { - true - } else { - self.check_response_body.unwrap() + match self.check_response_body { + None => true, + Some(c) => c } }