chore: error for oauth (#268)

* chore: error for oauth

* chore: fmt

* chore: fmt

* chore: add error type

* chore: fix ci
This commit is contained in:
Nathan.fooo 2024-01-22 23:43:04 +08:00 committed by GitHub
parent 3dfc7e769b
commit ee3abdb27a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 23 additions and 13 deletions

1
Cargo.lock generated
View File

@ -1206,6 +1206,7 @@ dependencies = [
"bincode",
"brotli",
"bytes",
"chrono",
"collab",
"collab-entity",
"database-entity",

View File

@ -33,6 +33,12 @@ pub enum AppError {
#[error("{0}")]
OAuthError(String),
#[error("{0}")]
UserUnAuthorized(String),
#[error("{0}")]
UserAlreadyRegistered(String),
#[error("Missing Payload:{0}")]
MissingPayload(String),
@ -115,8 +121,8 @@ impl AppError {
matches!(self, AppError::Connect(_) | AppError::RequestTimeout(_))
}
pub fn is_oauth_error(&self) -> bool {
matches!(self, AppError::OAuthError(_))
pub fn is_unauthorized(&self) -> bool {
matches!(self, AppError::UserUnAuthorized(_))
}
pub fn code(&self) -> ErrorCode {
@ -128,6 +134,8 @@ impl AppError {
AppError::InvalidEmail(_) => ErrorCode::InvalidEmail,
AppError::InvalidPassword(_) => ErrorCode::InvalidPassword,
AppError::OAuthError(_) => ErrorCode::OAuthError,
AppError::UserUnAuthorized(_) => ErrorCode::UserUnAuthorized,
AppError::UserAlreadyRegistered(_) => ErrorCode::RecordAlreadyExists,
AppError::MissingPayload(_) => ErrorCode::MissingPayload,
AppError::DBError(_) => ErrorCode::DBError,
AppError::OpenError(_) => ErrorCode::OpenError,
@ -198,11 +206,13 @@ impl From<crate::gotrue::GoTrueError> for AppError {
GoTrueError::RequestTimeout(msg) => AppError::RequestTimeout(msg),
GoTrueError::InvalidRequest(msg) => AppError::InvalidRequest(msg),
GoTrueError::ClientError(err) => AppError::OAuthError(err.to_string()),
GoTrueError::Auth(err) => AppError::OAuthError(err),
GoTrueError::Auth(err) => AppError::UserUnAuthorized(err),
GoTrueError::Internal(err) => match (err.code, err.msg.as_str()) {
(400, m) if m.starts_with("oauth error") => AppError::OAuthError(err.msg),
(400, m) if m.starts_with("User already registered") => AppError::OAuthError(err.msg),
(401, _) => AppError::OAuthError(err.msg),
(400, m) if m.starts_with("User already registered") => {
AppError::UserAlreadyRegistered(err.msg)
},
(401, _) => AppError::UserUnAuthorized(err.msg),
(422, _) => AppError::InvalidRequest(err.msg),
_ => AppError::OAuthError(err.to_string()),
},
@ -252,6 +262,7 @@ pub enum ErrorCode {
S3ResponseError = 1021,
SerdeError = 1022,
NetworkError = 1023,
UserUnAuthorized = 1024,
}
impl ErrorCode {

View File

@ -31,6 +31,7 @@ url = "2.5.0"
mime = "0.3.17"
tokio-stream = { version = "0.1.14" }
realtime-entity = { workspace = true }
chrono = "0.4"
collab = { version = "0.1.0", optional = true }
collab-entity = { version = "0.1.0" }

View File

@ -37,7 +37,7 @@ use shared_entity::dto::workspace_dto::{
use shared_entity::response::{AppResponse, AppResponseError};
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::{Duration, SystemTime};
use std::time::Duration;
use tracing::{event, instrument, trace, warn};
use url::Url;
@ -1113,10 +1113,7 @@ impl Client {
let expires_at = self.token_expires_at()?;
// Refresh token if it's about to expire
let time_now_sec = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
let time_now_sec = chrono::Local::now().timestamp();
if time_now_sec + 10 > expires_at {
// Add 10 seconds buffer
self.refresh_token().await?;

View File

@ -120,7 +120,7 @@ impl Client {
}
async fn inner_refresh_token(&self) -> Result<(), AppResponseError> {
let retry_strategy = FixedInterval::new(Duration::from_secs(2)).take(4);
let retry_strategy = FixedInterval::new(Duration::from_secs(10)).take(4);
let action = RefreshTokenAction::new(self.token.clone(), self.gotrue_client.clone());
match RetryIf::spawn(retry_strategy, action, RefreshTokenRetryCondition).await {
Ok(_) => {
@ -132,7 +132,7 @@ impl Client {
event!(tracing::Level::ERROR, "refresh token failed: {}", err);
// If the error is an OAuth error, unset the token.
if err.is_oauth_error() {
if err.is_unauthorized() {
self.token.write().unset();
}
Err(err.into())

View File

@ -92,7 +92,7 @@ async fn sign_in_with_invalid_url() {
match c.sign_in_with_url(url_str).await {
Ok(_) => panic!("should not be ok"),
Err(e) => {
assert_eq!(e.code, ErrorCode::OAuthError);
assert_eq!(e.code, ErrorCode::UserUnAuthorized);
assert!(e
.message
.contains("invalid JWT: unable to parse or verify signature, token is expired by"));