diff --git a/src/database/entities/message.rs b/src/database/entities/message.rs index 13975de4f7c0f678134a482aca9740071fd15bc9..8009934349a0c4ab057996faa8c11daa3646653a 100644 --- a/src/database/entities/message.rs +++ b/src/database/entities/message.rs @@ -71,7 +71,7 @@ impl Message { pub async fn publish_delete(self) -> Result<()> { let channel = self.channel.clone(); - ClientboundNotification::MessageDelete(self.id) + ClientboundNotification::MessageDelete { id: self.id } .publish(channel) .await .ok(); diff --git a/src/database/permissions/channel.rs b/src/database/permissions/channel.rs index 7164b3ff1e5b2f41f44d149c7aff355c84cd9d6c..41656bd8b728711f5deeaad1032bd80987950d07 100644 --- a/src/database/permissions/channel.rs +++ b/src/database/permissions/channel.rs @@ -7,6 +7,7 @@ use std::ops; pub enum ChannelPermission { View = 1, SendMessage = 2, + ManageMessages = 4, } bitfield! { @@ -14,6 +15,7 @@ bitfield! { u32; pub get_view, _: 31; pub get_send_message, _: 30; + pub get_manage_messages, _: 29; } impl_op_ex!(+ |a: &ChannelPermission, b: &ChannelPermission| -> u32 { *a as u32 | *b as u32 }); @@ -23,7 +25,9 @@ pub async fn calculate(user: &User, target: &Channel) -> ChannelPermissions<[u32 match target { Channel::SavedMessages { user: owner, .. } => { if &user.id == owner { - ChannelPermissions([ChannelPermission::View + ChannelPermission::SendMessage]) + ChannelPermissions([ChannelPermission::View + + ChannelPermission::SendMessage + + ChannelPermission::ManageMessages]) } else { ChannelPermissions([0]) } diff --git a/src/notifications/events.rs b/src/notifications/events.rs index cde3946232aaed49d024a827d0c4904b0d1b82f5..15beec5a79dc9f00aae3571be1556c43cd3b43e6 100644 --- a/src/notifications/events.rs +++ b/src/notifications/events.rs @@ -38,7 +38,9 @@ pub enum ClientboundNotification { Message(Message), MessageEdit(Message), - MessageDelete(String), + MessageDelete { + id: String, + }, /*MessageCreate { id: String, diff --git a/src/routes/channels/message_delete.rs b/src/routes/channels/message_delete.rs new file mode 100644 index 0000000000000000000000000000000000000000..61204e70d76bfaae7ddc04c17d69ddfee1a792fd --- /dev/null +++ b/src/routes/channels/message_delete.rs @@ -0,0 +1,39 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use mongodb::bson::doc; + +#[delete("/<target>/messages/<msg>")] +pub async fn req(user: User, target: Ref, msg: Ref) -> Result<()> { + let channel = target.fetch_channel().await?; + + let perm = permissions::channel::calculate(&user, &channel).await; + if !perm.get_view() { + Err(Error::LabelMe)? + } + + let message = msg.fetch_message().await?; + if message.author != user.id && !perm.get_manage_messages() { + match channel { + Channel::SavedMessages { .. } => unreachable!(), + _ => Err(Error::CannotEditMessage)?, + } + } + + get_collection("messages") + .delete_one( + doc! { + "_id": &message.id + }, + None, + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "delete_one", + with: "message", + })?; + + message.publish_delete().await?; + + Ok(()) +} diff --git a/src/routes/channels/message_edit.rs b/src/routes/channels/message_edit.rs index ccc2f8a320fcc35efbb38730f438e449e2772edb..0e57c1868cd260a3c999b9ae8fb2dbde67acef06 100644 --- a/src/routes/channels/message_edit.rs +++ b/src/routes/channels/message_edit.rs @@ -2,7 +2,7 @@ use crate::database::*; use crate::util::result::{Error, Result}; use chrono::Utc; -use mongodb::bson::{Bson, DateTime, doc}; +use mongodb::bson::{doc, Bson, DateTime}; use rocket_contrib::json::Json; use serde::{Deserialize, Serialize}; use validator::Validate; diff --git a/src/routes/channels/mod.rs b/src/routes/channels/mod.rs index f8885574c592ca6c209c29d3d18bee1027db8e28..dd20b77631b414817b1831164c71b767ec0552d5 100644 --- a/src/routes/channels/mod.rs +++ b/src/routes/channels/mod.rs @@ -2,6 +2,7 @@ use rocket::Route; mod delete_channel; mod fetch_channel; +mod message_delete; mod message_edit; mod message_fetch; mod message_query; @@ -14,6 +15,7 @@ pub fn routes() -> Vec<Route> { message_send::req, message_query::req, message_fetch::req, - message_edit::req + message_edit::req, + message_delete::req ] }