feat: ratelimit user edit route and discriminator changes
This commit is contained in:
@@ -76,6 +76,10 @@ pub async fn create_database(db: &MongoDb) {
|
||||
.await
|
||||
.expect("Failed to create bots collection.");
|
||||
|
||||
db.create_collection("ratelimit_events", None)
|
||||
.await
|
||||
.expect("Failed to create ratelimit_events collection.");
|
||||
|
||||
db.create_collection(
|
||||
"pubsub",
|
||||
CreateCollectionOptions::builder()
|
||||
@@ -209,5 +213,24 @@ pub async fn create_database(db: &MongoDb) {
|
||||
.await
|
||||
.expect("Failed to save migration info.");
|
||||
|
||||
db.run_command(
|
||||
doc! {
|
||||
"createIndexes": "ratelimit_events",
|
||||
"indexes": [
|
||||
{
|
||||
"key": {
|
||||
"_id": 1_i32,
|
||||
"target_id": 1_i32,
|
||||
"event_type": 1_i32,
|
||||
},
|
||||
"name": "compound_key"
|
||||
}
|
||||
]
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.expect("Failed to create ratelimit_events index.");
|
||||
|
||||
info!("Created database.");
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ struct MigrationInfo {
|
||||
revision: i32,
|
||||
}
|
||||
|
||||
pub const LATEST_REVISION: i32 = 25;
|
||||
pub const LATEST_REVISION: i32 = 26;
|
||||
|
||||
pub async fn migrate_database(db: &MongoDb) {
|
||||
let migrations = db.col::<Document>("migrations");
|
||||
@@ -947,8 +947,37 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 {
|
||||
.expect("Failed to create username index.");
|
||||
}
|
||||
|
||||
if revision <= 25 {
|
||||
info!("Running migration [revision 25 / 15-06-2023]: Add collection `ratelimit_events` with index.");
|
||||
|
||||
db.db()
|
||||
.create_collection("ratelimit_events", None)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
db.db()
|
||||
.run_command(
|
||||
doc! {
|
||||
"createIndexes": "ratelimit_events",
|
||||
"indexes": [
|
||||
{
|
||||
"key": {
|
||||
"_id": 1_i32,
|
||||
"target_id": 1_i32,
|
||||
"event_type": 1_i32,
|
||||
},
|
||||
"name": "compound_key"
|
||||
}
|
||||
]
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.expect("Failed to create ratelimit_events index.");
|
||||
}
|
||||
|
||||
// Need to migrate fields on attachments, change `user_id`, `object_id`, etc to `parent`.
|
||||
|
||||
// Reminder to update LATEST_REVISION when adding new migrations.
|
||||
LATEST_REVISION
|
||||
LATEST_REVISION.max(revision)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ mod bots;
|
||||
mod channel_webhooks;
|
||||
mod channels;
|
||||
mod files;
|
||||
mod ratelimit_events;
|
||||
mod safety_strikes;
|
||||
mod server_members;
|
||||
mod servers;
|
||||
@@ -14,6 +15,7 @@ pub use bots::*;
|
||||
pub use channel_webhooks::*;
|
||||
pub use channels::*;
|
||||
pub use files::*;
|
||||
pub use ratelimit_events::*;
|
||||
pub use safety_strikes::*;
|
||||
pub use server_members::*;
|
||||
pub use servers::*;
|
||||
@@ -30,6 +32,7 @@ pub trait AbstractDatabase:
|
||||
+ channels::AbstractChannels
|
||||
+ channel_webhooks::AbstractWebhooks
|
||||
+ files::AbstractAttachments
|
||||
+ ratelimit_events::AbstractRatelimitEvents
|
||||
+ safety_strikes::AbstractAccountStrikes
|
||||
+ server_members::AbstractServerMembers
|
||||
+ servers::AbstractServers
|
||||
|
||||
5
crates/core/database/src/models/ratelimit_events/mod.rs
Normal file
5
crates/core/database/src/models/ratelimit_events/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod model;
|
||||
mod ops;
|
||||
|
||||
pub use model::*;
|
||||
pub use ops::*;
|
||||
25
crates/core/database/src/models/ratelimit_events/model.rs
Normal file
25
crates/core/database/src/models/ratelimit_events/model.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use std::fmt;
|
||||
|
||||
auto_derived!(
|
||||
/// Ratelimit Event
|
||||
pub struct RatelimitEvent {
|
||||
/// Id
|
||||
#[serde(rename = "_id")]
|
||||
pub id: String,
|
||||
/// Relevant Object Id
|
||||
pub target_id: String,
|
||||
/// Type of event
|
||||
pub event_type: RatelimitEventType,
|
||||
}
|
||||
|
||||
/// Event type
|
||||
pub enum RatelimitEventType {
|
||||
DiscriminatorChange,
|
||||
}
|
||||
);
|
||||
|
||||
impl fmt::Display for RatelimitEventType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
20
crates/core/database/src/models/ratelimit_events/ops.rs
Normal file
20
crates/core/database/src/models/ratelimit_events/ops.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::{revolt_result::Result, RatelimitEvent, RatelimitEventType};
|
||||
mod mongodb;
|
||||
mod reference;
|
||||
|
||||
#[async_trait]
|
||||
pub trait AbstractRatelimitEvents: Sync + Send {
|
||||
/// Insert a new ratelimit event
|
||||
async fn insert_ratelimit_event(&self, event: &RatelimitEvent) -> Result<()>;
|
||||
|
||||
/// Count number of events in given duration and check if we've hit the limit
|
||||
async fn has_ratelimited(
|
||||
&self,
|
||||
target_id: &str,
|
||||
event_type: RatelimitEventType,
|
||||
period: Duration,
|
||||
count: usize,
|
||||
) -> Result<bool>;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use super::AbstractRatelimitEvents;
|
||||
use crate::{MongoDb, RatelimitEvent, RatelimitEventType};
|
||||
use revolt_result::Result;
|
||||
use ulid::Ulid;
|
||||
|
||||
static COL: &str = "ratelimit_events";
|
||||
|
||||
#[async_trait]
|
||||
impl AbstractRatelimitEvents for MongoDb {
|
||||
/// Insert a new ratelimit event
|
||||
async fn insert_ratelimit_event(&self, event: &RatelimitEvent) -> Result<()> {
|
||||
query!(self, insert_one, COL, &event).map(|_| ())
|
||||
}
|
||||
|
||||
/// Count number of events in given duration and check if we've hit the limit
|
||||
async fn has_ratelimited(
|
||||
&self,
|
||||
target_id: &str,
|
||||
event_type: RatelimitEventType,
|
||||
period: Duration,
|
||||
count: usize,
|
||||
) -> Result<bool> {
|
||||
self.col::<RatelimitEvent>(COL)
|
||||
.count_documents(
|
||||
doc! {
|
||||
"_id": {
|
||||
"$gte": Ulid::from_datetime(SystemTime::now() - period).to_string()
|
||||
},
|
||||
"target_id": target_id,
|
||||
"event_type": event_type.to_string()
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map(|c| c as usize >= count)
|
||||
.map_err(|_| create_database_error!("count_documents", COL))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use super::AbstractRatelimitEvents;
|
||||
use crate::RatelimitEvent;
|
||||
use crate::RatelimitEventType;
|
||||
use crate::ReferenceDb;
|
||||
use revolt_result::Result;
|
||||
|
||||
#[async_trait]
|
||||
impl AbstractRatelimitEvents for ReferenceDb {
|
||||
/// Insert a new ratelimit event
|
||||
async fn insert_ratelimit_event(&self, _event: &RatelimitEvent) -> Result<()> {
|
||||
// TODO: implement
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Count number of events in given duration and check if we've hit the limit
|
||||
async fn has_ratelimited(
|
||||
&self,
|
||||
_target_id: &str,
|
||||
_event_type: RatelimitEventType,
|
||||
_period: Duration,
|
||||
_count: usize,
|
||||
) -> Result<bool> {
|
||||
// TODO: implement
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user