request_handler.rs 4.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. use crate::{negative_report::EncryptedNegativeReport, positive_report::PositiveReport, *};
  2. use hyper::{body, header::HeaderValue, Body, Method, Request, Response, StatusCode};
  3. use serde_json::json;
  4. use sled::Db;
  5. use std::convert::Infallible;
  6. // Handle submitted reports
  7. pub async fn handle(db: &Db, req: Request<Body>) -> Result<Response<Body>, Infallible> {
  8. match req.method() {
  9. &Method::OPTIONS => Ok(Response::builder()
  10. .header("Access-Control-Allow-Origin", HeaderValue::from_static("*"))
  11. .header("Access-Control-Allow-Headers", "accept, content-type")
  12. .header("Access-Control-Allow-Methods", "POST")
  13. .status(200)
  14. .body(Body::from("Allow POST"))
  15. .unwrap()),
  16. _ => match (req.method(), req.uri().path()) {
  17. #[cfg(feature = "simulation")]
  18. (&Method::POST, "/nrkey") => Ok::<_, Infallible>({
  19. // We need a way for simulated users to get the keys to
  20. // encrypt their negative reports. As Troll Patrol may
  21. // not be directly accessible when users are submitting
  22. // negative reports, in practice we expect that these
  23. // keys will be made available elsewhere.
  24. let bytes = body::to_bytes(req.into_body()).await.unwrap();
  25. // Expect the body to contain the date for the key the
  26. // user requests.
  27. let date: u32 = match serde_json::from_slice(&bytes) {
  28. Ok(date) => date,
  29. Err(e) => {
  30. let response = json!({"error": e.to_string()});
  31. let val = serde_json::to_string(&response).unwrap();
  32. return Ok(prepare_header(val));
  33. }
  34. };
  35. // Get the current key or generate a new one. Note that
  36. // this code is only called in simulation. In
  37. // production, users should not be able to induce Troll
  38. // Patrol to generate new keys.
  39. let pubkey = match get_negative_report_public_key(&db, date) {
  40. Some(k) => Some(k),
  41. None => new_negative_report_key(&db, date),
  42. };
  43. prepare_header(serde_json::to_string(&pubkey).unwrap())
  44. }),
  45. (&Method::POST, "/negativereport") => Ok::<_, Infallible>({
  46. let bytes = body::to_bytes(req.into_body()).await.unwrap();
  47. // We cannot depend on the transport layer providing E2EE, so
  48. // negative reports should be separately encrypted.
  49. let enr: EncryptedNegativeReport = match bincode::deserialize(&bytes) {
  50. Ok(enr) => enr,
  51. Err(e) => {
  52. let response = json!({"error": e.to_string()});
  53. let val = serde_json::to_string(&response).unwrap();
  54. return Ok(prepare_header(val));
  55. }
  56. };
  57. handle_encrypted_negative_report(db, enr);
  58. prepare_header("OK".to_string())
  59. }),
  60. (&Method::POST, "/positivereport") => Ok::<_, Infallible>({
  61. let bytes = body::to_bytes(req.into_body()).await.unwrap();
  62. let pr = match PositiveReport::from_slice(&bytes) {
  63. Ok(pr) => pr,
  64. Err(e) => {
  65. let response = json!({"error": e});
  66. let val = serde_json::to_string(&response).unwrap();
  67. return Ok(prepare_header(val));
  68. }
  69. };
  70. save_positive_report_to_process(db, pr);
  71. prepare_header("OK".to_string())
  72. }),
  73. _ => {
  74. // Return 404 not found response.
  75. Ok(Response::builder()
  76. .status(StatusCode::NOT_FOUND)
  77. .body(Body::from("Not found"))
  78. .unwrap())
  79. }
  80. },
  81. }
  82. }
  83. // Prepare HTTP Response for successful Server Request
  84. pub fn prepare_header(response: String) -> Response<Body> {
  85. let mut resp = Response::new(Body::from(response));
  86. resp.headers_mut()
  87. .insert("Access-Control-Allow-Origin", HeaderValue::from_static("*"));
  88. resp
  89. }