12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- 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<Body>) -> Result<Response<Body>, 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()) {
- #[cfg(feature = "simulation")]
- (&Method::POST, "/nrkey") => Ok::<_, Infallible>({
- // We need a way for simulated users to get the keys to
- // encrypt their negative reports. As Troll Patrol may
- // not be directly accessible when users are submitting
- // negative reports, in practice we expect that these
- // keys will be made available elsewhere.
- let bytes = body::to_bytes(req.into_body()).await.unwrap();
- // Expect the body to contain the date for the key the
- // user requests.
- let date: u32 = match serde_json::from_slice(&bytes) {
- Ok(date) => date,
- Err(e) => {
- let response = json!({"error": e.to_string()});
- let val = serde_json::to_string(&response).unwrap();
- return Ok(prepare_header(val));
- }
- };
- // Get the current key or generate a new one. Note that
- // this code is only called in simulation. In
- // production, users should not be able to induce Troll
- // Patrol to generate new keys.
- let pubkey = match get_negative_report_public_key(&db, date) {
- Some(k) => Some(k),
- None => new_negative_report_key(&db, date),
- };
- prepare_header(serde_json::to_string(&pubkey).unwrap())
- }),
- (&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
- // negative 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
- pub fn prepare_header(response: String) -> Response<Body> {
- let mut resp = Response::new(Body::from(response));
- resp.headers_mut()
- .insert("Access-Control-Allow-Origin", HeaderValue::from_static("*"));
- resp
- }
|