ptth/crates/ptth_relay/src/scraper_api.rs

101 lines
2.1 KiB
Rust

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")?)
}
}