use actix_web::dev::Payload;
use actix_web::{FromRequest, HttpMessage, HttpRequest};
use std::future::{ready, Ready};
#[derive(Clone, Debug)]
pub struct Authenticated {
pub identity_key: String,
}
impl FromRequest for Authenticated {
type Error = actix_web::Error;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
match req.extensions().get::<Authenticated>() {
Some(auth) => ready(Ok(auth.clone())),
None => ready(Err(actix_web::error::ErrorUnauthorized(
serde_json::json!({
"status": "error",
"code": "ERR_NOT_AUTHENTICATED",
"description": "Authentication required"
}),
))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use actix_web::test::TestRequest;
use actix_web::FromRequest;
#[actix_web::test]
async fn test_from_request_with_authenticated() {
let identity = "02abc123def456";
let req = TestRequest::default().to_http_request();
req.extensions_mut().insert(Authenticated {
identity_key: identity.to_string(),
});
let mut payload = Payload::None;
let result = Authenticated::from_request(&req, &mut payload).await;
let auth = result.expect("should extract Authenticated");
assert_eq!(auth.identity_key, identity);
}
#[actix_web::test]
async fn test_from_request_without_authenticated() {
let req = TestRequest::default().to_http_request();
let mut payload = Payload::None;
let result = Authenticated::from_request(&req, &mut payload).await;
let err = result.expect_err("should return error without Authenticated");
let resp = err.as_response_error().error_response();
assert_eq!(resp.status(), actix_web::http::StatusCode::UNAUTHORIZED);
let body = actix_web::body::to_bytes(resp.into_body()).await.unwrap();
let json: serde_json::Value = serde_json::from_slice(&body).unwrap();
assert_eq!(json["status"], "error");
assert_eq!(json["code"], "ERR_NOT_AUTHENTICATED");
assert_eq!(json["description"], "Authentication required");
}
#[test]
fn test_authenticated_clone() {
let auth = Authenticated {
identity_key: "02abc123".to_string(),
};
let cloned = auth.clone();
assert_eq!(auth.identity_key, cloned.identity_key);
}
}