Skip to content
Clone
1480255
99 lines 3.0 KB Rust
use actix_web::body::{BoxBody, MessageBody};
use actix_web::dev::{ServiceRequest, ServiceResponse};
use actix_web::middleware::Next;
use actix_web::web::Data;
use actix_web::{Error, HttpMessage, HttpResponse};
use ::session::Session;
use export::AppState;
use crate::middleware::cookie::append_cookie;
const SKIP_PREFIXES: [&str; 8] = [
"/healthz",
"/readyz",
"/api/docs",
"/api/v1/auth/",
"/api/v1/internal",
"/assets",
"/pages",
"/swagger",
];
pub async fn revalidate<B>(
request: ServiceRequest,
next: Next<B>,
) -> Result<ServiceResponse<BoxBody>, Error>
where
B: MessageBody + 'static,
{
if SKIP_PREFIXES
.iter()
.any(|prefix| request.path().starts_with(prefix))
{
return Ok(next.call(request).await?.map_into_boxed_body());
}
let Some(state) = request
.app_data::<Data<AppState>>()
.map(|value| value.get_ref().clone())
else {
return Ok(next.call(request).await?.map_into_boxed_body());
};
let Some(session) = request.extensions().get::<Session>().cloned() else {
return Ok(next.call(request).await?.map_into_boxed_body());
};
let Some(user_id) = session.uid() else {
return Ok(next.call(request).await?.map_into_boxed_body());
};
let Some(version) = session.security_version().ok().flatten() else {
return Ok(next.call(request).await?.map_into_boxed_body());
};
let Some(session_id) = session.session_id() else {
return Ok(next.call(request).await?.map_into_boxed_body());
};
let Some(accounts) = request
.app_data::<Data<auth::Accounts>>()
.map(|value| value.get_ref().clone())
else {
return Ok(next.call(request).await?.map_into_boxed_body());
};
let key = format!("auth:recheck:{session_id}:{version}");
if export::redis::get_string(&state.redis, &key)
.await
.ok()
.flatten()
.is_some()
{
return Ok(next.call(request).await?.map_into_boxed_body());
}
match accounts.get_session(user_id, version, &session_id).await {
Ok(_) => {
let _ = export::redis::set_string(
&state.redis,
&key,
"1",
state.config.session.recheck_secs,
)
.await;
Ok(next.call(request).await?.map_into_boxed_body())
}
Err(export::KenAuthError::Unauthenticated) | Err(export::KenAuthError::NotFound) => {
let mut response = HttpResponse::Unauthorized().json(serde_json::json!({
"code": 401,
"message": "session_revoked",
"data": null,
"error": null,
"error_code": "session_revoked",
"request_id": null,
}));
append_cookie(
&mut response,
&session::clear_session_cookie(&state.config.session),
);
Ok(request.into_response(response))
}
Err(_) => Ok(next.call(request).await?.map_into_boxed_body()),
}
}