2020-09-05 03:24:04 +00:00
|
|
|
use blocking::unblock;
|
|
|
|
use futures_lite::*;
|
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
use sled::Db;
|
2020-09-09 01:26:40 +00:00
|
|
|
use tide::log::{self, LogMiddleware};
|
2020-09-05 03:24:04 +00:00
|
|
|
|
|
|
|
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
|
|
|
|
|
|
|
|
mod iptables;
|
|
|
|
mod rules;
|
|
|
|
mod startup;
|
|
|
|
|
2020-09-09 01:26:40 +00:00
|
|
|
use self::{rules::Rule, startup::Interfaces, templates::statics::StaticFile};
|
2020-09-05 03:24:04 +00:00
|
|
|
|
|
|
|
static INTERFACES: Lazy<Interfaces> = Lazy::new(|| {
|
|
|
|
let interfaces = Interfaces::init_blocking().unwrap();
|
|
|
|
interfaces.reset_blocking().unwrap();
|
|
|
|
interfaces
|
|
|
|
});
|
|
|
|
|
|
|
|
static DB: Lazy<Db> = Lazy::new(|| sled::open("router-db-0-34-3").unwrap());
|
|
|
|
|
2020-09-09 01:26:40 +00:00
|
|
|
static QS: Lazy<serde_qs::Config> = Lazy::new(|| serde_qs::Config::new(3, false));
|
|
|
|
|
2020-09-05 03:24:04 +00:00
|
|
|
async fn rules_page(_: tide::Request<()>) -> tide::Result {
|
|
|
|
let mut html = Vec::new();
|
|
|
|
|
|
|
|
let rules = unblock(move || rules::read(&DB)).await?;
|
|
|
|
|
|
|
|
templates::rules(&mut html, &rules)?;
|
|
|
|
|
|
|
|
Ok(tide::Response::builder(200)
|
|
|
|
.body(html)
|
|
|
|
.content_type(
|
|
|
|
"text/html;charset=utf-8"
|
|
|
|
.parse::<tide::http::Mime>()
|
|
|
|
.unwrap(),
|
|
|
|
)
|
|
|
|
.build())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn save_rule(mut req: tide::Request<()>) -> tide::Result {
|
2020-09-09 01:26:40 +00:00
|
|
|
let body_string = req.body_string().await?;
|
|
|
|
|
|
|
|
let rule: Rule = QS.deserialize_str(&body_string)?;
|
|
|
|
|
|
|
|
rules::save(&DB, &rule).await?;
|
2020-09-05 03:24:04 +00:00
|
|
|
|
|
|
|
rules::apply(&INTERFACES, rule).await?;
|
|
|
|
|
|
|
|
Ok(to_rules_page())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn delete_rule(req: tide::Request<()>) -> tide::Result {
|
|
|
|
let id = req.param("id")?;
|
2020-09-09 01:26:40 +00:00
|
|
|
let rule = rules::delete(&DB, id).await?;
|
2020-09-05 03:24:04 +00:00
|
|
|
rules::unset(&INTERFACES, rule).await?;
|
|
|
|
|
|
|
|
Ok(to_rules_page())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_rules_page() -> tide::Response {
|
|
|
|
tide::Response::builder(301)
|
|
|
|
.header("Location", "/rules")
|
|
|
|
.build()
|
|
|
|
}
|
|
|
|
|
2020-09-09 01:26:40 +00:00
|
|
|
async fn statics(req: tide::Request<()>) -> tide::Result {
|
|
|
|
let file: String = req.param("file")?;
|
|
|
|
|
|
|
|
if let Some(data) = StaticFile::get(&file) {
|
|
|
|
Ok(tide::Response::builder(200)
|
|
|
|
.header("Content-Type", data.mime.to_string())
|
|
|
|
.body(data.content)
|
|
|
|
.build())
|
|
|
|
} else {
|
|
|
|
Ok(tide::Response::builder(404).build())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-05 03:24:04 +00:00
|
|
|
fn main() -> Result<(), anyhow::Error> {
|
|
|
|
future::block_on(async {
|
|
|
|
println!("Hello, world!");
|
|
|
|
|
2020-09-09 01:26:40 +00:00
|
|
|
log::with_level(log::LevelFilter::Debug);
|
|
|
|
|
2020-09-05 03:24:04 +00:00
|
|
|
rules::apply_all(&DB, &INTERFACES).await?;
|
|
|
|
|
|
|
|
let mut app = tide::new();
|
2020-09-09 01:26:40 +00:00
|
|
|
app.with(LogMiddleware::new());
|
|
|
|
app.at("/static/:file").get(statics);
|
2020-09-05 03:24:04 +00:00
|
|
|
app.at("/rules").get(rules_page).post(save_rule);
|
2020-09-09 01:26:40 +00:00
|
|
|
app.at("/rules/:id").get(delete_rule);
|
2020-09-05 03:24:04 +00:00
|
|
|
|
|
|
|
let listeners: Vec<String> = INTERFACES
|
|
|
|
.internal
|
|
|
|
.iter()
|
|
|
|
.map(|info| format!("{}:8080", info.ip))
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
app.listen(listeners).await?;
|
|
|
|
|
|
|
|
Ok(()) as Result<(), anyhow::Error>
|
|
|
|
})?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|