From 1e81421444538e7232c8b9d9cefe97284204dd56 Mon Sep 17 00:00:00 2001 From: _ <> Date: Sun, 13 Dec 2020 01:12:56 +0000 Subject: [PATCH] :shirt: refactor: Extract functions for scraper API endpoints --- crates/ptth_relay/src/lib.rs | 127 ++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 45 deletions(-) diff --git a/crates/ptth_relay/src/lib.rs b/crates/ptth_relay/src/lib.rs index 1ea4d2b..49b1a3c 100644 --- a/crates/ptth_relay/src/lib.rs +++ b/crates/ptth_relay/src/lib.rs @@ -408,22 +408,94 @@ async fn handle_server_list ( Ok (ok_reply (s)?) } +#[instrument (level = "trace", skip (req, state))] +async fn handle_scraper_api_v1 ( + req: Request , + state: Arc , + path_rest: &str +) +-> Result , RequestError> +{ + use key_validity::KeyValidity; + + let api_key = req.headers ().get ("X-ApiKey"); + + let api_key = match api_key { + None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run scraper without an API key")?), + Some (x) => x, + }; + + let bad_key = || error_reply (StatusCode::FORBIDDEN, "403 Forbidden"); + + { + let config = state.config.read ().await; + + let dev_mode = match &config.iso.dev_mode { + None => return Ok (bad_key ()?), + Some (x) => x, + }; + + let expected_key = match &dev_mode.scraper_key { + None => return Ok (bad_key ()?), + Some (x) => x, + }; + + let now = chrono::Utc::now (); + + match expected_key.is_valid (now, api_key.as_bytes ()) { + KeyValidity::Valid => (), + KeyValidity::WrongKey (bad_hash) => { + error! ("Bad scraper key with hash {:?}", bad_hash); + return Ok (bad_key ()?); + } + err => { + error! ("Bad scraper key {:?}", err); + return Ok (bad_key ()?); + }, + } + } + + if path_rest == "test" { + Ok (error_reply (StatusCode::OK, "You're valid!")?) + } + else { + Ok (error_reply (StatusCode::NOT_FOUND, "Unknown API endpoint")?) + } +} + +#[instrument (level = "trace", skip (req, state))] +async fn handle_scraper_api ( + req: Request , + state: Arc , + path_rest: &str +) +-> Result , RequestError> +{ + if let Some (rest) = prefix_match ("v1/", path_rest) { + handle_scraper_api_v1 (req, state, rest).await + } + else if let Some (rest) = prefix_match ("api/", path_rest) { + handle_scraper_api_v1 (req, state, rest).await + } + else { + Ok (error_reply (StatusCode::NOT_FOUND, "Unknown scraper API version")?) + } +} + #[instrument (level = "trace", skip (req, state))] async fn handle_all (req: Request , state: Arc ) -> Result , RequestError> { - let path = req.uri ().path (); + let path = req.uri ().path ().to_string (); //println! ("{}", path); debug! ("Request path: {}", path); - let api_key = req.headers ().get ("X-ApiKey"); - if req.method () == Method::POST { // This is stuff the server can use. Clients can't // POST right now - return if let Some (request_code) = prefix_match ("/7ZSFUKGV/http_response/", path) { + return if let Some (request_code) = prefix_match ("/7ZSFUKGV/http_response/", &path) { let request_code = request_code.into (); Ok (server_endpoint::handle_response (req, state, request_code).await?) } @@ -432,14 +504,16 @@ async fn handle_all (req: Request , state: Arc ) }; } - if let Some (listen_code) = prefix_match ("/7ZSFUKGV/http_listen/", path) { + if let Some (listen_code) = prefix_match ("/7ZSFUKGV/http_listen/", &path) { + let api_key = req.headers ().get ("X-ApiKey"); + let api_key = match api_key { None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run server without an API key")?), Some (x) => x, }; server_endpoint::handle_listen (state, listen_code.into (), api_key.as_bytes ()).await } - else if let Some (rest) = prefix_match ("/frontend/servers/", path) { + else if let Some (rest) = prefix_match ("/frontend/servers/", &path) { if rest == "" { Ok (handle_server_list (state).await?) } @@ -464,45 +538,8 @@ async fn handle_all (req: Request , state: Arc ) else if path == "/frontend/test_mysterious_error" { Err (RequestError::Mysterious) } - else if path == "/scraper/v1/test" || path == "/scraper/api/test" { - use key_validity::KeyValidity; - - let api_key = match api_key { - None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run scraper without an API key")?), - Some (x) => x, - }; - - let bad_key = || error_reply (StatusCode::FORBIDDEN, "403 Forbidden"); - - { - let config = state.config.read ().await; - - let dev_mode = match &config.iso.dev_mode { - None => return Ok (bad_key ()?), - Some (x) => x, - }; - - let expected_key = match &dev_mode.scraper_key { - None => return Ok (bad_key ()?), - Some (x) => x, - }; - - let now = chrono::Utc::now (); - - match expected_key.is_valid (now, api_key.as_bytes ()) { - KeyValidity::Valid => (), - KeyValidity::WrongKey (bad_hash) => { - error! ("Bad scraper key with hash {:?}", bad_hash); - return Ok (bad_key ()?); - } - err => { - error! ("Bad scraper key {:?}", err); - return Ok (bad_key ()?); - }, - } - } - - Ok (error_reply (StatusCode::OK, "You're valid!")?) + else if let Some (rest) = prefix_match ("/scraper/", &path) { + handle_scraper_api (req, state, rest).await } else { Ok (error_reply (StatusCode::OK, "Hi")?)