use crate::claims;
use crate::client::NucleusClient;
use actix_web::dev::Payload;
use actix_web::error::ErrorUnauthorized;
use actix_web::{web, Error, FromRequest, HttpRequest};
use futures_util::future::BoxFuture;
#[derive(Debug, Clone)]
pub struct NucleusClaims(pub claims::NucleusClaims);
impl std::ops::Deref for NucleusClaims {
type Target = claims::NucleusClaims;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromRequest for NucleusClaims {
type Error = Error;
type Future = BoxFuture<'static, Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
let client = req
.app_data::<web::Data<NucleusClient>>()
.cloned();
let auth_header = req
.headers()
.get("Authorization")
.and_then(|v| v.to_str().ok())
.and_then(|v| v.strip_prefix("Bearer "))
.map(|s| s.to_owned());
Box::pin(async move {
let client = client
.ok_or_else(|| ErrorUnauthorized("NucleusClient not configured"))?;
let token = auth_header
.ok_or_else(|| ErrorUnauthorized("Missing Authorization header"))?;
let claims = client
.verify_token(&token)
.await
.map_err(|e| ErrorUnauthorized(format!("Invalid token: {e}")))?;
Ok(NucleusClaims(claims))
})
}
}