fix: don't allow mention spam

add: ip banning, ip ban management page
This commit is contained in:
trisua 2025-04-03 11:22:56 -04:00
parent 131a38abb9
commit e52733b00c
14 changed files with 260 additions and 15 deletions

View file

@ -2,7 +2,7 @@ use super::*;
use crate::cache::Cache;
use crate::model::moderation::AuditLogEntry;
use crate::model::{Error, Result, auth::IpBan, auth::User, permissions::FinePermission};
use crate::{auto_method, execute, get, query_row};
use crate::{auto_method, execute, get, query_row, query_rows};
#[cfg(feature = "sqlite")]
use rusqlite::Row;
@ -26,7 +26,32 @@ impl DataManager {
auto_method!(get_ipban_by_ip(&str)@get_ipban_from_row -> "SELECT * FROM ipbans WHERE ip = $1" --name="ip ban" --returns=IpBan --cache-key-tmpl="atto.ipban:{}");
/// Create a new user block in the database.
/// Get all IP bans (paginated).
///
/// # Arguments
/// * `batch` - the limit of items in each page
/// * `page` - the page number
pub async fn get_ipbans(&self, batch: usize, page: usize) -> Result<Vec<IpBan>> {
let conn = match self.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
};
let res = query_rows!(
&conn,
"SELECT * FROM ipbans ORDER BY created DESC LIMIT $1 OFFSET $2",
&[&(batch as isize), &((page * batch) as isize)],
|x| { Self::get_ipban_from_row(x) }
);
if res.is_err() {
return Err(Error::GeneralNotFound("ip ban".to_string()));
}
Ok(res.unwrap())
}
/// Create a new IP ban in the database.
///
/// # Arguments
/// * `data` - a mock [`IpBan`] object to insert

View file

@ -1,3 +1,5 @@
use std::collections::HashMap;
use super::*;
use crate::cache::Cache;
use crate::model::auth::Notification;
@ -314,17 +316,27 @@ impl DataManager {
}
// send mention notifications
let mut already_notified: HashMap<String, User> = HashMap::new();
for username in User::parse_mentions(&data.content) {
let user = self.get_user_by_username(&username).await?;
self.create_notification(Notification::new(
"You've been mentioned in a post!".to_string(),
format!(
"[Somebody](/api/v1/auth/profile/find/{}) mentioned you in their [post](/post/{}).",
data.owner, data.id
),
user.id,
))
.await?;
let user = {
if let Some(ua) = already_notified.get(&username) {
ua.to_owned()
} else {
let user = self.get_user_by_username(&username).await?;
self.create_notification(Notification::new(
"You've been mentioned in a post!".to_string(),
format!(
"[Somebody](/api/v1/auth/profile/find/{}) mentioned you in their [post](/post/{}).",
data.owner, data.id
),
user.id,
))
.await?;
already_notified.insert(username.to_owned(), user.clone());
user
}
};
data.content = data.content.replace(
&format!("@{username}"),
&format!("[@{username}](/api/v1/auth/profile/find/{})", user.id),