sdk: Make RefreshTokenError authentication API-agnostic

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
Kévin Commaille
2023-08-03 14:16:06 +02:00
committed by Jonas Platte
parent dc3636d766
commit 302cff6ba9
5 changed files with 24 additions and 30 deletions

View File

@@ -76,13 +76,13 @@ where
res.as_ref().map_err(HttpError::client_api_error_kind)
{
if let Err(refresh_error) = client.refresh_access_token().await {
match &refresh_error {
HttpError::RefreshToken(RefreshTokenError::RefreshTokenRequired) => {
match refresh_error {
RefreshTokenError::RefreshTokenRequired => {
// Refreshing access tokens is not supported by
// this `Session`, ignore.
}
_ => {
return Err(refresh_error);
return Err(refresh_error.into());
}
}
} else {

View File

@@ -950,9 +950,9 @@ impl Client {
///
/// See the documentation of the authentication API's `refresh_access_token`
/// method for more information.
pub async fn refresh_access_token(&self) -> HttpResult<()> {
pub async fn refresh_access_token(&self) -> Result<(), RefreshTokenError> {
let Some(auth_api) = self.auth_api() else {
return Err(RefreshTokenError::RefreshTokenRequired.into());
return Err(RefreshTokenError::RefreshTokenRequired);
};
match auth_api {
@@ -1295,12 +1295,12 @@ impl Client {
{
if let Err(refresh_error) = self.refresh_access_token().await {
match &refresh_error {
HttpError::RefreshToken(RefreshTokenError::RefreshTokenRequired) => {
RefreshTokenError::RefreshTokenRequired => {
// Refreshing access tokens is not supported by
// this `Session`, ignore.
}
_ => {
return Err(refresh_error);
return Err(refresh_error.into());
}
}
} else {

View File

@@ -14,7 +14,7 @@
//! Error conditions.
use std::io::Error as IoError;
use std::{io::Error as IoError, sync::Arc};
#[cfg(feature = "qrcode")]
use matrix_sdk_base::crypto::ScanError;
@@ -416,18 +416,13 @@ pub enum ImageError {
/// [handling refresh tokens]: crate::ClientBuilder::handle_refresh_tokens()
#[derive(Debug, Error, Clone)]
pub enum RefreshTokenError {
/// The Matrix endpoint returned an error.
#[error(transparent)]
ClientApi(#[from] ruma::api::client::Error),
/// Tried to send a refresh token request without a refresh token.
#[error("missing refresh token")]
RefreshTokenRequired,
/// There was an ongoing refresh token call that failed and the error could
/// not be forwarded.
#[error("the access token could not be refreshed")]
UnableToRefreshToken,
/// An error occurred interacting with the native Matrix authentication API.
#[error(transparent)]
MatrixAuth(Arc<HttpError>),
}
/// Errors that can occur when manipulating push notification settings.

View File

@@ -44,7 +44,7 @@ use crate::{
authentication::AuthData,
config::RequestConfig,
error::{HttpError, HttpResult},
Client, Error, RefreshTokenError, Result, RumaApiError,
Client, Error, RefreshTokenError, Result,
};
mod login_builder;
@@ -446,14 +446,16 @@ impl MatrixAuth {
/// [`UnknownToken`]: ruma::api::client::error::ErrorKind::UnknownToken
/// [restore the session]: Client::restore_session
/// [`ClientBuilder::handle_refresh_tokens()`]: crate::ClientBuilder::handle_refresh_tokens
pub async fn refresh_access_token(&self) -> HttpResult<Option<refresh_token::v3::Response>> {
pub async fn refresh_access_token(
&self,
) -> Result<Option<refresh_token::v3::Response>, RefreshTokenError> {
let client = &self.client;
let lock = client.inner.refresh_token_lock.try_lock();
if let Ok(mut guard) = lock {
let Some(mut session_tokens) = self.session_tokens() else {
*guard = Err(RefreshTokenError::RefreshTokenRequired);
return Err(RefreshTokenError::RefreshTokenRequired.into());
return Err(RefreshTokenError::RefreshTokenRequired);
};
let refresh_token = session_tokens
@@ -477,20 +479,16 @@ impl MatrixAuth {
Ok(Some(res))
}
Err(error) => {
*guard = match error.as_ruma_api_error() {
Some(RumaApiError::ClientApi(api_error)) => {
Err(RefreshTokenError::ClientApi(api_error.to_owned()))
}
_ => Err(RefreshTokenError::UnableToRefreshToken),
};
let error = RefreshTokenError::MatrixAuth(error.into());
*guard = Err(error.clone());
Err(error)
}
}
} else {
match *client.inner.refresh_token_lock.lock().await {
match client.inner.refresh_token_lock.lock().await.as_ref() {
Ok(_) => Ok(None),
Err(_) => Err(RefreshTokenError::UnableToRefreshToken.into()),
Err(error) => Err(error.clone()),
}
}
}

View File

@@ -154,7 +154,7 @@ async fn no_refresh_token() {
.await;
let res = client.refresh_access_token().await;
assert_matches!(res, Err(HttpError::RefreshToken(RefreshTokenError::RefreshTokenRequired)));
assert_matches!(res, Err(RefreshTokenError::RefreshTokenRequired));
}
#[async_test]
@@ -348,8 +348,9 @@ async fn refresh_token_handled_failure() {
.mount(&server)
.await;
let res = client.whoami().await.unwrap_err();
assert_matches!(res.client_api_error_kind(), Some(ErrorKind::UnknownToken { .. }))
let res = client.whoami().await;
let http_err = assert_matches!(res, Err(HttpError::RefreshToken(RefreshTokenError::MatrixAuth(http_err))) => http_err);
assert_matches!(http_err.client_api_error_kind(), Some(ErrorKind::UnknownToken { .. }))
}
#[async_test]