feat: implement creating strikes

feat: add moderator_id to strikes
fix: use correct collection for strikes
This commit is contained in:
Paul Makles
2023-05-31 19:04:20 +01:00
parent 28b1170633
commit 53c9160cd6
12 changed files with 120 additions and 31 deletions

6
Cargo.lock generated
View File

@@ -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",

View File

@@ -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",
]

View File

@@ -1,6 +1,6 @@
[package]
name = "revolt-bonfire"
version = "0.5.20"
version = "0.5.21"
license = "AGPL-3.0-or-later"
edition = "2021"

View File

@@ -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.

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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"

View File

@@ -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 {

View 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)
}

View File

@@ -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

View File

@@ -1,6 +1,6 @@
[package]
name = "revolt-quark"
version = "0.5.20"
version = "0.5.21"
edition = "2021"
license = "AGPL-3.0-or-later"