Broke out settings and fixed a bug with the dns resolver not being persisted

This commit is contained in:
Slatian 2023-08-05 22:53:48 +02:00
parent d88b15ba02
commit 55897585ff
3 changed files with 70 additions and 80 deletions

View File

@ -39,6 +39,7 @@ mod config;
mod geoip;
mod ipinfo;
mod ratelimit;
mod settings;
mod simple_dns;
mod templating_engine;
mod idna;
@ -51,12 +52,8 @@ use crate::geoip::{
};
use crate::idna::IdnaName;
use crate::simple_dns::DnsLookupResult;
use crate::templating_engine::{
View,
ResponseFormat,
TemplateSettings,
Selectable,
};
use crate::settings::*;
use crate::templating_engine::View;
use crate::ipinfo::{AddressCast,AddressInfo,AddressScope};
#[derive(Deserialize, Serialize, Clone)]
@ -66,13 +63,6 @@ pub struct SettingsQuery {
dns: Option<String>,
}
#[derive(Clone, Serialize)]
pub struct QuerySettings {
#[serde(skip)]
template: TemplateSettings,
dns_resolver_id: String,
}
#[derive(Deserialize, Serialize, Clone)]
pub struct SearchQuery {
query: Option<String>,
@ -414,12 +404,9 @@ async fn settings_query_middleware<B>(
}
// Add the request settings extension
req.extensions_mut().insert(QuerySettings{
template: TemplateSettings{
format: format.unwrap_or(ResponseFormat::TextHtml),
lang: query.lang.unwrap_or("en".to_string()),
available_dns_resolvers: derived_config.dns_resolver_selectables,
dns_resolver: dns_resolver_id.clone(),
},
format: format.unwrap_or(ResponseFormat::TextHtml),
lang: query.lang.unwrap_or("en".to_string()),
available_dns_resolvers: derived_config.dns_resolver_selectables,
dns_resolver_id: dns_resolver_id,
});
next.run(req).await
@ -432,7 +419,7 @@ async fn not_found_handler(
let state = Arc::clone(&arc_state);
state.templating_engine.render_view(
&settings.template,
&settings,
&View::NotFound,
).await
}
@ -444,7 +431,7 @@ async fn hello_world_handler(
let state = Arc::clone(&arc_state);
state.templating_engine.render_view(
&settings.template,
&settings,
&View::Message{
title: "Hey There!".to_string(),
message: "You,You are an awesome Creature!".to_string()
@ -480,7 +467,7 @@ async fn handle_default_route(
}
}
let result = get_ip_result(&address, &settings.template.lang, &"default".to_string(), &state).await;
let result = get_ip_result(&address, &settings.lang, &"default".to_string(), &state).await;
let user_agent: Option<String> = match user_agent_header {
Some(TypedHeader(user_agent)) => Some(user_agent.to_string()),
@ -488,7 +475,7 @@ async fn handle_default_route(
};
state.templating_engine.render_view(
&settings.template,
&settings,
&View::Index{
result: result,
user_agent: user_agent,
@ -518,7 +505,7 @@ async fn handle_search_request(
// Render a dummy template that can at least link to other pages
let state = Arc::clone(&arc_state);
return state.templating_engine.render_view(
&settings.template,
&settings,
&View::Asn{asn: asn},
).await
}
@ -555,7 +542,7 @@ async fn handle_dns_resolver_route(
) -> Response {
let state = Arc::clone(&arc_state);
state.templating_engine.render_view(
&settings.template,
&settings,
&View::DnsResolverList,
).await
}
@ -569,12 +556,12 @@ async fn handle_dns_resolver_route_with_path(
let state = Arc::clone(&arc_state);
if let Some(resolver) = state.config.dns.resolver.get(&query) {
state.templating_engine.render_view(
&settings.template,
&settings,
&View::DnsResolver{ config: resolver.clone() },
).await
} else {
state.templating_engine.render_view(
&settings.template,
&settings,
&View::NotFound,
).await
}
@ -601,12 +588,12 @@ async fn handle_ip_request(
let state = Arc::clone(&arc_state);
let result = get_ip_result(
&address,
&settings.template.lang,
&settings.lang,
&settings.dns_resolver_id,
&state).await;
state.templating_engine.render_view(
&settings.template,
&settings,
&View::Ip{result: result}
).await
}
@ -695,7 +682,7 @@ async fn handle_dig_request(
).await;
state.templating_engine.render_view(
&settings.template,
&settings,
&View::Dig{ query: dig_query, result: dig_result}
).await

49
src/settings.rs Normal file
View File

@ -0,0 +1,49 @@
use serde::{Deserialize,Serialize};
/* Response format */
#[derive(Deserialize, Serialize, Clone, Copy)]
pub enum ResponseFormat {
#[serde(rename="text/plain", alias="text")]
TextPlain,
#[serde(rename="text/html", alias="html")]
TextHtml,
#[serde(rename="application/json", alias="json")]
ApplicationJson,
}
impl ToString for ResponseFormat {
fn to_string(&self) -> String {
match self {
ResponseFormat::TextPlain => "text/plain",
ResponseFormat::TextHtml => "text/html",
ResponseFormat::ApplicationJson => "application/json",
}.to_string()
}
}
impl ResponseFormat {
pub fn to_file_extension(&self) -> String {
match self {
ResponseFormat::TextPlain => ".txt",
ResponseFormat::TextHtml => ".html",
ResponseFormat::ApplicationJson => ".json",
}.to_string()
}
}
/* Query and Template Settings */
#[derive(Deserialize, Serialize, Clone)]
pub struct QuerySettings {
pub format: ResponseFormat,
pub lang: String,
pub available_dns_resolvers: Vec<Selectable>,
pub dns_resolver_id: String,
}
#[derive(Deserialize, Serialize, Clone)]
pub struct Selectable {
pub id: String,
pub name: String,
}

View File

@ -20,54 +20,8 @@ use toml::Table;
use crate::DigResult;
use crate::IpResult;
use crate::config::DnsResolverConfig;
use crate::settings::*;
/* Response format */
#[derive(serde::Deserialize, serde::Serialize, Clone, Copy)]
pub enum ResponseFormat {
#[serde(rename="text/plain", alias="text")]
TextPlain,
#[serde(rename="text/html", alias="html")]
TextHtml,
#[serde(rename="application/json", alias="json")]
ApplicationJson,
}
impl ToString for ResponseFormat {
fn to_string(&self) -> String {
match self {
ResponseFormat::TextPlain => "text/plain",
ResponseFormat::TextHtml => "text/html",
ResponseFormat::ApplicationJson => "application/json",
}.to_string()
}
}
impl ResponseFormat {
fn to_file_extension(&self) -> String {
match self {
ResponseFormat::TextPlain => ".txt",
ResponseFormat::TextHtml => ".html",
ResponseFormat::ApplicationJson => ".json",
}.to_string()
}
}
/* Template Settings */
#[derive(serde::Deserialize, serde::Serialize, Clone)]
pub struct TemplateSettings {
pub format: ResponseFormat,
pub lang: String,
pub available_dns_resolvers: Vec<Selectable>,
pub dns_resolver: String,
}
#[derive(serde::Deserialize, serde::Serialize, Clone)]
pub struct Selectable {
pub id: String,
pub name: String,
}
/* The echoip view */
@ -111,7 +65,7 @@ pub struct Engine {
impl Engine {
pub async fn render_view(
&self,
settings: &TemplateSettings,
settings: &QuerySettings,
view: &View,
) -> Response {
let mut response = match settings.format {
@ -124,7 +78,7 @@ impl Engine {
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);
context.insert("dns_resolver_id", &settings.dns_resolver_id);
context.insert("data", &view);
context.insert("extra", &self.template_config);
@ -166,7 +120,7 @@ impl Engine {
View::NotFound => *response.status_mut() = StatusCode::NOT_FOUND,
_ => {},
}
let cookie = Cookie::build("dns_resolver",settings.dns_resolver.clone())
let cookie = Cookie::build("dns_resolver",settings.dns_resolver_id.clone())
.path("/")
.same_site(cookie::SameSite::Strict)
.finish();