From c9983b8dcb0654716a9bdf9f2ea0db21c55c8bab Mon Sep 17 00:00:00 2001 From: trisua Date: Mon, 2 Jun 2025 16:36:06 -0400 Subject: [PATCH] add: ability to ban strings/characters through server config --- crates/core/src/config.rs | 22 ++++++++++++++++++++++ crates/core/src/database/posts.rs | 20 ++++++++++++++++++++ example/tetratto.toml | 6 ++++++ 3 files changed, 48 insertions(+) diff --git a/crates/core/src/config.rs b/crates/core/src/config.rs index d1789e7..c0dece2 100644 --- a/crates/core/src/config.rs +++ b/crates/core/src/config.rs @@ -211,6 +211,20 @@ impl Default for ManualsConfig { } } +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] +pub enum StringBan { + /// An exact string. + String(String), + /// A unicode codepoint. + Unicode(u32), +} + +impl Default for StringBan { + fn default() -> Self { + Self::String(String::new()) + } +} + /// Configuration file #[derive(Clone, Serialize, Deserialize, Debug)] pub struct Config { @@ -277,6 +291,9 @@ pub struct Config { /// The relative paths to manuals. #[serde(default)] pub manuals: ManualsConfig, + /// A list of banned content in posts. + #[serde(default)] + pub banned_data: Vec, } fn default_name() -> String { @@ -353,6 +370,10 @@ fn default_manuals() -> ManualsConfig { ManualsConfig::default() } +fn default_banned_data() -> Vec { + Vec::new() +} + impl Default for Config { fn default() -> Self { Self { @@ -374,6 +395,7 @@ impl Default for Config { html_footer_path: String::new(), stripe: None, manuals: default_manuals(), + banned_data: default_banned_data(), } } } diff --git a/crates/core/src/database/posts.rs b/crates/core/src/database/posts.rs index b9cc171..55843e2 100644 --- a/crates/core/src/database/posts.rs +++ b/crates/core/src/database/posts.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use super::*; use crate::cache::Cache; +use crate::config::StringBan; use crate::model::auth::Notification; use crate::model::communities::Question; use crate::model::communities_permissions::CommunityPermission; @@ -1153,6 +1154,25 @@ impl DataManager { /// # Arguments /// * `data` - a mock [`Post`] object to insert pub async fn create_post(&self, mut data: Post) -> Result { + // check characters + for ban in &self.0.banned_data { + match ban { + StringBan::String(x) => { + if data.content.contains(x) { + return Ok(0); + } + } + StringBan::Unicode(x) => { + if data.content.contains(&match char::from_u32(x.to_owned()) { + Some(c) => c.to_string(), + None => continue, + }) { + return Ok(0); + } + } + } + } + // check values (if this isn't reposting something else) let is_reposting = if let Some(ref repost) = data.context.repost { repost.reposting.is_some() diff --git a/example/tetratto.toml b/example/tetratto.toml index 837924b..37119a4 100644 --- a/example/tetratto.toml +++ b/example/tetratto.toml @@ -43,3 +43,9 @@ privacy = "/public/privacy.html" [turnstile] site_key = "1x00000000000000000000AA" secret_key = "1x0000000000000000000000000000000AA" + +[[banned_data]] +String = "test banned string" + +[[banned_data]] +Unicode = 3662