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;
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) {
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};
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;
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) {
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;
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;
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
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> {
#[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() {
#[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]