feat(safety): fetch reports and fetch snapshot API
This commit is contained in:
17
crates/delta/src/routes/safety/fetch_reports.rs
Normal file
17
crates/delta/src/routes/safety/fetch_reports.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
use revolt_quark::models::{Report, User};
|
||||||
|
use revolt_quark::{Db, Error, Result};
|
||||||
|
use rocket::serde::json::Json;
|
||||||
|
|
||||||
|
/// # Fetch Reports
|
||||||
|
///
|
||||||
|
/// Fetch all available reports
|
||||||
|
#[openapi(tag = "User Safety")]
|
||||||
|
#[get("/reports")]
|
||||||
|
pub async fn fetch_reports(db: &Db, user: User) -> Result<Json<Vec<Report>>> {
|
||||||
|
// Must be privileged for this route
|
||||||
|
if !user.privileged {
|
||||||
|
return Err(Error::NotPrivileged);
|
||||||
|
}
|
||||||
|
|
||||||
|
db.fetch_reports().await.map(Json)
|
||||||
|
}
|
||||||
17
crates/delta/src/routes/safety/fetch_snapshot.rs
Normal file
17
crates/delta/src/routes/safety/fetch_snapshot.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
use revolt_quark::models::{Snapshot, User};
|
||||||
|
use revolt_quark::{Db, Error, Result};
|
||||||
|
use rocket::serde::json::Json;
|
||||||
|
|
||||||
|
/// # Fetch Snapshot
|
||||||
|
///
|
||||||
|
/// Fetch a snapshot for a given report
|
||||||
|
#[openapi(tag = "User Safety")]
|
||||||
|
#[get("/snapshot/<report_id>")]
|
||||||
|
pub async fn fetch_snapshot(db: &Db, user: User, report_id: String) -> Result<Json<Snapshot>> {
|
||||||
|
// Must be privileged for this route
|
||||||
|
if !user.privileged {
|
||||||
|
return Err(Error::NotPrivileged);
|
||||||
|
}
|
||||||
|
|
||||||
|
db.fetch_snapshot(&report_id).await.map(Json)
|
||||||
|
}
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi;
|
use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi;
|
||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
|
mod fetch_reports;
|
||||||
mod report_content;
|
mod report_content;
|
||||||
|
|
||||||
|
mod fetch_snapshot;
|
||||||
|
|
||||||
pub fn routes() -> (Vec<Route>, OpenApi) {
|
pub fn routes() -> (Vec<Route>, OpenApi) {
|
||||||
openapi_get_routes_spec![
|
openapi_get_routes_spec![
|
||||||
// Reports
|
// Reports
|
||||||
report_content::report_content
|
report_content::report_content,
|
||||||
|
fetch_reports::fetch_reports,
|
||||||
|
// Snapshots
|
||||||
|
fetch_snapshot::fetch_snapshot
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use revolt_quark::events::client::EventV1;
|
use revolt_quark::events::client::EventV1;
|
||||||
use revolt_quark::models::report::ReportedContent;
|
use revolt_quark::models::report::{ReportStatus, ReportedContent};
|
||||||
use revolt_quark::models::snapshot::{Snapshot, SnapshotContent};
|
use revolt_quark::models::snapshot::{Snapshot, SnapshotContent};
|
||||||
use revolt_quark::models::{Report, User};
|
use revolt_quark::models::{Report, User};
|
||||||
use revolt_quark::{Db, Error, Result};
|
use revolt_quark::{Db, Error, Result};
|
||||||
@@ -149,6 +149,7 @@ pub async fn report_content(db: &Db, user: User, data: Json<DataReportContent>)
|
|||||||
author_id: user.id,
|
author_id: user.id,
|
||||||
content: data.content,
|
content: data.content,
|
||||||
additional_context: data.additional_context,
|
additional_context: data.additional_context,
|
||||||
|
status: ReportStatus::Created,
|
||||||
};
|
};
|
||||||
|
|
||||||
db.insert_report(&report).await?;
|
db.insert_report(&report).await?;
|
||||||
|
|||||||
@@ -9,4 +9,8 @@ impl AbstractReport for DummyDb {
|
|||||||
info!("Insert {:?}", report);
|
info!("Insert {:?}", report);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn fetch_reports(&self) -> Result<Vec<Report>> {
|
||||||
|
Ok(vec![])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,8 @@ impl AbstractSnapshot for DummyDb {
|
|||||||
info!("Insert {:?}", snapshot);
|
info!("Insert {:?}", snapshot);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn fetch_snapshot(&self, _report_id: &str) -> Result<Snapshot> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,4 +10,8 @@ impl AbstractReport for MongoDb {
|
|||||||
async fn insert_report(&self, report: &Report) -> Result<()> {
|
async fn insert_report(&self, report: &Report) -> Result<()> {
|
||||||
self.insert_one(COL, report).await.map(|_| ())
|
self.insert_one(COL, report).await.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn fetch_reports(&self) -> Result<Vec<Report>> {
|
||||||
|
self.find(COL, doc! {}).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,4 +10,14 @@ impl AbstractSnapshot for MongoDb {
|
|||||||
async fn insert_snapshot(&self, snapshot: &Snapshot) -> Result<()> {
|
async fn insert_snapshot(&self, snapshot: &Snapshot) -> Result<()> {
|
||||||
self.insert_one(COL, snapshot).await.map(|_| ())
|
self.insert_one(COL, snapshot).await.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn fetch_snapshot(&self, report_id: &str) -> Result<Snapshot> {
|
||||||
|
self.find_one(
|
||||||
|
COL,
|
||||||
|
doc! {
|
||||||
|
"report_id": report_id
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ pub enum UserReportReason {
|
|||||||
Underage,
|
Underage,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The content being reported
|
||||||
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
|
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ReportedContent {
|
pub enum ReportedContent {
|
||||||
@@ -70,6 +71,20 @@ pub enum ReportedContent {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Status of the report
|
||||||
|
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
|
||||||
|
#[serde(tag = "status")]
|
||||||
|
pub enum ReportStatus {
|
||||||
|
/// Report is waiting for triage / action
|
||||||
|
Created,
|
||||||
|
|
||||||
|
/// Report was rejected
|
||||||
|
Rejected { rejection_reason: String },
|
||||||
|
|
||||||
|
/// Report was actioned and resolved
|
||||||
|
Resolved,
|
||||||
|
}
|
||||||
|
|
||||||
/// User-generated platform moderation report.
|
/// User-generated platform moderation report.
|
||||||
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
|
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
|
||||||
pub struct Report {
|
pub struct Report {
|
||||||
@@ -82,4 +97,7 @@ pub struct Report {
|
|||||||
pub content: ReportedContent,
|
pub content: ReportedContent,
|
||||||
/// Additional report context
|
/// Additional report context
|
||||||
pub additional_context: String,
|
pub additional_context: String,
|
||||||
|
/// Status of the report
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub status: ReportStatus,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ use crate::models::{Message, Server, User};
|
|||||||
pub enum SnapshotContent {
|
pub enum SnapshotContent {
|
||||||
Message {
|
Message {
|
||||||
/// Context before the message
|
/// Context before the message
|
||||||
#[serde(rename = "_prior_context")]
|
#[serde(rename = "_prior_context", default)]
|
||||||
prior_context: Vec<Message>,
|
prior_context: Vec<Message>,
|
||||||
|
|
||||||
/// Context after the message
|
/// Context after the message
|
||||||
#[serde(rename = "_leading_context")]
|
#[serde(rename = "_leading_context", default)]
|
||||||
leading_context: Vec<Message>,
|
leading_context: Vec<Message>,
|
||||||
|
|
||||||
/// Message
|
/// Message
|
||||||
|
|||||||
@@ -5,4 +5,7 @@ use crate::Result;
|
|||||||
pub trait AbstractReport: Sync + Send {
|
pub trait AbstractReport: Sync + Send {
|
||||||
/// Insert a new report into the database
|
/// Insert a new report into the database
|
||||||
async fn insert_report(&self, report: &Report) -> Result<()>;
|
async fn insert_report(&self, report: &Report) -> Result<()>;
|
||||||
|
|
||||||
|
/// Fetch reports
|
||||||
|
async fn fetch_reports(&self) -> Result<Vec<Report>>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,7 @@ use crate::Result;
|
|||||||
pub trait AbstractSnapshot: Sync + Send {
|
pub trait AbstractSnapshot: Sync + Send {
|
||||||
/// Insert a new snapshot into the database
|
/// Insert a new snapshot into the database
|
||||||
async fn insert_snapshot(&self, snapshot: &Snapshot) -> Result<()>;
|
async fn insert_snapshot(&self, snapshot: &Snapshot) -> Result<()>;
|
||||||
|
|
||||||
|
/// Fetch a snapshot by a report's id
|
||||||
|
async fn fetch_snapshot(&self, report_id: &str) -> Result<Snapshot>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ pub enum Error {
|
|||||||
permission: UserPermission,
|
permission: UserPermission,
|
||||||
},
|
},
|
||||||
NotElevated,
|
NotElevated,
|
||||||
|
NotPrivileged,
|
||||||
CannotGiveMissingPermissions,
|
CannotGiveMissingPermissions,
|
||||||
NotOwner,
|
NotOwner,
|
||||||
|
|
||||||
@@ -174,6 +175,7 @@ impl<'r> Responder<'r, 'static> for Error {
|
|||||||
Error::MissingPermission { .. } => Status::Forbidden,
|
Error::MissingPermission { .. } => Status::Forbidden,
|
||||||
Error::MissingUserPermission { .. } => Status::Forbidden,
|
Error::MissingUserPermission { .. } => Status::Forbidden,
|
||||||
Error::NotElevated => Status::Forbidden,
|
Error::NotElevated => Status::Forbidden,
|
||||||
|
Error::NotPrivileged => Status::Forbidden,
|
||||||
Error::CannotGiveMissingPermissions => Status::Forbidden,
|
Error::CannotGiveMissingPermissions => Status::Forbidden,
|
||||||
Error::NotOwner => Status::Forbidden,
|
Error::NotOwner => Status::Forbidden,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user