diff --git a/.env.example b/.env.example index 6fbd203..b4fd227 100644 --- a/.env.example +++ b/.env.example @@ -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 \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0d4553d..1bd33c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -858,6 +858,7 @@ dependencies = [ "diesel", "dotenvy", "futures", + "http-body-util", "http-serde", "jsonwebtoken", "listenfd", @@ -934,12 +935,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http 1.1.0", "http-body 1.0.0", "pin-project-lite", diff --git a/Cargo.toml b/Cargo.toml index 7a1fc32..78c2efc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" @@ -45,4 +46,4 @@ uuid = { version = "1.10", features = [ "fast-rng", "macro-diagnostics", ] } -validator = { version = "0.18", features = ["derive"] } \ No newline at end of file +validator = { version = "0.18", features = ["derive"] } diff --git a/src/config.rs b/src/config.rs index f6b7e05..eb84a87 100644 --- a/src/config.rs +++ b/src/config.rs @@ -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, @@ -38,5 +36,4 @@ pub static ENV: Lazy = 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"), }); diff --git a/src/enums/errors/external/auth_error.rs b/src/enums/errors/external/auth_error.rs index 12b20bf..f72201e 100644 --- a/src/enums/errors/external/auth_error.rs +++ b/src/enums/errors/external/auth_error.rs @@ -10,8 +10,6 @@ pub enum AuthError { WrongToken, WrongPassword, WrongEmail, - MissingCredentials, - MissingDevice, TokenCreation, UserNotFound, UserAlreadyExists, @@ -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"), @@ -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"), @@ -80,8 +74,6 @@ impl From 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, diff --git a/src/enums/errors/external/mod.rs b/src/enums/errors/external/mod.rs index 206336b..abadd7f 100644 --- a/src/enums/errors/external/mod.rs +++ b/src/enums/errors/external/mod.rs @@ -25,6 +25,7 @@ pub enum ExternalError { DeviceError(DeviceError), CountryError(CountryError), SessionError(SessionError), + SerializationError, Internal, } @@ -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"), } } diff --git a/src/enums/errors/internal/auth_error.rs b/src/enums/errors/internal/auth_error.rs index 3ff5a3e..e09f0e7 100644 --- a/src/enums/errors/internal/auth_error.rs +++ b/src/enums/errors/internal/auth_error.rs @@ -3,8 +3,6 @@ pub enum AuthError { WrongToken, WrongPassword, WrongEmail, - MissingCredentials, - MissingDevice, TokenCreation, UserNotFound, UserAlreadyExists, @@ -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"), diff --git a/src/enums/errors/internal/mod.rs b/src/enums/errors/internal/mod.rs index 1919e9c..41d1bf1 100644 --- a/src/enums/errors/internal/mod.rs +++ b/src/enums/errors/internal/mod.rs @@ -32,6 +32,7 @@ pub enum InternalError { SessionError(SessionError), DatabaseError(DatabaseError), ReqwestError(ReqwestError), + SerializationError, UuidParse, Internal, } @@ -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"), } diff --git a/src/extractors/mod.rs b/src/extractors/mod.rs new file mode 100644 index 0000000..1039c05 --- /dev/null +++ b/src/extractors/mod.rs @@ -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(pub T); + +#[async_trait] +impl FromRequest for Json +where + axum::Json: FromRequest, + S: Send + Sync, +{ + type Rejection = (StatusCode, axum::Json); + + async fn from_request(req: Request, state: &S) -> Result { + match axum::Json::::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))) + } + } + } +} diff --git a/src/guards/auth/access_token_guard.rs b/src/guards/auth/access_token_guard.rs index f41cb4b..5044986 100644 --- a/src/guards/auth/access_token_guard.rs +++ b/src/guards/auth/access_token_guard.rs @@ -29,7 +29,7 @@ where let TypedHeader(Authorization(bearer)) = parts .extract::>>() .await - .map_err(|_| ExternalError::AuthError(AuthError::MissingCredentials))?; + .map_err(|_| ExternalError::AuthError(AuthError::WrongToken))?; let token_data = decode::( bearer.token(), diff --git a/src/guards/auth/refresh_token_guard.rs b/src/guards/auth/refresh_token_guard.rs index f809f73..8afd9f2 100644 --- a/src/guards/auth/refresh_token_guard.rs +++ b/src/guards/auth/refresh_token_guard.rs @@ -29,7 +29,7 @@ where let TypedHeader(Authorization(bearer)) = parts .extract::>>() .await - .map_err(|_| ExternalError::AuthError(AuthError::MissingCredentials))?; + .map_err(|_| ExternalError::AuthError(AuthError::WrongToken))?; let token_data = decode::( bearer.token(), diff --git a/src/handlers/auth/sign_in.rs b/src/handlers/auth/sign_in.rs index 0791776..f348a21 100644 --- a/src/handlers/auth/sign_in.rs +++ b/src/handlers/auth/sign_in.rs @@ -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; diff --git a/src/main.rs b/src/main.rs index 3007568..364a939 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ mod services; mod state; mod tests; mod utils; +mod extractors; async fn start_main_server() { let state = AppState::default(); diff --git a/src/tests/e2e/auth/logout.rs b/src/tests/e2e/auth/logout.rs index 8980539..70180b5 100644 --- a/src/tests/e2e/auth/logout.rs +++ b/src/tests/e2e/auth/logout.rs @@ -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; @@ -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] @@ -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() - ); } }