From 01fc1228d510470d5fd1bc90414d5250fc356658 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Thu, 25 Mar 2021 20:30:15 +0100 Subject: [PATCH] Fix API and clippy warnings --- crates/api/src/community.rs | 5 +- crates/api/src/lib.rs | 121 +--------------- crates/api/src/local_user.rs | 7 +- crates/api_crud/src/comment/create.rs | 4 +- crates/api_crud/src/comment/delete.rs | 6 +- crates/api_crud/src/comment/update.rs | 4 +- crates/api_crud/src/community/delete.rs | 21 ++- crates/api_crud/src/community/mod.rs | 4 +- crates/api_crud/src/community/read.rs | 5 +- crates/api_crud/src/community/update.rs | 9 +- crates/api_crud/src/lib.rs | 116 ++++++++++++++- crates/api_crud/src/post/create.rs | 4 +- crates/api_crud/src/post/delete.rs | 6 +- crates/api_crud/src/post/read.rs | 5 +- crates/api_crud/src/post/update.rs | 4 +- crates/api_crud/src/private_message/create.rs | 4 +- crates/api_crud/src/private_message/delete.rs | 4 +- crates/api_crud/src/private_message/update.rs | 4 +- crates/api_crud/src/routes.rs | 133 ------------------ crates/api_crud/src/site/update.rs | 4 +- crates/apub/src/activities/receive/comment.rs | 10 +- .../src/activities/receive/comment_undo.rs | 6 +- .../apub/src/activities/receive/community.rs | 10 +- crates/apub/src/activities/receive/post.rs | 10 +- .../apub/src/activities/receive/post_undo.rs | 6 +- .../src/activities/receive/private_message.rs | 10 +- crates/db_views/src/local_user_view.rs | 8 +- crates/websocket/src/chat_server.rs | 82 +++++++---- crates/websocket/src/handlers.rs | 30 ++-- crates/websocket/src/lib.rs | 75 ++++++---- crates/websocket/src/messages.rs | 20 +-- crates/websocket/src/routes.rs | 6 +- docker/federation/docker-compose.yml | 2 +- crates/api/src/routes.rs => src/api_routes.rs | 102 +++++++++++++- src/lib.rs | 1 + src/main.rs | 8 +- 36 files changed, 440 insertions(+), 416 deletions(-) delete mode 100644 crates/api_crud/src/routes.rs rename crates/api/src/routes.rs => src/api_routes.rs (60%) diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index 1ee2a9a76..f1cf570c0 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -188,10 +188,7 @@ impl Perform for BanFromCommunity { // Mod tables // TODO eventually do correct expires - let expires = match data.expires { - Some(time) => Some(naive_from_unix(time)), - None => None, - }; + let expires = data.expires.map(naive_from_unix); let form = ModBanFromCommunityForm { mod_person_id: local_user_view.person.id, diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 277498f1f..17aaf407f 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -12,7 +12,6 @@ mod local_user; mod post; mod post_report; mod private_message; -pub mod routes; mod site; mod websocket; @@ -33,29 +32,15 @@ pub async fn match_websocket_operation( op: UserOperation, data: &str, ) -> Result { - //TODO: handle commented out actions in crud crate - match op { // User ops - UserOperation::Login => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::Register => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } + UserOperation::Login => do_websocket_operation::(context, id, op, data).await, UserOperation::GetCaptcha => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetPersonDetails => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::GetReplies => do_websocket_operation::(context, id, op, data).await, UserOperation::AddAdmin => do_websocket_operation::(context, id, op, data).await, UserOperation::BanPerson => do_websocket_operation::(context, id, op, data).await, UserOperation::GetPersonMentions => { - //do_websocket_operation::(context, id, op, data).await - todo!() + do_websocket_operation::(context, id, op, data).await } UserOperation::MarkPersonMentionAsRead => { do_websocket_operation::(context, id, op, data).await @@ -63,10 +48,6 @@ pub async fn match_websocket_operation( UserOperation::MarkAllAsRead => { do_websocket_operation::(context, id, op, data).await } - UserOperation::DeleteAccount => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::PasswordReset => { do_websocket_operation::(context, id, op, data).await } @@ -87,40 +68,12 @@ pub async fn match_websocket_operation( } // Private Message ops - UserOperation::CreatePrivateMessage => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::EditPrivateMessage => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::DeletePrivateMessage => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::MarkPrivateMessageAsRead => { do_websocket_operation::(context, id, op, data).await } - UserOperation::GetPrivateMessages => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } // Site ops UserOperation::GetModlog => do_websocket_operation::(context, id, op, data).await, - UserOperation::CreateSite => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::EditSite => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::GetSite => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::GetSiteConfig => { do_websocket_operation::(context, id, op, data).await } @@ -136,30 +89,6 @@ pub async fn match_websocket_operation( } // Community ops - UserOperation::GetCommunity => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::ListCommunities => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::CreateCommunity => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::EditCommunity => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::DeleteCommunity => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::RemoveCommunity => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::FollowCommunity => { do_websocket_operation::(context, id, op, data).await } @@ -174,30 +103,6 @@ pub async fn match_websocket_operation( } // Post ops - UserOperation::CreatePost => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::GetPost => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::GetPosts => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::EditPost => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::DeletePost => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::RemovePost => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::LockPost => do_websocket_operation::(context, id, op, data).await, UserOperation::StickyPost => do_websocket_operation::(context, id, op, data).await, UserOperation::CreatePostLike => { @@ -215,32 +120,12 @@ pub async fn match_websocket_operation( } // Comment ops - UserOperation::CreateComment => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::EditComment => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::DeleteComment => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } - UserOperation::RemoveComment => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::MarkCommentAsRead => { do_websocket_operation::(context, id, op, data).await } UserOperation::SaveComment => { do_websocket_operation::(context, id, op, data).await } - UserOperation::GetComments => { - //do_websocket_operation::(context, id, op, data).await - todo!() - } UserOperation::CreateCommentLike => { do_websocket_operation::(context, id, op, data).await } @@ -326,7 +211,7 @@ pub(crate) fn espeak_wav_base64(text: &str) -> Result { #[cfg(test)] mod tests { - use crate::{captcha_espeak_wav_base64, check_validator_time}; + use crate::captcha_espeak_wav_base64; use lemmy_api_common::check_validator_time; use lemmy_db_queries::{establish_unpooled_connection, source::local_user::LocalUser_, Crud}; use lemmy_db_schema::source::{ diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index aacb7d0bf..ff28341b3 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -153,7 +153,7 @@ impl Perform for GetCaptcha { context.chat_server().do_send(captcha_item); Ok(GetCaptchaResponse { - ok: Some(CaptchaResponse { png, uuid, wav }), + ok: Some(CaptchaResponse { png, wav, uuid }), }) } } @@ -407,10 +407,7 @@ impl Perform for BanPerson { } // Mod tables - let expires = match data.expires { - Some(time) => Some(naive_from_unix(time)), - None => None, - }; + let expires = data.expires.map(naive_from_unix); let form = ModBanForm { mod_person_id: local_user_view.person.id, diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index 74ef27f15..57c850135 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -18,7 +18,7 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for CreateComment { @@ -158,7 +158,7 @@ impl PerformCrud for CreateComment { }; context.chat_server().do_send(SendComment { - op: UserOperation::CreateComment, + op: UserOperationCrud::CreateComment, comment: res.clone(), websocket_id, }); diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs index 1980106b3..bbac9c84b 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -13,7 +13,7 @@ use lemmy_db_queries::{source::comment::Comment_, Crud}; use lemmy_db_schema::source::{comment::*, moderator::*}; use lemmy_db_views::comment_view::CommentView; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeleteComment { @@ -95,7 +95,7 @@ impl PerformCrud for DeleteComment { }; context.chat_server().do_send(SendComment { - op: UserOperation::DeleteComment, + op: UserOperationCrud::DeleteComment, comment: res.clone(), websocket_id, }); @@ -200,7 +200,7 @@ impl PerformCrud for RemoveComment { }; context.chat_server().do_send(SendComment { - op: UserOperation::RemoveComment, + op: UserOperationCrud::RemoveComment, comment: res.clone(), websocket_id, }); diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index 46d99e936..fb6bdaf11 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -17,7 +17,7 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditComment { @@ -93,7 +93,7 @@ impl PerformCrud for EditComment { }; context.chat_server().do_send(SendComment { - op: UserOperation::EditComment, + op: UserOperationCrud::EditComment, comment: res.clone(), websocket_id, }); diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index e59ccd6bc..9b52660f6 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -9,7 +9,7 @@ use lemmy_db_schema::source::{ }; use lemmy_db_views_actor::community_view::CommunityView; use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{LemmyContext, UserOperation}; +use lemmy_websocket::{LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeleteCommunity { @@ -61,7 +61,12 @@ impl PerformCrud for DeleteCommunity { let res = CommunityResponse { community_view }; - send_community_websocket(&res, context, websocket_id, UserOperation::DeleteCommunity); + send_community_websocket( + &res, + context, + websocket_id, + UserOperationCrud::DeleteCommunity, + ); Ok(res) } @@ -95,10 +100,7 @@ impl PerformCrud for RemoveCommunity { }; // Mod tables - let expires = match data.expires { - Some(time) => Some(naive_from_unix(time)), - None => None, - }; + let expires = data.expires.map(naive_from_unix); let form = ModRemoveCommunityForm { mod_person_id: local_user_view.person.id, community_id: data.community_id, @@ -127,7 +129,12 @@ impl PerformCrud for RemoveCommunity { let res = CommunityResponse { community_view }; - send_community_websocket(&res, context, websocket_id, UserOperation::RemoveCommunity); + send_community_websocket( + &res, + context, + websocket_id, + UserOperationCrud::RemoveCommunity, + ); Ok(res) } diff --git a/crates/api_crud/src/community/mod.rs b/crates/api_crud/src/community/mod.rs index 874aba9a1..9098cb541 100644 --- a/crates/api_crud/src/community/mod.rs +++ b/crates/api_crud/src/community/mod.rs @@ -1,7 +1,7 @@ use actix_web::web::Data; use lemmy_api_common::community::CommunityResponse; use lemmy_utils::ConnectionId; -use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperationCrud}; mod create; mod delete; @@ -12,7 +12,7 @@ pub(in crate::community) fn send_community_websocket( res: &CommunityResponse, context: &Data, websocket_id: Option, - op: UserOperation, + op: UserOperationCrud, ) { // Strip out the person id and subscribed when sending to others let mut res_sent = res.clone(); diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index af83a7749..08982aa15 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -87,10 +87,7 @@ impl PerformCrud for ListCommunities { let data: &ListCommunities = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; - let person_id = match &local_user_view { - Some(uv) => Some(uv.person.id), - None => None, - }; + let person_id = local_user_view.to_owned().map(|l| l.person.id); // Don't show NSFW by default let show_nsfw = match &local_user_view { diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index d7fa3061e..1e5b9d0c4 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -21,7 +21,7 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{LemmyContext, UserOperation}; +use lemmy_websocket::{LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditCommunity { @@ -102,7 +102,12 @@ impl PerformCrud for EditCommunity { let res = CommunityResponse { community_view }; - send_community_websocket(&res, context, websocket_id, UserOperation::EditCommunity); + send_community_websocket( + &res, + context, + websocket_id, + UserOperationCrud::EditCommunity, + ); Ok(res) } diff --git a/crates/api_crud/src/lib.rs b/crates/api_crud/src/lib.rs index 77a900dd4..c6385d050 100644 --- a/crates/api_crud/src/lib.rs +++ b/crates/api_crud/src/lib.rs @@ -1,12 +1,13 @@ -use actix_web::web::Data; +use actix_web::{web, web::Data}; +use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*}; use lemmy_utils::{ConnectionId, LemmyError}; -use lemmy_websocket::LemmyContext; +use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperationCrud}; +use serde::Deserialize; mod comment; mod community; mod post; mod private_message; -pub mod routes; mod site; mod user; @@ -20,3 +21,112 @@ pub trait PerformCrud { websocket_id: Option, ) -> Result; } + +pub async fn match_websocket_operation_crud( + context: LemmyContext, + id: ConnectionId, + op: UserOperationCrud, + data: &str, +) -> Result { + //TODO: handle commented out actions in crud crate + + match op { + // User ops + UserOperationCrud::Register => do_websocket_operation::(context, id, op, data).await, + UserOperationCrud::GetPersonDetails => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::DeleteAccount => { + do_websocket_operation::(context, id, op, data).await + } + + // Private Message ops + UserOperationCrud::CreatePrivateMessage => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::EditPrivateMessage => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::DeletePrivateMessage => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::GetPrivateMessages => { + do_websocket_operation::(context, id, op, data).await + } + + // Site ops + UserOperationCrud::CreateSite => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::EditSite => do_websocket_operation::(context, id, op, data).await, + UserOperationCrud::GetSite => do_websocket_operation::(context, id, op, data).await, + + // Community ops + UserOperationCrud::GetCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::ListCommunities => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::CreateCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::EditCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::DeleteCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::RemoveCommunity => { + do_websocket_operation::(context, id, op, data).await + } + + // Post ops + UserOperationCrud::CreatePost => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::GetPost => do_websocket_operation::(context, id, op, data).await, + UserOperationCrud::GetPosts => do_websocket_operation::(context, id, op, data).await, + UserOperationCrud::EditPost => do_websocket_operation::(context, id, op, data).await, + UserOperationCrud::DeletePost => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::RemovePost => { + do_websocket_operation::(context, id, op, data).await + } + + // Comment ops + UserOperationCrud::CreateComment => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::EditComment => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::DeleteComment => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::RemoveComment => { + do_websocket_operation::(context, id, op, data).await + } + UserOperationCrud::GetComments => { + do_websocket_operation::(context, id, op, data).await + } + } +} + +async fn do_websocket_operation<'a, 'b, Data>( + context: LemmyContext, + id: ConnectionId, + op: UserOperationCrud, + data: &str, +) -> Result +where + for<'de> Data: Deserialize<'de> + 'a, + Data: PerformCrud, +{ + let parsed_data: Data = serde_json::from_str(&data)?; + let res = parsed_data + .perform(&web::Data::new(context), Some(id)) + .await?; + serialize_websocket_message(&op, &res) +} diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index 231a891d4..f8bce061f 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -12,7 +12,7 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for CreatePost { @@ -120,7 +120,7 @@ impl PerformCrud for CreatePost { let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::CreatePost, + op: UserOperationCrud::CreatePost, post: res.clone(), websocket_id, }); diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs index ca25f3b11..32b4e9ff0 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -12,7 +12,7 @@ use lemmy_db_queries::{source::post::Post_, Crud}; use lemmy_db_schema::source::{moderator::*, post::*}; use lemmy_db_views::post_view::PostView; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeletePost { @@ -70,7 +70,7 @@ impl PerformCrud for DeletePost { let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::DeletePost, + op: UserOperationCrud::DeletePost, post: res.clone(), websocket_id, }); @@ -151,7 +151,7 @@ impl PerformCrud for RemovePost { let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::RemovePost, + op: UserOperationCrud::RemovePost, post: res.clone(), websocket_id, }); diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 1b173418b..d8897317a 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -92,10 +92,7 @@ impl PerformCrud for GetPosts { let data: &GetPosts = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; - let person_id = match &local_user_view { - Some(uv) => Some(uv.person.id), - None => None, - }; + let person_id = local_user_view.to_owned().map(|l| l.person.id); let show_nsfw = match &local_user_view { Some(uv) => uv.local_user.show_nsfw, diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index c03bddf82..e1efc7900 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -12,7 +12,7 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditPost { @@ -106,7 +106,7 @@ impl PerformCrud for EditPost { let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::EditPost, + op: UserOperationCrud::EditPost, post: res.clone(), websocket_id, }); diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index 9654d22fd..025612630 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -11,7 +11,7 @@ use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; use lemmy_db_schema::source::private_message::{PrivateMessage, PrivateMessageForm}; use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView}; use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for CreatePrivateMessage { @@ -100,7 +100,7 @@ impl PerformCrud for CreatePrivateMessage { let local_recipient_id = local_recipient.local_user.id; context.chat_server().do_send(SendUserRoomMessage { - op: UserOperation::CreatePrivateMessage, + op: UserOperationCrud::CreatePrivateMessage, response: res.clone(), local_recipient_id, websocket_id, diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index 120f57aaa..506b0490a 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -10,7 +10,7 @@ use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView}; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeletePrivateMessage { @@ -76,7 +76,7 @@ impl PerformCrud for DeletePrivateMessage { { let local_recipient_id = local_recipient.local_user.id; context.chat_server().do_send(SendUserRoomMessage { - op: UserOperation::DeletePrivateMessage, + op: UserOperationCrud::DeletePrivateMessage, response: res.clone(), local_recipient_id, websocket_id, diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index b6baa0365..4bfb1bb99 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -10,7 +10,7 @@ use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView}; use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditPrivateMessage { @@ -70,7 +70,7 @@ impl PerformCrud for EditPrivateMessage { { let local_recipient_id = local_recipient.local_user.id; context.chat_server().do_send(SendUserRoomMessage { - op: UserOperation::EditPrivateMessage, + op: UserOperationCrud::EditPrivateMessage, response: res.clone(), local_recipient_id, websocket_id, diff --git a/crates/api_crud/src/routes.rs b/crates/api_crud/src/routes.rs deleted file mode 100644 index 774268b69..000000000 --- a/crates/api_crud/src/routes.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::PerformCrud; -use actix_web::{error::ErrorBadRequest, *}; -use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*}; -use lemmy_utils::rate_limit::RateLimit; -use lemmy_websocket::LemmyContext; -use serde::Deserialize; - -pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { - cfg - .service( - web::scope("/api/v2") - // Site - .service( - web::scope("/site") - .wrap(rate_limit.message()) - .route("", web::get().to(route_get::)) - // Admin Actions - .route("", web::post().to(route_post::)) - .route("", web::put().to(route_post::)), - ) - // Community - .service( - web::resource("/community") - .guard(guard::Post()) - .wrap(rate_limit.register()) - .route(web::post().to(route_post::)), - ) - .service( - web::scope("/community") - .wrap(rate_limit.message()) - .route("", web::get().to(route_get::)) - .route("", web::put().to(route_post::)) - .route("/list", web::get().to(route_get::)) - .route("/delete", web::post().to(route_post::)) - // Mod Actions - .route("/remove", web::post().to(route_post::)), - ) - // Post - .service( - // Handle POST to /post separately to add the post() rate limitter - web::resource("/post") - .guard(guard::Post()) - .wrap(rate_limit.post()) - .route(web::post().to(route_post::)), - ) - .service( - web::scope("/post") - .wrap(rate_limit.message()) - .route("", web::get().to(route_get::)) - .route("", web::put().to(route_post::)) - .route("/delete", web::post().to(route_post::)) - .route("/remove", web::post().to(route_post::)) - .route("/list", web::get().to(route_get::)), - ) - // Comment - .service( - web::scope("/comment") - .wrap(rate_limit.message()) - .route("", web::post().to(route_post::)) - .route("", web::put().to(route_post::)) - .route("/delete", web::post().to(route_post::)) - .route("/remove", web::post().to(route_post::)) - .route("/list", web::get().to(route_get::)), - ), - ) - // Private Message - .service( - web::scope("/private_message") - .wrap(rate_limit.message()) - .route("/list", web::get().to(route_get::)) - .route("", web::post().to(route_post::)) - .route("", web::put().to(route_post::)) - .route( - "/delete", - web::post().to(route_post::), - ), - ) - // User - .service( - // Account action, I don't like that it's in /user maybe /accounts - // Handle /user/register separately to add the register() rate limitter - web::resource("/user/register") - .guard(guard::Post()) - .wrap(rate_limit.register()) - .route(web::post().to(route_post::)), - ) - // User actions - .service( - web::scope("/user") - .wrap(rate_limit.message()) - .route("", web::get().to(route_get::)) - .route( - "/delete_account", - web::post().to(route_post::), - ), - ); -} - -async fn perform( - data: Request, - context: web::Data, -) -> Result -where - Request: PerformCrud, - Request: Send + 'static, -{ - let res = data - .perform(&context, None) - .await - .map(|json| HttpResponse::Ok().json(json)) - .map_err(ErrorBadRequest)?; - Ok(res) -} - -async fn route_get<'a, Data>( - data: web::Query, - context: web::Data, -) -> Result -where - Data: Deserialize<'a> + Send + 'static + PerformCrud, -{ - perform::(data.0, context).await -} - -async fn route_post<'a, Data>( - data: web::Json, - context: web::Data, -) -> Result -where - Data: Deserialize<'a> + Send + 'static + PerformCrud, -{ - perform::(data.0, context).await -} diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index 3a4f50729..06940a75c 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -18,7 +18,7 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditSite { @@ -64,7 +64,7 @@ impl PerformCrud for EditSite { let res = SiteResponse { site_view }; context.chat_server().do_send(SendAllMessage { - op: UserOperation::EditSite, + op: UserOperationCrud::EditSite, response: res.clone(), websocket_id, }); diff --git a/crates/apub/src/activities/receive/comment.rs b/crates/apub/src/activities/receive/comment.rs index 2575035bd..d79ef84a2 100644 --- a/crates/apub/src/activities/receive/comment.rs +++ b/crates/apub/src/activities/receive/comment.rs @@ -12,7 +12,7 @@ use lemmy_db_schema::source::{ }; use lemmy_db_views::comment_view::CommentView; use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError}; -use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation, UserOperationCrud}; pub(crate) async fn receive_create_comment( create: Create, @@ -57,7 +57,7 @@ pub(crate) async fn receive_create_comment( }; context.chat_server().do_send(SendComment { - op: UserOperation::CreateComment, + op: UserOperationCrud::CreateComment, comment: res, websocket_id: None, }); @@ -98,7 +98,7 @@ pub(crate) async fn receive_update_comment( }; context.chat_server().do_send(SendComment { - op: UserOperation::EditComment, + op: UserOperationCrud::EditComment, comment: res, websocket_id: None, }); @@ -220,7 +220,7 @@ pub(crate) async fn receive_delete_comment( form_id: None, }; context.chat_server().do_send(SendComment { - op: UserOperation::EditComment, + op: UserOperationCrud::EditComment, comment: res, websocket_id: None, }); @@ -252,7 +252,7 @@ pub(crate) async fn receive_remove_comment( form_id: None, }; context.chat_server().do_send(SendComment { - op: UserOperation::EditComment, + op: UserOperationCrud::EditComment, comment: res, websocket_id: None, }); diff --git a/crates/apub/src/activities/receive/comment_undo.rs b/crates/apub/src/activities/receive/comment_undo.rs index 12a49ee38..7214c8f02 100644 --- a/crates/apub/src/activities/receive/comment_undo.rs +++ b/crates/apub/src/activities/receive/comment_undo.rs @@ -5,7 +5,7 @@ use lemmy_db_queries::{source::comment::Comment_, Likeable}; use lemmy_db_schema::source::comment::{Comment, CommentLike}; use lemmy_db_views::comment_view::CommentView; use lemmy_utils::LemmyError; -use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation, UserOperationCrud}; pub(crate) async fn receive_undo_like_comment( like: &Like, @@ -108,7 +108,7 @@ pub(crate) async fn receive_undo_delete_comment( }; context.chat_server().do_send(SendComment { - op: UserOperation::EditComment, + op: UserOperationCrud::EditComment, comment: res, websocket_id: None, }); @@ -141,7 +141,7 @@ pub(crate) async fn receive_undo_remove_comment( }; context.chat_server().do_send(SendComment { - op: UserOperation::EditComment, + op: UserOperationCrud::EditComment, comment: res, websocket_id: None, }); diff --git a/crates/apub/src/activities/receive/community.rs b/crates/apub/src/activities/receive/community.rs index d6dba673d..a40bcdfa7 100644 --- a/crates/apub/src/activities/receive/community.rs +++ b/crates/apub/src/activities/receive/community.rs @@ -3,7 +3,7 @@ use lemmy_db_queries::source::community::Community_; use lemmy_db_schema::source::community::Community; use lemmy_db_views_actor::community_view::CommunityView; use lemmy_utils::LemmyError; -use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperationCrud}; pub(crate) async fn receive_delete_community( context: &LemmyContext, @@ -24,7 +24,7 @@ pub(crate) async fn receive_delete_community( let community_id = res.community_view.community.id; context.chat_server().do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, + op: UserOperationCrud::EditCommunity, response: res, community_id, websocket_id: None, @@ -52,7 +52,7 @@ pub(crate) async fn receive_remove_community( let community_id = res.community_view.community.id; context.chat_server().do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, + op: UserOperationCrud::EditCommunity, response: res, community_id, websocket_id: None, @@ -80,7 +80,7 @@ pub(crate) async fn receive_undo_delete_community( let community_id = res.community_view.community.id; context.chat_server().do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, + op: UserOperationCrud::EditCommunity, response: res, community_id, websocket_id: None, @@ -109,7 +109,7 @@ pub(crate) async fn receive_undo_remove_community( let community_id = res.community_view.community.id; context.chat_server().do_send(SendCommunityRoomMessage { - op: UserOperation::EditCommunity, + op: UserOperationCrud::EditCommunity, response: res, community_id, websocket_id: None, diff --git a/crates/apub/src/activities/receive/post.rs b/crates/apub/src/activities/receive/post.rs index e490964d1..2f4290d0b 100644 --- a/crates/apub/src/activities/receive/post.rs +++ b/crates/apub/src/activities/receive/post.rs @@ -21,7 +21,7 @@ use lemmy_db_schema::{ }; use lemmy_db_views::post_view::PostView; use lemmy_utils::{location_info, LemmyError}; -use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation, UserOperationCrud}; pub(crate) async fn receive_create_post( create: Create, @@ -44,7 +44,7 @@ pub(crate) async fn receive_create_post( let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::CreatePost, + op: UserOperationCrud::CreatePost, post: res, websocket_id: None, }); @@ -107,7 +107,7 @@ pub(crate) async fn receive_update_post( let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::EditPost, + op: UserOperationCrud::EditPost, post: res, websocket_id: None, }); @@ -209,7 +209,7 @@ pub(crate) async fn receive_delete_post( let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::EditPost, + op: UserOperationCrud::EditPost, post: res, websocket_id: None, }); @@ -235,7 +235,7 @@ pub(crate) async fn receive_remove_post( let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::EditPost, + op: UserOperationCrud::EditPost, post: res, websocket_id: None, }); diff --git a/crates/apub/src/activities/receive/post_undo.rs b/crates/apub/src/activities/receive/post_undo.rs index 589b0d229..2ed6ecac0 100644 --- a/crates/apub/src/activities/receive/post_undo.rs +++ b/crates/apub/src/activities/receive/post_undo.rs @@ -5,7 +5,7 @@ use lemmy_db_queries::{source::post::Post_, Likeable}; use lemmy_db_schema::source::post::{Post, PostLike}; use lemmy_db_views::post_view::PostView; use lemmy_utils::LemmyError; -use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation, UserOperationCrud}; pub(crate) async fn receive_undo_like_post( like: &Like, @@ -89,7 +89,7 @@ pub(crate) async fn receive_undo_delete_post( let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::EditPost, + op: UserOperationCrud::EditPost, post: res, websocket_id: None, }); @@ -116,7 +116,7 @@ pub(crate) async fn receive_undo_remove_post( let res = PostResponse { post_view }; context.chat_server().do_send(SendPost { - op: UserOperation::EditPost, + op: UserOperationCrud::EditPost, post: res, websocket_id: None, }); diff --git a/crates/apub/src/activities/receive/private_message.rs b/crates/apub/src/activities/receive/private_message.rs index 47067b7a6..6d90e8681 100644 --- a/crates/apub/src/activities/receive/private_message.rs +++ b/crates/apub/src/activities/receive/private_message.rs @@ -18,7 +18,7 @@ use lemmy_db_queries::source::private_message::PrivateMessage_; use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView}; use lemmy_utils::{location_info, LemmyError}; -use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; +use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud}; use url::Url; pub(crate) async fn receive_create_private_message( @@ -60,7 +60,7 @@ pub(crate) async fn receive_create_private_message( .id; context.chat_server().do_send(SendUserRoomMessage { - op: UserOperation::CreatePrivateMessage, + op: UserOperationCrud::CreatePrivateMessage, response: res, local_recipient_id, websocket_id: None, @@ -106,7 +106,7 @@ pub(crate) async fn receive_update_private_message( .id; context.chat_server().do_send(SendUserRoomMessage { - op: UserOperation::EditPrivateMessage, + op: UserOperationCrud::EditPrivateMessage, response: res, local_recipient_id, websocket_id: None, @@ -146,7 +146,7 @@ pub(crate) async fn receive_delete_private_message( .id; context.chat_server().do_send(SendUserRoomMessage { - op: UserOperation::EditPrivateMessage, + op: UserOperationCrud::EditPrivateMessage, response: res, local_recipient_id, websocket_id: None, @@ -191,7 +191,7 @@ pub(crate) async fn receive_undo_delete_private_message( .id; context.chat_server().do_send(SendUserRoomMessage { - op: UserOperation::EditPrivateMessage, + op: UserOperationCrud::EditPrivateMessage, response: res, local_recipient_id, websocket_id: None, diff --git a/crates/db_views/src/local_user_view.rs b/crates/db_views/src/local_user_view.rs index 85a83e156..63dedb866 100644 --- a/crates/db_views/src/local_user_view.rs +++ b/crates/db_views/src/local_user_view.rs @@ -70,9 +70,9 @@ impl LocalUserView { )) .first::(conn)?; Ok(Self { + local_user, person, counts, - local_user, }) } @@ -92,9 +92,9 @@ impl LocalUserView { )) .first::(conn)?; Ok(Self { + local_user, person, counts, - local_user, }) } @@ -110,9 +110,9 @@ impl LocalUserView { )) .first::(conn)?; Ok(Self { + local_user, person, counts, - local_user, }) } } @@ -139,9 +139,9 @@ impl LocalUserSettingsView { )) .first::(conn)?; Ok(Self { + local_user, person, counts, - local_user, }) } } diff --git a/crates/websocket/src/chat_server.rs b/crates/websocket/src/chat_server.rs index f1c936d6d..e08aa94a5 100644 --- a/crates/websocket/src/chat_server.rs +++ b/crates/websocket/src/chat_server.rs @@ -1,4 +1,11 @@ -use crate::{messages::*, serialize_websocket_message, LemmyContext, UserOperation}; +use crate::{ + messages::*, + serialize_websocket_message, + LemmyContext, + OperationType, + UserOperation, + UserOperationCrud, +}; use actix::prelude::*; use anyhow::Context as acontext; use background_jobs::QueueHandle; @@ -33,6 +40,13 @@ type MessageHandlerType = fn( data: &str, ) -> Pin> + '_>>; +type MessageHandlerCrudType = fn( + context: LemmyContext, + id: ConnectionId, + op: UserOperationCrud, + data: &str, +) -> Pin> + '_>>; + /// `ChatServer` manages chat rooms and responsible for coordinating chat /// session. pub struct ChatServer { @@ -63,6 +77,7 @@ pub struct ChatServer { pub(super) captchas: Vec, message_handler: MessageHandlerType, + message_handler_crud: MessageHandlerCrudType, /// An HTTP Client client: Client, @@ -83,6 +98,7 @@ impl ChatServer { pool: Pool>, rate_limiter: RateLimit, message_handler: MessageHandlerType, + message_handler_crud: MessageHandlerCrudType, client: Client, activity_queue: QueueHandle, ) -> ChatServer { @@ -97,6 +113,7 @@ impl ChatServer { rate_limiter, captchas: Vec::new(), message_handler, + message_handler_crud, client, activity_queue, } @@ -207,14 +224,15 @@ impl ChatServer { Ok(()) } - fn send_post_room_message( + fn send_post_room_message( &self, - op: &UserOperation, + op: &OP, response: &Response, post_id: PostId, websocket_id: Option, ) -> Result<(), LemmyError> where + OP: OperationType + ToString, Response: Serialize, { let res_str = &serialize_websocket_message(op, response)?; @@ -231,14 +249,15 @@ impl ChatServer { Ok(()) } - pub fn send_community_room_message( + pub fn send_community_room_message( &self, - op: &UserOperation, + op: &OP, response: &Response, community_id: CommunityId, websocket_id: Option, ) -> Result<(), LemmyError> where + OP: OperationType + ToString, Response: Serialize, { let res_str = &serialize_websocket_message(op, response)?; @@ -255,14 +274,15 @@ impl ChatServer { Ok(()) } - pub fn send_mod_room_message( + pub fn send_mod_room_message( &self, - op: &UserOperation, + op: &OP, response: &Response, community_id: CommunityId, websocket_id: Option, ) -> Result<(), LemmyError> where + OP: OperationType + ToString, Response: Serialize, { let res_str = &serialize_websocket_message(op, response)?; @@ -279,13 +299,14 @@ impl ChatServer { Ok(()) } - pub fn send_all_message( + pub fn send_all_message( &self, - op: &UserOperation, + op: &OP, response: &Response, websocket_id: Option, ) -> Result<(), LemmyError> where + OP: OperationType + ToString, Response: Serialize, { let res_str = &serialize_websocket_message(op, response)?; @@ -300,14 +321,15 @@ impl ChatServer { Ok(()) } - pub fn send_user_room_message( + pub fn send_user_room_message( &self, - op: &UserOperation, + op: &OP, response: &Response, recipient_id: LocalUserId, websocket_id: Option, ) -> Result<(), LemmyError> where + OP: OperationType + ToString, Response: Serialize, { let res_str = &serialize_websocket_message(op, response)?; @@ -324,12 +346,15 @@ impl ChatServer { Ok(()) } - pub fn send_comment( + pub fn send_comment( &self, - user_operation: &UserOperation, + user_operation: &OP, comment: &CommentResponse, websocket_id: Option, - ) -> Result<(), LemmyError> { + ) -> Result<(), LemmyError> + where + OP: OperationType + ToString, + { let mut comment_reply_sent = comment.clone(); // Strip out my specific user info @@ -373,12 +398,15 @@ impl ChatServer { Ok(()) } - pub fn send_post( + pub fn send_post( &self, - user_operation: &UserOperation, + user_operation: &OP, post_res: &PostResponse, websocket_id: Option, - ) -> Result<(), LemmyError> { + ) -> Result<(), LemmyError> + where + OP: OperationType + ToString, + { let community_id = post_res.post_view.community.id; // Don't send my data with it @@ -424,6 +452,7 @@ impl ChatServer { client: self.client.to_owned(), activity_queue: self.activity_queue.to_owned(), }; + let message_handler_crud = self.message_handler_crud; let message_handler = self.message_handler; async move { let json: Value = serde_json::from_str(&msg.msg)?; @@ -432,13 +461,18 @@ impl ChatServer { message: "Unknown op type".to_string(), })?; - let user_operation = UserOperation::from_str(&op)?; - let fut = (message_handler)(context, msg.id, user_operation.clone(), data); - match user_operation { - UserOperation::Register => rate_limiter.register().wrap(ip, fut).await, - UserOperation::CreatePost => rate_limiter.post().wrap(ip, fut).await, - UserOperation::CreateCommunity => rate_limiter.register().wrap(ip, fut).await, - _ => rate_limiter.message().wrap(ip, fut).await, + if let Ok(user_operation_crud) = UserOperationCrud::from_str(&op) { + let fut = (message_handler_crud)(context, msg.id, user_operation_crud.clone(), data); + match user_operation_crud { + UserOperationCrud::Register => rate_limiter.register().wrap(ip, fut).await, + UserOperationCrud::CreatePost => rate_limiter.post().wrap(ip, fut).await, + UserOperationCrud::CreateCommunity => rate_limiter.register().wrap(ip, fut).await, + _ => rate_limiter.message().wrap(ip, fut).await, + } + } else { + let user_operation = UserOperation::from_str(&op)?; + let fut = (message_handler)(context, msg.id, user_operation.clone(), data); + rate_limiter.message().wrap(ip, fut).await } } } diff --git a/crates/websocket/src/handlers.rs b/crates/websocket/src/handlers.rs index 30cd9639b..055129cd3 100644 --- a/crates/websocket/src/handlers.rs +++ b/crates/websocket/src/handlers.rs @@ -1,6 +1,7 @@ use crate::{ chat_server::{ChatServer, SessionInfo}, messages::*, + OperationType, }; use actix::{Actor, Context, Handler, ResponseFuture}; use lemmy_db_schema::naive_now; @@ -82,26 +83,28 @@ impl Handler for ChatServer { } } -impl Handler> for ChatServer +impl Handler> for ChatServer where + OP: OperationType + ToString, Response: Serialize, { type Result = (); - fn handle(&mut self, msg: SendAllMessage, _: &mut Context) { + fn handle(&mut self, msg: SendAllMessage, _: &mut Context) { self .send_all_message(&msg.op, &msg.response, msg.websocket_id) .ok(); } } -impl Handler> for ChatServer +impl Handler> for ChatServer where + OP: OperationType + ToString, Response: Serialize, { type Result = (); - fn handle(&mut self, msg: SendUserRoomMessage, _: &mut Context) { + fn handle(&mut self, msg: SendUserRoomMessage, _: &mut Context) { self .send_user_room_message( &msg.op, @@ -113,13 +116,14 @@ where } } -impl Handler> for ChatServer +impl Handler> for ChatServer where + OP: OperationType + ToString, Response: Serialize, { type Result = (); - fn handle(&mut self, msg: SendCommunityRoomMessage, _: &mut Context) { + fn handle(&mut self, msg: SendCommunityRoomMessage, _: &mut Context) { self .send_community_room_message(&msg.op, &msg.response, msg.community_id, msg.websocket_id) .ok(); @@ -139,18 +143,24 @@ where } } -impl Handler for ChatServer { +impl Handler> for ChatServer +where + OP: OperationType + ToString, +{ type Result = (); - fn handle(&mut self, msg: SendPost, _: &mut Context) { + fn handle(&mut self, msg: SendPost, _: &mut Context) { self.send_post(&msg.op, &msg.post, msg.websocket_id).ok(); } } -impl Handler for ChatServer { +impl Handler> for ChatServer +where + OP: OperationType + ToString, +{ type Result = (); - fn handle(&mut self, msg: SendComment, _: &mut Context) { + fn handle(&mut self, msg: SendComment, _: &mut Context) { self .send_comment(&msg.op, &msg.comment, msg.websocket_id) .ok(); diff --git a/crates/websocket/src/lib.rs b/crates/websocket/src/lib.rs index 56b18a179..0b2a9fb4f 100644 --- a/crates/websocket/src/lib.rs +++ b/crates/websocket/src/lib.rs @@ -66,12 +66,13 @@ struct WebsocketResponse { data: T, } -pub fn serialize_websocket_message( - op: &UserOperation, +pub fn serialize_websocket_message( + op: &OP, data: &Response, ) -> Result where Response: Serialize, + OP: ToString, { let response = WebsocketResponse { op: op.to_string(), @@ -83,28 +84,14 @@ where #[derive(EnumString, ToString, Debug, Clone)] pub enum UserOperation { Login, - Register, GetCaptcha, - CreateCommunity, - CreatePost, - ListCommunities, - GetPost, - GetCommunity, - CreateComment, - EditComment, - DeleteComment, - RemoveComment, MarkCommentAsRead, SaveComment, CreateCommentLike, CreateCommentReport, ResolveCommentReport, ListCommentReports, - GetPosts, CreatePostLike, - EditPost, - DeletePost, - RemovePost, LockPost, StickyPost, SavePost, @@ -112,21 +99,14 @@ pub enum UserOperation { ResolvePostReport, ListPostReports, GetReportCount, - EditCommunity, - DeleteCommunity, - RemoveCommunity, FollowCommunity, GetFollowedCommunities, - GetPersonDetails, GetReplies, GetPersonMentions, MarkPersonMentionAsRead, GetModlog, BanFromCommunity, AddModToCommunity, - CreateSite, - EditSite, - GetSite, AddAdmin, BanPerson, Search, @@ -134,19 +114,56 @@ pub enum UserOperation { SaveUserSettings, TransferCommunity, TransferSite, - DeleteAccount, PasswordReset, PasswordChange, - CreatePrivateMessage, - EditPrivateMessage, - DeletePrivateMessage, MarkPrivateMessageAsRead, - GetPrivateMessages, UserJoin, - GetComments, GetSiteConfig, SaveSiteConfig, PostJoin, CommunityJoin, ModJoin, } + +#[derive(EnumString, ToString, Debug, Clone)] +pub enum UserOperationCrud { + // Site + CreateSite, + GetSite, + EditSite, + // Community + CreateCommunity, + ListCommunities, + GetCommunity, + EditCommunity, + DeleteCommunity, + RemoveCommunity, + // Post + CreatePost, + GetPost, + GetPosts, + EditPost, + DeletePost, + RemovePost, + // Comment + CreateComment, + GetComments, + EditComment, + DeleteComment, + RemoveComment, + // User + Register, + GetPersonDetails, + DeleteAccount, + // Private Message + CreatePrivateMessage, + GetPrivateMessages, + EditPrivateMessage, + DeletePrivateMessage, +} + +pub trait OperationType {} + +impl OperationType for UserOperationCrud {} + +impl OperationType for UserOperation {} diff --git a/crates/websocket/src/messages.rs b/crates/websocket/src/messages.rs index 31ca755f1..1ef3da5b5 100644 --- a/crates/websocket/src/messages.rs +++ b/crates/websocket/src/messages.rs @@ -40,16 +40,16 @@ pub struct StandardMessage { #[derive(Message)] #[rtype(result = "()")] -pub struct SendAllMessage { - pub op: UserOperation, +pub struct SendAllMessage { + pub op: OP, pub response: Response, pub websocket_id: Option, } #[derive(Message)] #[rtype(result = "()")] -pub struct SendUserRoomMessage { - pub op: UserOperation, +pub struct SendUserRoomMessage { + pub op: OP, pub response: Response, pub local_recipient_id: LocalUserId, pub websocket_id: Option, @@ -57,8 +57,8 @@ pub struct SendUserRoomMessage { #[derive(Message)] #[rtype(result = "()")] -pub struct SendCommunityRoomMessage { - pub op: UserOperation, +pub struct SendCommunityRoomMessage { + pub op: OP, pub response: Response, pub community_id: CommunityId, pub websocket_id: Option, @@ -75,16 +75,16 @@ pub struct SendModRoomMessage { #[derive(Message)] #[rtype(result = "()")] -pub struct SendPost { - pub op: UserOperation, +pub struct SendPost { + pub op: OP, pub post: PostResponse, pub websocket_id: Option, } #[derive(Message)] #[rtype(result = "()")] -pub struct SendComment { - pub op: UserOperation, +pub struct SendComment { + pub op: OP, pub comment: CommentResponse, pub websocket_id: Option, } diff --git a/crates/websocket/src/routes.rs b/crates/websocket/src/routes.rs index 8a487813e..a240646f8 100644 --- a/crates/websocket/src/routes.rs +++ b/crates/websocket/src/routes.rs @@ -15,8 +15,12 @@ const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5); /// How long before lack of client response causes a timeout const CLIENT_TIMEOUT: Duration = Duration::from_secs(10); +pub fn config(cfg: &mut web::ServiceConfig) { + cfg.service(web::resource("/ws").to(chat_route)); +} + /// Entry point for our route -pub async fn chat_route( +async fn chat_route( req: HttpRequest, stream: web::Payload, context: web::Data, diff --git a/docker/federation/docker-compose.yml b/docker/federation/docker-compose.yml index 03355aa49..4925c1bdb 100644 --- a/docker/federation/docker-compose.yml +++ b/docker/federation/docker-compose.yml @@ -29,7 +29,7 @@ services: - ./volumes/pictrs_alpha:/mnt lemmy-alpha-ui: - image: dessalines/lemmy-ui:0.9.9 + image: dessalines/lemmy-ui:0.10.0-rc.12 environment: - LEMMY_INTERNAL_HOST=lemmy-alpha:8541 - LEMMY_EXTERNAL_HOST=localhost:8541 diff --git a/crates/api/src/routes.rs b/src/api_routes.rs similarity index 60% rename from crates/api/src/routes.rs rename to src/api_routes.rs index cdc9e736b..345015193 100644 --- a/crates/api/src/routes.rs +++ b/src/api_routes.rs @@ -1,20 +1,22 @@ -use crate::Perform; use actix_web::{error::ErrorBadRequest, *}; +use lemmy_api::Perform; use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*, websocket::*}; +use lemmy_api_crud::PerformCrud; use lemmy_utils::rate_limit::RateLimit; -use lemmy_websocket::{routes::chat_route, LemmyContext}; +use lemmy_websocket::LemmyContext; use serde::Deserialize; pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { cfg.service( web::scope("/api/v2") - // Websockets - .service(web::resource("/ws").to(chat_route)) // Site .service( web::scope("/site") .wrap(rate_limit.message()) + .route("", web::get().to(route_get_crud::)) // Admin Actions + .route("", web::post().to(route_post_crud::)) + .route("", web::put().to(route_post_crud::)) .route("/transfer", web::post().to(route_post::)) .route("/config", web::get().to(route_get::)) .route("/config", web::put().to(route_post::)), @@ -30,10 +32,28 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { .route(web::get().to(route_get::)), ) // Community + .service( + web::resource("/community") + .guard(guard::Post()) + .wrap(rate_limit.register()) + .route(web::post().to(route_post_crud::)), + ) .service( web::scope("/community") .wrap(rate_limit.message()) + .route("", web::get().to(route_get_crud::)) + .route("", web::put().to(route_post_crud::)) + .route("/list", web::get().to(route_get_crud::)) .route("/follow", web::post().to(route_post::)) + .route( + "/delete", + web::post().to(route_post_crud::), + ) + // Mod Actions + .route( + "/remove", + web::post().to(route_post_crud::), + ) .route("/transfer", web::post().to(route_post::)) .route("/ban_user", web::post().to(route_post::)) .route("/mod", web::post().to(route_post::)) @@ -41,11 +61,23 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { .route("/mod/join", web::post().to(route_post::)), ) // Post + .service( + // Handle POST to /post separately to add the post() rate limitter + web::resource("/post") + .guard(guard::Post()) + .wrap(rate_limit.post()) + .route(web::post().to(route_post_crud::)), + ) .service( web::scope("/post") .wrap(rate_limit.message()) + .route("", web::get().to(route_get_crud::)) + .route("", web::put().to(route_post_crud::)) + .route("/delete", web::post().to(route_post_crud::)) + .route("/remove", web::post().to(route_post_crud::)) .route("/lock", web::post().to(route_post::)) .route("/sticky", web::post().to(route_post::)) + .route("/list", web::get().to(route_get_crud::)) .route("/like", web::post().to(route_post::)) .route("/save", web::put().to(route_post::)) .route("/join", web::post().to(route_post::)) @@ -60,12 +92,17 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { .service( web::scope("/comment") .wrap(rate_limit.message()) + .route("", web::post().to(route_post_crud::)) + .route("", web::put().to(route_post_crud::)) + .route("/delete", web::post().to(route_post_crud::)) + .route("/remove", web::post().to(route_post_crud::)) .route( "/mark_as_read", web::post().to(route_post::), ) .route("/like", web::post().to(route_post::)) .route("/save", web::put().to(route_post::)) + .route("/list", web::get().to(route_get_crud::)) .route("/report", web::post().to(route_post::)) .route( "/report/resolve", @@ -80,15 +117,32 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { .service( web::scope("/private_message") .wrap(rate_limit.message()) + .route("/list", web::get().to(route_get_crud::)) + .route("", web::post().to(route_post_crud::)) + .route("", web::put().to(route_post_crud::)) + .route( + "/delete", + web::post().to(route_post_crud::), + ) .route( "/mark_as_read", web::post().to(route_post::), ), ) + // User + .service( + // Account action, I don't like that it's in /user maybe /accounts + // Handle /user/register separately to add the register() rate limitter + web::resource("/user/register") + .guard(guard::Post()) + .wrap(rate_limit.register()) + .route(web::post().to(route_post_crud::)), + ) // User actions .service( web::scope("/user") .wrap(rate_limit.message()) + .route("", web::get().to(route_get_crud::)) .route("/mention", web::get().to(route_get::)) .route( "/mention/mark_as_read", @@ -105,6 +159,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) { // Account actions. I don't like that they're in /user maybe /accounts .route("/login", web::post().to(route_post::)) .route("/get_captcha", web::get().to(route_get::)) + .route( + "/delete_account", + web::post().to(route_post_crud::), + ) .route( "/password_reset", web::post().to(route_post::), @@ -168,3 +226,39 @@ where { perform::(data.0, context).await } + +async fn perform_crud( + data: Request, + context: web::Data, +) -> Result +where + Request: PerformCrud, + Request: Send + 'static, +{ + let res = data + .perform(&context, None) + .await + .map(|json| HttpResponse::Ok().json(json)) + .map_err(ErrorBadRequest)?; + Ok(res) +} + +async fn route_get_crud<'a, Data>( + data: web::Query, + context: web::Data, +) -> Result +where + Data: Deserialize<'a> + Send + 'static + PerformCrud, +{ + perform_crud::(data.0, context).await +} + +async fn route_post_crud<'a, Data>( + data: web::Json, + context: web::Data, +) -> Result +where + Data: Deserialize<'a> + Send + 'static + PerformCrud, +{ + perform_crud::(data.0, context).await +} diff --git a/src/lib.rs b/src/lib.rs index 16cddf631..ea79cbb08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ #![recursion_limit = "512"] +pub mod api_routes; pub mod code_migrations; pub mod scheduled_tasks; diff --git a/src/main.rs b/src/main.rs index 3cdab3ec7..7f241733b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,10 +9,11 @@ use diesel::{ }; use lemmy_api::match_websocket_operation; use lemmy_api_common::blocking; +use lemmy_api_crud::match_websocket_operation_crud; use lemmy_apub::activity_queue::create_activity_queue; use lemmy_db_queries::get_database_url_from_env; use lemmy_routes::{feeds, images, nodeinfo, webfinger}; -use lemmy_server::{code_migrations::run_advanced_migrations, scheduled_tasks}; +use lemmy_server::{api_routes, code_migrations::run_advanced_migrations, scheduled_tasks}; use lemmy_utils::{ rate_limit::{rate_limiter::RateLimiter, RateLimit}, settings::structs::Settings, @@ -70,6 +71,7 @@ async fn main() -> Result<(), LemmyError> { pool.clone(), rate_limiter.clone(), |c, i, o, d| Box::pin(match_websocket_operation(c, i, o, d)), + |c, i, o, d| Box::pin(match_websocket_operation_crud(c, i, o, d)), Client::default(), activity_queue.clone(), ) @@ -88,8 +90,8 @@ async fn main() -> Result<(), LemmyError> { .wrap(middleware::Logger::default()) .data(context) // The routes - .configure(|cfg| lemmy_api_crud::routes::config(cfg, &rate_limiter)) - .configure(|cfg| lemmy_api::routes::config(cfg, &rate_limiter)) + .configure(|cfg| api_routes::config(cfg, &rate_limiter)) + .configure(lemmy_websocket::routes::config) .configure(lemmy_apub::routes::config) .configure(feeds::config) .configure(|cfg| images::config(cfg, &rate_limiter))