use std::future::{Ready, ready};
use actix_web::dev::Payload;
use actix_web::web::Data;
use actix_web::{Error, FromRequest, HttpRequest};
use super::GuardNotConfigured;
use crate::guard::Guard;
impl FromRequest for Guard {
type Error = Error;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
match req.app_data::<Data<Guard>>() {
Some(data) => {
let guard: &Guard = data;
ready(Ok(guard.clone()))
}
None => ready(Err(actix_web::error::ErrorInternalServerError(
GuardNotConfigured,
))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use actix_web::test;
fn guard() -> Guard {
Guard::from_master_key(&[7u8; 32], "aes-256-gcm").unwrap()
}
#[actix_web::test]
async fn extracts_from_app_data() {
let req = test::TestRequest::default()
.app_data(Data::new(guard()))
.to_http_request();
let extracted = Guard::from_request(&req, &mut Payload::None).await.unwrap();
assert_eq!(extracted.identifiers().len(), 5);
}
#[actix_web::test]
async fn missing_app_data_is_a_500() {
let req = test::TestRequest::default().to_http_request();
let err = Guard::from_request(&req, &mut Payload::None)
.await
.unwrap_err();
assert_eq!(
err.as_response_error().status_code(),
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR
);
}
#[actix_web::test]
async fn handler_and_state_share_one_encrypter() {
let state = guard();
let token = state.encrypt("共享".as_bytes()).unwrap();
let req = test::TestRequest::default()
.app_data(Data::new(state))
.to_http_request();
let extracted = Guard::from_request(&req, &mut Payload::None).await.unwrap();
assert_eq!(extracted.decrypt(&token).unwrap(), "共享".as_bytes());
}
#[actix_web::test]
async fn data_from_arc_shares_the_allocation() {
use std::sync::Arc;
let shared = Arc::new(guard());
let token = shared.encrypt(b"x").unwrap();
let req = test::TestRequest::default()
.app_data(Data::from(shared.clone()))
.to_http_request();
let extracted = Guard::from_request(&req, &mut Payload::None).await.unwrap();
assert_eq!(extracted.decrypt(&token).unwrap(), b"x");
assert_eq!(Arc::strong_count(&shared), 2);
}
}