feat(safety): implement report content API

This commit is contained in:
Paul Makles
2023-02-21 12:38:35 +01:00
parent 49598daf70
commit 056c0380b2
17 changed files with 284 additions and 23 deletions

View File

@@ -1,25 +1,13 @@
use revolt_quark::models::User;
use revolt_quark::models::report::ReportedContent;
use revolt_quark::models::snapshot::{Snapshot, SnapshotContent};
use revolt_quark::models::{Report, User};
use revolt_quark::{Db, Error, Result};
use serde::Deserialize;
use ulid::Ulid;
use validator::Validate;
use rocket::serde::json::Json;
#[derive(Deserialize, JsonSchema)]
enum UserReportReason {
NoneSpecified,
InappropriateProfile,
}
// TODO: move me into models
#[derive(Deserialize, JsonSchema)]
pub enum ReportedContent {
User {
id: String,
report_reason: UserReportReason,
},
}
/// # Report Data
#[derive(Validate, Deserialize, JsonSchema)]
pub struct DataReportContent {
@@ -46,7 +34,76 @@ pub async fn report_content(db: &Db, user: User, data: Json<DataReportContent>)
return Err(Error::IsBot);
}
// find the content and create the report here
// Find the content and create a snapshot of it
// Also retrieve any references to Files
let (content, files): (SnapshotContent, Vec<String>) = match &data.content {
ReportedContent::Message { id, .. } => {
let message = db.fetch_message(id).await?;
// Collect message attachments
let files = message
.attachments
.as_ref()
.map(|attachments| attachments.iter().map(|x| x.id.to_string()).collect())
.unwrap_or_default();
(SnapshotContent::Message(message), files)
}
ReportedContent::Server { id, .. } => {
let server = db.fetch_server(id).await?;
// Collect server's icon and banner
let files = [&server.icon, &server.banner]
.iter()
.filter_map(|x| x.as_ref().map(|x| x.id.to_string()))
.collect();
(SnapshotContent::Server(server), files)
}
ReportedContent::User { id, .. } => {
let user = db.fetch_user(id).await?;
// Collect user's avatar and profile background
let files = [
user.avatar.as_ref(),
user.profile
.as_ref()
.and_then(|profile| profile.background.as_ref()),
]
.iter()
.filter_map(|x| x.as_ref().map(|x| x.id.to_string()))
.collect();
(SnapshotContent::User(user), files)
}
};
// Mark all the attachments as reported
for file in files {
db.mark_attachment_as_reported(&file).await?;
}
// Generate an id for the report
let id = Ulid::new().to_string();
// Save a snapshot of the content
let snapshot = Snapshot {
id: Ulid::new().to_string(),
report_id: id.to_string(),
content,
};
db.insert_snapshot(&snapshot).await?;
// Save the report
let report = Report {
id,
author_id: user.id,
content: data.content,
additional_context: data.additional_context,
};
db.insert_report(&report).await?;
Ok(())
}