MCPcopy Create free account
hub / github.com/actix/examples / encrypt_payloads

Function encrypt_payloads

middleware/encrypted-payloads/src/main.rs:88–157  ·  view source on GitHub ↗
(
    mut req: dev::ServiceRequest,
    next: Next<impl MessageBody>,
)

Source from the content-addressed store, hash-verified

86}
87
88async 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

Callers

nothing calls this directly

Calls 4

decodeMethod · 0.80
encodeMethod · 0.80
bytes_to_payloadFunction · 0.70
callMethod · 0.45

Tested by

no test coverage detected