add: check for ip bans

This commit is contained in:
trisua 2025-07-25 18:33:16 -04:00
parent 06b0aa0b4c
commit 70adae5b66
9 changed files with 84 additions and 47 deletions

View file

@ -1,3 +1,5 @@
use std::env::var;
use crate::{
State,
model::{Entry, EntryMetadata},
@ -5,6 +7,7 @@ use crate::{
use axum::{
Extension, Json, Router,
extract::Path,
http::{HeaderMap, HeaderValue},
response::{Html, IntoResponse},
routing::{get, get_service, post},
};
@ -48,18 +51,15 @@ pub fn routes() -> Router {
fn default_context(data: &DataClient, build_code: &str) -> Context {
let mut ctx = Context::new();
ctx.insert(
"name",
&std::env::var("NAME").unwrap_or("Attobin".to_string()),
);
ctx.insert("name", &var("NAME").unwrap_or("Fluffle".to_string()));
ctx.insert(
"theme_color",
&std::env::var("THEME_COLOR").unwrap_or("#fbc27f".to_string()),
&var("THEME_COLOR").unwrap_or("#a3b3ff".to_string()),
);
ctx.insert("tetratto", &data.host);
ctx.insert(
"what_page_slug",
&std::env::var("WHAT_SLUG").unwrap_or("what".to_string()),
&var("WHAT_SLUG").unwrap_or("what".to_string()),
);
ctx.insert("build_code", &build_code);
ctx
@ -306,11 +306,27 @@ const CREATE_WAIT_TIME: usize = 5000;
async fn create_request(
jar: CookieJar,
headers: HeaderMap,
Extension(data): Extension<State>,
Json(req): Json<CreateEntry>,
) -> std::result::Result<impl IntoResponse, Json<ApiReturn<()>>> {
let (ref data, _, _) = *data.read().await;
// get real ip
let real_ip = headers
.get(var("REAL_IP_HEADER").unwrap_or("CF-Connecting-IP".to_string()))
.unwrap_or(&HeaderValue::from_static(""))
.to_str()
.unwrap_or("")
.to_string();
// check for ip ban
if !real_ip.is_empty() {
if data.check_ip(&real_ip.as_str()).await.is_ok() {
return Err(Json(Error::NotAllowed.into()));
}
}
// check wait time
if let Some(cookie) = jar.get("__Secure-Claim-Next") {
if unix_epoch_timestamp()
@ -394,6 +410,7 @@ async fn create_request(
edited: created,
content: req.content,
metadata: req.metadata,
last_edit_from: real_ip,
})
.unwrap(),
)
@ -441,12 +458,28 @@ struct EditEntry {
}
async fn edit_request(
headers: HeaderMap,
Extension(data): Extension<State>,
Path(slug): Path<String>,
Json(req): Json<EditEntry>,
) -> impl IntoResponse {
let (ref data, _, _) = *data.read().await;
// get real ip
let real_ip = headers
.get(var("REAL_IP_HEADER").unwrap_or("CF-Connecting-IP".to_string()))
.unwrap_or(&HeaderValue::from_static(""))
.to_str()
.unwrap_or("")
.to_string();
// check for ip ban
if !real_ip.is_empty() {
if data.check_ip(&real_ip.as_str()).await.is_ok() {
return Json(Error::NotAllowed.into());
}
}
// check content length
if req.content.len() < 2 {
return Json(Error::DataTooShort("content".to_string()).into());
@ -586,6 +619,7 @@ async fn edit_request(
// update
entry.content = req.content;
entry.metadata = req.metadata;
entry.last_edit_from = real_ip;
entry.edited = unix_epoch_timestamp();
if let Err(e) = data