diff --git a/crates/core/database/src/drivers/reference.rs b/crates/core/database/src/drivers/reference.rs index ee2f5fc2..0f3a8664 100644 --- a/crates/core/database/src/drivers/reference.rs +++ b/crates/core/database/src/drivers/reference.rs @@ -4,7 +4,7 @@ use futures::lock::Mutex; use crate::{ Bot, Channel, ChannelCompositeKey, ChannelUnread, Emoji, File, Invite, Member, - MemberCompositeKey, Server, User, UserSettings, Webhook, + MemberCompositeKey, Server, ServerBan, User, UserSettings, Webhook, }; database_derived!( @@ -19,10 +19,10 @@ database_derived!( pub emojis: Arc>>, pub user_settings: Arc>>, pub users: Arc>>, + pub server_bans: Arc>>, pub server_members: Arc>>, pub servers: Arc>>, pub files: Arc>>, - pub server_bans: Arc>>, pub safety_reports: Arc>>, pub safety_snapshots: Arc>>, pub messages: Arc>>, diff --git a/crates/core/database/src/models/mod.rs b/crates/core/database/src/models/mod.rs index 463bb2e1..2609d557 100644 --- a/crates/core/database/src/models/mod.rs +++ b/crates/core/database/src/models/mod.rs @@ -7,6 +7,7 @@ mod channels; mod emojis; mod files; mod ratelimit_events; +mod server_bans; mod server_members; mod servers; mod user_settings; @@ -21,6 +22,7 @@ pub use channels::*; pub use emojis::*; pub use files::*; pub use ratelimit_events::*; +pub use server_bans::*; pub use server_members::*; pub use servers::*; pub use user_settings::*; @@ -40,6 +42,7 @@ pub trait AbstractDatabase: + emojis::AbstractEmojis + files::AbstractAttachments + ratelimit_events::AbstractRatelimitEvents + + server_bans::AbstractServerBans + server_members::AbstractServerMembers + servers::AbstractServers + user_settings::AbstractUserSettings diff --git a/crates/core/database/src/models/server_bans/mod.rs b/crates/core/database/src/models/server_bans/mod.rs new file mode 100644 index 00000000..4d801b73 --- /dev/null +++ b/crates/core/database/src/models/server_bans/mod.rs @@ -0,0 +1,5 @@ +mod model; +mod ops; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/server_bans/model.rs b/crates/core/database/src/models/server_bans/model.rs new file mode 100644 index 00000000..8e5175a0 --- /dev/null +++ b/crates/core/database/src/models/server_bans/model.rs @@ -0,0 +1,12 @@ +use crate::MemberCompositeKey; + +auto_derived!( + /// Server Ban + pub struct ServerBan { + /// Unique member id + #[serde(rename = "_id")] + pub id: MemberCompositeKey, + /// Reason for ban creation + pub reason: Option, + } +); diff --git a/crates/core/database/src/models/server_bans/ops.rs b/crates/core/database/src/models/server_bans/ops.rs new file mode 100644 index 00000000..90cb4df3 --- /dev/null +++ b/crates/core/database/src/models/server_bans/ops.rs @@ -0,0 +1,21 @@ +use revolt_result::Result; + +use crate::{MemberCompositeKey, ServerBan}; + +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractServerBans: Sync + Send { + /// Insert new ban into database + async fn insert_ban(&self, ban: &ServerBan) -> Result<()>; + + /// Fetch a server ban by server and user id + async fn fetch_ban(&self, server_id: &str, user_id: &str) -> Result; + + /// Fetch all bans in a server + async fn fetch_bans(&self, server_id: &str) -> Result>; + + /// Delete a ban from the database + async fn delete_ban(&self, id: &MemberCompositeKey) -> Result<()>; +} diff --git a/crates/core/database/src/models/server_bans/ops/mongodb.rs b/crates/core/database/src/models/server_bans/ops/mongodb.rs new file mode 100644 index 00000000..10dc2aa9 --- /dev/null +++ b/crates/core/database/src/models/server_bans/ops/mongodb.rs @@ -0,0 +1,57 @@ +use futures::StreamExt; +use revolt_result::Result; + +use crate::MongoDb; +use crate::{MemberCompositeKey, ServerBan}; + +use super::AbstractServerBans; + +static COL: &str = "server_bans"; + +#[async_trait] +impl AbstractServerBans for MongoDb { + /// Insert new ban into database + async fn insert_ban(&self, ban: &ServerBan) -> Result<()> { + query!(self, insert_one, COL, &ban).map(|_| ()) + } + + /// Fetch a server ban by server and user id + async fn fetch_ban(&self, server_id: &str, user_id: &str) -> Result { + query!( + self, + find_one, + COL, + doc! { + "_id.server": server_id, + "_id.user": user_id + } + )? + .ok_or_else(|| create_error!(NotFound)) + } + + /// Fetch all bans in a server + async fn fetch_bans(&self, server_id: &str) -> Result> { + query!( + self, + find, + COL, + doc! { + "_id.server": server_id + } + ) + } + + /// Delete a ban from the database + async fn delete_ban(&self, id: &MemberCompositeKey) -> Result<()> { + query!( + self, + delete_one, + COL, + doc! { + "_id.server": &id.server, + "_id.user": &id.user + } + ) + .map(|_| ()) + } +} diff --git a/crates/core/database/src/models/server_bans/ops/reference.rs b/crates/core/database/src/models/server_bans/ops/reference.rs new file mode 100644 index 00000000..2609a2ea --- /dev/null +++ b/crates/core/database/src/models/server_bans/ops/reference.rs @@ -0,0 +1,52 @@ +use revolt_result::Result; + +use crate::ReferenceDb; +use crate::{MemberCompositeKey, ServerBan}; + +use super::AbstractServerBans; + +#[async_trait] +impl AbstractServerBans for ReferenceDb { + /// Insert new ban into database + async fn insert_ban(&self, ban: &ServerBan) -> Result<()> { + let mut server_bans = self.server_bans.lock().await; + if server_bans.contains_key(&ban.id) { + Err(create_database_error!("insert", "ban")) + } else { + server_bans.insert(ban.id.clone(), ban.clone()); + Ok(()) + } + } + + /// Fetch a server ban by server and user id + async fn fetch_ban(&self, server_id: &str, user_id: &str) -> Result { + let server_bans = self.server_bans.lock().await; + server_bans + .get(&MemberCompositeKey { + server: server_id.to_string(), + user: user_id.to_string(), + }) + .cloned() + .ok_or_else(|| create_error!(NotFound)) + } + + /// Fetch all bans in a server + async fn fetch_bans(&self, server_id: &str) -> Result> { + let server_bans = self.server_bans.lock().await; + Ok(server_bans + .values() + .filter(|member| member.id.server == server_id) + .cloned() + .collect()) + } + + /// Delete a ban from the database + async fn delete_ban(&self, id: &MemberCompositeKey) -> Result<()> { + let mut server_bans = self.server_bans.lock().await; + if server_bans.remove(id).is_some() { + Ok(()) + } else { + Err(create_error!(NotFound)) + } + } +} diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index bc7e052f..84601851 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -294,6 +294,15 @@ impl From for Metadata { } } +impl From for ServerBan { + fn from(value: crate::ServerBan) -> Self { + ServerBan { + id: value.id, + reason: value.reason, + } + } +} + impl From for Member { fn from(value: crate::Member) -> Self { Member { diff --git a/crates/core/models/src/v0/mod.rs b/crates/core/models/src/v0/mod.rs index 917d2d0f..3c13f3bc 100644 --- a/crates/core/models/src/v0/mod.rs +++ b/crates/core/models/src/v0/mod.rs @@ -5,6 +5,7 @@ mod channel_webhooks; mod channels; mod emojis; mod files; +mod server_bans; mod server_members; mod servers; mod user_settings; @@ -17,6 +18,7 @@ pub use channel_webhooks::*; pub use channels::*; pub use emojis::*; pub use files::*; +pub use server_bans::*; pub use server_members::*; pub use servers::*; pub use user_settings::*; diff --git a/crates/core/models/src/v0/server_bans.rs b/crates/core/models/src/v0/server_bans.rs new file mode 100644 index 00000000..cf243ee7 --- /dev/null +++ b/crates/core/models/src/v0/server_bans.rs @@ -0,0 +1,12 @@ +use super::MemberCompositeKey; + +auto_derived!( + /// Server Ban + pub struct ServerBan { + /// Unique member id + #[cfg_attr(feature = "serde", serde(rename = "_id"))] + pub id: MemberCompositeKey, + /// Reason for ban creation + pub reason: Option, + } +);