feat: filter reports on fetch
This commit is contained in:
@@ -1,17 +1,61 @@
|
|||||||
|
use revolt_quark::models::report::{ReportStatus, ReportStatusString, ReportedContent};
|
||||||
use revolt_quark::models::{Report, User};
|
use revolt_quark::models::{Report, User};
|
||||||
use revolt_quark::{Db, Error, Result};
|
use revolt_quark::{Db, Error, Result};
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
/// # Query Parameters
|
||||||
|
#[derive(Deserialize, JsonSchema, FromForm)]
|
||||||
|
pub struct OptionsFetchReports {
|
||||||
|
/// Find reports against messages, servers, or users
|
||||||
|
content_id: Option<String>,
|
||||||
|
|
||||||
|
/// Find reports created by user
|
||||||
|
author_id: Option<String>,
|
||||||
|
|
||||||
|
/// Report status to include in search
|
||||||
|
status: Option<ReportStatusString>,
|
||||||
|
}
|
||||||
|
|
||||||
/// # Fetch Reports
|
/// # Fetch Reports
|
||||||
///
|
///
|
||||||
/// Fetch all available reports
|
/// Fetch all available reports
|
||||||
#[openapi(tag = "User Safety")]
|
#[openapi(tag = "User Safety")]
|
||||||
#[get("/reports")]
|
#[get("/reports?<options..>")]
|
||||||
pub async fn fetch_reports(db: &Db, user: User) -> Result<Json<Vec<Report>>> {
|
pub async fn fetch_reports(
|
||||||
|
db: &Db,
|
||||||
|
user: User,
|
||||||
|
options: OptionsFetchReports,
|
||||||
|
) -> Result<Json<Vec<Report>>> {
|
||||||
// Must be privileged for this route
|
// Must be privileged for this route
|
||||||
if !user.privileged {
|
if !user.privileged {
|
||||||
return Err(Error::NotPrivileged);
|
return Err(Error::NotPrivileged);
|
||||||
}
|
}
|
||||||
|
|
||||||
db.fetch_reports().await.map(Json)
|
let mut reports = db.fetch_reports().await?;
|
||||||
|
|
||||||
|
if let Some(content_id) = options.content_id {
|
||||||
|
reports.retain(|report| match &report.content {
|
||||||
|
ReportedContent::Message { id, .. }
|
||||||
|
| ReportedContent::Server { id, .. }
|
||||||
|
| ReportedContent::User { id, .. } => id == &content_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(author_id) = options.author_id {
|
||||||
|
reports.retain(|report| report.author_id == author_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(status) = options.status {
|
||||||
|
reports.retain(|report| {
|
||||||
|
matches!(
|
||||||
|
(&status, &report.status),
|
||||||
|
(ReportStatusString::Created, ReportStatus::Created { .. })
|
||||||
|
| (ReportStatusString::Rejected, ReportStatus::Rejected { .. })
|
||||||
|
| (ReportStatusString::Resolved, ReportStatus::Resolved { .. })
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Json(reports))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,30 @@
|
|||||||
use crate::{models::report::PartialReport, models::Report, Database, Result};
|
use iso8601_timestamp::Timestamp;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
models::report::PartialReport,
|
||||||
|
models::{report::ReportStatus, Report},
|
||||||
|
Database, Result,
|
||||||
|
};
|
||||||
|
|
||||||
impl Report {
|
impl Report {
|
||||||
/// Update report data
|
/// Update report data
|
||||||
pub async fn update(&mut self, db: &Database, partial: PartialReport) -> Result<()> {
|
pub async fn update(&mut self, db: &Database, partial: PartialReport) -> Result<()> {
|
||||||
self.apply_options(partial.clone());
|
self.apply_options(partial.clone());
|
||||||
|
|
||||||
|
match &mut self.status {
|
||||||
|
ReportStatus::Created {} => {}
|
||||||
|
ReportStatus::Rejected { closed_at, .. } => {
|
||||||
|
if closed_at.is_none() {
|
||||||
|
closed_at.replace(Timestamp::now_utc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReportStatus::Resolved { closed_at } => {
|
||||||
|
if closed_at.is_none() {
|
||||||
|
closed_at.replace(Timestamp::now_utc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
db.update_report(&self.id, &partial).await
|
db.update_report(&self.id, &partial).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use iso8601_timestamp::Timestamp;
|
use iso8601_timestamp::Timestamp;
|
||||||
|
use rocket::FromFormField;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Reason for reporting content (message or server)
|
/// Reason for reporting content (message or server)
|
||||||
@@ -119,6 +120,19 @@ pub enum ReportStatus {
|
|||||||
Resolved { closed_at: Option<Timestamp> },
|
Resolved { closed_at: Option<Timestamp> },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Just the status of the report
|
||||||
|
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, FromFormField)]
|
||||||
|
pub enum ReportStatusString {
|
||||||
|
/// Report is waiting for triage / action
|
||||||
|
Created,
|
||||||
|
|
||||||
|
/// Report was rejected
|
||||||
|
Rejected,
|
||||||
|
|
||||||
|
/// Report was actioned and resolved
|
||||||
|
Resolved,
|
||||||
|
}
|
||||||
|
|
||||||
/// User-generated platform moderation report.
|
/// User-generated platform moderation report.
|
||||||
#[derive(Serialize, Deserialize, JsonSchema, Debug, OptionalStruct, Clone)]
|
#[derive(Serialize, Deserialize, JsonSchema, Debug, OptionalStruct, Clone)]
|
||||||
#[optional_derive(Serialize, Deserialize, JsonSchema, Debug, Default, Clone)]
|
#[optional_derive(Serialize, Deserialize, JsonSchema, Debug, Default, Clone)]
|
||||||
|
|||||||
Reference in New Issue
Block a user