encryption/integrations/
poem.rs1use poem::http::StatusCode;
29use poem::web::{FromRequest, RequestBody};
30use poem::{Error, Request, Result};
31
32use super::GuardNotConfigured;
33use crate::guard::Guard;
34
35impl<'a> FromRequest<'a> for Guard {
36 async fn from_request(req: &'a Request, _body: &mut RequestBody) -> Result<Self> {
37 req.extensions().get::<Guard>().cloned().ok_or_else(|| {
38 Error::from_string(
39 GuardNotConfigured.to_string(),
40 StatusCode::INTERNAL_SERVER_ERROR,
41 )
42 })
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use poem::Request;
50
51 fn guard() -> Guard {
52 Guard::from_master_key(&[7u8; 32], "aes-256-gcm").unwrap()
53 }
54
55 async fn extract(req: &Request) -> Result<Guard> {
56 let mut body = RequestBody::default();
57 Guard::from_request(req, &mut body).await
58 }
59
60 #[tokio::test]
61 async fn extracts_from_request_extensions() {
62 let mut req = Request::builder().finish();
63 req.extensions_mut().insert(guard());
64
65 let extracted = extract(&req).await.unwrap();
66 assert_eq!(extracted.identifiers().len(), 5);
67 }
68
69 #[tokio::test]
71 async fn missing_data_is_a_500() {
72 let req = Request::builder().finish();
73 let err = extract(&req).await.unwrap_err();
74 assert_eq!(err.status(), StatusCode::INTERNAL_SERVER_ERROR);
75 }
76
77 #[tokio::test]
78 async fn handler_and_state_share_one_encrypter() {
79 let state = guard();
80 let token = state.encrypt("共享".as_bytes()).unwrap();
81
82 let mut req = Request::builder().finish();
83 req.extensions_mut().insert(state);
84
85 let extracted = extract(&req).await.unwrap();
86 assert_eq!(extracted.decrypt(&token).unwrap(), "共享".as_bytes());
87 }
88}