feat: implement creating strikes
feat: add moderator_id to strikes fix: use correct collection for strikes
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -2837,7 +2837,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "revolt-bonfire"
|
name = "revolt-bonfire"
|
||||||
version = "0.5.20"
|
version = "0.5.21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
"async-std",
|
||||||
"async-tungstenite",
|
"async-tungstenite",
|
||||||
@@ -2879,7 +2879,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "revolt-delta"
|
name = "revolt-delta"
|
||||||
version = "0.5.20"
|
version = "0.5.21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"async-std",
|
"async-std",
|
||||||
@@ -2951,7 +2951,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "revolt-quark"
|
name = "revolt-quark"
|
||||||
version = "0.5.20"
|
version = "0.5.21"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock",
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ disallowed-methods = [
|
|||||||
# Shouldn't need to access these directly
|
# Shouldn't need to access these directly
|
||||||
"revolt_database::models::bots::model::Bot::remove_field",
|
"revolt_database::models::bots::model::Bot::remove_field",
|
||||||
|
|
||||||
# Prefer to use Object::update()
|
# Prefer to use Object::create()
|
||||||
|
"revolt_database::models::safety_strikes::ops::AbstractAccountStrikes::insert_account_strike",
|
||||||
|
|
||||||
|
# Prefer to use Object::update(&self)
|
||||||
"revolt_database::models::bots::ops::AbstractBots::update_bot",
|
"revolt_database::models::bots::ops::AbstractBots::update_bot",
|
||||||
"revolt_database::models::safety_strikes::ops::AbstractAccountStrikes::update_account_strike",
|
"revolt_database::models::safety_strikes::ops::AbstractAccountStrikes::update_account_strike",
|
||||||
|
|
||||||
# Prefer to use Object::delete()
|
# Prefer to use Object::delete(&self)
|
||||||
"revolt_database::models::bots::ops::AbstractBots::delete_bot",
|
"revolt_database::models::bots::ops::AbstractBots::delete_bot",
|
||||||
"revolt_database::models::safety_strikes::ops::AbstractAccountStrikes::delete_account_strike",
|
"revolt_database::models::safety_strikes::ops::AbstractAccountStrikes::delete_account_strike",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "revolt-bonfire"
|
name = "revolt-bonfire"
|
||||||
version = "0.5.20"
|
version = "0.5.21"
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct MigrationInfo {
|
|||||||
revision: i32,
|
revision: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const LATEST_REVISION: i32 = 22;
|
pub const LATEST_REVISION: i32 = 23;
|
||||||
|
|
||||||
pub async fn migrate_database(db: &MongoDb) {
|
pub async fn migrate_database(db: &MongoDb) {
|
||||||
let migrations = db.col::<Document>("migrations");
|
let migrations = db.col::<Document>("migrations");
|
||||||
@@ -751,6 +751,23 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if revision <= 22 {
|
||||||
|
info!("Running migration [revision 22 / 31-05-2023]: Add moderator_id to account strikes.");
|
||||||
|
|
||||||
|
db.col::<Document>("safety_strikes")
|
||||||
|
.update_many(
|
||||||
|
doc! {},
|
||||||
|
doc! {
|
||||||
|
"$set": {
|
||||||
|
"moderator_id": "01EX2NCWQ0CHS3QJF0FEQS1GR4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("Failed to update server members.");
|
||||||
|
}
|
||||||
|
|
||||||
// Need to migrate fields on attachments, change `user_id`, `object_id`, etc to `parent`.
|
// Need to migrate fields on attachments, change `user_id`, `object_id`, etc to `parent`.
|
||||||
|
|
||||||
// Reminder to update LATEST_REVISION when adding new migrations.
|
// Reminder to update LATEST_REVISION when adding new migrations.
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ auto_derived_partial!(
|
|||||||
/// Strike Id
|
/// Strike Id
|
||||||
#[serde(rename = "_id")]
|
#[serde(rename = "_id")]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
/// User Id of reported user
|
/// Id of reported user
|
||||||
pub user_id: String,
|
pub user_id: String,
|
||||||
|
/// Id of moderator
|
||||||
|
pub moderator_id: String,
|
||||||
|
|
||||||
/// Attached reason
|
/// Attached reason
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
@@ -19,6 +21,23 @@ auto_derived_partial!(
|
|||||||
|
|
||||||
#[allow(clippy::disallowed_methods)]
|
#[allow(clippy::disallowed_methods)]
|
||||||
impl AccountStrike {
|
impl AccountStrike {
|
||||||
|
pub async fn create(
|
||||||
|
db: &Database,
|
||||||
|
user_id: String,
|
||||||
|
reason: String,
|
||||||
|
moderator_id: String,
|
||||||
|
) -> Result<AccountStrike> {
|
||||||
|
let strike = AccountStrike {
|
||||||
|
id: ulid::Ulid::new().to_string(),
|
||||||
|
user_id,
|
||||||
|
moderator_id,
|
||||||
|
reason,
|
||||||
|
};
|
||||||
|
|
||||||
|
db.insert_account_strike(&strike).await?;
|
||||||
|
Ok(strike)
|
||||||
|
}
|
||||||
|
|
||||||
/// Update this strike
|
/// Update this strike
|
||||||
pub async fn update(&mut self, db: &Database, partial: PartialAccountStrike) -> Result<()> {
|
pub async fn update(&mut self, db: &Database, partial: PartialAccountStrike) -> Result<()> {
|
||||||
db.update_account_strike(&self.id, &partial).await?;
|
db.update_account_strike(&self.id, &partial).await?;
|
||||||
@@ -42,16 +61,15 @@ mod tests {
|
|||||||
async fn crud() {
|
async fn crud() {
|
||||||
database_test!(|db| async move {
|
database_test!(|db| async move {
|
||||||
let user_id = "user";
|
let user_id = "user";
|
||||||
let strike_a = "a";
|
|
||||||
let strike_b = "b";
|
|
||||||
|
|
||||||
let strike = AccountStrike {
|
let strike = AccountStrike::create(
|
||||||
id: strike_a.to_string(),
|
&db,
|
||||||
user_id: user_id.to_string(),
|
user_id.to_string(),
|
||||||
reason: "reason 1".to_string(),
|
"reason 1".to_string(),
|
||||||
};
|
"moderator_id".to_string(),
|
||||||
|
)
|
||||||
db.insert_account_strike(&strike).await.unwrap();
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut updated_strike = strike.clone();
|
let mut updated_strike = strike.clone();
|
||||||
updated_strike
|
updated_strike
|
||||||
@@ -65,11 +83,12 @@ mod tests {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
db.insert_account_strike(&AccountStrike {
|
let strike2 = AccountStrike::create(
|
||||||
id: strike_b.to_string(),
|
&db,
|
||||||
user_id: user_id.to_string(),
|
user_id.to_string(),
|
||||||
reason: "reason 2".to_string(),
|
"reason 2".to_string(),
|
||||||
})
|
"moderator_id".to_string(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -81,12 +100,12 @@ mod tests {
|
|||||||
.map(|strike| strike.id)
|
.map(|strike| strike.id)
|
||||||
.collect::<HashSet<String>>();
|
.collect::<HashSet<String>>();
|
||||||
|
|
||||||
assert!(ids.contains(strike_a));
|
assert!(ids.contains(&strike.id));
|
||||||
assert!(ids.contains(strike_b));
|
assert!(ids.contains(&strike2.id));
|
||||||
|
|
||||||
let fetched_strike = strikes
|
let fetched_strike = strikes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|strike| strike.id == strike_a)
|
.find(|strike| strike.id == strike.id)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(fetched_strike, updated_strike);
|
assert_eq!(fetched_strike, updated_strike);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use crate::{AccountStrike, PartialAccountStrike};
|
|||||||
|
|
||||||
use super::AbstractAccountStrikes;
|
use super::AbstractAccountStrikes;
|
||||||
|
|
||||||
static COL: &str = "bots";
|
static COL: &str = "safety_strikes";
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AbstractAccountStrikes for MongoDb {
|
impl AbstractAccountStrikes for MongoDb {
|
||||||
|
|||||||
@@ -4,14 +4,23 @@ auto_derived!(
|
|||||||
/// Strike Id
|
/// Strike Id
|
||||||
#[serde(rename = "_id")]
|
#[serde(rename = "_id")]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
/// User Id of reported user
|
/// Id of reported user
|
||||||
pub user_id: String,
|
pub user_id: String,
|
||||||
|
|
||||||
/// Attached reason
|
/// Attached reason
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Strike Data
|
/// New strike information
|
||||||
|
pub struct DataCreateStrike {
|
||||||
|
/// Id of reported user
|
||||||
|
pub user_id: String,
|
||||||
|
|
||||||
|
/// Attached reason
|
||||||
|
pub reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// New strike information
|
||||||
pub struct DataEditAccountStrike {
|
pub struct DataEditAccountStrike {
|
||||||
/// New attached reason
|
/// New attached reason
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "revolt-delta"
|
name = "revolt-delta"
|
||||||
version = "0.5.20"
|
version = "0.5.21"
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
authors = ["Paul Makles <paulmakles@gmail.com>"]
|
authors = ["Paul Makles <paulmakles@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|||||||
@@ -158,7 +158,12 @@ fn custom_openapi_spec() -> OpenApi {
|
|||||||
servers: vec![
|
servers: vec![
|
||||||
Server {
|
Server {
|
||||||
url: "https://api.revolt.chat".to_owned(),
|
url: "https://api.revolt.chat".to_owned(),
|
||||||
description: Some("Revolt API".to_owned()),
|
description: Some("Revolt Production".to_owned()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
Server {
|
||||||
|
url: "https://revolt.chat/api".to_owned(),
|
||||||
|
description: Some("Revolt Staging".to_owned()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Server {
|
Server {
|
||||||
|
|||||||
34
crates/delta/src/routes/safety/create_strike.rs
Normal file
34
crates/delta/src/routes/safety/create_strike.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
use revolt_database::{AccountStrike, Database};
|
||||||
|
use revolt_models::v0::{AccountStrike as AccountStrikeModel, DataCreateStrike};
|
||||||
|
use revolt_quark::models::User;
|
||||||
|
use revolt_quark::{Error, Result};
|
||||||
|
use rocket::serde::json::Json;
|
||||||
|
use rocket::State;
|
||||||
|
|
||||||
|
/// # Create Strike
|
||||||
|
///
|
||||||
|
/// Create a new account strike
|
||||||
|
#[openapi(tag = "User Safety")]
|
||||||
|
#[post("/strikes", data = "<data>")]
|
||||||
|
pub async fn create_strike(
|
||||||
|
db: &State<Database>,
|
||||||
|
user: User,
|
||||||
|
data: Json<DataCreateStrike>,
|
||||||
|
) -> Result<Json<AccountStrikeModel>> {
|
||||||
|
// Must be privileged for this route
|
||||||
|
if !user.privileged {
|
||||||
|
return Err(Error::NotPrivileged);
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = data.into_inner();
|
||||||
|
let target = db
|
||||||
|
.fetch_user(&data.user_id)
|
||||||
|
.await
|
||||||
|
.map_err(Error::from_core)?;
|
||||||
|
|
||||||
|
AccountStrike::create(db, target.id, data.reason, user.id)
|
||||||
|
.await
|
||||||
|
.map(|strike| strike.into())
|
||||||
|
.map(Json)
|
||||||
|
.map_err(Error::from_core)
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ mod report_content;
|
|||||||
|
|
||||||
mod fetch_snapshots;
|
mod fetch_snapshots;
|
||||||
|
|
||||||
|
mod create_strike;
|
||||||
mod delete_strike;
|
mod delete_strike;
|
||||||
mod edit_strike;
|
mod edit_strike;
|
||||||
mod fetch_strikes;
|
mod fetch_strikes;
|
||||||
@@ -22,6 +23,7 @@ pub fn routes() -> (Vec<Route>, OpenApi) {
|
|||||||
// Snapshots
|
// Snapshots
|
||||||
fetch_snapshots::fetch_snapshots,
|
fetch_snapshots::fetch_snapshots,
|
||||||
// Strikes
|
// Strikes
|
||||||
|
create_strike::create_strike,
|
||||||
fetch_strikes::fetch_strikes,
|
fetch_strikes::fetch_strikes,
|
||||||
edit_strike::edit_strike,
|
edit_strike::edit_strike,
|
||||||
delete_strike::delete_strike
|
delete_strike::delete_strike
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "revolt-quark"
|
name = "revolt-quark"
|
||||||
version = "0.5.20"
|
version = "0.5.21"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user