Skip to content

Commit

Permalink
feature: detailed serialization error response
Browse files Browse the repository at this point in the history
  • Loading branch information
ParzivalEugene committed Aug 7, 2024
1 parent 9b193a8 commit dc46535
Show file tree
Hide file tree
Showing 14 changed files with 49 additions and 35 deletions.
3 changes: 1 addition & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ DATABASE_PASSWORD=some_strong_pass
DATABASE_HOST=localhost
DATABASE_URL=postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}
JWT_ACCESS_SECRET=some_jwt_access
JWT_REFRESH_SECRET=some_jwt_refresh
RUST_ENV=development
JWT_REFRESH_SECRET=some_jwt_refresh
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ diesel = { version = "2.1.0", features = [
] }
dotenvy = "0.15"
futures = "0.3.30"
http-body-util = "0.1.2"
http-serde = "2.1.1"
jsonwebtoken = "9.3.0"
listenfd = "1.0.1"
Expand Down Expand Up @@ -45,4 +46,4 @@ uuid = { version = "1.10", features = [
"fast-rng",
"macro-diagnostics",
] }
validator = { version = "0.18", features = ["derive"] }
validator = { version = "0.18", features = ["derive"] }
3 changes: 0 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ pub struct Config {
pub jwt_access_secret: String,
/// The secret used to sign refresh tokens.
pub jwt_refresh_secret: String,
/// Version of the rust environment.
pub rust_env: String,
pub discord_client_secret: String,
pub discord_client_id: String,
pub github_client_secret: String,
Expand All @@ -38,5 +36,4 @@ pub static ENV: Lazy<Config> = Lazy::new(|| Config {
google_client_secret: env::var("GOOGLE_CLIENT_SECRET")
.expect("GOOGLE_CLIENT_SECRET must be set"),
google_client_id: env::var("GOOGLE_CLIENT_ID").expect("GOOGLE_CLIENT_ID must be set"),
rust_env: env::var("RUST_ENV").expect("RUST_ENV must be set"),
});
8 changes: 0 additions & 8 deletions src/enums/errors/external/auth_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ pub enum AuthError {
WrongToken,
WrongPassword,
WrongEmail,
MissingCredentials,
MissingDevice,
TokenCreation,
UserNotFound,
UserAlreadyExists,
Expand All @@ -28,8 +26,6 @@ impl std::fmt::Display for AuthError {
AuthError::WrongToken => write!(f, "WrongToken"),
AuthError::WrongPassword => write!(f, "WrongPassword"),
AuthError::WrongEmail => write!(f, "WrongEmail"),
AuthError::MissingCredentials => write!(f, "MissingCredentials"),
AuthError::MissingDevice => write!(f, "MissingDevice"),
AuthError::TokenCreation => write!(f, "TokenCreation"),
AuthError::UserNotFound => write!(f, "UserNotFound"),
AuthError::UserAlreadyExists => write!(f, "UserAlreadyExists"),
Expand All @@ -48,8 +44,6 @@ impl IntoResponse for AuthError {
AuthError::WrongToken => (StatusCode::UNAUTHORIZED, "Wrong token"),
AuthError::WrongPassword => (StatusCode::UNAUTHORIZED, "Wrong password"),
AuthError::WrongEmail => (StatusCode::UNAUTHORIZED, "Wrong email"),
AuthError::MissingCredentials => (StatusCode::BAD_REQUEST, "Missing credentials"),
AuthError::MissingDevice => (StatusCode::BAD_REQUEST, "Missing device"),
AuthError::TokenCreation => (StatusCode::INTERNAL_SERVER_ERROR, "Token creation error"),
AuthError::UserNotFound => (StatusCode::NOT_FOUND, "User not found"),
AuthError::UserAlreadyExists => (StatusCode::CONFLICT, "User already exists"),
Expand Down Expand Up @@ -80,8 +74,6 @@ impl From<internal::AuthError> for AuthError {
internal::AuthError::WrongToken => AuthError::WrongToken,
internal::AuthError::WrongPassword => AuthError::WrongPassword,
internal::AuthError::WrongEmail => AuthError::WrongEmail,
internal::AuthError::MissingCredentials => AuthError::MissingCredentials,
internal::AuthError::MissingDevice => AuthError::MissingDevice,
internal::AuthError::TokenCreation => AuthError::TokenCreation,
internal::AuthError::UserNotFound => AuthError::UserNotFound,
internal::AuthError::UserAlreadyExists => AuthError::UserAlreadyExists,
Expand Down
2 changes: 2 additions & 0 deletions src/enums/errors/external/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub enum ExternalError {
DeviceError(DeviceError),
CountryError(CountryError),
SessionError(SessionError),
SerializationError,
Internal,
}

Expand All @@ -35,6 +36,7 @@ impl std::fmt::Display for ExternalError {
ExternalError::DeviceError(e) => write!(f, "{}", e),
ExternalError::CountryError(e) => write!(f, "{}", e),
ExternalError::SessionError(e) => write!(f, "{}", e),
ExternalError::SerializationError => write!(f, "Serialization error"),
ExternalError::Internal => write!(f, "Internal server error"),
}
}
Expand Down
4 changes: 0 additions & 4 deletions src/enums/errors/internal/auth_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ pub enum AuthError {
WrongToken,
WrongPassword,
WrongEmail,
MissingCredentials,
MissingDevice,
TokenCreation,
UserNotFound,
UserAlreadyExists,
Expand All @@ -21,8 +19,6 @@ impl std::fmt::Display for AuthError {
AuthError::WrongToken => write!(f, "Wrong token"),
AuthError::WrongPassword => write!(f, "Wrong password"),
AuthError::WrongEmail => write!(f, "Wrong email"),
AuthError::MissingCredentials => write!(f, "Missing credentials"),
AuthError::MissingDevice => write!(f, "Missing device"),
AuthError::TokenCreation => write!(f, "Token creation error"),
AuthError::UserNotFound => write!(f, "User not found"),
AuthError::UserAlreadyExists => write!(f, "User already exists"),
Expand Down
2 changes: 2 additions & 0 deletions src/enums/errors/internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub enum InternalError {
SessionError(SessionError),
DatabaseError(DatabaseError),
ReqwestError(ReqwestError),
SerializationError,
UuidParse,
Internal,
}
Expand All @@ -47,6 +48,7 @@ impl std::fmt::Display for InternalError {
InternalError::CountryError(e) => write!(f, "{}", e),
InternalError::SessionError(e) => write!(f, "{}", e),
InternalError::ReqwestError(e) => write!(f, "{}", e),
InternalError::SerializationError => write!(f, "Serialization error"),
InternalError::UuidParse => write!(f, "Uuid parse error"),
InternalError::Internal => write!(f, "Internal error"),
}
Expand Down
33 changes: 33 additions & 0 deletions src/extractors/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use axum::{
async_trait,
extract::{rejection::JsonRejection, FromRequest, MatchedPath, Request},
http::StatusCode,
RequestPartsExt,
};
use serde_json::{json, Value};

use crate::enums::errors::external::ExternalError;

pub struct Json<T>(pub T);

#[async_trait]
impl<S, T> FromRequest<S> for Json<T>
where
axum::Json<T>: FromRequest<S, Rejection = JsonRejection>,
S: Send + Sync,
{
type Rejection = (StatusCode, axum::Json<Value>);

async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
match axum::Json::<T>::from_request(req, state).await {
Ok(value) => Ok(Self(value.0)),
Err(rejection) => {
let payload = json!({
"message": rejection.body_text(),
"error": ExternalError::SerializationError,
});
Err((rejection.status(), axum::Json(payload)))
}
}
}
}
2 changes: 1 addition & 1 deletion src/guards/auth/access_token_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ where
let TypedHeader(Authorization(bearer)) = parts
.extract::<TypedHeader<Authorization<Bearer>>>()
.await
.map_err(|_| ExternalError::AuthError(AuthError::MissingCredentials))?;
.map_err(|_| ExternalError::AuthError(AuthError::WrongToken))?;

let token_data = decode::<AccessToken>(
bearer.token(),
Expand Down
2 changes: 1 addition & 1 deletion src/guards/auth/refresh_token_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ where
let TypedHeader(Authorization(bearer)) = parts
.extract::<TypedHeader<Authorization<Bearer>>>()
.await
.map_err(|_| ExternalError::AuthError(AuthError::MissingCredentials))?;
.map_err(|_| ExternalError::AuthError(AuthError::WrongToken))?;

let token_data = decode::<RefreshToken>(
bearer.token(),
Expand Down
3 changes: 2 additions & 1 deletion src/handlers/auth/sign_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use crate::{
response::success::Response,
},
enums::errors::external::ExternalError,
extractors::Json,
services::user_service,
};
use axum::{extract::State, http::StatusCode, Json};
use axum::{extract::State, http::StatusCode};
use deadpool_diesel::postgres::Pool;
use tracing::info;

Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ mod services;
mod state;

Check warning on line 25 in src/main.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/master-backend-rust/master-backend-rust/src/main.rs
mod tests;
mod utils;
mod extractors;

async fn start_main_server() {
let state = AppState::default();
Expand Down
11 changes: 0 additions & 11 deletions src/tests/e2e/auth/logout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ mod test {
use crate::{
data::enums::OS,
dto::{auth::response::Tokens, response},
enums::errors::external::{AuthError, ExternalError},
tests::config::ENV,
};
use serde_json::json;
Expand Down Expand Up @@ -52,11 +51,6 @@ mod test {
let response = client.post(&url).send().await.unwrap();

assert_eq!(response.status(), 400);
let body: response::error::RawResponse = response.json().await.unwrap();
assert_eq!(
body.error,
ExternalError::AuthError(AuthError::MissingCredentials).to_string()
);
}

#[tokio::test]
Expand All @@ -67,10 +61,5 @@ mod test {
let response = client.post(&url).send().await.unwrap();

assert_eq!(response.status(), 400);
let body: response::error::RawResponse = response.json().await.unwrap();
assert_eq!(
body.error,
ExternalError::AuthError(AuthError::MissingCredentials).to_string()
);
}
}

0 comments on commit dc46535

Please sign in to comment.