use rocket::{Data, Request, Response};
use rocket::fairing::{Fairing, Info, Kind};
use sa_token_core::SaTokenContext;
use sa_token_plugin_rocket_core::SaTokenState;
use crate::adapter::RocketCapturedRequest;
pub struct SaTokenLayer {
state: SaTokenState,
}
impl SaTokenLayer {
pub fn new(state: SaTokenState) -> Self {
Self { state }
}
}
#[rocket::async_trait]
impl Fairing for SaTokenLayer {
fn info(&self) -> Info {
Info {
name: "Sa-Token Authentication",
kind: Kind::Request | Kind::Response,
}
}
async fn on_request(&self, req: &mut Request<'_>, _: &mut Data<'_>) {
let adapter = RocketCapturedRequest::capture(req, self.state.manager.config.token_name.as_str());
let flow =
sa_token_plugin_rocket_core::run_auth_flow(&adapter, &self.state.manager, None).await;
if let Some(ref t) = flow.token {
req.local_cache(|| Some(t.clone()));
}
if let Some(ref id) = flow.login_id {
req.local_cache(|| Some(id.clone()));
}
SaTokenContext::set_current(flow.context.clone());
req.local_cache(|| std::sync::Arc::new(flow.context));
}
async fn on_response<'r>(&self, _req: &'r Request<'_>, _res: &mut Response<'r>) {
SaTokenContext::clear();
}
}