diff --git a/src/notifications/events.rs b/src/notifications/events.rs index 3d747e5a..74b55755 100644 --- a/src/notifications/events.rs +++ b/src/notifications/events.rs @@ -15,6 +15,7 @@ pub enum WebSocketError { InvalidSession, OnboardingNotFinished, AlreadyAuthenticated, + MalformedData { msg: String }, } #[derive(Deserialize, Debug)] diff --git a/src/notifications/websocket.rs b/src/notifications/websocket.rs index 64373cee..b8831942 100644 --- a/src/notifications/websocket.rs +++ b/src/notifications/websocket.rs @@ -74,7 +74,20 @@ async fn accept(stream: TcpStream) { let incoming = read.try_for_each(async move |msg| { let mutex = mutex_generator(); if let Message::Text(text) = msg { - if let Ok(notification) = serde_json::from_str::(&text) { + let maybe_decoded = serde_json::from_str::(&text); + + // If serde fails to decode the data, return a `MalformedData` error + if let Err(why) = maybe_decoded { + send(ClientboundNotification::Error( + WebSocketError::MalformedData { + msg: why.to_string() + } + )); + + return Ok(()); + } + + if let Ok(notification) = maybe_decoded { match notification { ServerboundNotification::Authenticate(auth) => { { diff --git a/src/routes/bots/delete.rs b/src/routes/bots/delete.rs index 629cec92..45efe287 100644 --- a/src/routes/bots/delete.rs +++ b/src/routes/bots/delete.rs @@ -1,11 +1,11 @@ use crate::database::*; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, EmptyResponse, Result}; use mongodb::bson::doc; #[delete("/")] -pub async fn delete_bot(user: User, target: Ref) -> Result<()> { +pub async fn delete_bot(user: User, target: Ref) -> Result { let bot = target.fetch_bot().await?; if bot.owner != user.id { return Err(Error::MissingPermission); @@ -58,6 +58,6 @@ pub async fn delete_bot(user: User, target: Ref) -> Result<()> { with: "bot", operation: "delete_one" })?; - - Ok(()) + + Ok(EmptyResponse {}) } diff --git a/src/routes/bots/edit.rs b/src/routes/bots/edit.rs index 75396bd6..dc97067b 100644 --- a/src/routes/bots/edit.rs +++ b/src/routes/bots/edit.rs @@ -1,5 +1,5 @@ use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::RemoveBotField}; use mongodb::bson::doc; @@ -25,7 +25,7 @@ pub struct Data { } #[patch("/", data = "")] -pub async fn edit_bot(user: User, target: Ref, data: Json) -> Result<()> { +pub async fn edit_bot(user: User, target: Ref, data: Json) -> Result { let data = data.into_inner(); data.validate() .map_err(|error| Error::FailedValidation { error })?; @@ -112,5 +112,5 @@ pub async fn edit_bot(user: User, target: Ref, data: Json) -> Result<()> { })?; } - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/bots/invite.rs b/src/routes/bots/invite.rs index 0f7399ef..c197e629 100644 --- a/src/routes/bots/invite.rs +++ b/src/routes/bots/invite.rs @@ -1,5 +1,5 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use rocket::serde::json::Json; use serde::Deserialize; @@ -22,7 +22,7 @@ pub enum Destination { } #[post("//invite", data = "")] -pub async fn invite_bot(user: User, target: Ref, dest: Json) -> Result<()> { +pub async fn invite_bot(user: User, target: Ref, dest: Json) -> Result { let bot = target.fetch_bot().await?; if !bot.public { @@ -39,13 +39,13 @@ pub async fn invite_bot(user: User, target: Ref, dest: Json) -> Res .with_server(&server) .for_server() .await?; - + if !perm.get_manage_server() { Err(Error::MissingPermission)? } server.join_member(&bot.id).await?; - Ok(()) + Ok(EmptyResponse {}) } Destination::Group(GroupId { group }) => { let channel = Ref::from(group)?.fetch_channel().await?; @@ -54,7 +54,7 @@ pub async fn invite_bot(user: User, target: Ref, dest: Json) -> Res .with_channel(&channel) .for_channel() .await?; - + if !perm.get_invite_others() { Err(Error::MissingPermission)? } diff --git a/src/routes/channels/channel_ack.rs b/src/routes/channels/channel_ack.rs index d0763b1f..ce56a2d2 100644 --- a/src/routes/channels/channel_ack.rs +++ b/src/routes/channels/channel_ack.rs @@ -1,16 +1,16 @@ use crate::database::*; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; use mongodb::options::UpdateOptions; #[put("//ack/")] -pub async fn req(user: User, target: Ref, message: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref, message: Ref) -> Result { if user.bot.is_some() { return Err(Error::IsBot) } - + let target = target.fetch_channel().await?; let perm = permissions::PermissionCalculator::new(&user) @@ -52,5 +52,5 @@ pub async fn req(user: User, target: Ref, message: Ref) -> Result<()> { } .publish(user.id); - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/channels/channel_delete.rs b/src/routes/channels/channel_delete.rs index 6bff3df9..be1ba540 100644 --- a/src/routes/channels/channel_delete.rs +++ b/src/routes/channels/channel_delete.rs @@ -1,10 +1,10 @@ -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::ClientboundNotification}; use mongodb::bson::doc; #[delete("/")] -pub async fn req(user: User, target: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref) -> Result { let target = target.fetch_channel().await?; let perm = permissions::PermissionCalculator::new(&user) @@ -37,7 +37,7 @@ pub async fn req(user: User, target: Ref) -> Result<()> { with: "channel", })?; - Ok(()) + Ok(EmptyResponse {}) } Channel::Group { id, @@ -103,7 +103,7 @@ pub async fn req(user: User, target: Ref) -> Result<()> { .await .ok(); - Ok(()) + Ok(EmptyResponse {}) } Channel::TextChannel { .. } | Channel::VoiceChannel { .. } => { diff --git a/src/routes/channels/channel_edit.rs b/src/routes/channels/channel_edit.rs index d32a5a87..f48e2643 100644 --- a/src/routes/channels/channel_edit.rs +++ b/src/routes/channels/channel_edit.rs @@ -1,5 +1,5 @@ use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::RemoveChannelField}; use mongodb::bson::{doc, to_document}; @@ -21,7 +21,7 @@ pub struct Data { } #[patch("/", data = "")] -pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, data: Json) -> Result { let data = data.into_inner(); data.validate() .map_err(|error| Error::FailedValidation { error })?; @@ -31,7 +31,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { && data.icon.is_none() && data.remove.is_none() { - return Ok(()); + return Ok(EmptyResponse {}); } let target = target.fetch_channel().await?; @@ -146,7 +146,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { } } - Ok(()) + Ok(EmptyResponse {}) } _ => Err(Error::InvalidOperation), } diff --git a/src/routes/channels/group_add_member.rs b/src/routes/channels/group_add_member.rs index f2108373..37e2bbe9 100644 --- a/src/routes/channels/group_add_member.rs +++ b/src/routes/channels/group_add_member.rs @@ -1,10 +1,10 @@ -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::database::*; use mongodb::bson::doc; #[put("//recipients/")] -pub async fn req(user: User, target: Ref, member: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref, member: Ref) -> Result { if get_relationship(&user, &member.id) != RelationshipStatus::Friend { Err(Error::NotFriends)? } @@ -19,5 +19,6 @@ pub async fn req(user: User, target: Ref, member: Ref) -> Result<()> { Err(Error::MissingPermission)? } - channel.add_to_group(member.id, user.id).await + channel.add_to_group(member.id, user.id).await; + Ok(EmptyResponse {}) } diff --git a/src/routes/channels/group_remove_member.rs b/src/routes/channels/group_remove_member.rs index fa59a214..83e0e5ee 100644 --- a/src/routes/channels/group_remove_member.rs +++ b/src/routes/channels/group_remove_member.rs @@ -1,10 +1,10 @@ -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::ClientboundNotification}; use mongodb::bson::doc; #[delete("//recipients/")] -pub async fn req(user: User, target: Ref, member: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref, member: Ref) -> Result { if &user.id == &member.id { Err(Error::CannotRemoveYourself)? } @@ -59,7 +59,7 @@ pub async fn req(user: User, target: Ref, member: Ref) -> Result<()> { .await .ok(); - Ok(()) + Ok(EmptyResponse {}) } else { Err(Error::InvalidOperation) } diff --git a/src/routes/channels/message_delete.rs b/src/routes/channels/message_delete.rs index c0f3ac57..f22762d9 100644 --- a/src/routes/channels/message_delete.rs +++ b/src/routes/channels/message_delete.rs @@ -1,10 +1,10 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; #[delete("//messages/")] -pub async fn req(user: User, target: Ref, msg: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref, msg: Ref) -> Result { let channel = target.fetch_channel().await?; channel.has_messaging()?; @@ -24,5 +24,6 @@ pub async fn req(user: User, target: Ref, msg: Ref) -> Result<()> { } } - message.delete().await + message.delete().await; + Ok(EmptyResponse {}) } diff --git a/src/routes/channels/message_edit.rs b/src/routes/channels/message_edit.rs index 7b44c585..094b950b 100644 --- a/src/routes/channels/message_edit.rs +++ b/src/routes/channels/message_edit.rs @@ -1,5 +1,5 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use chrono::Utc; use mongodb::bson::{doc, Bson, DateTime, Document}; @@ -14,7 +14,7 @@ pub struct Data { } #[patch("//messages/", data = "")] -pub async fn req(user: User, target: Ref, msg: Ref, edit: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, msg: Ref, edit: Json) -> Result { edit.validate() .map_err(|error| Error::FailedValidation { error })?; @@ -73,5 +73,6 @@ pub async fn req(user: User, target: Ref, msg: Ref, edit: Json) -> Result< with: "message", })?; - message.publish_update(update).await + message.publish_update(update).await; + Ok(EmptyResponse {}) } diff --git a/src/routes/channels/permissions_set.rs b/src/routes/channels/permissions_set.rs index bd464a92..785e9c54 100644 --- a/src/routes/channels/permissions_set.rs +++ b/src/routes/channels/permissions_set.rs @@ -6,7 +6,7 @@ use validator::Contains; use crate::database::*; use crate::database::permissions::channel::ChannelPermission; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; #[derive(Serialize, Deserialize)] pub struct Data { @@ -14,7 +14,7 @@ pub struct Data { } #[put("//permissions/", data = "", rank = 2)] -pub async fn req(user: User, target: Ref, role: String, data: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, role: String, data: Json) -> Result { let target = target.fetch_channel().await?; match target { @@ -25,7 +25,7 @@ pub async fn req(user: User, target: Ref, role: String, data: Json) -> Res .with_server(&target) .for_server() .await?; - + if !perm.get_manage_roles() { return Err(Error::MissingPermission); } @@ -33,9 +33,9 @@ pub async fn req(user: User, target: Ref, role: String, data: Json) -> Res if !target.roles.has_element(&role) { return Err(Error::NotFound); } - + let permissions: u32 = ChannelPermission::View as u32 | data.permissions; - + get_collection("channels") .update_one( doc! { "_id": &id }, @@ -51,7 +51,7 @@ pub async fn req(user: User, target: Ref, role: String, data: Json) -> Res operation: "update_one", with: "channel" })?; - + role_permissions.insert(role, permissions as i32); ClientboundNotification::ChannelUpdate { id: id.clone(), @@ -62,7 +62,7 @@ pub async fn req(user: User, target: Ref, role: String, data: Json) -> Res } .publish(id); - Ok(()) + Ok(EmptyResponse {}) } _ => Err(Error::InvalidOperation) } diff --git a/src/routes/channels/permissions_set_default.rs b/src/routes/channels/permissions_set_default.rs index 4907b278..41589bbe 100644 --- a/src/routes/channels/permissions_set_default.rs +++ b/src/routes/channels/permissions_set_default.rs @@ -5,7 +5,7 @@ use serde::{Serialize, Deserialize}; use crate::database::*; use crate::database::permissions::channel::{ ChannelPermission, DEFAULT_PERMISSION_DM }; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; #[derive(Serialize, Deserialize)] pub struct Data { @@ -13,14 +13,14 @@ pub struct Data { } #[put("//permissions/default", data = "", rank = 1)] -pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, data: Json) -> Result { let target = target.fetch_channel().await?; match target { Channel::Group { id, owner, .. } => { if user.id == owner { let permissions: u32 = ChannelPermission::View as u32 | (data.permissions & *DEFAULT_PERMISSION_DM); - + get_collection("channels") .update_one( doc! { "_id": &id }, @@ -36,7 +36,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { operation: "update_one", with: "channel" })?; - + ClientboundNotification::ChannelUpdate { id: id.clone(), data: json!({ @@ -45,8 +45,8 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { clear: None } .publish(id); - - Ok(()) + + Ok(EmptyResponse {}) } else { Err(Error::MissingPermission) } @@ -58,13 +58,13 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { .with_server(&target) .for_server() .await?; - + if !perm.get_manage_roles() { return Err(Error::MissingPermission); } let permissions: u32 = ChannelPermission::View as u32 | data.permissions; - + get_collection("channels") .update_one( doc! { "_id": &id }, @@ -80,7 +80,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { operation: "update_one", with: "channel" })?; - + ClientboundNotification::ChannelUpdate { id: id.clone(), data: json!({ @@ -90,7 +90,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { } .publish(id); - Ok(()) + Ok(EmptyResponse {}) } _ => Err(Error::InvalidOperation) } diff --git a/src/routes/invites/invite_delete.rs b/src/routes/invites/invite_delete.rs index afd36b5a..c5557ad9 100644 --- a/src/routes/invites/invite_delete.rs +++ b/src/routes/invites/invite_delete.rs @@ -1,8 +1,8 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; #[delete("/")] -pub async fn req(user: User, target: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref) -> Result { let target = target.fetch_invite().await?; if target.creator() == &user.id { @@ -20,7 +20,8 @@ pub async fn req(user: User, target: Ref) -> Result<()> { return Err(Error::MissingPermission); } - target.delete().await + target.delete().await; + Ok(EmptyResponse {}) } _ => unreachable!(), } diff --git a/src/routes/onboard/complete.rs b/src/routes/onboard/complete.rs index 25726771..54f2e330 100644 --- a/src/routes/onboard/complete.rs +++ b/src/routes/onboard/complete.rs @@ -1,5 +1,5 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; use rauth::auth::Session; @@ -19,7 +19,7 @@ pub struct Data { } #[post("/complete", data = "")] -pub async fn req(session: Session, user: Option, data: Json) -> Result<()> { +pub async fn req(session: Session, user: Option, data: Json) -> Result { if user.is_some() { Err(Error::AlreadyOnboarded)? } @@ -45,5 +45,5 @@ pub async fn req(session: Session, user: Option, data: Json) -> Resu with: "user", })?; - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/push/subscribe.rs b/src/routes/push/subscribe.rs index ac23628b..565750de 100644 --- a/src/routes/push/subscribe.rs +++ b/src/routes/push/subscribe.rs @@ -4,7 +4,7 @@ use crate::util::result::{Error, Result}; use mongodb::bson::{doc, to_document}; use rauth::auth::Session; use rocket::serde::json::Json; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize, EmptyResponse}; #[derive(Serialize, Deserialize)] pub struct Subscription { @@ -14,7 +14,7 @@ pub struct Subscription { } #[post("/subscribe", data = "")] -pub async fn req(session: Session, data: Json) -> Result<()> { +pub async fn req(session: Session, data: Json) -> Result { let data = data.into_inner(); get_collection("accounts") .update_one( @@ -33,5 +33,5 @@ pub async fn req(session: Session, data: Json) -> Result<()> { .await .map_err(|_| Error::DatabaseError { operation: "update_one", with: "account" })?; - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/push/unsubscribe.rs b/src/routes/push/unsubscribe.rs index 41634e7b..19deaeb9 100644 --- a/src/routes/push/unsubscribe.rs +++ b/src/routes/push/unsubscribe.rs @@ -1,11 +1,11 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; use rauth::auth::Session; #[post("/unsubscribe")] -pub async fn req(session: Session) -> Result<()> { +pub async fn req(session: Session) -> Result { get_collection("accounts") .update_one( doc! { @@ -25,5 +25,5 @@ pub async fn req(session: Session) -> Result<()> { with: "subscription", })?; - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/ban_create.rs b/src/routes/servers/ban_create.rs index 3207f492..6dc215c7 100644 --- a/src/routes/servers/ban_create.rs +++ b/src/routes/servers/ban_create.rs @@ -1,5 +1,5 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; use rocket::serde::json::Json; @@ -13,7 +13,7 @@ pub struct Data { } #[put("//bans/", data = "")] -pub async fn req(user: User, server: Ref, target: Ref, data: Json) -> Result<()> { +pub async fn req(user: User, server: Ref, target: Ref, data: Json) -> Result { let data = data.into_inner(); data.validate() .map_err(|error| Error::FailedValidation { error })?; @@ -57,5 +57,6 @@ pub async fn req(user: User, server: Ref, target: Ref, data: Json) -> Resu with: "server_ban", })?; - server.remove_member(&target.id, RemoveMember::Ban).await + server.remove_member(&target.id, RemoveMember::Ban).await; + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/ban_remove.rs b/src/routes/servers/ban_remove.rs index ac345585..a4f1d6db 100644 --- a/src/routes/servers/ban_remove.rs +++ b/src/routes/servers/ban_remove.rs @@ -1,10 +1,10 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; 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) @@ -39,5 +39,5 @@ pub async fn req(user: User, server: Ref, target: Ref) -> Result<()> { with: "server_ban", })?; - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/member_edit.rs b/src/routes/servers/member_edit.rs index 4e834a8f..dc1b79e5 100644 --- a/src/routes/servers/member_edit.rs +++ b/src/routes/servers/member_edit.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::RemoveMemberField}; use mongodb::bson::{doc, to_document}; @@ -19,7 +19,7 @@ pub struct Data { } #[patch("//members/", data = "")] -pub async fn req(user: User, server: Ref, target: String, data: Json) -> Result<()> { +pub async fn req(user: User, server: Ref, target: String, data: Json) -> Result { let data = data.into_inner(); data.validate() .map_err(|error| Error::FailedValidation { error })?; @@ -154,5 +154,5 @@ pub async fn req(user: User, server: Ref, target: String, data: Json) -> R } } - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/member_remove.rs b/src/routes/servers/member_remove.rs index 8fce3a14..6abe2e65 100644 --- a/src/routes/servers/member_remove.rs +++ b/src/routes/servers/member_remove.rs @@ -1,10 +1,10 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; #[delete("//members/")] -pub async fn req(user: User, target: Ref, member: String) -> Result<()> { +pub async fn req(user: User, target: Ref, member: String) -> Result { let target = target.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) @@ -27,5 +27,7 @@ pub async fn req(user: User, target: Ref, member: String) -> Result<()> { target .remove_member(&member.id.user, RemoveMember::Kick) - .await + .await; + + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/permissions_set.rs b/src/routes/servers/permissions_set.rs index 49ad53c8..4626dcab 100644 --- a/src/routes/servers/permissions_set.rs +++ b/src/routes/servers/permissions_set.rs @@ -6,7 +6,7 @@ use crate::database::*; use crate::database::permissions::channel::ChannelPermission; use crate::database::permissions::server::ServerPermission; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; #[derive(Serialize, Deserialize)] pub struct Values { @@ -20,7 +20,7 @@ pub struct Data { } #[put("//permissions/", data = "", rank = 2)] -pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> Result { let target = target.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) @@ -38,7 +38,7 @@ pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> let server_permissions: u32 = ServerPermission::View as u32 | data.permissions.server; let channel_permissions: u32 = ChannelPermission::View as u32 | data.permissions.channel; - + get_collection("servers") .update_one( doc! { "_id": &target.id }, @@ -57,7 +57,7 @@ pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> operation: "update_one", with: "server" })?; - + ClientboundNotification::ServerRoleUpdate { id: target.id.clone(), role_id, @@ -71,5 +71,5 @@ pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> } .publish(target.id); - Ok(()) + Ok(EmptyResponse) } diff --git a/src/routes/servers/permissions_set_default.rs b/src/routes/servers/permissions_set_default.rs index d6982767..52e03545 100644 --- a/src/routes/servers/permissions_set_default.rs +++ b/src/routes/servers/permissions_set_default.rs @@ -6,7 +6,7 @@ use crate::database::*; use crate::database::permissions::channel::ChannelPermission; use crate::database::permissions::server::ServerPermission; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; #[derive(Serialize, Deserialize)] pub struct Values { @@ -20,7 +20,7 @@ pub struct Data { } #[put("//permissions/default", data = "", rank = 1)] -pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, data: Json) -> Result { let target = target.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) @@ -34,7 +34,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { let server_permissions: u32 = ServerPermission::View as u32 | data.permissions.server; let channel_permissions: u32 = ChannelPermission::View as u32 | data.permissions.channel; - + get_collection("servers") .update_one( doc! { "_id": &target.id }, @@ -53,7 +53,7 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { operation: "update_one", with: "server" })?; - + ClientboundNotification::ServerUpdate { id: target.id.clone(), data: json!({ @@ -66,5 +66,5 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { } .publish(target.id); - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/roles_delete.rs b/src/routes/servers/roles_delete.rs index 09c7b2c5..6b2dc33d 100644 --- a/src/routes/servers/roles_delete.rs +++ b/src/routes/servers/roles_delete.rs @@ -1,11 +1,11 @@ use crate::database::*; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; #[delete("//roles/")] -pub async fn req(user: User, target: Ref, role_id: String) -> Result<()> { +pub async fn req(user: User, target: Ref, role_id: String) -> Result { let target = target.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) @@ -70,12 +70,12 @@ pub async fn req(user: User, target: Ref, role_id: String) -> Result<()> { operation: "update_many", with: "server_members" })?; - + ClientboundNotification::ServerRoleDelete { id: target.id.clone(), role_id } .publish(target.id); - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/roles_edit.rs b/src/routes/servers/roles_edit.rs index 1f942e17..046d5c8a 100644 --- a/src/routes/servers/roles_edit.rs +++ b/src/routes/servers/roles_edit.rs @@ -1,5 +1,5 @@ use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::RemoveRoleField}; use mongodb::bson::doc; @@ -19,7 +19,7 @@ pub struct Data { } #[patch("//roles/", data = "")] -pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> Result { let data = data.into_inner(); data.validate() .map_err(|error| Error::FailedValidation { error })?; @@ -106,5 +106,5 @@ pub async fn req(user: User, target: Ref, role_id: String, data: Json) -> } .publish(target.id.clone()); - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/server_ack.rs b/src/routes/servers/server_ack.rs index a11e2908..199fb843 100644 --- a/src/routes/servers/server_ack.rs +++ b/src/routes/servers/server_ack.rs @@ -1,12 +1,12 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; #[put("//ack")] -pub async fn req(user: User, target: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref) -> Result { if user.bot.is_some() { return Err(Error::IsBot) } - + let target = target.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) @@ -18,5 +18,6 @@ pub async fn req(user: User, target: Ref) -> Result<()> { Err(Error::MissingPermission)? } - target.mark_as_read(&user.id).await + target.mark_as_read(&user.id).await; + Ok(EmptyResponse {}) } diff --git a/src/routes/servers/server_delete.rs b/src/routes/servers/server_delete.rs index e335b81c..a7abaafd 100644 --- a/src/routes/servers/server_delete.rs +++ b/src/routes/servers/server_delete.rs @@ -1,10 +1,10 @@ use crate::database::*; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; #[delete("/")] -pub async fn req(user: User, target: Ref) -> Result<()> { +pub async fn req(user: User, target: Ref) -> Result { let target = target.fetch_server().await?; let perm = permissions::PermissionCalculator::new(&user) .with_server(&target) diff --git a/src/routes/servers/server_edit.rs b/src/routes/servers/server_edit.rs index b4f7368a..d7cc17d6 100644 --- a/src/routes/servers/server_edit.rs +++ b/src/routes/servers/server_edit.rs @@ -1,5 +1,5 @@ use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::RemoveServerField}; use mongodb::bson::{doc, to_bson, to_document}; @@ -21,14 +21,14 @@ pub struct Data { } #[patch("/", data = "")] -pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { +pub async fn req(user: User, target: Ref, data: Json) -> Result { let data = data.into_inner(); data.validate() .map_err(|error| Error::FailedValidation { error })?; if data.name.is_none() && data.description.is_none() && data.icon.is_none() && data.banner.is_none() && data.remove.is_none() && data.categories.is_none() && data.system_messages.is_none() { - return Ok(()); + return Ok(EmptyResponse {}); } let target = target.fetch_server().await?; @@ -145,5 +145,5 @@ pub async fn req(user: User, target: Ref, data: Json) -> Result<()> { } } - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/sync/set_settings.rs b/src/routes/sync/set_settings.rs index a67bebb5..18f6867b 100644 --- a/src/routes/sync/set_settings.rs +++ b/src/routes/sync/set_settings.rs @@ -1,6 +1,6 @@ use crate::database::*; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use chrono::prelude::*; use mongodb::bson::{doc, to_bson}; @@ -18,11 +18,11 @@ pub struct Options { } #[post("/settings/set?", data = "")] -pub async fn req(user: User, data: Json, options: Options) -> Result<()> { +pub async fn req(user: User, data: Json, options: Options) -> Result { if user.bot.is_some() { return Err(Error::IsBot) } - + let data = data.into_inner(); let current_time = Utc::now().timestamp_millis(); let timestamp = if let Some(timestamp) = options.timestamp { @@ -70,5 +70,5 @@ pub async fn req(user: User, data: Json, options: Options) -> Result<()> { } .publish(user.id); - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/users/change_username.rs b/src/routes/users/change_username.rs index 713a69e1..95a08ca5 100644 --- a/src/routes/users/change_username.rs +++ b/src/routes/users/change_username.rs @@ -1,6 +1,6 @@ use crate::database::*; use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use mongodb::bson::doc; use rauth::auth::{Auth, Session}; @@ -31,11 +31,11 @@ pub async fn req( user: User, data: Json, _ignore_id: String, -) -> Result<()> { +) -> Result { if user.bot.is_some() { return Err(Error::IsBot) } - + data.validate() .map_err(|error| Error::FailedValidation { error })?; @@ -69,5 +69,5 @@ pub async fn req( } .publish_as_user(user.id.clone()); - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/routes/users/edit_user.rs b/src/routes/users/edit_user.rs index e17ebb54..d943ccb1 100644 --- a/src/routes/users/edit_user.rs +++ b/src/routes/users/edit_user.rs @@ -1,5 +1,5 @@ use crate::notifications::events::ClientboundNotification; -use crate::util::result::{Error, Result}; +use crate::util::result::{Error, Result, EmptyResponse}; use crate::{database::*, notifications::events::RemoveUserField}; use mongodb::bson::{doc, to_document}; @@ -29,7 +29,7 @@ pub struct Data { } #[patch("/<_ignore_id>", data = "")] -pub async fn req(user: User, data: Json, _ignore_id: String) -> Result<()> { +pub async fn req(user: User, data: Json, _ignore_id: String) -> Result { let mut data = data.into_inner(); data.validate() @@ -40,7 +40,7 @@ pub async fn req(user: User, data: Json, _ignore_id: String) -> Result<()> && data.avatar.is_none() && data.remove.is_none() { - return Ok(()); + return Ok(EmptyResponse {}); } let mut unset = doc! {}; @@ -152,5 +152,5 @@ pub async fn req(user: User, data: Json, _ignore_id: String) -> Result<()> } } - Ok(()) + Ok(EmptyResponse {}) } diff --git a/src/util/result.rs b/src/util/result.rs index 1591cf00..845cfdf1 100644 --- a/src/util/result.rs +++ b/src/util/result.rs @@ -68,8 +68,17 @@ pub enum Error { NoEffect, } +pub struct EmptyResponse; pub type Result = std::result::Result; +impl<'r> Responder<'r> for EmptyResponse { + fn respond_to(self, req: &Request) -> response::Result<'r> { + Response::build() + .status(rocket::http::Status { code: 204 }) + .ok() + } +} + /// HTTP response builder for Error enum impl<'r> Responder<'r, 'static> for Error { fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {