use crate::middleware::session::{CleaningMemoryStore, session_db::RuniqueSessionStore};
use crate::utils::aliases::{
ADb, ARlockmap, ASecurityCsp, ASecurityHosts, ATera, new, new_registry,
};
use axum::{Router, middleware};
use std::sync::{Arc, LazyLock, RwLock};
use tera::Tera;
use crate::config::RuniqueConfig;
use crate::middleware::{
HostPolicy, MiddlewareConfig, SecurityPolicy, allowed_hosts_middleware, csrf_middleware,
dev_no_cache_middleware, error_handler_middleware, https_redirect_middleware,
security_headers_middleware,
};
#[cfg(feature = "orm")]
use sea_orm::DatabaseConnection;
#[derive(Debug)]
pub struct RuniqueEngine {
pub config: RuniqueConfig,
pub tera: ATera,
#[cfg(feature = "orm")]
pub db: ADb,
pub url_registry: ARlockmap,
pub features: MiddlewareConfig,
pub security_csp: ASecurityCsp,
pub security_hosts: ASecurityHosts,
pub session_store: LazyLock<RwLock<Option<Arc<CleaningMemoryStore>>>>,
pub session_db_store: LazyLock<RwLock<Option<Arc<RuniqueSessionStore>>>>,
}
impl RuniqueEngine {
#[cfg(feature = "orm")]
pub fn new(config: RuniqueConfig, tera: Tera, db: DatabaseConnection) -> Self {
let features = MiddlewareConfig::from_env();
let security_csp = SecurityPolicy::default();
let security_hosts = HostPolicy::default();
Self {
config,
tera: new(tera),
db: new(db),
url_registry: new_registry(),
features,
security_csp: new(security_csp),
security_hosts: new(security_hosts),
session_store: LazyLock::new(|| RwLock::new(None)),
session_db_store: LazyLock::new(|| RwLock::new(None)),
}
}
pub fn attach_middlewares(engine: Arc<Self>, router: Router) -> Router {
let mut router = router;
let f = &engine.features;
if engine.config.security.enforce_https {
router = router.layer(middleware::from_fn_with_state(
engine.clone(),
https_redirect_middleware,
));
}
if f.enable_host_validation {
router = router.layer(middleware::from_fn_with_state(
engine.clone(),
allowed_hosts_middleware,
));
}
router = router.layer(middleware::from_fn_with_state(
engine.clone(),
csrf_middleware,
));
if !f.enable_cache {
router = router.layer(middleware::from_fn_with_state(
engine.clone(),
dev_no_cache_middleware,
));
}
if f.enable_csp {
router = router.layer(middleware::from_fn_with_state(
engine.clone(),
security_headers_middleware,
));
}
if f.enable_debug_errors {
router = router.layer(middleware::from_fn(error_handler_middleware));
}
router
}
}