diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs index dc2869a6..b0a6cedd 100644 --- a/src/database/entities/channel.rs +++ b/src/database/entities/channel.rs @@ -190,7 +190,7 @@ impl Channel { if let Channel::TextChannel { server, .. } = &self { get_collection("servers") .update_one( - doc !{ + doc! { "_id": server }, doc! { diff --git a/src/database/entities/server.rs b/src/database/entities/server.rs index 069a4ec4..461891a7 100644 --- a/src/database/entities/server.rs +++ b/src/database/entities/server.rs @@ -1,10 +1,10 @@ use crate::database::*; use crate::notifications::events::ClientboundNotification; use crate::util::result::{Error, Result}; -use mongodb::bson::Document; -use mongodb::bson::doc; use futures::StreamExt; +use mongodb::bson::doc; use mongodb::bson::to_document; +use mongodb::bson::Document; use mongodb::options::FindOptions; use rocket_contrib::json::JsonValue; use serde::{Deserialize, Serialize}; @@ -149,9 +149,9 @@ impl Server { operation: "delete_many", with: "messages", })?; - + // Delete all channels, members, bans and invites. - for with in [ "channels", "invites" ] { + for with in ["channels", "invites"] { get_collection(with) .delete_many( doc! { @@ -166,7 +166,7 @@ impl Server { })?; } - for with in [ "server_members", "server_bans" ] { + for with in ["server_members", "server_bans"] { get_collection(with) .delete_many( doc! { @@ -194,7 +194,10 @@ impl Server { with: "server", })?; - ClientboundNotification::ServerDelete { id: self.id.clone() }.publish(self.id.clone()); + ClientboundNotification::ServerDelete { + id: self.id.clone(), + } + .publish(self.id.clone()); if let Some(attachment) = &self.icon { attachment.delete().await?; @@ -240,15 +243,16 @@ impl Server { "_id.server": &self.id, "_id.user": &id }, - None + None, ) .await .map_err(|_| Error::DatabaseError { operation: "find_one", with: "server_bans", })? - .is_some() { - return Err(Error::Banned) + .is_some() + { + return Err(Error::Banned); } get_collection("server_members") @@ -266,10 +270,10 @@ impl Server { operation: "insert_one", with: "server_members", })?; - + ClientboundNotification::ServerMemberJoin { id: self.id.clone(), - user: id.to_string() + user: id.to_string(), } .publish(self.id.clone()); @@ -292,11 +296,11 @@ impl Server { operation: "delete_one", with: "server_members", })?; - + if result.deleted_count > 0 { ClientboundNotification::ServerMemberLeave { id: self.id.clone(), - user: id.to_string() + user: id.to_string(), } .publish(self.id.clone()); } diff --git a/src/database/guards/reference.rs b/src/database/guards/reference.rs index 3fe6e06f..3570a29e 100644 --- a/src/database/guards/reference.rs +++ b/src/database/guards/reference.rs @@ -78,10 +78,12 @@ impl Ref { })? .ok_or_else(|| Error::NotFound)?; - Ok(from_document::(doc).map_err(|_| Error::DatabaseError { - operation: "from_document", - with: "server_member", - })?) + Ok( + from_document::(doc).map_err(|_| Error::DatabaseError { + operation: "from_document", + with: "server_member", + })?, + ) } pub async fn fetch_ban(&self, server: &str) -> Result { diff --git a/src/database/permissions/channel.rs b/src/database/permissions/channel.rs index 1f302882..c47a21b0 100644 --- a/src/database/permissions/channel.rs +++ b/src/database/permissions/channel.rs @@ -9,12 +9,12 @@ use std::ops; #[derive(Debug, PartialEq, Eq, TryFromPrimitive, Copy, Clone)] #[repr(u32)] pub enum ChannelPermission { - View = 0b00000000000000000000000000000001, // 1 - SendMessage = 0b00000000000000000000000000000010, // 2 + View = 0b00000000000000000000000000000001, // 1 + SendMessage = 0b00000000000000000000000000000010, // 2 ManageMessages = 0b00000000000000000000000000000100, // 4 - ManageChannel = 0b00000000000000000000000000001000, // 8 - VoiceCall = 0b00000000000000000000000000010000, // 16 - InviteOthers = 0b00000000000000000000000000100000, // 32 + ManageChannel = 0b00000000000000000000000000001000, // 8 + VoiceCall = 0b00000000000000000000000000010000, // 16 + InviteOthers = 0b00000000000000000000000000100000, // 32 } impl_op_ex!(+ |a: &ChannelPermission, b: &ChannelPermission| -> u32 { *a as u32 | *b as u32 }); diff --git a/src/database/permissions/server.rs b/src/database/permissions/server.rs index c4af2dda..8c4b6f16 100644 --- a/src/database/permissions/server.rs +++ b/src/database/permissions/server.rs @@ -8,18 +8,18 @@ use std::ops; #[derive(Debug, PartialEq, Eq, TryFromPrimitive, Copy, Clone)] #[repr(u32)] pub enum ServerPermission { - View = 0b00000000000000000000000000000001, // 1 - ManageMembers = 0b00000000000000000000000000000010, // 2 - ManageChannels = 0b00000000000000000000000000000100, // 4 - ManageServer = 0b00000000000000000000000000001000, // 8 - KickMembers = 0b00000000000000000000000000010000, // 16 - BanMembers = 0b00000000000000000000000000100000, // 32 + View = 0b00000000000000000000000000000001, // 1 + ManageMembers = 0b00000000000000000000000000000010, // 2 + ManageChannels = 0b00000000000000000000000000000100, // 4 + ManageServer = 0b00000000000000000000000000001000, // 8 + KickMembers = 0b00000000000000000000000000010000, // 16 + BanMembers = 0b00000000000000000000000000100000, // 32 // 6 bits of space - ChangeNickname = 0b00000000000000000001000000000000, // 4096 + ChangeNickname = 0b00000000000000000001000000000000, // 4096 ManageNicknames = 0b00000000000000000010000000000000, // 8192 - ChangeAvatar = 0b00000000000000000100000000000000, // 16392 - RemoveAvatars = 0b00000000000000001000000000000000, // 32784 - // 16 bits of space + ChangeAvatar = 0b00000000000000000100000000000000, // 16392 + RemoveAvatars = 0b00000000000000001000000000000000, // 32784 + // 16 bits of space } impl_op_ex!(+ |a: &ServerPermission, b: &ServerPermission| -> u32 { *a as u32 | *b as u32 }); @@ -52,7 +52,9 @@ impl<'a> PermissionCalculator<'a> { if self.perspective.id == server.owner { Ok(u32::MAX) } else { - Ok(ServerPermission::View + ServerPermission::ChangeNickname + ServerPermission::ChangeAvatar) + Ok(ServerPermission::View + + ServerPermission::ChangeNickname + + ServerPermission::ChangeAvatar) } } diff --git a/src/database/permissions/user.rs b/src/database/permissions/user.rs index 11f9fc9c..b68bf839 100644 --- a/src/database/permissions/user.rs +++ b/src/database/permissions/user.rs @@ -10,10 +10,10 @@ use std::ops; #[derive(Debug, PartialEq, Eq, TryFromPrimitive, Copy, Clone)] #[repr(u32)] pub enum UserPermission { - Access = 0b00000000000000000000000000000001, // 1 + Access = 0b00000000000000000000000000000001, // 1 ViewProfile = 0b00000000000000000000000000000010, // 2 SendMessage = 0b00000000000000000000000000000100, // 4 - Invite = 0b00000000000000000000000000001000, // 8 + Invite = 0b00000000000000000000000000001000, // 8 } bitfield! { diff --git a/src/notifications/events.rs b/src/notifications/events.rs index 52fee131..fbc67c9d 100644 --- a/src/notifications/events.rs +++ b/src/notifications/events.rs @@ -53,7 +53,7 @@ pub enum RemoveServerField { #[derive(Serialize, Deserialize, Debug, Clone)] pub enum RemoveMemberField { Nickname, - Avatar + Avatar, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -216,35 +216,23 @@ pub async fn posthandle_hook(notification: &ClientboundNotification) { get_hive().hive.drop_topic(&id).ok(); } ClientboundNotification::ChannelGroupLeave { id, user } => { - get_hive() - .hive - .unsubscribe(user, id) - .ok(); + get_hive().hive.unsubscribe(user, id).ok(); } ClientboundNotification::ServerDelete { id } => { get_hive().hive.drop_topic(&id).ok(); } ClientboundNotification::ServerMemberLeave { id, user } => { - get_hive() - .hive - .unsubscribe(user, id) - .ok(); + get_hive().hive.unsubscribe(user, id).ok(); if let Ok(server) = Ref::from_unchecked(id.clone()).fetch_server().await { for channel in server.channels { - get_hive() - .hive - .unsubscribe(user, &channel) - .ok(); + get_hive().hive.unsubscribe(user, &channel).ok(); } } } ClientboundNotification::UserRelationship { id, user, status } => { if status == &RelationshipStatus::None { - get_hive() - .hive - .unsubscribe(id, &user.id) - .ok(); + get_hive().hive.unsubscribe(id, &user.id).ok(); } } _ => {} diff --git a/src/routes/channels/delete_channel.rs b/src/routes/channels/delete_channel.rs index faf877e6..9c6245c5 100644 --- a/src/routes/channels/delete_channel.rs +++ b/src/routes/channels/delete_channel.rs @@ -11,7 +11,7 @@ pub async fn req(user: User, target: Ref) -> Result<()> { .with_channel(&target) .for_channel() .await?; - + if !perm.get_view() { Err(Error::MissingPermission)? } diff --git a/src/routes/channels/edit_channel.rs b/src/routes/channels/edit_channel.rs index afafdbb6..249b29ba 100644 --- a/src/routes/channels/edit_channel.rs +++ b/src/routes/channels/edit_channel.rs @@ -45,8 +45,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { } match &target { - Channel::Group { id, icon, .. } | - Channel::TextChannel { id, icon, .. } => { + Channel::Group { id, icon, .. } | Channel::TextChannel { id, icon, .. } => { let mut set = doc! {}; let mut unset = doc! {}; diff --git a/src/routes/invites/invite_delete.rs b/src/routes/invites/invite_delete.rs index ac3ea122..afd36b5a 100644 --- a/src/routes/invites/invite_delete.rs +++ b/src/routes/invites/invite_delete.rs @@ -21,8 +21,8 @@ pub async fn req(user: User, target: Ref) -> Result<()> { } target.delete().await - }, - _ => unreachable!() + } + _ => unreachable!(), } } } diff --git a/src/routes/invites/invite_fetch.rs b/src/routes/invites/invite_fetch.rs index 27020a62..3fbb6077 100644 --- a/src/routes/invites/invite_fetch.rs +++ b/src/routes/invites/invite_fetch.rs @@ -18,8 +18,8 @@ pub enum InviteResponse { channel_description: Option, user_name: String, #[serde(skip_serializing_if = "Option::is_none")] - user_avatar: Option - } + user_avatar: Option, + }, } #[get("/")] @@ -28,14 +28,18 @@ pub async fn req(target: Ref) -> Result { match target { Invite::Server { - channel, - creator, - .. + channel, creator, .. } => { let channel = Ref::from_unchecked(channel).fetch_channel().await?; let creator = Ref::from_unchecked(creator).fetch_user().await?; - if let Channel::TextChannel { server, name, description, .. } = channel { + if let Channel::TextChannel { + server, + name, + description, + .. + } = channel + { let server = Ref::from_unchecked(server).fetch_server().await?; Ok(json!(InviteResponse::Server { diff --git a/src/routes/invites/invite_join.rs b/src/routes/invites/invite_join.rs index cf7a601c..afa6baec 100644 --- a/src/routes/invites/invite_join.rs +++ b/src/routes/invites/invite_join.rs @@ -8,10 +8,7 @@ pub async fn req(user: User, target: Ref) -> Result { let target = target.fetch_invite().await?; match target { - Invite::Server { - channel, - .. - } => { + Invite::Server { channel, .. } => { let channel = Ref::from_unchecked(channel).fetch_channel().await?; let server = if let Channel::TextChannel { server, .. } = &channel { Ref::from_unchecked(server.clone()).fetch_server().await? diff --git a/src/routes/servers/ban_create.rs b/src/routes/servers/ban_create.rs index 76a7428f..b14a814b 100644 --- a/src/routes/servers/ban_create.rs +++ b/src/routes/servers/ban_create.rs @@ -2,9 +2,9 @@ use crate::database::*; use crate::util::result::{Error, Result}; use mongodb::bson::doc; -use validator::Validate; use rocket_contrib::json::Json; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; +use validator::Validate; #[derive(Validate, Serialize, Deserialize)] pub struct Data { @@ -17,14 +17,14 @@ pub async fn req(user: User, server: Ref, target: Ref, data: Json) -> Resu let data = data.into_inner(); data.validate() .map_err(|error| Error::FailedValidation { error })?; - + let server = server.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) .with_server(&server) .for_server() .await?; - + if !perm.get_ban_members() { Err(Error::MissingPermission)? } @@ -42,15 +42,12 @@ pub async fn req(user: User, server: Ref, target: Ref, data: Json) -> Resu } get_collection("server_bans") - .insert_one( - document, - None - ) + .insert_one(document, None) .await .map_err(|_| Error::DatabaseError { operation: "insert_one", - with: "server_ban" + with: "server_ban", })?; - + server.remove_member(&target.id).await } diff --git a/src/routes/servers/ban_list.rs b/src/routes/servers/ban_list.rs index 56899aa4..62e8c82e 100644 --- a/src/routes/servers/ban_list.rs +++ b/src/routes/servers/ban_list.rs @@ -2,8 +2,8 @@ use crate::database::*; use crate::util::result::{Error, Result}; use futures::StreamExt; -use rocket_contrib::json::JsonValue; use mongodb::bson::{doc, from_document}; +use rocket_contrib::json::JsonValue; #[get("//bans")] pub async fn req(user: User, target: Ref) -> Result { @@ -13,7 +13,7 @@ pub async fn req(user: User, target: Ref) -> Result { .with_server(&target) .for_server() .await?; - + if !perm.get_manage_members() { Err(Error::MissingPermission)? } @@ -30,7 +30,7 @@ pub async fn req(user: User, target: Ref) -> Result { operation: "find", with: "server_bans", })?; - + let mut bans = vec![]; while let Some(result) = cursor.next().await { if let Ok(doc) = result { @@ -39,6 +39,6 @@ pub async fn req(user: User, target: Ref) -> Result { } } } - + Ok(json!(bans)) } diff --git a/src/routes/servers/ban_remove.rs b/src/routes/servers/ban_remove.rs index 76e44ddb..ac345585 100644 --- a/src/routes/servers/ban_remove.rs +++ b/src/routes/servers/ban_remove.rs @@ -4,24 +4,24 @@ use crate::util::result::{Error, Result}; use mongodb::bson::doc; #[delete("//bans/")] -pub async fn req(user: User, server: Ref, target: Ref) -> Result<()> { +pub async fn req(user: User, server: Ref, target: Ref) -> Result<()> { let server = server.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) .with_server(&server) .for_server() .await?; - + if !perm.get_ban_members() { Err(Error::MissingPermission)? } if target.id == user.id { - return Err(Error::InvalidOperation) + return Err(Error::InvalidOperation); } if target.id == server.owner { - return Err(Error::MissingPermission) + return Err(Error::MissingPermission); } let target = target.fetch_ban(&server.id).await?; @@ -31,13 +31,13 @@ pub async fn req(user: User, server: Ref, target: Ref) -> Result<()> { "_id.server": &server.id, "_id.user": &target.id.user }, - None + None, ) .await .map_err(|_| Error::DatabaseError { operation: "delete_one", - with: "server_ban" + with: "server_ban", })?; - + Ok(()) } diff --git a/src/routes/servers/invites_fetch.rs b/src/routes/servers/invites_fetch.rs index f55dce7e..9ef36073 100644 --- a/src/routes/servers/invites_fetch.rs +++ b/src/routes/servers/invites_fetch.rs @@ -1,10 +1,10 @@ use crate::database::*; use crate::util::result::{Error, Result}; -use rocket_contrib::json::JsonValue; -use serde::{Serialize, Deserialize}; -use mongodb::bson::{doc, from_document}; use futures::StreamExt; +use mongodb::bson::{doc, from_document}; +use rocket_contrib::json::JsonValue; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ServerInvite { @@ -22,7 +22,7 @@ pub async fn req(user: User, target: Ref) -> Result { .with_server(&target) .for_server() .await?; - + if !perm.get_manage_server() { Err(Error::MissingPermission)? } @@ -39,7 +39,7 @@ pub async fn req(user: User, target: Ref) -> Result { operation: "find", with: "invites", })?; - + let mut invites = vec![]; while let Some(result) = cursor.next().await { if let Ok(doc) = result { @@ -48,6 +48,6 @@ pub async fn req(user: User, target: Ref) -> Result { } } } - + Ok(json!(invites)) } diff --git a/src/routes/servers/member_edit.rs b/src/routes/servers/member_edit.rs index 29f930b4..2b34dd58 100644 --- a/src/routes/servers/member_edit.rs +++ b/src/routes/servers/member_edit.rs @@ -21,8 +21,7 @@ pub async fn req(user: User, server: Ref, target: String, data: Json) -> R data.validate() .map_err(|error| Error::FailedValidation { error })?; - if data.nickname.is_none() && data.avatar.is_none() && data.remove.is_none() - { + if data.nickname.is_none() && data.avatar.is_none() && data.remove.is_none() { return Ok(()); } @@ -35,30 +34,31 @@ pub async fn req(user: User, server: Ref, target: String, data: Json) -> R .await?; if target.id.user == user.id { - if (data.nickname.is_some() && !perm.get_change_nickname()) || - (data.avatar.is_some() && !perm.get_change_avatar()) { - return Err(Error::MissingPermission) + if (data.nickname.is_some() && !perm.get_change_nickname()) + || (data.avatar.is_some() && !perm.get_change_avatar()) + { + return Err(Error::MissingPermission); } if let Some(remove) = &data.remove { if match remove { RemoveMemberField::Avatar => !perm.get_change_avatar(), - RemoveMemberField::Nickname => !perm.get_change_nickname() + RemoveMemberField::Nickname => !perm.get_change_nickname(), } { - return Err(Error::MissingPermission) + return Err(Error::MissingPermission); } } } else { if data.avatar.is_some() || (data.nickname.is_some() && !perm.get_manage_nicknames()) { - return Err(Error::MissingPermission) + return Err(Error::MissingPermission); } if let Some(remove) = &data.remove { if match remove { RemoveMemberField::Avatar => !perm.get_remove_avatars(), - RemoveMemberField::Nickname => !perm.get_manage_nicknames() + RemoveMemberField::Nickname => !perm.get_manage_nicknames(), } { - return Err(Error::MissingPermission) + return Err(Error::MissingPermission); } } } @@ -84,7 +84,8 @@ pub async fn req(user: User, server: Ref, target: String, data: Json) -> R } if let Some(attachment_id) = &data.avatar { - let attachment = File::find_and_use(&attachment_id, "avatars", "user", &target.id.user).await?; + let attachment = + File::find_and_use(&attachment_id, "avatars", "user", &target.id.user).await?; set.insert( "avatar", to_document(&attachment).map_err(|_| Error::DatabaseError { @@ -107,7 +108,11 @@ pub async fn req(user: User, server: Ref, target: String, data: Json) -> R if operations.len() > 0 { get_collection("server_members") - .update_one(doc! { "_id.server": &server.id, "_id.user": &target.id.user }, operations, None) + .update_one( + doc! { "_id.server": &server.id, "_id.user": &target.id.user }, + operations, + None, + ) .await .map_err(|_| Error::DatabaseError { operation: "update_one", diff --git a/src/routes/servers/member_fetch.rs b/src/routes/servers/member_fetch.rs index 2f8d21e1..7631c2f2 100644 --- a/src/routes/servers/member_fetch.rs +++ b/src/routes/servers/member_fetch.rs @@ -12,7 +12,7 @@ pub async fn req(user: User, target: Ref, member: String) -> Result { .with_server(&target) .for_server() .await?; - + if !perm.get_view() { Err(Error::MissingPermission)? } diff --git a/src/routes/servers/member_fetch_all.rs b/src/routes/servers/member_fetch_all.rs index c12c3d15..4733c642 100644 --- a/src/routes/servers/member_fetch_all.rs +++ b/src/routes/servers/member_fetch_all.rs @@ -2,8 +2,8 @@ use crate::database::*; use crate::util::result::{Error, Result}; use futures::StreamExt; +use mongodb::bson::{doc, from_document, Document}; use rocket_contrib::json::JsonValue; -use mongodb::bson::{Document, doc, from_document}; // ! FIXME: this is a temporary route while permissions are being worked on. @@ -15,7 +15,7 @@ pub async fn req(user: User, target: Ref) -> Result { .with_server(&target) .for_server() .await?; - + if !perm.get_view() { Err(Error::MissingPermission)? } diff --git a/src/routes/servers/member_remove.rs b/src/routes/servers/member_remove.rs index 0c78cfb8..cac0807d 100644 --- a/src/routes/servers/member_remove.rs +++ b/src/routes/servers/member_remove.rs @@ -11,18 +11,18 @@ pub async fn req(user: User, target: Ref, member: String) -> Result<()> { .with_server(&target) .for_server() .await?; - + if !perm.get_manage_members() { - return Err(Error::MissingPermission) + return Err(Error::MissingPermission); } let member = Ref::from(member)?.fetch_member(&target.id).await?; if member.id.user == user.id { - return Err(Error::InvalidOperation) + return Err(Error::InvalidOperation); } if target.id == target.owner { - return Err(Error::MissingPermission) + return Err(Error::MissingPermission); } target.remove_member(&member.id.user).await diff --git a/src/routes/servers/mod.rs b/src/routes/servers/mod.rs index 26638b49..d9d700fc 100644 --- a/src/routes/servers/mod.rs +++ b/src/routes/servers/mod.rs @@ -2,19 +2,19 @@ use rocket::Route; mod server_create; mod server_delete; -mod server_fetch; mod server_edit; +mod server_fetch; mod channel_create; +mod member_edit; +mod member_fetch; mod member_fetch_all; mod member_remove; -mod member_fetch; -mod member_edit; mod ban_create; -mod ban_remove; mod ban_list; +mod ban_remove; mod invites_fetch; diff --git a/src/routes/servers/server_fetch.rs b/src/routes/servers/server_fetch.rs index 465b2ef0..8208464d 100644 --- a/src/routes/servers/server_fetch.rs +++ b/src/routes/servers/server_fetch.rs @@ -11,7 +11,7 @@ pub async fn req(user: User, target: Ref) -> Result { .with_server(&target) .for_server() .await?; - + if !perm.get_view() { Err(Error::MissingPermission)? } diff --git a/src/util/result.rs b/src/util/result.rs index b3225a0d..06dc9614 100644 --- a/src/util/result.rs +++ b/src/util/result.rs @@ -39,7 +39,7 @@ pub enum Error { // ? Server related errors. UnknownServer, Banned, - + // ? General errors. TooManyIds, FailedValidation {