diff --git a/src/web/api/v1/extractors/mod.rs b/src/web/api/v1/extractors/mod.rs index 36d737ca..2c55e042 100644 --- a/src/web/api/v1/extractors/mod.rs +++ b/src/web/api/v1/extractors/mod.rs @@ -1 +1,2 @@ pub mod bearer_token; +pub mod user_id; diff --git a/src/web/api/v1/extractors/user_id.rs b/src/web/api/v1/extractors/user_id.rs new file mode 100644 index 00000000..71cdad1f --- /dev/null +++ b/src/web/api/v1/extractors/user_id.rs @@ -0,0 +1,37 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use axum::extract::{FromRef, FromRequestParts}; +use axum::http::request::Parts; +use axum::response::{IntoResponse, Response}; + +use super::bearer_token; +use crate::common::AppData; +use crate::errors::ServiceError; +use crate::models::user::UserId; + +pub struct ExtractLoggedInUser(pub UserId); + +#[async_trait] +impl FromRequestParts for ExtractLoggedInUser +where + Arc: FromRef, + S: Send + Sync, +{ + type Rejection = Response; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let maybe_bearer_token = match bearer_token::Extract::from_request_parts(parts, state).await { + Ok(maybe_bearer_token) => maybe_bearer_token.0, + Err(_) => return Err(ServiceError::Unauthorized.into_response()), + }; + + //Extracts the app state + let app_data = Arc::from_ref(state); + + match app_data.auth.get_user_id_from_bearer_token(&maybe_bearer_token).await { + Ok(user_id) => Ok(ExtractLoggedInUser(user_id)), + Err(error) => Err(error.into_response()), + } + } +}