mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 05:26:59 +00:00
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]]
|
||||
name = "revolt-bonfire"
|
||||
version = "0.5.20"
|
||||
version = "0.5.21"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"async-tungstenite",
|
||||
@@ -2879,7 +2879,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-delta"
|
||||
version = "0.5.20"
|
||||
version = "0.5.21"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-std",
|
||||
@@ -2951,7 +2951,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-quark"
|
||||
version = "0.5.20"
|
||||
version = "0.5.21"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"async-recursion",
|
||||
|
||||
@@ -2,11 +2,14 @@ disallowed-methods = [
|
||||
# Shouldn't need to access these directly
|
||||
"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::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::safety_strikes::ops::AbstractAccountStrikes::delete_account_strike",
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-bonfire"
|
||||
version = "0.5.20"
|
||||
version = "0.5.21"
|
||||
license = "AGPL-3.0-or-later"
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ struct MigrationInfo {
|
||||
revision: i32,
|
||||
}
|
||||
|
||||
pub const LATEST_REVISION: i32 = 22;
|
||||
pub const LATEST_REVISION: i32 = 23;
|
||||
|
||||
pub async fn migrate_database(db: &MongoDb) {
|
||||
let migrations = db.col::<Document>("migrations");
|
||||
@@ -751,6 +751,23 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 {
|
||||
.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`.
|
||||
|
||||
// Reminder to update LATEST_REVISION when adding new migrations.
|
||||
|
||||
@@ -8,8 +8,10 @@ auto_derived_partial!(
|
||||
/// Strike Id
|
||||
#[serde(rename = "_id")]
|
||||
pub id: String,
|
||||
/// User Id of reported user
|
||||
/// Id of reported user
|
||||
pub user_id: String,
|
||||
/// Id of moderator
|
||||
pub moderator_id: String,
|
||||
|
||||
/// Attached reason
|
||||
pub reason: String,
|
||||
@@ -19,6 +21,23 @@ auto_derived_partial!(
|
||||
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
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
|
||||
pub async fn update(&mut self, db: &Database, partial: PartialAccountStrike) -> Result<()> {
|
||||
db.update_account_strike(&self.id, &partial).await?;
|
||||
@@ -42,16 +61,15 @@ mod tests {
|
||||
async fn crud() {
|
||||
database_test!(|db| async move {
|
||||
let user_id = "user";
|
||||
let strike_a = "a";
|
||||
let strike_b = "b";
|
||||
|
||||
let strike = AccountStrike {
|
||||
id: strike_a.to_string(),
|
||||
user_id: user_id.to_string(),
|
||||
reason: "reason 1".to_string(),
|
||||
};
|
||||
|
||||
db.insert_account_strike(&strike).await.unwrap();
|
||||
let strike = AccountStrike::create(
|
||||
&db,
|
||||
user_id.to_string(),
|
||||
"reason 1".to_string(),
|
||||
"moderator_id".to_string(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut updated_strike = strike.clone();
|
||||
updated_strike
|
||||
@@ -65,11 +83,12 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
db.insert_account_strike(&AccountStrike {
|
||||
id: strike_b.to_string(),
|
||||
user_id: user_id.to_string(),
|
||||
reason: "reason 2".to_string(),
|
||||
})
|
||||
let strike2 = AccountStrike::create(
|
||||
&db,
|
||||
user_id.to_string(),
|
||||
"reason 2".to_string(),
|
||||
"moderator_id".to_string(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -81,12 +100,12 @@ mod tests {
|
||||
.map(|strike| strike.id)
|
||||
.collect::<HashSet<String>>();
|
||||
|
||||
assert!(ids.contains(strike_a));
|
||||
assert!(ids.contains(strike_b));
|
||||
assert!(ids.contains(&strike.id));
|
||||
assert!(ids.contains(&strike2.id));
|
||||
|
||||
let fetched_strike = strikes
|
||||
.into_iter()
|
||||
.find(|strike| strike.id == strike_a)
|
||||
.find(|strike| strike.id == strike.id)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(fetched_strike, updated_strike);
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{AccountStrike, PartialAccountStrike};
|
||||
|
||||
use super::AbstractAccountStrikes;
|
||||
|
||||
static COL: &str = "bots";
|
||||
static COL: &str = "safety_strikes";
|
||||
|
||||
#[async_trait]
|
||||
impl AbstractAccountStrikes for MongoDb {
|
||||
|
||||
@@ -4,14 +4,23 @@ auto_derived!(
|
||||
/// Strike Id
|
||||
#[serde(rename = "_id")]
|
||||
pub id: String,
|
||||
/// User Id of reported user
|
||||
/// Id of reported user
|
||||
pub user_id: String,
|
||||
|
||||
/// Attached reason
|
||||
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 {
|
||||
/// New attached reason
|
||||
pub reason: String,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-delta"
|
||||
version = "0.5.20"
|
||||
version = "0.5.21"
|
||||
license = "AGPL-3.0-or-later"
|
||||
authors = ["Paul Makles <paulmakles@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
@@ -158,7 +158,12 @@ fn custom_openapi_spec() -> OpenApi {
|
||||
servers: vec![
|
||||
Server {
|
||||
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()
|
||||
},
|
||||
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 create_strike;
|
||||
mod delete_strike;
|
||||
mod edit_strike;
|
||||
mod fetch_strikes;
|
||||
@@ -22,6 +23,7 @@ pub fn routes() -> (Vec<Route>, OpenApi) {
|
||||
// Snapshots
|
||||
fetch_snapshots::fetch_snapshots,
|
||||
// Strikes
|
||||
create_strike::create_strike,
|
||||
fetch_strikes::fetch_strikes,
|
||||
edit_strike::edit_strike,
|
||||
delete_strike::delete_strike
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-quark"
|
||||
version = "0.5.20"
|
||||
version = "0.5.21"
|
||||
edition = "2021"
|
||||
license = "AGPL-3.0-or-later"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user