/* * This is the echoip-slatecave templating engine. * It wraps around tera in is specialized for echoip-slatecave. */ use axum::{ headers::HeaderValue, http::StatusCode, http::header::SET_COOKIE, response::Html, response::IntoResponse, response::Response, response::Json, }; use axum_extra::extract::cookie::Cookie; use axum_extra::extract::cookie; use tera::Tera; use toml::Table; use crate::view::View; use crate::mycelium::MycView; use crate::mycelium::MycFormat; use crate::mycelium::MycFormatFamily; use crate::settings::QuerySettings; use crate::settings::ResponseFormat; /* The engine itself */ #[derive(Clone)] pub struct Engine { pub tera: Tera, pub template_config: Option, } impl Engine { pub async fn render_view( &self, settings: &QuerySettings, view: &View, ) -> Response { let mut response = match settings.format.get_family() { MycFormatFamily::Template => { let template_name = view.get_template_name(); let mut context = tera::Context::new(); context.insert("view", &template_name); //intented for shared macros context.insert("format", &settings.format.to_string()); context.insert("language", &settings.lang); context.insert("dns_resolvers", &settings.available_dns_resolvers); context.insert("dns_resolver_id", &settings.dns_resolver_id); context.insert("data", &view); context.insert("extra", &self.template_config); match self.tera.render(&(template_name.clone()+&settings.format.get_file_extension()), &context) { Ok(text) => match settings.format { ResponseFormat::Html => Html(text).into_response(), _ => text.into_response(), } Err(e) => { println!("There was an error while rendering template {}: {e:?}", template_name); ( StatusCode::INTERNAL_SERVER_ERROR, format!("Template error in {}, contact owner or see logs.\n", template_name) ).into_response() } } } MycFormatFamily::API => { match view { View::Dig{result, ..} => { Json(result).into_response() }, View::Index{result, ..} | View::Ip{result, ..} => { Json(result).into_response() }, View::DnsResolverList => { Json(settings.available_dns_resolvers.clone()).into_response() }, View::DnsResolver{ config } => { Json(config).into_response() } _ => Json(view).into_response(), } } }; // Set status code let status_code = view.get_status_code(); if status_code != StatusCode::OK { *response.status_mut() = status_code; } // Set cookies let cookie = Cookie::build("dns_resolver",settings.dns_resolver_id.to_string()) .path("/") .same_site(cookie::SameSite::Strict) .finish(); if let Ok(header_value) = HeaderValue::from_str(&cookie.to_string()) { response.headers_mut().append( SET_COOKIE, header_value, ); } // return response response } }