diff --git a/config/config.hjson b/config/config.hjson index 7c73aaafa..8d2ae84c7 100644 --- a/config/config.hjson +++ b/config/config.hjson @@ -5,4 +5,8 @@ federation: { enabled: true } + slur_filter: + ''' + (fag(g|got|tard)?\b|cock\s?sucker(s|ing)?|ni((g{2,}|q)+|[gq]{2,})[e3r]+(s|z)?|mudslime?s?|kikes?|\bspi(c|k)s?\b|\bchinks?|gooks?|bitch(es|ing|y)?|whor(es?|ing)|\btr(a|@)nn?(y|ies?)|\b(b|re|r)tard(ed)?s?) + ''' } diff --git a/config/defaults.hjson b/config/defaults.hjson index 6907c36ff..ff6df36da 100644 --- a/config/defaults.hjson +++ b/config/defaults.hjson @@ -104,8 +104,7 @@ tls_enabled: true # Address where pictrs is available (for image hosting) pictrs_url: "http:#localhost:8080" - # Regex for slurs which are prohibited. Example: `(\bThis\b)|(\bis\b)|(\bsample\b)` - additional_slurs: "string" + slur_filter: "(\bThis\b)|(\bis\b)|(\bsample\b)" # Maximum length of local community and user names actor_name_max_length: 20 } diff --git a/crates/utils/src/settings/mod.rs b/crates/utils/src/settings/mod.rs index 40dd91664..e7bd5eb0e 100644 --- a/crates/utils/src/settings/mod.rs +++ b/crates/utils/src/settings/mod.rs @@ -113,15 +113,12 @@ impl Settings { WEBFINGER_USER_REGEX.to_owned() } - pub fn slur_regex(&self) -> Regex { - let mut slurs = r"(fag(g|got|tard)?\b|cock\s?sucker(s|ing)?|ni((g{2,}|q)+|[gq]{2,})[e3r]+(s|z)?|mudslime?s?|kikes?|\bspi(c|k)s?\b|\bchinks?|gooks?|bitch(es|ing|y)?|whor(es?|ing)|\btr(a|@)nn?(y|ies?)|\b(b|re|r)tard(ed)?s?)".to_string(); - if let Some(additional_slurs) = &self.additional_slurs { - slurs.push('|'); - slurs.push_str(additional_slurs); - }; - RegexBuilder::new(&slurs) - .case_insensitive(true) - .build() - .expect("compile regex") + pub fn slur_regex(&self) -> Option { + self.slur_filter.as_ref().map(|slurs| { + RegexBuilder::new(slurs) + .case_insensitive(true) + .build() + .expect("compile regex") + }) } } diff --git a/crates/utils/src/settings/structs.rs b/crates/utils/src/settings/structs.rs index 4ec17906b..300030816 100644 --- a/crates/utils/src/settings/structs.rs +++ b/crates/utils/src/settings/structs.rs @@ -40,9 +40,9 @@ pub struct Settings { #[default(None)] #[doku(example = "http://localhost:8080")] pub pictrs_url: Option, - /// Regex for slurs which are prohibited. Example: `(\bThis\b)|(\bis\b)|(\bsample\b)` #[default(None)] - pub additional_slurs: Option, + #[doku(example = "(\\bThis\\b)|(\\bis\\b)|(\\bsample\\b)")] + pub slur_filter: Option, /// Maximum length of local community and user names #[default(20)] pub actor_name_max_length: usize, diff --git a/crates/utils/src/utils.rs b/crates/utils/src/utils.rs index 96dc340e4..3039a1cd4 100644 --- a/crates/utils/src/utils.rs +++ b/crates/utils/src/utils.rs @@ -28,30 +28,44 @@ pub fn convert_datetime(datetime: NaiveDateTime) -> DateTime { DateTime::::from_utc(datetime, FixedOffset::east(0)) } -pub fn remove_slurs(test: &str, slur_regex: &Regex) -> String { - slur_regex.replace_all(test, "*removed*").to_string() -} - -pub(crate) fn slur_check<'a>(test: &'a str, slur_regex: &'a Regex) -> Result<(), Vec<&'a str>> { - let mut matches: Vec<&str> = slur_regex.find_iter(test).map(|mat| mat.as_str()).collect(); - - // Unique - matches.sort_unstable(); - matches.dedup(); - - if matches.is_empty() { - Ok(()) +pub fn remove_slurs(test: &str, slur_regex: &Option) -> String { + if let Some(slur_regex) = slur_regex { + slur_regex.replace_all(test, "*removed*").to_string() } else { - Err(matches) + test.to_string() } } -pub fn check_slurs(text: &str, slur_regex: &Regex) -> Result<(), ApiError> { - slur_check(text, slur_regex) - .map_err(|slurs| ApiError::err_plain(&slurs_vec_to_str(slurs.clone()))) +pub(crate) fn slur_check<'a>( + test: &'a str, + slur_regex: &'a Option, +) -> Result<(), Vec<&'a str>> { + if let Some(slur_regex) = slur_regex { + let mut matches: Vec<&str> = slur_regex.find_iter(test).map(|mat| mat.as_str()).collect(); + + // Unique + matches.sort_unstable(); + matches.dedup(); + + if matches.is_empty() { + Ok(()) + } else { + Err(matches) + } + } else { + Ok(()) + } } -pub fn check_slurs_opt(text: &Option, slur_regex: &Regex) -> Result<(), ApiError> { +pub fn check_slurs(text: &str, slur_regex: &Option) -> Result<(), ApiError> { + if let Err(slurs) = slur_check(text, slur_regex) { + Err(ApiError::err_plain(&slurs_vec_to_str(slurs))) + } else { + Ok(()) + } +} + +pub fn check_slurs_opt(text: &Option, slur_regex: &Option) -> Result<(), ApiError> { match text { Some(t) => check_slurs(t, slur_regex), None => Ok(()), diff --git a/docker/lemmy.hjson b/docker/lemmy.hjson index 4c42d8aea..54975feca 100644 --- a/docker/lemmy.hjson +++ b/docker/lemmy.hjson @@ -34,6 +34,10 @@ # maximum number of active sql connections pool_size: 5 } + slur_filter: + ''' + (fag(g|got|tard)?\b|cock\s?sucker(s|ing)?|ni((g{2,}|q)+|[gq]{2,})[e3r]+(s|z)?|mudslime?s?|kikes?|\bspi(c|k)s?\b|\bchinks?|gooks?|bitch(es|ing|y)?|whor(es?|ing)|\btr(a|@)nn?(y|ies?)|\b(b|re|r)tard(ed)?s?) + ''' # # optional: email sending configuration # email: { # # hostname and port of the smtp server