add: check ip ban endpoint

This commit is contained in:
trisua 2025-07-23 14:44:47 -04:00
parent 8786cb4781
commit e78c43ab62
8 changed files with 68 additions and 6 deletions

2
Cargo.lock generated
View file

@ -3320,7 +3320,7 @@ dependencies = [
[[package]]
name = "tetratto-core"
version = "12.0.0"
version = "12.0.1"
dependencies = [
"async-recursion",
"base16ct",

View file

@ -72,6 +72,25 @@ export default function tetratto({
);
}
async function check_ip(ip) {
if (!api_key) {
throw Error("No API key provided.");
}
return api_promise(
json_parse(
await (
await fetch(`${host}/api/v1/bans/${ip}`, {
method: "GET",
headers: {
"Atto-Secret-Key": api_key,
},
})
).text(),
),
);
}
async function query(body) {
if (!api_key) {
throw Error("No API key provided.");
@ -285,6 +304,7 @@ export default function tetratto({
api_key,
// app data
app,
check_ip,
query,
insert,
update,

View file

@ -1,12 +1,34 @@
use crate::{
State, get_user_from_token,
get_app_from_key, get_user_from_token,
model::{ApiReturn, Error},
routes::api::v1::CreateIpBan,
State,
};
use axum::{Extension, Json, extract::Path, response::IntoResponse};
use axum::{extract::Path, http::HeaderMap, response::IntoResponse, Extension, Json};
use crate::cookie::CookieJar;
use tetratto_core::model::{addr::RemoteAddr, auth::IpBan, permissions::FinePermission};
/// Check if the given IP is banned.
pub async fn check_request(
headers: HeaderMap,
Path(ip): Path<String>,
Extension(data): Extension<State>,
) -> impl IntoResponse {
let data = &(data.read().await).0;
if get_app_from_key!(data, headers).is_none() {
return Json(Error::NotAllowed.into());
}
Json(ApiReturn {
ok: true,
message: "Success".to_string(),
payload: data
.get_ipban_by_addr(&RemoteAddr::from(ip.as_str()))
.await
.is_ok(),
})
}
/// Create a new IP ban.
pub async fn create_request(
jar: CookieJar,

View file

@ -495,6 +495,7 @@ pub fn routes() -> Router {
post(communities::communities::update_membership_role),
)
// ipbans
.route("/bans/{ip}", get(auth::ipbans::check_request))
.route("/bans/{ip}", post(auth::ipbans::create_request))
.route("/bans/{ip}", delete(auth::ipbans::delete_request))
// reports

View file

@ -1,7 +1,7 @@
[package]
name = "tetratto-core"
description = "The core behind Tetratto"
version = "12.0.0"
version = "12.0.1"
edition = "2024"
authors.workspace = true
repository.workspace = true

View file

@ -408,6 +408,10 @@ impl DataManager {
// check muted phrases
for phrase in receiver.settings.muted {
if phrase.is_empty() {
continue;
}
if data.content.contains(&phrase) {
// act like the question was created so theyre less likely to try and send it again or bypass
return Ok(0);

View file

@ -75,6 +75,22 @@ impl DataClient {
}
}
/// Check if the given IP is IP banned from the Tetratto host. You will only know
/// if the IP is banned or not, meaning you will not be shown the reason if it
/// is banned.
pub async fn check_ip(&self, ip: &str) -> Result<bool> {
match self
.http
.get(format!("{}/api/v1/bans/{}", self.host, ip))
.header("Atto-Secret-Key", &self.api_key)
.send()
.await
{
Ok(x) => api_return_ok!(bool, x),
Err(e) => Err(Error::MiscError(e.to_string())),
}
}
/// Query the app's data.
pub async fn query(&self, query: &SimplifiedQuery) -> Result<AppDataQueryResult> {
match self

View file

@ -31,9 +31,8 @@ pub fn clean_html(html: String, allowed_attributes: HashSet<&str>) -> String {
.rm_tags(&["script", "style", "link", "canvas"])
.add_tag_attributes("a", &["href", "target"])
.add_url_schemes(&["atto"])
.clean(&html)
.clean(&html.replace("<video ", "<video controls "))
.to_string()
.replace("<video loading=", "<video controls loading=")
}
/// Render markdown input into HTML