Skip to content

Commit

Permalink
feat(api): [#143] axum api. GET /api/whitelist/reload endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Jan 11, 2023
1 parent 2ddf268 commit a58d831
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/apis/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ pub async fn delete_torrent_from_whitelist_handler(
}
}

pub async fn reload_whitelist_handler(State(tracker): State<Arc<Tracker>>) -> Response {
match tracker.load_whitelist().await {
Ok(..) => response_ok(),
Err(..) => response_err("failed to reload whitelist".to_string()),
}
}

/// Serde deserialization decorator to map empty Strings to None,
fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
where
Expand Down
14 changes: 13 additions & 1 deletion src/apis/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ use warp::hyper;
use super::middlewares::auth::auth;
use super::routes::{
add_torrent_to_whitelist_handler, delete_torrent_from_whitelist_handler, get_stats_handler, get_torrent_handler,
get_torrents_handler,
get_torrents_handler, reload_whitelist_handler,
};
use crate::tracker;

pub fn start(socket_addr: SocketAddr, tracker: &Arc<tracker::Tracker>) -> impl Future<Output = hyper::Result<()>> {
// todo: duplicate routes definition. See `start_tls` function.
let app = Router::new()
// Stats
.route("/stats", get(get_stats_handler).with_state(tracker.clone()))
Expand All @@ -32,6 +33,11 @@ pub fn start(socket_addr: SocketAddr, tracker: &Arc<tracker::Tracker>) -> impl F
"/whitelist/:info_hash",
delete(delete_torrent_from_whitelist_handler).with_state(tracker.clone()),
)
// Whitelist command
.route(
"/whitelist/:info_hash",
get(reload_whitelist_handler).with_state(tracker.clone()),
)
.layer(middleware::from_fn_with_state(tracker.config.clone(), auth));

let server = axum::Server::bind(&socket_addr).serve(app.into_make_service());
Expand All @@ -47,6 +53,7 @@ pub fn start_tls(
ssl_config: RustlsConfig,
tracker: &Arc<tracker::Tracker>,
) -> impl Future<Output = Result<(), std::io::Error>> {
// todo: duplicate routes definition. See `start` function.
let app = Router::new()
// Stats
.route("/stats", get(get_stats_handler).with_state(tracker.clone()))
Expand All @@ -62,6 +69,11 @@ pub fn start_tls(
"/whitelist/:info_hash",
delete(delete_torrent_from_whitelist_handler).with_state(tracker.clone()),
)
// Whitelist command
.route(
"/whitelist/:info_hash",
get(reload_whitelist_handler).with_state(tracker.clone()),
)
.layer(middleware::from_fn_with_state(tracker.config.clone(), auth));

let handle = Handle::new();
Expand Down
2 changes: 2 additions & 0 deletions tests/api/asserts.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// code-review: should we use macros to return the exact line where the assert fails?

use reqwest::Response;

pub async fn assert_torrent_not_known(response: Response) {
Expand Down
46 changes: 44 additions & 2 deletions tests/tracker_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -950,8 +950,8 @@ mod tracker_apis {
use torrust_tracker::protocol::info_hash::InfoHash;

use crate::api::asserts::{
assert_failed_to_remove_torrent_from_whitelist, assert_failed_to_whitelist_torrent, assert_token_not_valid,
assert_unauthorized,
assert_failed_to_reload_whitelist, assert_failed_to_remove_torrent_from_whitelist,
assert_failed_to_whitelist_torrent, assert_token_not_valid, assert_unauthorized,
};
use crate::api::client::Client;
use crate::api::connection_info::{connection_with_invalid_token, connection_with_no_token};
Expand Down Expand Up @@ -1080,5 +1080,47 @@ mod tracker_apis {

assert_unauthorized(response).await;
}

#[tokio::test]
async fn should_allow_reload_the_whitelist_from_the_database() {
let api_server = start_default_api(&Version::Axum).await;

let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
let info_hash = InfoHash::from_str(&hash).unwrap();
api_server.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap();

let response = Client::new(api_server.get_connection_info(), &Version::Axum)
.reload_whitelist()
.await;

assert_eq!(response.status(), 200);
/* This assert fails because the whitelist has not been reloaded yet.
We could add a new endpoint GET /api/whitelist/:info_hash to check if a torrent
is whitelisted and use that endpoint to check if the torrent is still there after reloading.
assert!(
!(api_server
.tracker
.is_info_hash_whitelisted(&InfoHash::from_str(&info_hash).unwrap())
.await)
);
*/
}

#[tokio::test]
async fn should_return_an_error_when_the_whitelist_cannot_be_reloaded_from_the_database() {
let api_server = start_default_api(&Version::Axum).await;

let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
let info_hash = InfoHash::from_str(&hash).unwrap();
api_server.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap();

force_database_error(&api_server.tracker);

let response = Client::new(api_server.get_connection_info(), &Version::Axum)
.reload_whitelist()
.await;

assert_failed_to_reload_whitelist(response).await;
}
}
}

0 comments on commit a58d831

Please sign in to comment.