use crate::{negative_report::EncryptedNegativeReport, positive_report::PositiveReport, *}; use hyper::{body, header::HeaderValue, Body, Method, Request, Response, StatusCode}; use serde_json::json; use sled::Db; use std::convert::Infallible; // Handle submitted reports pub async fn handle(db: &Db, req: Request) -> Result, Infallible> { match req.method() { &Method::OPTIONS => Ok(Response::builder() .header("Access-Control-Allow-Origin", HeaderValue::from_static("*")) .header("Access-Control-Allow-Headers", "accept, content-type") .header("Access-Control-Allow-Methods", "POST") .status(200) .body(Body::from("Allow POST")) .unwrap()), _ => match (req.method(), req.uri().path()) { (&Method::POST, "/negativereport") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); // We cannot depend on the transport layer providing E2EE, so // positive reports should be separately encrypted. let enr: EncryptedNegativeReport = match bincode::deserialize(&bytes) { Ok(enr) => enr, Err(e) => { let response = json!({"error": e.to_string()}); let val = serde_json::to_string(&response).unwrap(); return Ok(prepare_header(val)); } }; handle_encrypted_negative_report(&db, enr); prepare_header("OK".to_string()) }), (&Method::POST, "/positivereport") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); let pr = match PositiveReport::from_slice(&bytes) { Ok(pr) => pr, Err(e) => { let response = json!({"error": e}); let val = serde_json::to_string(&response).unwrap(); return Ok(prepare_header(val)); } }; save_positive_report_to_process(&db, pr); prepare_header("OK".to_string()) }), _ => { // Return 404 not found response. Ok(Response::builder() .status(StatusCode::NOT_FOUND) .body(Body::from("Not found")) .unwrap()) } }, } } // Prepare HTTP Response for successful Server Request fn prepare_header(response: String) -> Response { let mut resp = Response::new(Body::from(response)); resp.headers_mut() .insert("Access-Control-Allow-Origin", HeaderValue::from_static("*")); resp }