]> Untitled Git - lemmy.git/commitdiff
Returning specific slurs from slur filter on failure. Fixes #463
authorDessalines <tyhou13@gmx.com>
Mon, 3 Feb 2020 03:51:54 +0000 (22:51 -0500)
committerDessalines <tyhou13@gmx.com>
Mon, 3 Feb 2020 03:51:54 +0000 (22:51 -0500)
server/src/api/community.rs
server/src/api/mod.rs
server/src/api/post.rs
server/src/api/site.rs
server/src/api/user.rs
server/src/lib.rs

index 80cc2b65acecb4050661a4987ed4d21934509ef1..936e54cda33212c9fbb7de0cdf6f20fc7db0caaf 100644 (file)
@@ -176,11 +176,18 @@ impl Perform<CommunityResponse> for Oper<CreateCommunity> {
       Err(_e) => return Err(APIError::err("not_logged_in").into()),
     };
 
-    if has_slurs(&data.name)
-      || has_slurs(&data.title)
-      || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
-    {
-      return Err(APIError::err("no_slurs").into());
+    if let Err(slurs) = slur_check(&data.name) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Err(slurs) = slur_check(&data.title) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Some(description) = &data.description {
+      if let Err(slurs) = slur_check(description) {
+        return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+      }
     }
 
     let user_id = claims.id;
@@ -242,8 +249,18 @@ impl Perform<CommunityResponse> for Oper<EditCommunity> {
   fn perform(&self, conn: &PgConnection) -> Result<CommunityResponse, Error> {
     let data: &EditCommunity = &self.data;
 
-    if has_slurs(&data.name) || has_slurs(&data.title) {
-      return Err(APIError::err("no_slurs").into());
+    if let Err(slurs) = slur_check(&data.name) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Err(slurs) = slur_check(&data.title) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Some(description) = &data.description {
+      if let Err(slurs) = slur_check(description) {
+        return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+      }
     }
 
     let claims = match Claims::decode(&data.auth) {
index cb09d7fa0344e6ace36ec972d2bf46d812bf5071..155c706af05f689f89b8d047ceea1f2776647429 100644 (file)
@@ -17,7 +17,9 @@ use crate::db::user_mention::*;
 use crate::db::user_mention_view::*;
 use crate::db::user_view::*;
 use crate::db::*;
-use crate::{extract_usernames, has_slurs, naive_from_unix, naive_now, remove_slurs};
+use crate::{
+  extract_usernames, naive_from_unix, naive_now, remove_slurs, slur_check, slurs_vec_to_str,
+};
 use diesel::PgConnection;
 use failure::Error;
 use serde::{Deserialize, Serialize};
index 086705bced93fde5ebb8f937e219b0cad9a76de3..bd276be5a56aa310fe8dc4b235e2ede7ed6e972d 100644 (file)
@@ -88,8 +88,14 @@ impl Perform<PostResponse> for Oper<CreatePost> {
       Err(_e) => return Err(APIError::err("not_logged_in").into()),
     };
 
-    if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) {
-      return Err(APIError::err("no_slurs").into());
+    if let Err(slurs) = slur_check(&data.name) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Some(body) = &data.body {
+      if let Err(slurs) = slur_check(body) {
+        return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+      }
     }
 
     let user_id = claims.id;
@@ -298,8 +304,15 @@ impl Perform<PostResponse> for Oper<CreatePostLike> {
 impl Perform<PostResponse> for Oper<EditPost> {
   fn perform(&self, conn: &PgConnection) -> Result<PostResponse, Error> {
     let data: &EditPost = &self.data;
-    if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) {
-      return Err(APIError::err("no_slurs").into());
+
+    if let Err(slurs) = slur_check(&data.name) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Some(body) = &data.body {
+      if let Err(slurs) = slur_check(body) {
+        return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+      }
     }
 
     let claims = match Claims::decode(&data.auth) {
index dfbd5ff041ea66a83bf2fd8c3c1cd138b4cdf1bd..ef1a28287617575a82c23c46faf9e4e986be7314 100644 (file)
@@ -186,10 +186,14 @@ impl Perform<SiteResponse> for Oper<CreateSite> {
       Err(_e) => return Err(APIError::err("not_logged_in").into()),
     };
 
-    if has_slurs(&data.name)
-      || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
-    {
-      return Err(APIError::err("no_slurs").into());
+    if let Err(slurs) = slur_check(&data.name) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Some(description) = &data.description {
+      if let Err(slurs) = slur_check(description) {
+        return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+      }
     }
 
     let user_id = claims.id;
@@ -229,10 +233,14 @@ impl Perform<SiteResponse> for Oper<EditSite> {
       Err(_e) => return Err(APIError::err("not_logged_in").into()),
     };
 
-    if has_slurs(&data.name)
-      || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
-    {
-      return Err(APIError::err("no_slurs").into());
+    if let Err(slurs) = slur_check(&data.name) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+    }
+
+    if let Some(description) = &data.description {
+      if let Err(slurs) = slur_check(description) {
+        return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
+      }
     }
 
     let user_id = claims.id;
index 0b1abb68efe36d17ca0205285a68355652ca8a35..99072a749f0e44c0ac5827bbe867e5c482742894 100644 (file)
@@ -240,8 +240,8 @@ impl Perform<LoginResponse> for Oper<Register> {
       return Err(APIError::err("passwords_dont_match").into());
     }
 
-    if has_slurs(&data.username) {
-      return Err(APIError::err("no_slurs").into());
+    if let Err(slurs) = slur_check(&data.username) {
+      return Err(APIError::err(&slurs_vec_to_str(slurs)).into());
     }
 
     // Make sure there are no admins
index a9bd5dac7d3d2282cfcb77e29e5fded219197917..2e6b6fd6e17ea7d895d0386b11d8644032085fa3 100644 (file)
@@ -62,8 +62,24 @@ pub fn remove_slurs(test: &str) -> String {
   SLUR_REGEX.replace_all(test, "*removed*").to_string()
 }
 
-pub fn has_slurs(test: &str) -> bool {
-  SLUR_REGEX.is_match(test)
+pub fn slur_check(test: &str) -> Result<(), Vec<&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(())
+  } else {
+    Err(matches)
+  }
+}
+
+pub fn slurs_vec_to_str(slurs: Vec<&str>) -> String {
+  let start = "No slurs - ";
+  let combined = &slurs.join(", ");
+  [start, combined].concat()
 }
 
 pub fn extract_usernames(test: &str) -> Vec<&str> {
@@ -127,7 +143,7 @@ pub fn send_email(
 
 #[cfg(test)]
 mod tests {
-  use crate::{extract_usernames, has_slurs, is_email_regex, remove_slurs};
+  use crate::{extract_usernames, is_email_regex, remove_slurs, slur_check, slurs_vec_to_str};
 
   #[test]
   fn test_email() {
@@ -138,15 +154,29 @@ mod tests {
   #[test]
   fn test_slur_filter() {
     let test =
-      "coons test dindu ladyboy tranny retardeds. Capitalized Niggerz. This is a bunch of other safe text.".to_string();
+      "coons test dindu ladyboy tranny retardeds. Capitalized Niggerz. This is a bunch of other safe text.";
     let slur_free = "No slurs here";
     assert_eq!(
       remove_slurs(&test),
       "*removed* test *removed* *removed* *removed* *removed*. Capitalized *removed*. This is a bunch of other safe text."
         .to_string()
     );
-    assert!(has_slurs(&test));
-    assert!(!has_slurs(slur_free));
+
+    let has_slurs_vec = vec![
+      "Niggerz",
+      "coons",
+      "dindu",
+      "ladyboy",
+      "retardeds",
+      "tranny",
+    ];
+    let has_slurs_err_str = "No slurs - Niggerz, coons, dindu, ladyboy, retardeds, tranny";
+
+    assert_eq!(slur_check(test), Err(has_slurs_vec));
+    assert_eq!(slur_check(slur_free), Ok(()));
+    if let Err(slur_vec) = slur_check(test) {
+      assert_eq!(&slurs_vec_to_str(slur_vec), has_slurs_err_str);
+    }
   }
 
   #[test]