use std::sync::Arc; use actix_jwt_session::{Authenticated, RedisMiddlewareFactory, RedisStorage}; use actix_web::get; use actix_web::http::StatusCode; use actix_web::web::Data; use actix_web::HttpResponse; use actix_web::{http::header::ContentType, test, App}; use jsonwebtoken::*; use ring::rand::SystemRandom; use ring::signature::{Ed25519KeyPair, KeyPair}; use serde::{Deserialize, Serialize}; use uuid::Uuid; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] struct Claims { id: Uuid, } impl actix_jwt_session::Claims for Claims { fn jti(&self) -> Uuid { self.id } } #[tokio::test(flavor = "multi_thread")] async fn not_authenticated() { const JWT_SIGNING_ALGO: Algorithm = Algorithm::EdDSA; let validator = Validation::new(JWT_SIGNING_ALGO); let redis = { use redis_async_pool::{RedisConnectionManager, RedisPool}; RedisPool::new( RedisConnectionManager::new( redis::Client::open("redis://localhost:6379").expect("Fail to connect to redis"), true, None, ), 5, ) }; let keys = JwtSigningKeys::generate().unwrap(); let factory = RedisMiddlewareFactory::::new( Arc::new(keys.decoding_key), Arc::new(validator), Arc::new(RedisStorage::new(redis.clone())), ); let app = App::new() .wrap(factory.clone()) .app_data(Data::new(redis.clone())) .service(sign_in) .service(sign_out) .service(session) .service(root); let app = actix_web::test::init_service(app).await; let res = test::call_service(&app, test::TestRequest::default() .insert_header(ContentType::plaintext()) .to_request()).await; assert!(res.status().is_success()); let res = test::call_service(&app, test::TestRequest::default() .uri("/s") .insert_header(ContentType::plaintext()) .to_request()).await; let s = StatusCode::UNAUTHORIZED; assert_eq!(res.status(), s); } #[get("/in")] async fn sign_in(store: Data>) -> HttpResponse { HttpResponse::Ok().body("") } #[get("/out")] async fn sign_out(store: Data>) -> HttpResponse { HttpResponse::Ok().body("") } #[get("/s")] async fn session(auth: Authenticated) -> HttpResponse { HttpResponse::Ok().json(&*auth) } #[get("/")] async fn root() -> HttpResponse { HttpResponse::Ok().body("") } pub struct JwtSigningKeys { encoding_key: EncodingKey, decoding_key: DecodingKey, } impl JwtSigningKeys { fn generate() -> Result> { let doc = Ed25519KeyPair::generate_pkcs8(&SystemRandom::new())?; let keypair = Ed25519KeyPair::from_pkcs8(doc.as_ref())?; let encoding_key = EncodingKey::from_ed_der(doc.as_ref()); let decoding_key = DecodingKey::from_ed_der(keypair.public_key().as_ref()); Ok(JwtSigningKeys { encoding_key, decoding_key, }) } }