use crate::context::Request;
use crate::flash::Message;
use crate::middleware::auth::{get_user_id, is_authenticated};
use crate::utils::aliases::AEngine;
use crate::utils::csrf::{CsrfContext, CsrfToken};
use axum::{extract::FromRequestParts, http::request::Parts, http::StatusCode};
use tower_sessions::Session;
pub struct RuniqueContext {
pub engine: AEngine,
pub tpl: Request,
pub flash: Message,
}
impl<S> FromRequestParts<S> for RuniqueContext
where
S: Send + Sync,
{
type Rejection = StatusCode;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let engine = parts
.extensions
.get::<AEngine>()
.ok_or(StatusCode::INTERNAL_SERVER_ERROR)?;
let session = parts
.extensions
.get::<Session>()
.ok_or(StatusCode::INTERNAL_SERVER_ERROR)?;
let csrf_token: CsrfToken = if let Some(token) = parts.extensions.get::<CsrfToken>() {
token.clone()
} else {
if is_authenticated(session).await {
if let Some(user_id) = get_user_id(session).await {
CsrfToken::generate_with_context(
CsrfContext::Authenticated { user_id },
&engine.config.server.secret_key,
)
} else {
let session_id = session.id().map(|id| id.to_string()).unwrap_or_default();
CsrfToken::generate_with_context(
CsrfContext::Anonymous {
session_id: &session_id,
},
&engine.config.server.secret_key,
)
}
} else {
let session_id = session.id().map(|id| id.to_string()).unwrap_or_default();
CsrfToken::generate_with_context(
CsrfContext::Anonymous {
session_id: &session_id,
},
&engine.config.server.secret_key,
)
}
};
Ok(Self {
engine: engine.clone(),
tpl: Request::new(
engine.clone(),
session.clone(),
csrf_token.clone(),
parts.method.clone(),
),
flash: Message {
session: session.clone(),
},
})
}
}