encryption/integrations/
rocket.rs1use rocket::State;
35use rocket::http::Status;
36use rocket::request::{FromRequest, Outcome, Request};
39
40use super::GuardNotConfigured;
41use crate::guard::Guard;
42
43#[rocket::async_trait]
44impl<'r> FromRequest<'r> for Guard {
45 type Error = GuardNotConfigured;
46
47 async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
48 match request.guard::<&State<Guard>>().await {
49 Outcome::Success(state) => Outcome::Success(state.inner().clone()),
50 Outcome::Error(_) | Outcome::Forward(_) => {
53 Outcome::Error((Status::InternalServerError, GuardNotConfigured))
54 }
55 }
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use rocket::local::blocking::Client;
63 use rocket::{get, routes};
64
65 fn guard() -> Guard {
66 Guard::from_master_key(&[7u8; 32], "aes-256-gcm").unwrap()
67 }
68
69 #[get("/encrypt")]
70 fn encrypt_route(guard: Guard) -> String {
71 let blob = guard.encrypt("13800138000".as_bytes()).unwrap();
72 crate::internal::hex_encode(&blob)
73 }
74
75 #[get("/decrypt/<payload>")]
76 fn decrypt_route(guard: Guard, payload: &str) -> String {
77 let blob = crate::internal::hex_decode(payload).unwrap_or_default();
78 guard
79 .decrypt(&blob)
80 .map(|plain| String::from_utf8_lossy(&plain).into_owned())
81 .unwrap_or_else(|_| "解不开".into())
82 }
83
84 #[test]
85 fn guard_is_injectable_end_to_end() {
86 let rocket = rocket::build()
87 .manage(guard())
88 .mount("/", routes![encrypt_route, decrypt_route]);
89 let client = Client::tracked(rocket).expect("rocket 应当能启动");
90
91 let res = client.get("/encrypt").dispatch();
92 assert_eq!(res.status(), Status::Ok);
93 let cipher = res.into_string().unwrap();
94 assert!(cipher.len() > 20, "应当拿到一段密文,实际 {cipher:?}");
95
96 let res = client.get(format!("/decrypt/{cipher}")).dispatch();
98 assert_eq!(res.status(), Status::Ok);
99 assert_eq!(res.into_string().unwrap(), "13800138000");
100 }
101
102 #[test]
104 fn missing_managed_state_is_a_500() {
105 let rocket = rocket::build().mount("/", routes![encrypt_route]);
106 let client = Client::tracked(rocket).expect("rocket 应当能启动");
107
108 let res = client.get("/encrypt").dispatch();
109 assert_eq!(res.status(), Status::InternalServerError);
110 }
111}