(
mut req: dev::ServiceRequest,
next: Next<impl MessageBody>,
)
| 86 | } |
| 87 | |
| 88 | async fn encrypt_payloads( |
| 89 | mut req: dev::ServiceRequest, |
| 90 | next: Next<impl MessageBody>, |
| 91 | ) -> Result<dev::ServiceResponse<impl MessageBody>, Error> { |
| 92 | // get cipher from app data |
| 93 | let cipher = req.extract::<web::Data<Aes256GcmSiv>>().await.unwrap(); |
| 94 | |
| 95 | // extract JSON with encrypted+encoded data field |
| 96 | let Json(Req { id, nonce, data }) = req.extract::<Json<Req>>().await?; |
| 97 | |
| 98 | log::info!("decrypting request {id:?}"); |
| 99 | |
| 100 | // decode nonce from payload |
| 101 | let nonce = BASE64_STANDARD.decode(nonce.unwrap()).unwrap(); |
| 102 | let nonce = Nonce::from_slice(&nonce); |
| 103 | |
| 104 | // decode and decrypt data field |
| 105 | let data_enc = BASE64_STANDARD.decode(&data).unwrap(); |
| 106 | let data = cipher.decrypt(nonce, data_enc.as_slice()).unwrap(); |
| 107 | |
| 108 | // construct request body format with plaintext data |
| 109 | let req_body = Req { |
| 110 | id, |
| 111 | nonce: None, |
| 112 | data: String::from_utf8(data).unwrap(), |
| 113 | }; |
| 114 | |
| 115 | // encode request body as JSON |
| 116 | let req_body = serde_json::to_vec(&req_body).unwrap(); |
| 117 | |
| 118 | // re-insert request body |
| 119 | req.set_payload(bytes_to_payload(web::Bytes::from(req_body))); |
| 120 | |
| 121 | // call next service |
| 122 | let res = next.call(req).await?; |
| 123 | |
| 124 | log::info!("encrypting response {id:?}"); |
| 125 | |
| 126 | // deconstruct response into parts |
| 127 | let (req, res) = res.into_parts(); |
| 128 | let (res, body) = res.into_parts(); |
| 129 | |
| 130 | // Read all bytes out of response stream. Only use `to_bytes` if you can guarantee all handlers |
| 131 | // wrapped by this middleware return complete responses or bounded streams. |
| 132 | let body = body::to_bytes(body).await.ok().unwrap(); |
| 133 | |
| 134 | // parse JSON from response body |
| 135 | let Res { data, .. } = serde_json::from_slice(&body).unwrap(); |
| 136 | |
| 137 | // generate and encode nonce for later |
| 138 | let nonce = Nonce::from_slice(b"unique nonce"); |
| 139 | let nonce_b64 = Some(BASE64_STANDARD.encode(nonce)); |
| 140 | |
| 141 | // encrypt and encode data field |
| 142 | let data_enc = cipher.encrypt(nonce, data.as_bytes()).unwrap(); |
| 143 | let data_enc = BASE64_STANDARD.encode(data_enc); |
| 144 | |
| 145 | // re-pack response into JSON format |
nothing calls this directly
no test coverage detected