diff --git a/src/apis/context/mod.rs b/src/apis/context/mod.rs index ce3527e5d..72ffaa505 100644 --- a/src/apis/context/mod.rs +++ b/src/apis/context/mod.rs @@ -1,2 +1,3 @@ pub mod auth_key; pub mod stats; +pub mod whitelist; diff --git a/src/apis/context/whitelist/handlers.rs b/src/apis/context/whitelist/handlers.rs new file mode 100644 index 000000000..c1e90a509 --- /dev/null +++ b/src/apis/context/whitelist/handlers.rs @@ -0,0 +1,46 @@ +use std::str::FromStr; +use std::sync::Arc; + +use axum::extract::{Path, State}; +use axum::response::Response; + +use super::responses::{ + failed_to_reload_whitelist_response, failed_to_remove_torrent_from_whitelist_response, failed_to_whitelist_torrent_response, +}; +use crate::apis::responses::{invalid_info_hash_param_response, ok_response}; +use crate::apis::InfoHashParam; +use crate::protocol::info_hash::InfoHash; +use crate::tracker::Tracker; + +pub async fn add_torrent_to_whitelist_handler( + State(tracker): State>, + Path(info_hash): Path, +) -> Response { + match InfoHash::from_str(&info_hash.0) { + Err(_) => invalid_info_hash_param_response(&info_hash.0), + Ok(info_hash) => match tracker.add_torrent_to_whitelist(&info_hash).await { + Ok(_) => ok_response(), + Err(e) => failed_to_whitelist_torrent_response(e), + }, + } +} + +pub async fn remove_torrent_from_whitelist_handler( + State(tracker): State>, + Path(info_hash): Path, +) -> Response { + match InfoHash::from_str(&info_hash.0) { + Err(_) => invalid_info_hash_param_response(&info_hash.0), + Ok(info_hash) => match tracker.remove_torrent_from_whitelist(&info_hash).await { + Ok(_) => ok_response(), + Err(e) => failed_to_remove_torrent_from_whitelist_response(e), + }, + } +} + +pub async fn reload_whitelist_handler(State(tracker): State>) -> Response { + match tracker.load_whitelist_from_database().await { + Ok(_) => ok_response(), + Err(e) => failed_to_reload_whitelist_response(e), + } +} diff --git a/src/apis/context/whitelist/mod.rs b/src/apis/context/whitelist/mod.rs new file mode 100644 index 000000000..f6f000f34 --- /dev/null +++ b/src/apis/context/whitelist/mod.rs @@ -0,0 +1,3 @@ +pub mod handlers; +pub mod responses; +pub mod routes; diff --git a/src/apis/context/whitelist/responses.rs b/src/apis/context/whitelist/responses.rs new file mode 100644 index 000000000..dd2727898 --- /dev/null +++ b/src/apis/context/whitelist/responses.rs @@ -0,0 +1,20 @@ +use std::error::Error; + +use axum::response::Response; + +use crate::apis::responses::unhandled_rejection_response; + +#[must_use] +pub fn failed_to_remove_torrent_from_whitelist_response(e: E) -> Response { + unhandled_rejection_response(format!("failed to remove torrent from whitelist: {e}")) +} + +#[must_use] +pub fn failed_to_whitelist_torrent_response(e: E) -> Response { + unhandled_rejection_response(format!("failed to whitelist torrent: {e}")) +} + +#[must_use] +pub fn failed_to_reload_whitelist_response(e: E) -> Response { + unhandled_rejection_response(format!("failed to reload whitelist: {e}")) +} diff --git a/src/apis/context/whitelist/routes.rs b/src/apis/context/whitelist/routes.rs new file mode 100644 index 000000000..1349f8bc1 --- /dev/null +++ b/src/apis/context/whitelist/routes.rs @@ -0,0 +1,22 @@ +use std::sync::Arc; + +use axum::routing::{delete, get, post}; +use axum::Router; + +use super::handlers::{add_torrent_to_whitelist_handler, reload_whitelist_handler, remove_torrent_from_whitelist_handler}; +use crate::tracker::Tracker; + +pub fn add(router: Router, tracker: Arc) -> Router { + router + // Whitelisted torrents + .route( + "/api/whitelist/:info_hash", + post(add_torrent_to_whitelist_handler).with_state(tracker.clone()), + ) + .route( + "/api/whitelist/:info_hash", + delete(remove_torrent_from_whitelist_handler).with_state(tracker.clone()), + ) + // Whitelist commands + .route("/api/whitelist/reload", get(reload_whitelist_handler).with_state(tracker)) +} diff --git a/src/apis/handlers.rs b/src/apis/handlers.rs index 70dbaf797..b688edd67 100644 --- a/src/apis/handlers.rs +++ b/src/apis/handlers.rs @@ -7,8 +7,7 @@ use axum::response::{IntoResponse, Json, Response}; use serde::{de, Deserialize, Deserializer}; use super::responses::{ - failed_to_reload_whitelist_response, failed_to_remove_torrent_from_whitelist_response, failed_to_whitelist_torrent_response, - invalid_info_hash_param_response, ok_response, torrent_info_response, torrent_list_response, torrent_not_known_response, + invalid_info_hash_param_response, torrent_info_response, torrent_list_response, torrent_not_known_response, }; use crate::apis::resources::torrent::ListItem; use crate::protocol::info_hash::InfoHash; @@ -16,7 +15,7 @@ use crate::tracker::services::torrent::{get_torrent_info, get_torrents, Paginati use crate::tracker::Tracker; #[derive(Deserialize)] -pub struct InfoHashParam(String); +pub struct InfoHashParam(pub String); pub async fn get_torrent_handler(State(tracker): State>, Path(info_hash): Path) -> Response { match InfoHash::from_str(&info_hash.0) { @@ -48,39 +47,6 @@ pub async fn get_torrents_handler( ) } -pub async fn add_torrent_to_whitelist_handler( - State(tracker): State>, - Path(info_hash): Path, -) -> Response { - match InfoHash::from_str(&info_hash.0) { - Err(_) => invalid_info_hash_param_response(&info_hash.0), - Ok(info_hash) => match tracker.add_torrent_to_whitelist(&info_hash).await { - Ok(_) => ok_response(), - Err(e) => failed_to_whitelist_torrent_response(e), - }, - } -} - -pub async fn remove_torrent_from_whitelist_handler( - State(tracker): State>, - Path(info_hash): Path, -) -> Response { - match InfoHash::from_str(&info_hash.0) { - Err(_) => invalid_info_hash_param_response(&info_hash.0), - Ok(info_hash) => match tracker.remove_torrent_from_whitelist(&info_hash).await { - Ok(_) => ok_response(), - Err(e) => failed_to_remove_torrent_from_whitelist_response(e), - }, - } -} - -pub async fn reload_whitelist_handler(State(tracker): State>) -> Response { - match tracker.load_whitelist_from_database().await { - Ok(_) => ok_response(), - Err(e) => failed_to_reload_whitelist_response(e), - } -} - /// Serde deserialization decorator to map empty Strings to None, fn empty_string_as_none<'de, D, T>(de: D) -> Result, D::Error> where diff --git a/src/apis/responses.rs b/src/apis/responses.rs index a889aa623..f272a203a 100644 --- a/src/apis/responses.rs +++ b/src/apis/responses.rs @@ -1,5 +1,3 @@ -use std::error::Error; - use axum::http::{header, StatusCode}; use axum::response::{IntoResponse, Json, Response}; use serde::Serialize; @@ -88,21 +86,6 @@ pub fn torrent_not_known_response() -> Response { Json(json!("torrent not known")).into_response() } -#[must_use] -pub fn failed_to_remove_torrent_from_whitelist_response(e: E) -> Response { - unhandled_rejection_response(format!("failed to remove torrent from whitelist: {e}")) -} - -#[must_use] -pub fn failed_to_whitelist_torrent_response(e: E) -> Response { - unhandled_rejection_response(format!("failed to whitelist torrent: {e}")) -} - -#[must_use] -pub fn failed_to_reload_whitelist_response(e: E) -> Response { - unhandled_rejection_response(format!("failed to reload whitelist: {e}")) -} - /// This error response is to keep backward compatibility with the old API. /// It should be a plain text or json. #[must_use] diff --git a/src/apis/routes.rs b/src/apis/routes.rs index 682069f16..3969c284a 100644 --- a/src/apis/routes.rs +++ b/src/apis/routes.rs @@ -1,13 +1,10 @@ use std::sync::Arc; -use axum::routing::{delete, get, post}; +use axum::routing::get; use axum::{middleware, Router}; -use super::context::{auth_key, stats}; -use super::handlers::{ - add_torrent_to_whitelist_handler, get_torrent_handler, get_torrents_handler, reload_whitelist_handler, - remove_torrent_from_whitelist_handler, -}; +use super::context::{auth_key, stats, whitelist}; +use super::handlers::{get_torrent_handler, get_torrents_handler}; use super::middlewares::auth::auth; use crate::tracker::Tracker; @@ -15,8 +12,9 @@ use crate::tracker::Tracker; pub fn router(tracker: Arc) -> Router { let router = Router::new(); - let router = stats::routes::add(router, tracker.clone()); let router = auth_key::routes::add(router, tracker.clone()); + let router = stats::routes::add(router, tracker.clone()); + let router = whitelist::routes::add(router, tracker.clone()); // Torrents router @@ -25,19 +23,5 @@ pub fn router(tracker: Arc) -> Router { get(get_torrent_handler).with_state(tracker.clone()), ) .route("/api/torrents", get(get_torrents_handler).with_state(tracker.clone())) - // Whitelisted torrents - .route( - "/api/whitelist/:info_hash", - post(add_torrent_to_whitelist_handler).with_state(tracker.clone()), - ) - .route( - "/api/whitelist/:info_hash", - delete(remove_torrent_from_whitelist_handler).with_state(tracker.clone()), - ) - // Whitelist command - .route( - "/api/whitelist/reload", - get(reload_whitelist_handler).with_state(tracker.clone()), - ) .layer(middleware::from_fn_with_state(tracker.config.clone(), auth)) }