Skip to content

Commit 996dffd

Browse files
committed
refactor: [#157] extract API context: whitelist
1 parent f1b3d84 commit 996dffd

8 files changed

Lines changed: 99 additions & 74 deletions

File tree

src/apis/context/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod auth_key;
22
pub mod stats;
3+
pub mod whitelist;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use std::str::FromStr;
2+
use std::sync::Arc;
3+
4+
use axum::extract::{Path, State};
5+
use axum::response::Response;
6+
7+
use super::responses::{
8+
failed_to_reload_whitelist_response, failed_to_remove_torrent_from_whitelist_response, failed_to_whitelist_torrent_response,
9+
};
10+
use crate::apis::responses::{invalid_info_hash_param_response, ok_response};
11+
use crate::apis::InfoHashParam;
12+
use crate::protocol::info_hash::InfoHash;
13+
use crate::tracker::Tracker;
14+
15+
pub async fn add_torrent_to_whitelist_handler(
16+
State(tracker): State<Arc<Tracker>>,
17+
Path(info_hash): Path<InfoHashParam>,
18+
) -> Response {
19+
match InfoHash::from_str(&info_hash.0) {
20+
Err(_) => invalid_info_hash_param_response(&info_hash.0),
21+
Ok(info_hash) => match tracker.add_torrent_to_whitelist(&info_hash).await {
22+
Ok(_) => ok_response(),
23+
Err(e) => failed_to_whitelist_torrent_response(e),
24+
},
25+
}
26+
}
27+
28+
pub async fn remove_torrent_from_whitelist_handler(
29+
State(tracker): State<Arc<Tracker>>,
30+
Path(info_hash): Path<InfoHashParam>,
31+
) -> Response {
32+
match InfoHash::from_str(&info_hash.0) {
33+
Err(_) => invalid_info_hash_param_response(&info_hash.0),
34+
Ok(info_hash) => match tracker.remove_torrent_from_whitelist(&info_hash).await {
35+
Ok(_) => ok_response(),
36+
Err(e) => failed_to_remove_torrent_from_whitelist_response(e),
37+
},
38+
}
39+
}
40+
41+
pub async fn reload_whitelist_handler(State(tracker): State<Arc<Tracker>>) -> Response {
42+
match tracker.load_whitelist_from_database().await {
43+
Ok(_) => ok_response(),
44+
Err(e) => failed_to_reload_whitelist_response(e),
45+
}
46+
}

src/apis/context/whitelist/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod handlers;
2+
pub mod responses;
3+
pub mod routes;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use std::error::Error;
2+
3+
use axum::response::Response;
4+
5+
use crate::apis::responses::unhandled_rejection_response;
6+
7+
#[must_use]
8+
pub fn failed_to_remove_torrent_from_whitelist_response<E: Error>(e: E) -> Response {
9+
unhandled_rejection_response(format!("failed to remove torrent from whitelist: {e}"))
10+
}
11+
12+
#[must_use]
13+
pub fn failed_to_whitelist_torrent_response<E: Error>(e: E) -> Response {
14+
unhandled_rejection_response(format!("failed to whitelist torrent: {e}"))
15+
}
16+
17+
#[must_use]
18+
pub fn failed_to_reload_whitelist_response<E: Error>(e: E) -> Response {
19+
unhandled_rejection_response(format!("failed to reload whitelist: {e}"))
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::sync::Arc;
2+
3+
use axum::routing::{delete, get, post};
4+
use axum::Router;
5+
6+
use super::handlers::{add_torrent_to_whitelist_handler, reload_whitelist_handler, remove_torrent_from_whitelist_handler};
7+
use crate::tracker::Tracker;
8+
9+
pub fn add(router: Router, tracker: Arc<Tracker>) -> Router {
10+
router
11+
// Whitelisted torrents
12+
.route(
13+
"/api/whitelist/:info_hash",
14+
post(add_torrent_to_whitelist_handler).with_state(tracker.clone()),
15+
)
16+
.route(
17+
"/api/whitelist/:info_hash",
18+
delete(remove_torrent_from_whitelist_handler).with_state(tracker.clone()),
19+
)
20+
// Whitelist commands
21+
.route("/api/whitelist/reload", get(reload_whitelist_handler).with_state(tracker))
22+
}

src/apis/handlers.rs

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@ use axum::response::{IntoResponse, Json, Response};
77
use serde::{de, Deserialize, Deserializer};
88

99
use super::responses::{
10-
failed_to_reload_whitelist_response, failed_to_remove_torrent_from_whitelist_response, failed_to_whitelist_torrent_response,
11-
invalid_info_hash_param_response, ok_response, torrent_info_response, torrent_list_response, torrent_not_known_response,
10+
invalid_info_hash_param_response, torrent_info_response, torrent_list_response, torrent_not_known_response,
1211
};
1312
use crate::apis::resources::torrent::ListItem;
1413
use crate::protocol::info_hash::InfoHash;
1514
use crate::tracker::services::torrent::{get_torrent_info, get_torrents, Pagination};
1615
use crate::tracker::Tracker;
1716

1817
#[derive(Deserialize)]
19-
pub struct InfoHashParam(String);
18+
pub struct InfoHashParam(pub String);
2019

2120
pub async fn get_torrent_handler(State(tracker): State<Arc<Tracker>>, Path(info_hash): Path<InfoHashParam>) -> Response {
2221
match InfoHash::from_str(&info_hash.0) {
@@ -48,39 +47,6 @@ pub async fn get_torrents_handler(
4847
)
4948
}
5049

51-
pub async fn add_torrent_to_whitelist_handler(
52-
State(tracker): State<Arc<Tracker>>,
53-
Path(info_hash): Path<InfoHashParam>,
54-
) -> Response {
55-
match InfoHash::from_str(&info_hash.0) {
56-
Err(_) => invalid_info_hash_param_response(&info_hash.0),
57-
Ok(info_hash) => match tracker.add_torrent_to_whitelist(&info_hash).await {
58-
Ok(_) => ok_response(),
59-
Err(e) => failed_to_whitelist_torrent_response(e),
60-
},
61-
}
62-
}
63-
64-
pub async fn remove_torrent_from_whitelist_handler(
65-
State(tracker): State<Arc<Tracker>>,
66-
Path(info_hash): Path<InfoHashParam>,
67-
) -> Response {
68-
match InfoHash::from_str(&info_hash.0) {
69-
Err(_) => invalid_info_hash_param_response(&info_hash.0),
70-
Ok(info_hash) => match tracker.remove_torrent_from_whitelist(&info_hash).await {
71-
Ok(_) => ok_response(),
72-
Err(e) => failed_to_remove_torrent_from_whitelist_response(e),
73-
},
74-
}
75-
}
76-
77-
pub async fn reload_whitelist_handler(State(tracker): State<Arc<Tracker>>) -> Response {
78-
match tracker.load_whitelist_from_database().await {
79-
Ok(_) => ok_response(),
80-
Err(e) => failed_to_reload_whitelist_response(e),
81-
}
82-
}
83-
8450
/// Serde deserialization decorator to map empty Strings to None,
8551
fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
8652
where

src/apis/responses.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::error::Error;
2-
31
use axum::http::{header, StatusCode};
42
use axum::response::{IntoResponse, Json, Response};
53
use serde::Serialize;
@@ -88,21 +86,6 @@ pub fn torrent_not_known_response() -> Response {
8886
Json(json!("torrent not known")).into_response()
8987
}
9088

91-
#[must_use]
92-
pub fn failed_to_remove_torrent_from_whitelist_response<E: Error>(e: E) -> Response {
93-
unhandled_rejection_response(format!("failed to remove torrent from whitelist: {e}"))
94-
}
95-
96-
#[must_use]
97-
pub fn failed_to_whitelist_torrent_response<E: Error>(e: E) -> Response {
98-
unhandled_rejection_response(format!("failed to whitelist torrent: {e}"))
99-
}
100-
101-
#[must_use]
102-
pub fn failed_to_reload_whitelist_response<E: Error>(e: E) -> Response {
103-
unhandled_rejection_response(format!("failed to reload whitelist: {e}"))
104-
}
105-
10689
/// This error response is to keep backward compatibility with the old API.
10790
/// It should be a plain text or json.
10891
#[must_use]

src/apis/routes.rs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
use std::sync::Arc;
22

3-
use axum::routing::{delete, get, post};
3+
use axum::routing::get;
44
use axum::{middleware, Router};
55

6-
use super::context::{auth_key, stats};
7-
use super::handlers::{
8-
add_torrent_to_whitelist_handler, get_torrent_handler, get_torrents_handler, reload_whitelist_handler,
9-
remove_torrent_from_whitelist_handler,
10-
};
6+
use super::context::{auth_key, stats, whitelist};
7+
use super::handlers::{get_torrent_handler, get_torrents_handler};
118
use super::middlewares::auth::auth;
129
use crate::tracker::Tracker;
1310

1411
#[allow(clippy::needless_pass_by_value)]
1512
pub fn router(tracker: Arc<Tracker>) -> Router {
1613
let router = Router::new();
1714

18-
let router = stats::routes::add(router, tracker.clone());
1915
let router = auth_key::routes::add(router, tracker.clone());
16+
let router = stats::routes::add(router, tracker.clone());
17+
let router = whitelist::routes::add(router, tracker.clone());
2018

2119
// Torrents
2220
router
@@ -25,19 +23,5 @@ pub fn router(tracker: Arc<Tracker>) -> Router {
2523
get(get_torrent_handler).with_state(tracker.clone()),
2624
)
2725
.route("/api/torrents", get(get_torrents_handler).with_state(tracker.clone()))
28-
// Whitelisted torrents
29-
.route(
30-
"/api/whitelist/:info_hash",
31-
post(add_torrent_to_whitelist_handler).with_state(tracker.clone()),
32-
)
33-
.route(
34-
"/api/whitelist/:info_hash",
35-
delete(remove_torrent_from_whitelist_handler).with_state(tracker.clone()),
36-
)
37-
// Whitelist command
38-
.route(
39-
"/api/whitelist/reload",
40-
get(reload_whitelist_handler).with_state(tracker.clone()),
41-
)
4226
.layer(middleware::from_fn_with_state(tracker.config.clone(), auth))
4327
}

0 commit comments

Comments
 (0)