👕 refactor: extract scraper_api module

main
_ 2020-12-13 03:42:00 +00:00
parent 5f947ed73c
commit 32e48697d5
2 changed files with 102 additions and 80 deletions

View File

@ -61,6 +61,7 @@ pub mod git_version;
pub mod key_validity; pub mod key_validity;
mod relay_state; mod relay_state;
mod scraper_api;
mod server_endpoint; mod server_endpoint;
pub use config::Config; pub use config::Config;
@ -68,6 +69,7 @@ pub use errors::*;
pub use relay_state::RelayState; pub use relay_state::RelayState;
use relay_state::*; use relay_state::*;
use scraper_api::*;
fn ok_reply <B: Into <Body>> (b: B) fn ok_reply <B: Into <Body>> (b: B)
-> Result <Response <Body>, http::Error> -> Result <Response <Body>, http::Error>
@ -324,86 +326,6 @@ async fn handle_server_list (
Ok (ok_reply (s)?) Ok (ok_reply (s)?)
} }
#[instrument (level = "trace", skip (req, state))]
async fn handle_scraper_api_v1 (
req: Request <Body>,
state: Arc <RelayState>,
path_rest: &str
)
-> Result <Response <Body>, 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 <Body>,
state: Arc <RelayState>,
path_rest: &str
)
-> Result <Response <Body>, RequestError>
{
{
if ! state.config.read ().await.iso.enable_scraper_auth {
return Ok (error_reply (StatusCode::FORBIDDEN, "Scraper API disabled")?);
}
}
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))] #[instrument (level = "trace", skip (req, state))]
async fn handle_all (req: Request <Body>, state: Arc <RelayState>) async fn handle_all (req: Request <Body>, state: Arc <RelayState>)
-> Result <Response <Body>, RequestError> -> Result <Response <Body>, RequestError>

View File

@ -0,0 +1,100 @@
use std::{
sync::Arc,
};
use hyper::{
Body,
Request,
Response,
StatusCode,
};
use tracing::{
error,
instrument,
};
use crate::{
RequestError,
error_reply,
key_validity::KeyValidity,
prefix_match,
relay_state::RelayState,
};
#[instrument (level = "trace", skip (req, state))]
pub async fn handle_scraper_api_v1 (
req: Request <Body>,
state: Arc <RelayState>,
path_rest: &str
)
-> Result <Response <Body>, RequestError>
{
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))]
pub async fn handle_scraper_api (
req: Request <Body>,
state: Arc <RelayState>,
path_rest: &str
)
-> Result <Response <Body>, RequestError>
{
{
if ! state.config.read ().await.iso.enable_scraper_auth {
return Ok (error_reply (StatusCode::FORBIDDEN, "Scraper API disabled")?);
}
}
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")?)
}
}