diff --git a/src/web/api/server/v1/contexts/torrent/handlers.rs b/src/web/api/server/v1/contexts/torrent/handlers.rs index e4a171d2..e72151e0 100644 --- a/src/web/api/server/v1/contexts/torrent/handlers.rs +++ b/src/web/api/server/v1/contexts/torrent/handlers.rs @@ -21,8 +21,7 @@ use crate::models::torrent_tag::TagId; use crate::services::torrent::{AddTorrentRequest, ListingRequest}; use crate::services::torrent_file::generate_random_torrent; use crate::utils::parse_torrent; -use crate::web::api::server::v1::auth::get_optional_logged_in_user; -use crate::web::api::server::v1::extractors::bearer_token::Extract; +use crate::web::api::server::v1::extractors::optional_user_id::ExtractOptionalLoggedInUser; use crate::web::api::server::v1::extractors::user_id::ExtractLoggedInUser; use crate::web::api::server::v1::responses::OkResponseData; use crate::web::api::server::v1::routes::API_VERSION_URL_PREFIX; @@ -69,7 +68,7 @@ impl InfoHashParam { #[allow(clippy::unused_async)] pub async fn download_torrent_handler( State(app_data): State>, - Extract(maybe_bearer_token): Extract, + ExtractOptionalLoggedInUser(opt_user_id): ExtractOptionalLoggedInUser, Path(info_hash): Path, ) -> Response { let Ok(info_hash) = InfoHash::from_str(&info_hash.lowercase()) else { @@ -82,11 +81,6 @@ pub async fn download_torrent_handler( debug!("Redirecting to URL with canonical info-hash"); redirect_response } else { - let opt_user_id = match get_optional_logged_in_user(maybe_bearer_token, app_data.clone()).await { - Ok(opt_user_id) => opt_user_id, - Err(error) => return error.into_response(), - }; - let torrent = match app_data.torrent_service.get_torrent(&info_hash, opt_user_id).await { Ok(torrent) => torrent, Err(error) => return error.into_response(), @@ -156,7 +150,7 @@ pub async fn get_torrents_handler(State(app_data): State>, Query(cr #[allow(clippy::unused_async)] pub async fn get_torrent_info_handler( State(app_data): State>, - Extract(maybe_bearer_token): Extract, + ExtractOptionalLoggedInUser(opt_user_id): ExtractOptionalLoggedInUser, Path(info_hash): Path, ) -> Response { let Ok(info_hash) = InfoHash::from_str(&info_hash.lowercase()) else { @@ -166,11 +160,6 @@ pub async fn get_torrent_info_handler( if let Some(redirect_response) = redirect_to_details_url_using_canonical_info_hash_if_needed(&app_data, &info_hash).await { redirect_response } else { - let opt_user_id = match get_optional_logged_in_user(maybe_bearer_token, app_data.clone()).await { - Ok(opt_user_id) => opt_user_id, - Err(error) => return error.into_response(), - }; - match app_data.torrent_service.get_torrent_info(&info_hash, opt_user_id).await { Ok(torrent_response) => Json(OkResponseData { data: torrent_response }).into_response(), Err(error) => error.into_response(), diff --git a/src/web/api/server/v1/extractors/mod.rs b/src/web/api/server/v1/extractors/mod.rs index 2c55e042..acf2d689 100644 --- a/src/web/api/server/v1/extractors/mod.rs +++ b/src/web/api/server/v1/extractors/mod.rs @@ -1,2 +1,3 @@ pub mod bearer_token; +pub mod optional_user_id; pub mod user_id; diff --git a/src/web/api/server/v1/extractors/optional_user_id.rs b/src/web/api/server/v1/extractors/optional_user_id.rs new file mode 100644 index 00000000..cdef65af --- /dev/null +++ b/src/web/api/server/v1/extractors/optional_user_id.rs @@ -0,0 +1,41 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use axum::extract::{FromRef, FromRequestParts}; +use axum::http::request::Parts; +use axum::response::Response; + +use crate::common::AppData; +use crate::models::user::UserId; +use crate::web::api::server::v1::extractors::bearer_token; + +pub struct ExtractOptionalLoggedInUser(pub Option); + +#[async_trait] +impl FromRequestParts for ExtractOptionalLoggedInUser +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::TokenNotFound.into_response()), + }; */ + + let bearer_token = match bearer_token::Extract::from_request_parts(parts, state).await { + Ok(bearer_token) => bearer_token.0, + Err(_) => None, + }; + + //Extracts the app state + let app_data = Arc::from_ref(state); + + match app_data.auth.get_user_id_from_bearer_token(&bearer_token).await { + Ok(user_id) => Ok(ExtractOptionalLoggedInUser(Some(user_id))), + Err(_) => Ok(ExtractOptionalLoggedInUser(None)), + } + } +}