diff --git a/Cargo.lock b/Cargo.lock index 2d1f70bc6..5f68a511e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2034,7 +2034,6 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" name = "lemmy_api" version = "0.16.5" dependencies = [ - "activitypub_federation", "actix-web", "anyhow", "async-trait", @@ -2044,7 +2043,6 @@ dependencies = [ "chrono", "diesel", "lemmy_api_common", - "lemmy_apub", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -2103,7 +2101,6 @@ dependencies = [ "async-trait", "bcrypt", "lemmy_api_common", - "lemmy_apub", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -2274,6 +2271,7 @@ dependencies = [ "reqwest-retry", "reqwest-tracing", "serde", + "serde_json", "tracing", "tracing-actix-web", "tracing-error", diff --git a/Cargo.toml b/Cargo.toml index 16ca864f4..e83f0c837 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,6 +135,7 @@ clokwerk = { workspace = true } doku = { workspace = true } parking_lot = { workspace = true } reqwest-retry = { workspace = true } +serde_json = { workspace = true } tracing-opentelemetry = { workspace = true, optional = true } opentelemetry = { workspace = true, optional = true } console-subscriber = { version = "0.1.8", optional = true } diff --git a/api_tests/src/community.spec.ts b/api_tests/src/community.spec.ts index 0ed50ec48..453ea5660 100644 --- a/api_tests/src/community.spec.ts +++ b/api_tests/src/community.spec.ts @@ -187,12 +187,15 @@ test("Admin actions in remote community are not federated to origin", async () = let gammaCommunity = ( await resolveCommunity(gamma, communityRes.community.actor_id) ).community.unwrap(); - let gammaFollow = await followCommunity( + await followCommunity( gamma, true, gammaCommunity.community.id ); - expect(gammaFollow.community_view.subscribed).toBe("Subscribed"); + gammaCommunity = ( + await resolveCommunity(gamma, communityRes.community.actor_id) + ).community.unwrap(); + expect(gammaCommunity.subscribed).toBe("Subscribed"); let gammaPost = (await createPost(gamma, gammaCommunity.community.id)) .post_view; expect(gammaPost.post.id).toBeDefined(); diff --git a/api_tests/src/follow.spec.ts b/api_tests/src/follow.spec.ts index f80b40de8..630e25f22 100644 --- a/api_tests/src/follow.spec.ts +++ b/api_tests/src/follow.spec.ts @@ -20,12 +20,13 @@ afterAll(async () => { test("Follow federated community", async () => { let betaCommunity = (await resolveBetaCommunity(alpha)).community.unwrap(); - let follow = await followCommunity(alpha, true, betaCommunity.community.id); + await followCommunity(alpha, true, betaCommunity.community.id); + betaCommunity = (await resolveBetaCommunity(alpha)).community.unwrap(); // Make sure the follow response went through - expect(follow.community_view.community.local).toBe(false); - expect(follow.community_view.community.name).toBe("main"); - expect(follow.community_view.subscribed).toBe(SubscribedType.Subscribed); + expect(betaCommunity.community.local).toBe(false); + expect(betaCommunity.community.name).toBe("main"); + expect(betaCommunity.subscribed).toBe(SubscribedType.Subscribed); // Check it from local let site = await getSite(alpha); diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 17c0127b4..f7f1b0bf3 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -14,14 +14,12 @@ path = "src/lib.rs" doctest = false [dependencies] -lemmy_apub = { workspace = true } lemmy_utils = { workspace = true } lemmy_db_schema = { workspace = true, features = ["full"] } lemmy_db_views = { workspace = true, features = ["full"] } lemmy_db_views_moderator = { workspace = true, features = ["full"] } lemmy_db_views_actor = { workspace = true, features = ["full"] } lemmy_api_common = { workspace = true, features = ["full"] } -activitypub_federation = { workspace = true } diesel = { workspace = true } bcrypt = { workspace = true } chrono = { workspace = true } diff --git a/crates/api/src/comment/like.rs b/crates/api/src/comment/like.rs index 1ba6ec791..fba61ed13 100644 --- a/crates/api/src/comment/like.rs +++ b/crates/api/src/comment/like.rs @@ -2,16 +2,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, CreateCommentLike}, + context::LemmyContext, utils::{check_community_ban, check_downvotes_enabled, get_local_user_view_from_jwt}, websocket::{send::send_comment_ws_message, UserOperation}, - LemmyContext, -}; -use lemmy_apub::{ - fetcher::post_or_comment::PostOrComment, - protocol::activities::voting::{ - undo_vote::UndoVote, - vote::{Vote, VoteType}, - }, }; use lemmy_db_schema::{ newtypes::LocalUserId, @@ -24,7 +17,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::{CommentView, LocalUserView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use std::convert::TryInto; #[async_trait::async_trait(?Send)] impl Perform for CreateCommentLike { @@ -78,33 +70,12 @@ impl Perform for CreateCommentLike { CommentLike::remove(context.pool(), person_id, comment_id).await?; // Only add the like if the score isnt 0 - let comment = orig_comment.comment; - let object = PostOrComment::Comment(Box::new(comment.into())); let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1); if do_add { let like_form2 = like_form.clone(); CommentLike::like(context.pool(), &like_form2) .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_comment"))?; - - Vote::send( - &object, - &local_user_view.person.clone().into(), - orig_comment.community.id, - like_form.score.try_into()?, - context, - ) - .await?; - } else { - // API doesn't distinguish between Undo/Like and Undo/Dislike - UndoVote::send( - &object, - &local_user_view.person.clone().into(), - orig_comment.community.id, - VoteType::Like, - context, - ) - .await?; } send_comment_ws_message( diff --git a/crates/api/src/comment/save.rs b/crates/api/src/comment/save.rs index cc6955de0..03051f6cc 100644 --- a/crates/api/src/comment/save.rs +++ b/crates/api/src/comment/save.rs @@ -2,8 +2,8 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, SaveComment}, + context::LemmyContext, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_schema::{ source::comment::{CommentSaved, CommentSavedForm}, diff --git a/crates/api/src/comment_report/create.rs b/crates/api/src/comment_report/create.rs index 99c653e23..bf3fec0a1 100644 --- a/crates/api/src/comment_report/create.rs +++ b/crates/api/src/comment_report/create.rs @@ -1,13 +1,11 @@ use crate::{check_report_reason, Perform}; -use activitypub_federation::core::object_id::ObjectId; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentReportResponse, CreateCommentReport}, + context::LemmyContext, utils::{check_community_ban, get_local_user_view_from_jwt}, websocket::{messages::SendModRoomMessage, UserOperation}, - LemmyContext, }; -use lemmy_apub::protocol::activities::community::report::Report; use lemmy_db_schema::{ source::{ comment_report::{CommentReport, CommentReportForm}, @@ -67,15 +65,6 @@ impl Perform for CreateCommentReport { websocket_id, }); - Report::send( - ObjectId::new(comment_view.comment.ap_id), - &local_user_view.person.into(), - ObjectId::new(comment_view.community.actor_id), - reason.to_string(), - context, - ) - .await?; - Ok(res) } } diff --git a/crates/api/src/comment_report/list.rs b/crates/api/src/comment_report/list.rs index b99716e88..8aa3fcbcd 100644 --- a/crates/api/src/comment_report/list.rs +++ b/crates/api/src/comment_report/list.rs @@ -2,8 +2,8 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{ListCommentReports, ListCommentReportsResponse}, + context::LemmyContext, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_views::comment_report_view::CommentReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/comment_report/resolve.rs b/crates/api/src/comment_report/resolve.rs index 16598ffa9..9df11fc23 100644 --- a/crates/api/src/comment_report/resolve.rs +++ b/crates/api/src/comment_report/resolve.rs @@ -2,9 +2,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentReportResponse, ResolveCommentReport}, + context::LemmyContext, utils::{get_local_user_view_from_jwt, is_mod_or_admin}, websocket::{messages::SendModRoomMessage, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{source::comment_report::CommentReport, traits::Reportable}; use lemmy_db_views::structs::CommentReportView; diff --git a/crates/api/src/community/add_mod.rs b/crates/api/src/community/add_mod.rs index d307a672d..ce3082f71 100644 --- a/crates/api/src/community/add_mod.rs +++ b/crates/api/src/community/add_mod.rs @@ -2,19 +2,14 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{AddModToCommunity, AddModToCommunityResponse}, + context::LemmyContext, utils::{get_local_user_view_from_jwt, is_mod_or_admin}, websocket::{messages::SendCommunityRoomMessage, UserOperation}, - LemmyContext, -}; -use lemmy_apub::{ - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::activities::community::{add_mod::AddMod, remove_mod::RemoveMod}, }; use lemmy_db_schema::{ source::{ community::{Community, CommunityModerator, CommunityModeratorForm}, moderator::{ModAddCommunity, ModAddCommunityForm}, - person::Person, }, traits::{Crud, Joinable}, }; @@ -69,28 +64,6 @@ impl Perform for AddModToCommunity { ModAddCommunity::create(context.pool(), &form).await?; - // Send to federated instances - let updated_mod_id = data.person_id; - let updated_mod: ApubPerson = Person::read(context.pool(), updated_mod_id).await?.into(); - let community: ApubCommunity = community.into(); - if data.added { - AddMod::send( - &community, - &updated_mod, - &local_user_view.person.into(), - context, - ) - .await?; - } else { - RemoveMod::send( - &community, - &updated_mod, - &local_user_view.person.into(), - context, - ) - .await?; - } - // Note: in case a remote mod is added, this returns the old moderators list, it will only get // updated once we receive an activity from the community (like `Announce/Add/Moderator`) let community_id = data.community_id; diff --git a/crates/api/src/community/ban.rs b/crates/api/src/community/ban.rs index 018ccd012..fb5e7fcfe 100644 --- a/crates/api/src/community/ban.rs +++ b/crates/api/src/community/ban.rs @@ -2,26 +2,19 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{BanFromCommunity, BanFromCommunityResponse}, + context::LemmyContext, utils::{get_local_user_view_from_jwt, is_mod_or_admin, remove_user_data_in_community}, websocket::{messages::SendCommunityRoomMessage, UserOperation}, - LemmyContext, -}; -use lemmy_apub::{ - activities::block::SiteOrCommunity, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser}, }; use lemmy_db_schema::{ source::{ community::{ - Community, CommunityFollower, CommunityFollowerForm, CommunityPersonBan, CommunityPersonBanForm, }, moderator::{ModBanFromCommunity, ModBanFromCommunityForm}, - person::Person, }, traits::{Bannable, Crud, Followable}, }; @@ -56,9 +49,6 @@ impl Perform for BanFromCommunity { expires: Some(expires), }; - let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); - let banned_person: ApubPerson = Person::read(context.pool(), banned_person_id).await?.into(); - if data.ban { CommunityPersonBan::ban(context.pool(), &community_user_ban_form) .await @@ -74,29 +64,10 @@ impl Perform for BanFromCommunity { CommunityFollower::unfollow(context.pool(), &community_follower_form) .await .ok(); - - BlockUser::send( - &SiteOrCommunity::Community(community), - &banned_person, - &local_user_view.person.clone().into(), - remove_data, - data.reason.clone(), - expires, - context, - ) - .await?; } else { CommunityPersonBan::unban(context.pool(), &community_user_ban_form) .await .map_err(|e| LemmyError::from_error_message(e, "community_user_already_banned"))?; - UndoBlockUser::send( - &SiteOrCommunity::Community(community), - &banned_person, - &local_user_view.person.clone().into(), - data.reason.clone(), - context, - ) - .await?; } // Remove/Restore their data if that's desired diff --git a/crates/api/src/community/block.rs b/crates/api/src/community/block.rs index 6c6efc213..914b5238e 100644 --- a/crates/api/src/community/block.rs +++ b/crates/api/src/community/block.rs @@ -2,16 +2,15 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{BlockCommunity, BlockCommunityResponse}, + context::LemmyContext, utils::get_local_user_view_from_jwt, - LemmyContext, }; -use lemmy_apub::protocol::activities::following::undo_follow::UndoFollow; use lemmy_db_schema::{ source::{ - community::{Community, CommunityFollower, CommunityFollowerForm}, + community::{CommunityFollower, CommunityFollowerForm}, community_block::{CommunityBlock, CommunityBlockForm}, }, - traits::{Blockable, Crud, Followable}, + traits::{Blockable, Followable}, }; use lemmy_db_views_actor::structs::CommunityView; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -52,8 +51,6 @@ impl Perform for BlockCommunity { CommunityFollower::unfollow(context.pool(), &community_follower_form) .await .ok(); - let community = Community::read(context.pool(), community_id).await?; - UndoFollow::send(&local_user_view.person.into(), &community.into(), context).await?; } else { CommunityBlock::unblock(context.pool(), &community_block_form) .await diff --git a/crates/api/src/community/follow.rs b/crates/api/src/community/follow.rs index 51d5ad9b6..dedfc9712 100644 --- a/crates/api/src/community/follow.rs +++ b/crates/api/src/community/follow.rs @@ -2,15 +2,8 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, FollowCommunity}, + context::LemmyContext, utils::{check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt}, - LemmyContext, -}; -use lemmy_apub::{ - objects::community::ApubCommunity, - protocol::activities::following::{ - follow::Follow as FollowCommunityApub, - undo_follow::UndoFollow, - }, }; use lemmy_db_schema::{ source::community::{Community, CommunityFollower, CommunityFollowerForm}, @@ -34,33 +27,22 @@ impl Perform for FollowCommunity { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let community_id = data.community_id; - let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); + let community = Community::read(context.pool(), community_id).await?; let community_follower_form = CommunityFollowerForm { community_id: data.community_id, person_id: local_user_view.person.id, pending: false, }; - if community.local { - if data.follow { - check_community_ban(local_user_view.person.id, community_id, context.pool()).await?; - check_community_deleted_or_removed(community_id, context.pool()).await?; + if community.local && data.follow { + check_community_ban(local_user_view.person.id, community_id, context.pool()).await?; + check_community_deleted_or_removed(community_id, context.pool()).await?; - CommunityFollower::follow(context.pool(), &community_follower_form) - .await - .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; - } else { - CommunityFollower::unfollow(context.pool(), &community_follower_form) - .await - .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; - } - } else if data.follow { - // Dont actually add to the community followers here, because you need - // to wait for the accept - FollowCommunityApub::send(&local_user_view.person.clone().into(), &community, context) - .await?; - } else { - UndoFollow::send(&local_user_view.person.clone().into(), &community, context).await?; + CommunityFollower::follow(context.pool(), &community_follower_form) + .await + .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; + } + if !data.follow { CommunityFollower::unfollow(context.pool(), &community_follower_form) .await .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; diff --git a/crates/api/src/community/hide.rs b/crates/api/src/community/hide.rs index 54a08135a..94ce7d745 100644 --- a/crates/api/src/community/hide.rs +++ b/crates/api/src/community/hide.rs @@ -2,11 +2,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, HideCommunity}, + context::LemmyContext, utils::{get_local_user_view_from_jwt, is_admin}, websocket::{send::send_community_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ source::{ community::{Community, CommunityUpdateForm}, @@ -45,19 +44,12 @@ impl Perform for HideCommunity { }; let community_id = data.community_id; - let updated_community = Community::update(context.pool(), community_id, &community_form) + Community::update(context.pool(), community_id, &community_form) .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community_hidden_status"))?; ModHideCommunity::create(context.pool(), &mod_hide_community_form).await?; - UpdateCommunity::send( - updated_community.into(), - &local_user_view.person.into(), - context, - ) - .await?; - let op = UserOperationCrud::EditCommunity; send_community_ws_message(data.community_id, op, websocket_id, None, context).await } diff --git a/crates/api/src/community/transfer.rs b/crates/api/src/community/transfer.rs index bb69de092..7ca174e4c 100644 --- a/crates/api/src/community/transfer.rs +++ b/crates/api/src/community/transfer.rs @@ -3,8 +3,8 @@ use actix_web::web::Data; use anyhow::Context; use lemmy_api_common::{ community::{GetCommunityResponse, TransferCommunity}, + context::LemmyContext, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 0473f1e88..5904a9b9b 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,81 +1,8 @@ -use actix_web::{web, web::Data}; +use actix_web::web::Data; use captcha::Captcha; -use lemmy_api_common::{ - comment::{ - CreateCommentLike, - CreateCommentReport, - ListCommentReports, - ResolveCommentReport, - SaveComment, - }, - community::{ - AddModToCommunity, - BanFromCommunity, - BlockCommunity, - FollowCommunity, - TransferCommunity, - }, - person::{ - AddAdmin, - BanPerson, - BlockPerson, - ChangePassword, - GetBannedPersons, - GetCaptcha, - GetPersonMentions, - GetReplies, - GetReportCount, - GetUnreadCount, - Login, - MarkAllAsRead, - MarkCommentReplyAsRead, - MarkPersonMentionAsRead, - PasswordChangeAfterReset, - PasswordReset, - SaveUserSettings, - VerifyEmail, - }, - post::{ - CreatePostLike, - CreatePostReport, - GetSiteMetadata, - ListPostReports, - LockPost, - MarkPostAsRead, - ResolvePostReport, - SavePost, - StickyPost, - }, - private_message::{ - CreatePrivateMessageReport, - ListPrivateMessageReports, - MarkPrivateMessageAsRead, - ResolvePrivateMessageReport, - }, - site::{ - ApproveRegistrationApplication, - GetModlog, - GetUnreadRegistrationApplicationCount, - LeaveAdmin, - ListRegistrationApplications, - PurgeComment, - PurgeCommunity, - PurgePerson, - PurgePost, - ResolveObject, - Search, - }, - utils::local_site_to_slur_regex, - websocket::{ - serialize_websocket_message, - structs::{CommunityJoin, ModJoin, PostJoin, UserJoin}, - UserOperation, - }, - LemmyContext, -}; +use lemmy_api_common::{context::LemmyContext, utils::local_site_to_slur_regex}; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_utils::{error::LemmyError, utils::check_slurs, ConnectionId}; -use serde::Deserialize; mod comment; mod comment_report; @@ -99,182 +26,6 @@ pub trait Perform { ) -> Result; } -pub async fn match_websocket_operation( - context: LemmyContext, - id: ConnectionId, - op: UserOperation, - data: &str, -) -> Result { - match op { - // User ops - UserOperation::Login => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetCaptcha => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetReplies => do_websocket_operation::(context, id, op, data).await, - UserOperation::AddAdmin => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetUnreadRegistrationApplicationCount => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListRegistrationApplications => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ApproveRegistrationApplication => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BanPerson => do_websocket_operation::(context, id, op, data).await, - UserOperation::GetBannedPersons => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BlockPerson => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetPersonMentions => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkPersonMentionAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkCommentReplyAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkAllAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PasswordReset => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PasswordChange => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::UserJoin => do_websocket_operation::(context, id, op, data).await, - UserOperation::PostJoin => do_websocket_operation::(context, id, op, data).await, - UserOperation::CommunityJoin => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ModJoin => do_websocket_operation::(context, id, op, data).await, - UserOperation::SaveUserSettings => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ChangePassword => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetReportCount => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetUnreadCount => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::VerifyEmail => { - do_websocket_operation::(context, id, op, data).await - } - - // Private Message ops - UserOperation::MarkPrivateMessageAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::CreatePrivateMessageReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ResolvePrivateMessageReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListPrivateMessageReports => { - do_websocket_operation::(context, id, op, data).await - } - - // Site ops - UserOperation::GetModlog => do_websocket_operation::(context, id, op, data).await, - UserOperation::PurgePerson => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PurgeCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::PurgePost => do_websocket_operation::(context, id, op, data).await, - UserOperation::PurgeComment => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::Search => do_websocket_operation::(context, id, op, data).await, - UserOperation::ResolveObject => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::TransferCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::LeaveAdmin => do_websocket_operation::(context, id, op, data).await, - - // Community ops - UserOperation::FollowCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BlockCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::BanFromCommunity => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::AddModToCommunity => { - do_websocket_operation::(context, id, op, data).await - } - - // Post ops - UserOperation::LockPost => do_websocket_operation::(context, id, op, data).await, - UserOperation::StickyPost => do_websocket_operation::(context, id, op, data).await, - UserOperation::CreatePostLike => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::MarkPostAsRead => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::SavePost => do_websocket_operation::(context, id, op, data).await, - UserOperation::CreatePostReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListPostReports => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ResolvePostReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::GetSiteMetadata => { - do_websocket_operation::(context, id, op, data).await - } - - // Comment ops - UserOperation::SaveComment => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::CreateCommentLike => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::CreateCommentReport => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ListCommentReports => { - do_websocket_operation::(context, id, op, data).await - } - UserOperation::ResolveCommentReport => { - do_websocket_operation::(context, id, op, data).await - } - } -} - -async fn do_websocket_operation<'a, 'b, Data>( - context: LemmyContext, - id: ConnectionId, - op: UserOperation, - data: &str, -) -> Result -where - for<'de> Data: Deserialize<'de> + 'a, - Data: Perform, -{ - 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) -} - /// Converts the captcha to a base64 encoded wav audio file pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> String { let letters = captcha.as_wav(); diff --git a/crates/api/src/local_user/add_admin.rs b/crates/api/src/local_user/add_admin.rs index 8091f97e4..78357f0c5 100644 --- a/crates/api/src/local_user/add_admin.rs +++ b/crates/api/src/local_user/add_admin.rs @@ -1,10 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{AddAdmin, AddAdminResponse}, utils::{get_local_user_view_from_jwt, is_admin}, websocket::{messages::SendAllMessage, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/local_user/ban_person.rs b/crates/api/src/local_user/ban_person.rs index a848175e4..0bb252349 100644 --- a/crates/api/src/local_user/ban_person.rs +++ b/crates/api/src/local_user/ban_person.rs @@ -1,14 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{BanPerson, BanPersonResponse}, utils::{get_local_user_view_from_jwt, is_admin, remove_user_data}, websocket::{messages::SendAllMessage, UserOperation}, - LemmyContext, -}; -use lemmy_apub::{ - activities::block::SiteOrCommunity, - protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser}, }; use lemmy_db_schema::{ source::{ @@ -17,7 +13,6 @@ use lemmy_db_schema::{ }, traits::Crud, }; -use lemmy_db_views::structs::SiteView; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, utils::naive_from_unix, ConnectionId}; @@ -79,32 +74,6 @@ impl Perform for BanPerson { let person_id = data.person_id; let person_view = PersonViewSafe::read(context.pool(), person_id).await?; - let site = SiteOrCommunity::Site(SiteView::read_local(context.pool()).await?.site.into()); - // if the action affects a local user, federate to other instances - if person.local { - if ban { - BlockUser::send( - &site, - &person.into(), - &local_user_view.person.into(), - remove_data, - data.reason.clone(), - expires, - context, - ) - .await?; - } else { - UndoBlockUser::send( - &site, - &person.into(), - &local_user_view.person.into(), - data.reason.clone(), - context, - ) - .await?; - } - } - let res = BanPersonResponse { person_view, banned: data.ban, diff --git a/crates/api/src/local_user/block.rs b/crates/api/src/local_user/block.rs index 798d36774..b57ecd551 100644 --- a/crates/api/src/local_user/block.rs +++ b/crates/api/src/local_user/block.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{BlockPerson, BlockPersonResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_schema::{ source::person_block::{PersonBlock, PersonBlockForm}, diff --git a/crates/api/src/local_user/change_password.rs b/crates/api/src/local_user/change_password.rs index e4e9004ea..2d0fd30e5 100644 --- a/crates/api/src/local_user/change_password.rs +++ b/crates/api/src/local_user/change_password.rs @@ -2,9 +2,9 @@ use crate::Perform; use actix_web::web::Data; use bcrypt::verify; use lemmy_api_common::{ + context::LemmyContext, person::{ChangePassword, LoginResponse}, utils::{get_local_user_view_from_jwt, password_length_check}, - LemmyContext, }; use lemmy_db_schema::source::local_user::LocalUser; use lemmy_utils::{claims::Claims, error::LemmyError, ConnectionId}; diff --git a/crates/api/src/local_user/change_password_after_reset.rs b/crates/api/src/local_user/change_password_after_reset.rs index f9556b533..c6de10d7a 100644 --- a/crates/api/src/local_user/change_password_after_reset.rs +++ b/crates/api/src/local_user/change_password_after_reset.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{LoginResponse, PasswordChangeAfterReset}, utils::password_length_check, - LemmyContext, }; use lemmy_db_schema::source::{ local_user::LocalUser, diff --git a/crates/api/src/local_user/get_captcha.rs b/crates/api/src/local_user/get_captcha.rs index 5eacc4fd8..50a2bdba2 100644 --- a/crates/api/src/local_user/get_captcha.rs +++ b/crates/api/src/local_user/get_captcha.rs @@ -3,9 +3,9 @@ use actix_web::web::Data; use captcha::{gen, Difficulty}; use chrono::Duration; use lemmy_api_common::{ + context::LemmyContext, person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse}, websocket::messages::CaptchaItem, - LemmyContext, }; use lemmy_db_schema::{source::local_site::LocalSite, utils::naive_now}; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/local_user/list_banned.rs b/crates/api/src/local_user/list_banned.rs index 31d4e3be6..60eb32b35 100644 --- a/crates/api/src/local_user/list_banned.rs +++ b/crates/api/src/local_user/list_banned.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{BannedPersonsResponse, GetBannedPersons}, utils::{get_local_user_view_from_jwt, is_admin}, - LemmyContext, }; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/local_user/login.rs b/crates/api/src/local_user/login.rs index dac0d9bf5..c60c0dcdf 100644 --- a/crates/api/src/local_user/login.rs +++ b/crates/api/src/local_user/login.rs @@ -2,9 +2,9 @@ use crate::Perform; use actix_web::web::Data; use bcrypt::verify; use lemmy_api_common::{ + context::LemmyContext, person::{Login, LoginResponse}, utils::{check_registration_application, check_user_valid}, - LemmyContext, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::LocalUserView; diff --git a/crates/api/src/local_user/notifications/list_mentions.rs b/crates/api/src/local_user/notifications/list_mentions.rs index 5e3b63e7a..c03e9d167 100644 --- a/crates/api/src/local_user/notifications/list_mentions.rs +++ b/crates/api/src/local_user/notifications/list_mentions.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetPersonMentions, GetPersonMentionsResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_views_actor::person_mention_view::PersonMentionQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/local_user/notifications/list_replies.rs b/crates/api/src/local_user/notifications/list_replies.rs index 375864b58..585db5e95 100644 --- a/crates/api/src/local_user/notifications/list_replies.rs +++ b/crates/api/src/local_user/notifications/list_replies.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetReplies, GetRepliesResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_views_actor::comment_reply_view::CommentReplyQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/local_user/notifications/mark_all_read.rs b/crates/api/src/local_user/notifications/mark_all_read.rs index 9f8926dc3..2515715bd 100644 --- a/crates/api/src/local_user/notifications/mark_all_read.rs +++ b/crates/api/src/local_user/notifications/mark_all_read.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetRepliesResponse, MarkAllAsRead}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_schema::source::{ comment_reply::CommentReply, diff --git a/crates/api/src/local_user/notifications/mark_mention_read.rs b/crates/api/src/local_user/notifications/mark_mention_read.rs index 655f78846..a3a75d929 100644 --- a/crates/api/src/local_user/notifications/mark_mention_read.rs +++ b/crates/api/src/local_user/notifications/mark_mention_read.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{MarkPersonMentionAsRead, PersonMentionResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_schema::{ source::person_mention::{PersonMention, PersonMentionUpdateForm}, diff --git a/crates/api/src/local_user/notifications/mark_reply_read.rs b/crates/api/src/local_user/notifications/mark_reply_read.rs index fa3367e33..3921e769d 100644 --- a/crates/api/src/local_user/notifications/mark_reply_read.rs +++ b/crates/api/src/local_user/notifications/mark_reply_read.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{CommentReplyResponse, MarkCommentReplyAsRead}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_schema::{ source::comment_reply::{CommentReply, CommentReplyUpdateForm}, diff --git a/crates/api/src/local_user/notifications/unread_count.rs b/crates/api/src/local_user/notifications/unread_count.rs index 442977a2c..715ccd286 100644 --- a/crates/api/src/local_user/notifications/unread_count.rs +++ b/crates/api/src/local_user/notifications/unread_count.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetUnreadCount, GetUnreadCountResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_views::structs::PrivateMessageView; use lemmy_db_views_actor::structs::{CommentReplyView, PersonMentionView}; diff --git a/crates/api/src/local_user/report_count.rs b/crates/api/src/local_user/report_count.rs index 7dd63b7ad..b59a06490 100644 --- a/crates/api/src/local_user/report_count.rs +++ b/crates/api/src/local_user/report_count.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetReportCount, GetReportCountResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_views::structs::{CommentReportView, PostReportView, PrivateMessageReportView}; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/local_user/reset_password.rs b/crates/api/src/local_user/reset_password.rs index 8def6d3c6..5d0e9d88b 100644 --- a/crates/api/src/local_user/reset_password.rs +++ b/crates/api/src/local_user/reset_password.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{PasswordReset, PasswordResetResponse}, utils::send_password_reset_email, - LemmyContext, }; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/local_user/save_settings.rs b/crates/api/src/local_user/save_settings.rs index 807e8262d..6672a67b0 100644 --- a/crates/api/src/local_user/save_settings.rs +++ b/crates/api/src/local_user/save_settings.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{LoginResponse, SaveUserSettings}, utils::{get_local_user_view_from_jwt, send_verification_email}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/local_user/verify_email.rs b/crates/api/src/local_user/verify_email.rs index 238692ff0..fb82b716b 100644 --- a/crates/api/src/local_user/verify_email.rs +++ b/crates/api/src/local_user/verify_email.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{VerifyEmail, VerifyEmailResponse}, utils::send_email_verification_success, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/post/get_link_metadata.rs b/crates/api/src/post/get_link_metadata.rs index aae211a50..eaf111eba 100644 --- a/crates/api/src/post/get_link_metadata.rs +++ b/crates/api/src/post/get_link_metadata.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{GetSiteMetadata, GetSiteMetadataResponse}, request::fetch_site_metadata, - LemmyContext, }; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/post/like.rs b/crates/api/src/post/like.rs index d15e649b9..59135ff21 100644 --- a/crates/api/src/post/like.rs +++ b/crates/api/src/post/like.rs @@ -1,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{CreatePostLike, PostResponse}, utils::{ check_community_ban, @@ -10,15 +11,6 @@ use lemmy_api_common::{ mark_post_as_read, }, websocket::{send::send_post_ws_message, UserOperation}, - LemmyContext, -}; -use lemmy_apub::{ - fetcher::post_or_comment::PostOrComment, - objects::post::ApubPost, - protocol::activities::voting::{ - undo_vote::UndoVote, - vote::{Vote, VoteType}, - }, }; use lemmy_db_schema::{ source::{ @@ -49,7 +41,7 @@ impl Perform for CreatePostLike { // Check for a community ban let post_id = data.post_id; - let post: ApubPost = Post::read(context.pool(), post_id).await?.into(); + let post = Post::read(context.pool(), post_id).await?; check_community_ban(local_user_view.person.id, post.community_id, context.pool()).await?; check_community_deleted_or_removed(post.community_id, context.pool()).await?; @@ -65,9 +57,6 @@ impl Perform for CreatePostLike { PostLike::remove(context.pool(), person_id, post_id).await?; - let community_id = post.community_id; - let object = PostOrComment::Post(Box::new(post)); - // Only add the like if the score isnt 0 let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1); if do_add { @@ -75,25 +64,6 @@ impl Perform for CreatePostLike { PostLike::like(context.pool(), &like_form2) .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_post"))?; - - Vote::send( - &object, - &local_user_view.person.clone().into(), - community_id, - like_form.score.try_into()?, - context, - ) - .await?; - } else { - // API doesn't distinguish between Undo/Like and Undo/Dislike - UndoVote::send( - &object, - &local_user_view.person.clone().into(), - community_id, - VoteType::Like, - context, - ) - .await?; } // Mark the post as read diff --git a/crates/api/src/post/lock.rs b/crates/api/src/post/lock.rs index 4348971fe..c5fa2a0f5 100644 --- a/crates/api/src/post/lock.rs +++ b/crates/api/src/post/lock.rs @@ -1,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{LockPost, PostResponse}, utils::{ check_community_ban, @@ -9,11 +10,6 @@ use lemmy_api_common::{ is_mod_or_admin, }, websocket::{send::send_post_ws_message, UserOperation}, - LemmyContext, -}; -use lemmy_apub::{ - objects::post::ApubPost, - protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType}, }; use lemmy_db_schema::{ source::{ @@ -60,13 +56,12 @@ impl Perform for LockPost { // Update the post let post_id = data.post_id; let locked = data.locked; - let updated_post: ApubPost = Post::update( + Post::update( context.pool(), post_id, &PostUpdateForm::builder().locked(Some(locked)).build(), ) - .await? - .into(); + .await?; // Mod tables let form = ModLockPostForm { @@ -76,15 +71,6 @@ impl Perform for LockPost { }; ModLockPost::create(context.pool(), &form).await?; - // apub updates - CreateOrUpdatePage::send( - updated_post, - &local_user_view.person.clone().into(), - CreateOrUpdateType::Update, - context, - ) - .await?; - send_post_ws_message( data.post_id, UserOperation::LockPost, diff --git a/crates/api/src/post/mark_read.rs b/crates/api/src/post/mark_read.rs index 228fdac0d..9fdf01b12 100644 --- a/crates/api/src/post/mark_read.rs +++ b/crates/api/src/post/mark_read.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{MarkPostAsRead, PostResponse}, utils::{get_local_user_view_from_jwt, mark_post_as_read, mark_post_as_unread}, - LemmyContext, }; use lemmy_db_views::structs::PostView; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/post/save.rs b/crates/api/src/post/save.rs index 9e8ca9ce1..b36f844b6 100644 --- a/crates/api/src/post/save.rs +++ b/crates/api/src/post/save.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{PostResponse, SavePost}, utils::{get_local_user_view_from_jwt, mark_post_as_read}, - LemmyContext, }; use lemmy_db_schema::{ source::post::{PostSaved, PostSavedForm}, diff --git a/crates/api/src/post/sticky.rs b/crates/api/src/post/sticky.rs index ccba5f2c3..3a8aee7ab 100644 --- a/crates/api/src/post/sticky.rs +++ b/crates/api/src/post/sticky.rs @@ -1,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{PostResponse, StickyPost}, utils::{ check_community_ban, @@ -9,11 +10,6 @@ use lemmy_api_common::{ is_mod_or_admin, }, websocket::{send::send_post_ws_message, UserOperation}, - LemmyContext, -}; -use lemmy_apub::{ - objects::post::ApubPost, - protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType}, }; use lemmy_db_schema::{ source::{ @@ -60,13 +56,12 @@ impl Perform for StickyPost { // Update the post let post_id = data.post_id; let stickied = data.stickied; - let updated_post: ApubPost = Post::update( + Post::update( context.pool(), post_id, &PostUpdateForm::builder().stickied(Some(stickied)).build(), ) - .await? - .into(); + .await?; // Mod tables let form = ModStickyPostForm { @@ -77,16 +72,6 @@ impl Perform for StickyPost { ModStickyPost::create(context.pool(), &form).await?; - // Apub updates - // TODO stickied should pry work like locked for ease of use - CreateOrUpdatePage::send( - updated_post, - &local_user_view.person.clone().into(), - CreateOrUpdateType::Update, - context, - ) - .await?; - send_post_ws_message( data.post_id, UserOperation::StickyPost, diff --git a/crates/api/src/post_report/create.rs b/crates/api/src/post_report/create.rs index 2fd2d08be..71be43623 100644 --- a/crates/api/src/post_report/create.rs +++ b/crates/api/src/post_report/create.rs @@ -1,13 +1,11 @@ use crate::{check_report_reason, Perform}; -use activitypub_federation::core::object_id::ObjectId; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{CreatePostReport, PostReportResponse}, utils::{check_community_ban, get_local_user_view_from_jwt}, websocket::{messages::SendModRoomMessage, UserOperation}, - LemmyContext, }; -use lemmy_apub::protocol::activities::community::report::Report; use lemmy_db_schema::{ source::{ local_site::LocalSite, @@ -67,15 +65,6 @@ impl Perform for CreatePostReport { websocket_id, }); - Report::send( - ObjectId::new(post_view.post.ap_id), - &local_user_view.person.into(), - ObjectId::new(post_view.community.actor_id), - reason.to_string(), - context, - ) - .await?; - Ok(res) } } diff --git a/crates/api/src/post_report/list.rs b/crates/api/src/post_report/list.rs index 188a722ff..2feed7ed2 100644 --- a/crates/api/src/post_report/list.rs +++ b/crates/api/src/post_report/list.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{ListPostReports, ListPostReportsResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_views::post_report_view::PostReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/post_report/resolve.rs b/crates/api/src/post_report/resolve.rs index 6c3d62f18..0e2b9e16a 100644 --- a/crates/api/src/post_report/resolve.rs +++ b/crates/api/src/post_report/resolve.rs @@ -1,10 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{PostReportResponse, ResolvePostReport}, utils::{get_local_user_view_from_jwt, is_mod_or_admin}, websocket::{messages::SendModRoomMessage, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{source::post_report::PostReport, traits::Reportable}; use lemmy_db_views::structs::PostReportView; diff --git a/crates/api/src/private_message/mark_read.rs b/crates/api/src/private_message/mark_read.rs index ba0e70d59..9c3c3d8ae 100644 --- a/crates/api/src/private_message/mark_read.rs +++ b/crates/api/src/private_message/mark_read.rs @@ -1,10 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, private_message::{MarkPrivateMessageAsRead, PrivateMessageResponse}, utils::get_local_user_view_from_jwt, websocket::{send::send_pm_ws_message, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{ source::private_message::{PrivateMessage, PrivateMessageUpdateForm}, diff --git a/crates/api/src/private_message_report/create.rs b/crates/api/src/private_message_report/create.rs index 6b923c102..66875c614 100644 --- a/crates/api/src/private_message_report/create.rs +++ b/crates/api/src/private_message_report/create.rs @@ -1,10 +1,10 @@ use crate::{check_report_reason, Perform}; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, private_message::{CreatePrivateMessageReport, PrivateMessageReportResponse}, utils::get_local_user_view_from_jwt, websocket::{messages::SendModRoomMessage, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{ newtypes::CommunityId, diff --git a/crates/api/src/private_message_report/list.rs b/crates/api/src/private_message_report/list.rs index 17fc438ff..98c2d9269 100644 --- a/crates/api/src/private_message_report/list.rs +++ b/crates/api/src/private_message_report/list.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, private_message::{ListPrivateMessageReports, ListPrivateMessageReportsResponse}, utils::{get_local_user_view_from_jwt, is_admin}, - LemmyContext, }; use lemmy_db_views::private_message_report_view::PrivateMessageReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api/src/private_message_report/resolve.rs b/crates/api/src/private_message_report/resolve.rs index eeda4ed42..2a3f677ad 100644 --- a/crates/api/src/private_message_report/resolve.rs +++ b/crates/api/src/private_message_report/resolve.rs @@ -1,10 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, private_message::{PrivateMessageReportResponse, ResolvePrivateMessageReport}, utils::{get_local_user_view_from_jwt, is_admin}, websocket::{messages::SendModRoomMessage, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{ newtypes::CommunityId, diff --git a/crates/api/src/site/leave_admin.rs b/crates/api/src/site/leave_admin.rs index 4674f43bf..7a75db51d 100644 --- a/crates/api/src/site/leave_admin.rs +++ b/crates/api/src/site/leave_admin.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{GetSiteResponse, LeaveAdmin}, utils::{get_local_user_view_from_jwt, is_admin}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/site/mod.rs b/crates/api/src/site/mod.rs index 531c05085..4e3694ce4 100644 --- a/crates/api/src/site/mod.rs +++ b/crates/api/src/site/mod.rs @@ -2,5 +2,3 @@ mod leave_admin; mod mod_log; mod purge; mod registration_applications; -mod resolve_object; -mod search; diff --git a/crates/api/src/site/mod_log.rs b/crates/api/src/site/mod_log.rs index 85bfc40ce..5e1c71a70 100644 --- a/crates/api/src/site/mod_log.rs +++ b/crates/api/src/site/mod_log.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{GetModlog, GetModlogResponse}, utils::{check_private_instance, get_local_user_view_from_jwt_opt, is_admin, is_mod_or_admin}, - LemmyContext, }; use lemmy_db_schema::{ newtypes::{CommunityId, PersonId}, diff --git a/crates/api/src/site/purge/comment.rs b/crates/api/src/site/purge/comment.rs index 54f3c0edf..71d2c7889 100644 --- a/crates/api/src/site/purge/comment.rs +++ b/crates/api/src/site/purge/comment.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{PurgeComment, PurgeItemResponse}, utils::{get_local_user_view_from_jwt, is_admin}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/site/purge/community.rs b/crates/api/src/site/purge/community.rs index c70c8c0a7..e3a673b74 100644 --- a/crates/api/src/site/purge/community.rs +++ b/crates/api/src/site/purge/community.rs @@ -1,10 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, request::purge_image_from_pictrs, site::{PurgeCommunity, PurgeItemResponse}, utils::{get_local_user_view_from_jwt, is_admin, purge_image_posts_for_community}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/site/purge/person.rs b/crates/api/src/site/purge/person.rs index 8a5f6ac09..658e50b6d 100644 --- a/crates/api/src/site/purge/person.rs +++ b/crates/api/src/site/purge/person.rs @@ -1,10 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, request::purge_image_from_pictrs, site::{PurgeItemResponse, PurgePerson}, utils::{get_local_user_view_from_jwt, is_admin, purge_image_posts_for_person}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/site/purge/post.rs b/crates/api/src/site/purge/post.rs index b3ec28eac..aa2e74839 100644 --- a/crates/api/src/site/purge/post.rs +++ b/crates/api/src/site/purge/post.rs @@ -1,10 +1,10 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, request::purge_image_from_pictrs, site::{PurgeItemResponse, PurgePost}, utils::{get_local_user_view_from_jwt, is_admin}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/site/registration_applications/approve.rs b/crates/api/src/site/registration_applications/approve.rs index c5089b5d5..61a686899 100644 --- a/crates/api/src/site/registration_applications/approve.rs +++ b/crates/api/src/site/registration_applications/approve.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{ApproveRegistrationApplication, RegistrationApplicationResponse}, utils::{get_local_user_view_from_jwt, is_admin, send_application_approved_email}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api/src/site/registration_applications/list.rs b/crates/api/src/site/registration_applications/list.rs index 1ce709b35..7be2e2e8e 100644 --- a/crates/api/src/site/registration_applications/list.rs +++ b/crates/api/src/site/registration_applications/list.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{ListRegistrationApplications, ListRegistrationApplicationsResponse}, utils::{get_local_user_view_from_jwt, is_admin}, - LemmyContext, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::registration_application_view::RegistrationApplicationQuery; diff --git a/crates/api/src/site/registration_applications/unread_count.rs b/crates/api/src/site/registration_applications/unread_count.rs index a22d14e95..fe33d17c8 100644 --- a/crates/api/src/site/registration_applications/unread_count.rs +++ b/crates/api/src/site/registration_applications/unread_count.rs @@ -1,9 +1,9 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{GetUnreadRegistrationApplicationCount, GetUnreadRegistrationApplicationCountResponse}, utils::{get_local_user_view_from_jwt, is_admin}, - LemmyContext, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::RegistrationApplicationView; diff --git a/crates/api/src/websocket.rs b/crates/api/src/websocket.rs index 0e0c015a1..ca755bde9 100644 --- a/crates/api/src/websocket.rs +++ b/crates/api/src/websocket.rs @@ -1,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, utils::get_local_user_view_from_jwt, websocket::{ messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom}, @@ -15,7 +16,6 @@ use lemmy_api_common::{ UserJoinResponse, }, }, - LemmyContext, }; use lemmy_utils::{error::LemmyError, ConnectionId}; diff --git a/crates/api_common/src/context.rs b/crates/api_common/src/context.rs new file mode 100644 index 000000000..e552af530 --- /dev/null +++ b/crates/api_common/src/context.rs @@ -0,0 +1,68 @@ +use crate::websocket::chat_server::ChatServer; +use actix::Addr; +use lemmy_db_schema::{source::secret::Secret, utils::DbPool}; +use lemmy_utils::{ + rate_limit::RateLimitCell, + settings::{structs::Settings, SETTINGS}, +}; +use reqwest_middleware::ClientWithMiddleware; + +pub struct LemmyContext { + pool: DbPool, + chat_server: Addr, + client: ClientWithMiddleware, + settings: Settings, + secret: Secret, + rate_limit_cell: RateLimitCell, +} + +impl LemmyContext { + pub fn create( + pool: DbPool, + chat_server: Addr, + client: ClientWithMiddleware, + settings: Settings, + secret: Secret, + rate_limit_cell: RateLimitCell, + ) -> LemmyContext { + LemmyContext { + pool, + chat_server, + client, + settings, + secret, + rate_limit_cell, + } + } + pub fn pool(&self) -> &DbPool { + &self.pool + } + pub fn chat_server(&self) -> &Addr { + &self.chat_server + } + pub fn client(&self) -> &ClientWithMiddleware { + &self.client + } + pub fn settings(&self) -> &'static Settings { + &SETTINGS + } + pub fn secret(&self) -> &Secret { + &self.secret + } + pub fn settings_updated_channel(&self) -> &RateLimitCell { + &self.rate_limit_cell + } +} + +impl Clone for LemmyContext { + fn clone(&self) -> Self { + LemmyContext { + pool: self.pool.clone(), + chat_server: self.chat_server.clone(), + client: self.client.clone(), + settings: self.settings.clone(), + secret: self.secret.clone(), + rate_limit_cell: self.rate_limit_cell.clone(), + } + } +} diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index 990780e15..29686aba6 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -1,5 +1,7 @@ pub mod comment; pub mod community; +#[cfg(feature = "full")] +pub mod context; pub mod person; pub mod post; pub mod private_message; @@ -9,6 +11,7 @@ pub mod sensitive; pub mod site; #[cfg(feature = "full")] pub mod utils; +#[cfg(feature = "full")] pub mod websocket; #[macro_use] @@ -17,138 +20,3 @@ pub extern crate lemmy_db_schema; pub extern crate lemmy_db_views; pub extern crate lemmy_db_views_actor; pub extern crate lemmy_db_views_moderator; - -use crate::websocket::chat_server::ChatServer; -use actix::Addr; -use anyhow::Context; -use lemmy_db_schema::{newtypes::DbUrl, source::secret::Secret, utils::DbPool}; -use lemmy_utils::{ - error::LemmyError, - location_info, - rate_limit::RateLimitCell, - settings::{structs::Settings, SETTINGS}, -}; -use reqwest_middleware::ClientWithMiddleware; -use url::{ParseError, Url}; - -pub struct LemmyContext { - pool: DbPool, - chat_server: Addr, - client: ClientWithMiddleware, - settings: Settings, - secret: Secret, - rate_limit_cell: RateLimitCell, -} - -impl LemmyContext { - pub fn create( - pool: DbPool, - chat_server: Addr, - client: ClientWithMiddleware, - settings: Settings, - secret: Secret, - settings_updated_channel: RateLimitCell, - ) -> LemmyContext { - LemmyContext { - pool, - chat_server, - client, - settings, - secret, - rate_limit_cell: settings_updated_channel, - } - } - pub fn pool(&self) -> &DbPool { - &self.pool - } - pub fn chat_server(&self) -> &Addr { - &self.chat_server - } - pub fn client(&self) -> &ClientWithMiddleware { - &self.client - } - pub fn settings(&self) -> &'static Settings { - &SETTINGS - } - pub fn secret(&self) -> &Secret { - &self.secret - } - pub fn settings_updated_channel(&self) -> &RateLimitCell { - &self.rate_limit_cell - } -} - -impl Clone for LemmyContext { - fn clone(&self) -> Self { - LemmyContext { - pool: self.pool.clone(), - chat_server: self.chat_server.clone(), - client: self.client.clone(), - settings: self.settings.clone(), - secret: self.secret.clone(), - rate_limit_cell: self.rate_limit_cell.clone(), - } - } -} - -pub enum EndpointType { - Community, - Person, - Post, - Comment, - PrivateMessage, -} - -/// Generates an apub endpoint for a given domain, IE xyz.tld -pub fn generate_local_apub_endpoint( - endpoint_type: EndpointType, - name: &str, - domain: &str, -) -> Result { - let point = match endpoint_type { - EndpointType::Community => "c", - EndpointType::Person => "u", - EndpointType::Post => "post", - EndpointType::Comment => "comment", - EndpointType::PrivateMessage => "private_message", - }; - - Ok(Url::parse(&format!("{}/{}/{}", domain, point, name))?.into()) -} - -pub fn generate_followers_url(actor_id: &DbUrl) -> Result { - Ok(Url::parse(&format!("{}/followers", actor_id))?.into()) -} - -pub fn generate_inbox_url(actor_id: &DbUrl) -> Result { - Ok(Url::parse(&format!("{}/inbox", actor_id))?.into()) -} - -pub fn generate_site_inbox_url(actor_id: &DbUrl) -> Result { - let mut actor_id: Url = actor_id.clone().into(); - actor_id.set_path("site_inbox"); - Ok(actor_id.into()) -} - -pub fn generate_shared_inbox_url(actor_id: &DbUrl) -> Result { - let actor_id: Url = actor_id.clone().into(); - let url = format!( - "{}://{}{}/inbox", - &actor_id.scheme(), - &actor_id.host_str().context(location_info!())?, - if let Some(port) = actor_id.port() { - format!(":{}", port) - } else { - String::new() - }, - ); - Ok(Url::parse(&url)?.into()) -} - -pub fn generate_outbox_url(actor_id: &DbUrl) -> Result { - Ok(Url::parse(&format!("{}/outbox", actor_id))?.into()) -} - -pub fn generate_moderators_url(community_id: &DbUrl) -> Result { - Ok(Url::parse(&format!("{}/moderators", community_id))?.into()) -} diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index 8c4131dd6..897dd998e 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -268,7 +268,7 @@ pub struct GetUnreadCountResponse { pub private_messages: i64, } -#[derive(Serialize, Deserialize, Clone, Default)] +#[derive(Serialize, Deserialize, Clone, Default, Debug)] pub struct VerifyEmail { pub token: String, } diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index 1e863e855..c85344992 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -1,8 +1,9 @@ use crate::{request::purge_image_from_pictrs, sensitive::Sensitive, site::FederatedInstances}; +use anyhow::Context; use chrono::NaiveDateTime; use lemmy_db_schema::{ impls::person::is_banned, - newtypes::{CommunityId, LocalUserId, PersonId, PostId}, + newtypes::{CommunityId, DbUrl, LocalUserId, PersonId, PostId}, source::{ comment::{Comment, CommentUpdateForm}, community::{Community, CommunityUpdateForm}, @@ -34,6 +35,7 @@ use lemmy_utils::{ claims::Claims, email::{send_email, translations::Lang}, error::LemmyError, + location_info, rate_limit::RateLimitConfig, settings::structs::Settings, utils::{build_slur_regex, generate_random_string}, @@ -43,6 +45,7 @@ use reqwest_middleware::ClientWithMiddleware; use rosetta_i18n::{Language, LanguageId}; use std::str::FromStr; use tracing::warn; +use url::{ParseError, Url}; #[tracing::instrument(skip_all)] pub async fn is_mod_or_admin( @@ -743,3 +746,65 @@ mod tests { assert!(honeypot_check(&Some("message".to_string())).is_err()); } } + +pub enum EndpointType { + Community, + Person, + Post, + Comment, + PrivateMessage, +} + +/// Generates an apub endpoint for a given domain, IE xyz.tld +pub fn generate_local_apub_endpoint( + endpoint_type: EndpointType, + name: &str, + domain: &str, +) -> Result { + let point = match endpoint_type { + EndpointType::Community => "c", + EndpointType::Person => "u", + EndpointType::Post => "post", + EndpointType::Comment => "comment", + EndpointType::PrivateMessage => "private_message", + }; + + Ok(Url::parse(&format!("{}/{}/{}", domain, point, name))?.into()) +} + +pub fn generate_followers_url(actor_id: &DbUrl) -> Result { + Ok(Url::parse(&format!("{}/followers", actor_id))?.into()) +} + +pub fn generate_inbox_url(actor_id: &DbUrl) -> Result { + Ok(Url::parse(&format!("{}/inbox", actor_id))?.into()) +} + +pub fn generate_site_inbox_url(actor_id: &DbUrl) -> Result { + let mut actor_id: Url = actor_id.clone().into(); + actor_id.set_path("site_inbox"); + Ok(actor_id.into()) +} + +pub fn generate_shared_inbox_url(actor_id: &DbUrl) -> Result { + let actor_id: Url = actor_id.clone().into(); + let url = format!( + "{}://{}{}/inbox", + &actor_id.scheme(), + &actor_id.host_str().context(location_info!())?, + if let Some(port) = actor_id.port() { + format!(":{}", port) + } else { + String::new() + }, + ); + Ok(Url::parse(&url)?.into()) +} + +pub fn generate_outbox_url(actor_id: &DbUrl) -> Result { + Ok(Url::parse(&format!("{}/outbox", actor_id))?.into()) +} + +pub fn generate_moderators_url(community_id: &DbUrl) -> Result { + Ok(Url::parse(&format!("{}/moderators", community_id))?.into()) +} diff --git a/crates/api_common/src/websocket/chat_server.rs b/crates/api_common/src/websocket/chat_server.rs index c8f59e3d2..b669a4fd3 100644 --- a/crates/api_common/src/websocket/chat_server.rs +++ b/crates/api_common/src/websocket/chat_server.rs @@ -1,14 +1,15 @@ use crate::{ comment::CommentResponse, + context::LemmyContext, post::PostResponse, websocket::{ messages::{CaptchaItem, StandardMessage, WsMessage}, serialize_websocket_message, OperationType, UserOperation, + UserOperationApub, UserOperationCrud, }, - LemmyContext, }; use actix::prelude::*; use anyhow::Context as acontext; @@ -50,6 +51,13 @@ type MessageHandlerCrudType = fn( data: &str, ) -> Pin> + '_>>; +type MessageHandlerApubType = fn( + context: LemmyContext, + id: ConnectionId, + op: UserOperationApub, + data: &str, +) -> Pin> + '_>>; + /// `ChatServer` manages chat rooms and responsible for coordinating chat /// session. pub struct ChatServer { @@ -84,6 +92,7 @@ pub struct ChatServer { message_handler: MessageHandlerType, message_handler_crud: MessageHandlerCrudType, + message_handler_apub: MessageHandlerApubType, /// An HTTP Client client: ClientWithMiddleware, @@ -105,6 +114,7 @@ impl ChatServer { pool: DbPool, message_handler: MessageHandlerType, message_handler_crud: MessageHandlerCrudType, + message_handler_apub: MessageHandlerApubType, client: ClientWithMiddleware, settings: Settings, secret: Secret, @@ -121,6 +131,7 @@ impl ChatServer { captchas: Vec::new(), message_handler, message_handler_crud, + message_handler_apub, client, settings, secret, @@ -453,16 +464,17 @@ impl ChatServer { None => IpAddr("blank_ip".to_string()), }; - let context = LemmyContext { - pool: self.pool.clone(), - chat_server: ctx.address(), - client: self.client.clone(), - settings: self.settings.clone(), - secret: self.secret.clone(), - rate_limit_cell: self.rate_limit_cell.clone(), - }; + let context = LemmyContext::create( + self.pool.clone(), + ctx.address(), + self.client.clone(), + self.settings.clone(), + self.secret.clone(), + self.rate_limit_cell.clone(), + ); let message_handler_crud = self.message_handler_crud; let message_handler = self.message_handler; + let message_handler_apub = self.message_handler_apub; let rate_limiter = self.rate_limit_cell.clone(); async move { let json: Value = serde_json::from_str(&msg.msg)?; @@ -482,15 +494,21 @@ impl ChatServer { }; let fut = (message_handler_crud)(context, msg.id, user_operation_crud, data); (passed, fut) - } else { - let user_operation = UserOperation::from_str(op)?; + } else if let Ok(user_operation) = UserOperation::from_str(op) { let passed = match user_operation { UserOperation::GetCaptcha => rate_limiter.post().check(ip), - UserOperation::Search => rate_limiter.search().check(ip), _ => rate_limiter.message().check(ip), }; let fut = (message_handler)(context, msg.id, user_operation, data); (passed, fut) + } else { + let user_operation = UserOperationApub::from_str(op)?; + let passed = match user_operation { + UserOperationApub::Search => rate_limiter.search().check(ip), + _ => rate_limiter.message().check(ip), + }; + let fut = (message_handler_apub)(context, msg.id, user_operation, data); + (passed, fut) }; // if rate limit passed, execute api call future diff --git a/crates/api_common/src/websocket/mod.rs b/crates/api_common/src/websocket/mod.rs index d1e30f448..430027cfa 100644 --- a/crates/api_common/src/websocket/mod.rs +++ b/crates/api_common/src/websocket/mod.rs @@ -63,8 +63,6 @@ pub enum UserOperation { ApproveRegistrationApplication, BanPerson, GetBannedPersons, - Search, - ResolveObject, MarkAllAsRead, SaveUserSettings, TransferCommunity, @@ -98,27 +96,23 @@ pub enum UserOperationCrud { // Community CreateCommunity, ListCommunities, - GetCommunity, EditCommunity, DeleteCommunity, RemoveCommunity, // Post CreatePost, GetPost, - GetPosts, EditPost, DeletePost, RemovePost, // Comment CreateComment, GetComment, - GetComments, EditComment, DeleteComment, RemoveComment, // User Register, - GetPersonDetails, DeleteAccount, // Private Message CreatePrivateMessage, @@ -127,8 +121,20 @@ pub enum UserOperationCrud { DeletePrivateMessage, } +#[derive(EnumString, Display, Debug, Clone)] +pub enum UserOperationApub { + GetPosts, + GetCommunity, + GetComments, + GetPersonDetails, + Search, + ResolveObject, +} + pub trait OperationType {} impl OperationType for UserOperationCrud {} impl OperationType for UserOperation {} + +impl OperationType for UserOperationApub {} diff --git a/crates/api_common/src/websocket/routes.rs b/crates/api_common/src/websocket/routes.rs index 7b500ce4c..936dc9998 100644 --- a/crates/api_common/src/websocket/routes.rs +++ b/crates/api_common/src/websocket/routes.rs @@ -1,9 +1,9 @@ use crate::{ + context::LemmyContext, websocket::{ chat_server::ChatServer, messages::{Connect, Disconnect, StandardMessage, WsMessage}, }, - LemmyContext, }; use actix::prelude::*; use actix_web::{web, Error, HttpRequest, HttpResponse}; diff --git a/crates/api_common/src/websocket/send.rs b/crates/api_common/src/websocket/send.rs index 6f3506aee..cd53955f9 100644 --- a/crates/api_common/src/websocket/send.rs +++ b/crates/api_common/src/websocket/send.rs @@ -1,6 +1,7 @@ use crate::{ comment::CommentResponse, community::CommunityResponse, + context::LemmyContext, post::PostResponse, private_message::PrivateMessageResponse, utils::{check_person_block, get_interface_language, send_email_to_user}, @@ -8,7 +9,6 @@ use crate::{ messages::{SendComment, SendCommunityRoomMessage, SendPost, SendUserRoomMessage}, OperationType, }, - LemmyContext, }; use lemmy_db_schema::{ newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId}, diff --git a/crates/api_crud/Cargo.toml b/crates/api_crud/Cargo.toml index 7a16aed5c..2d1774463 100644 --- a/crates/api_crud/Cargo.toml +++ b/crates/api_crud/Cargo.toml @@ -9,7 +9,6 @@ documentation.workspace = true repository.workspace = true [dependencies] -lemmy_apub = { workspace = true } lemmy_utils = { workspace = true } lemmy_db_schema = { workspace = true, features = ["full"] } lemmy_db_views = { workspace = true, features = ["full"] } diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index 5d9603ac3..8c61a0444 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -2,25 +2,21 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, CreateComment}, - generate_local_apub_endpoint, + context::LemmyContext, utils::{ check_community_ban, check_community_deleted_or_removed, check_post_deleted_or_removed, + generate_local_apub_endpoint, get_local_user_view_from_jwt, get_post, local_site_to_slur_regex, + EndpointType, }, websocket::{ send::{send_comment_ws_message, send_local_notifs}, UserOperationCrud, }, - EndpointType, - LemmyContext, -}; -use lemmy_apub::{ - objects::comment::ApubComment, - protocol::activities::{create_or_update::note::CreateOrUpdateNote, CreateOrUpdateType}, }; use lemmy_db_schema::{ source::{ @@ -157,16 +153,6 @@ impl PerformCrud for CreateComment { .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_comment"))?; - let apub_comment: ApubComment = updated_comment.into(); - CreateOrUpdateNote::send( - apub_comment.clone(), - &local_user_view.person.clone().into(), - CreateOrUpdateType::Create, - context, - &mut 0, - ) - .await?; - // If its a reply, mark the parent as read if let Some(parent) = parent_opt { let parent_id = parent.id; diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs index f14d0d415..211d04776 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -2,18 +2,16 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, DeleteComment}, + context::LemmyContext, utils::{check_community_ban, get_local_user_view_from_jwt}, websocket::{ send::{send_comment_ws_message, send_local_notifs}, UserOperationCrud, }, - LemmyContext, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, - community::Community, post::Post, }, traits::Crud, @@ -88,19 +86,6 @@ impl PerformCrud for DeleteComment { ) .await?; - // Send the apub message - let community = Community::read(context.pool(), orig_comment.post.community_id).await?; - let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into())); - send_apub_delete_in_community( - local_user_view.person, - community, - deletable, - None, - deleted, - context, - ) - .await?; - Ok(res) } } diff --git a/crates/api_crud/src/comment/mod.rs b/crates/api_crud/src/comment/mod.rs index 1e8328034..d3d789a02 100644 --- a/crates/api_crud/src/comment/mod.rs +++ b/crates/api_crud/src/comment/mod.rs @@ -1,6 +1,5 @@ mod create; mod delete; -mod list; mod read; mod remove; mod update; diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index 98b3431c2..c0136f06c 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -2,8 +2,8 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, GetComment}, + context::LemmyContext, utils::{check_private_instance, get_local_user_view_from_jwt_opt}, - LemmyContext, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::CommentView; diff --git a/crates/api_crud/src/comment/remove.rs b/crates/api_crud/src/comment/remove.rs index 09e5fdfca..1032f54c9 100644 --- a/crates/api_crud/src/comment/remove.rs +++ b/crates/api_crud/src/comment/remove.rs @@ -2,18 +2,16 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, RemoveComment}, + context::LemmyContext, utils::{check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin}, websocket::{ send::{send_comment_ws_message, send_local_notifs}, UserOperationCrud, }, - LemmyContext, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, - community::Community, moderator::{ModRemoveComment, ModRemoveCommentForm}, post::Post, }, @@ -96,19 +94,6 @@ impl PerformCrud for RemoveComment { ) .await?; - // Send the apub message - let community = Community::read(context.pool(), orig_comment.post.community_id).await?; - let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into())); - send_apub_delete_in_community( - local_user_view.person, - community, - deletable, - data.reason.clone().or_else(|| Some(String::new())), - removed, - context, - ) - .await?; - Ok(res) } } diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index d1fcccd9c..88de41158 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -2,6 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, EditComment}, + context::LemmyContext, utils::{ check_community_ban, check_community_deleted_or_removed, @@ -14,11 +15,6 @@ use lemmy_api_common::{ send::{send_comment_ws_message, send_local_notifs}, UserOperationCrud, }, - LemmyContext, -}; -use lemmy_apub::protocol::activities::{ - create_or_update::note::CreateOrUpdateNote, - CreateOrUpdateType, }; use lemmy_db_schema::{ source::{ @@ -114,16 +110,6 @@ impl PerformCrud for EditComment { ) .await?; - // Send the apub update - CreateOrUpdateNote::send( - updated_comment.into(), - &local_user_view.person.into(), - CreateOrUpdateType::Update, - context, - &mut 0, - ) - .await?; - send_comment_ws_message( data.comment_id, UserOperationCrud::EditComment, diff --git a/crates/api_crud/src/community/create.rs b/crates/api_crud/src/community/create.rs index 11a307668..cf894edbd 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -1,17 +1,20 @@ use crate::PerformCrud; -use activitypub_federation::core::{object_id::ObjectId, signatures::generate_actor_keypair}; +use activitypub_federation::core::signatures::generate_actor_keypair; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, CreateCommunity}, - generate_followers_url, - generate_inbox_url, - generate_local_apub_endpoint, - generate_shared_inbox_url, - utils::{get_local_user_view_from_jwt, is_admin, local_site_to_slur_regex}, - EndpointType, - LemmyContext, + context::LemmyContext, + utils::{ + generate_followers_url, + generate_inbox_url, + generate_local_apub_endpoint, + generate_shared_inbox_url, + get_local_user_view_from_jwt, + is_admin, + local_site_to_slur_regex, + EndpointType, + }, }; -use lemmy_apub::objects::community::ApubCommunity; use lemmy_db_schema::{ source::community::{ Community, @@ -21,7 +24,7 @@ use lemmy_db_schema::{ CommunityModerator, CommunityModeratorForm, }, - traits::{Crud, Followable, Joinable}, + traits::{ApubActor, Crud, Followable, Joinable}, utils::diesel_option_overwrite_to_url_create, }; use lemmy_db_views::structs::SiteView; @@ -73,9 +76,8 @@ impl PerformCrud for CreateCommunity { &data.name, &context.settings().get_protocol_and_hostname(), )?; - let community_actor_id_wrapped = ObjectId::::new(community_actor_id.clone()); - let community_dupe = community_actor_id_wrapped.dereference_local(context).await; - if community_dupe.is_ok() { + let community_dupe = Community::read_from_apub_id(context.pool(), &community_actor_id).await?; + if community_dupe.is_some() { return Err(LemmyError::from_message("community_already_exists")); } diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index 7d3122ab4..84de55477 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -2,11 +2,10 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, DeleteCommunity}, + context::LemmyContext, utils::get_local_user_view_from_jwt, websocket::{send::send_community_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::community::{Community, CommunityUpdateForm}, traits::Crud, @@ -41,7 +40,7 @@ impl PerformCrud for DeleteCommunity { // Do the delete let community_id = data.community_id; let deleted = data.deleted; - let updated_community = Community::update( + Community::update( context.pool(), community_id, &CommunityUpdateForm::builder() @@ -60,18 +59,6 @@ impl PerformCrud for DeleteCommunity { ) .await?; - // Send apub messages - let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into())); - send_apub_delete_in_community( - local_user_view.person, - updated_community, - deletable, - None, - deleted, - context, - ) - .await?; - Ok(res) } } diff --git a/crates/api_crud/src/community/list.rs b/crates/api_crud/src/community/list.rs index f77ebce75..4d2e7046f 100644 --- a/crates/api_crud/src/community/list.rs +++ b/crates/api_crud/src/community/list.rs @@ -2,8 +2,8 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{ListCommunities, ListCommunitiesResponse}, + context::LemmyContext, utils::{check_private_instance, get_local_user_view_from_jwt_opt}, - LemmyContext, }; use lemmy_db_schema::{source::local_site::LocalSite, traits::DeleteableOrRemoveable}; use lemmy_db_views_actor::community_view::CommunityQuery; diff --git a/crates/api_crud/src/community/mod.rs b/crates/api_crud/src/community/mod.rs index 1e8328034..3fc741652 100644 --- a/crates/api_crud/src/community/mod.rs +++ b/crates/api_crud/src/community/mod.rs @@ -1,6 +1,5 @@ mod create; mod delete; mod list; -mod read; mod remove; mod update; diff --git a/crates/api_crud/src/community/remove.rs b/crates/api_crud/src/community/remove.rs index 77c2bde30..215b39cf4 100644 --- a/crates/api_crud/src/community/remove.rs +++ b/crates/api_crud/src/community/remove.rs @@ -2,11 +2,10 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, RemoveCommunity}, + context::LemmyContext, utils::{get_local_user_view_from_jwt, is_admin}, websocket::{send::send_community_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::{ community::{Community, CommunityUpdateForm}, @@ -36,7 +35,7 @@ impl PerformCrud for RemoveCommunity { // Do the remove let community_id = data.community_id; let removed = data.removed; - let updated_community = Community::update( + Community::update( context.pool(), community_id, &CommunityUpdateForm::builder() @@ -66,17 +65,6 @@ impl PerformCrud for RemoveCommunity { ) .await?; - // Apub messages - let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into())); - send_apub_delete_in_community( - local_user_view.person, - updated_community, - deletable, - data.reason.clone().or_else(|| Some(String::new())), - removed, - context, - ) - .await?; Ok(res) } } diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 2bde94ea6..9059a4a6f 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -2,11 +2,10 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ community::{CommunityResponse, EditCommunity}, + context::LemmyContext, utils::{get_local_user_view_from_jwt, local_site_to_slur_regex}, websocket::{send::send_community_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ newtypes::PersonId, source::{ @@ -74,17 +73,10 @@ impl PerformCrud for EditCommunity { .build(); let community_id = data.community_id; - let updated_community = Community::update(context.pool(), community_id, &community_form) + Community::update(context.pool(), community_id, &community_form) .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?; - UpdateCommunity::send( - updated_community.into(), - &local_user_view.person.into(), - context, - ) - .await?; - let op = UserOperationCrud::EditCommunity; send_community_ws_message(data.community_id, op, websocket_id, None, context).await } diff --git a/crates/api_crud/src/lib.rs b/crates/api_crud/src/lib.rs index fde81eddb..d37dfbee2 100644 --- a/crates/api_crud/src/lib.rs +++ b/crates/api_crud/src/lib.rs @@ -1,28 +1,6 @@ -use actix_web::{web, web::Data}; -use lemmy_api_common::{ - comment::{CreateComment, DeleteComment, EditComment, GetComment, GetComments, RemoveComment}, - community::{ - CreateCommunity, - DeleteCommunity, - EditCommunity, - GetCommunity, - ListCommunities, - RemoveCommunity, - }, - person::{DeleteAccount, GetPersonDetails, Register}, - post::{CreatePost, DeletePost, EditPost, GetPost, GetPosts, RemovePost}, - private_message::{ - CreatePrivateMessage, - DeletePrivateMessage, - EditPrivateMessage, - GetPrivateMessages, - }, - site::{CreateSite, EditSite, GetSite}, - websocket::{serialize_websocket_message, UserOperationCrud}, - LemmyContext, -}; +use actix_web::web::Data; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::{error::LemmyError, ConnectionId}; -use serde::Deserialize; mod comment; mod community; @@ -41,115 +19,3 @@ 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::GetComment => { - 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 46d4a7f64..af62135e2 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -1,24 +1,20 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ - generate_local_apub_endpoint, + context::LemmyContext, post::{CreatePost, PostResponse}, request::fetch_site_data, utils::{ check_community_ban, check_community_deleted_or_removed, + generate_local_apub_endpoint, get_local_user_view_from_jwt, honeypot_check, local_site_to_slur_regex, mark_post_as_read, + EndpointType, }, websocket::{send::send_post_ws_message, UserOperationCrud}, - EndpointType, - LemmyContext, -}; -use lemmy_apub::{ - objects::post::ApubPost, - protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType}, }; use lemmy_db_schema::{ impls::actor_language::default_post_language, @@ -174,15 +170,6 @@ impl PerformCrud for CreatePost { } } - let apub_post: ApubPost = updated_post.into(); - CreateOrUpdatePage::send( - apub_post.clone(), - &local_user_view.person.clone().into(), - CreateOrUpdateType::Create, - context, - ) - .await?; - send_post_ws_message( inserted_post.id, UserOperationCrud::CreatePost, diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs index de1490b1c..57e5adb15 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -1,17 +1,13 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{DeletePost, PostResponse}, utils::{check_community_ban, check_community_deleted_or_removed, get_local_user_view_from_jwt}, websocket::{send::send_post_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ - source::{ - community::Community, - post::{Post, PostUpdateForm}, - }, + source::post::{Post, PostUpdateForm}, traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; @@ -54,7 +50,7 @@ impl PerformCrud for DeletePost { // Update the post let post_id = data.post_id; let deleted = data.deleted; - let updated_post = Post::update( + Post::update( context.pool(), post_id, &PostUpdateForm::builder().deleted(Some(deleted)).build(), @@ -70,18 +66,6 @@ impl PerformCrud for DeletePost { ) .await?; - // apub updates - let community = Community::read(context.pool(), orig_post.community_id).await?; - let deletable = DeletableObjects::Post(Box::new(updated_post.into())); - send_apub_delete_in_community( - local_user_view.person, - community, - deletable, - None, - deleted, - context, - ) - .await?; Ok(res) } } diff --git a/crates/api_crud/src/post/mod.rs b/crates/api_crud/src/post/mod.rs index 1e8328034..d3d789a02 100644 --- a/crates/api_crud/src/post/mod.rs +++ b/crates/api_crud/src/post/mod.rs @@ -1,6 +1,5 @@ mod create; mod delete; -mod list; mod read; mod remove; mod update; diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 44d1be63a..c6747c5e8 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -1,10 +1,10 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{GetPost, GetPostResponse}, utils::{check_private_instance, get_local_user_view_from_jwt_opt, mark_post_as_read}, websocket::messages::GetPostUsersOnline, - LemmyContext, }; use lemmy_db_schema::{ aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm}, diff --git a/crates/api_crud/src/post/remove.rs b/crates/api_crud/src/post/remove.rs index 525c08a68..66af2ca95 100644 --- a/crates/api_crud/src/post/remove.rs +++ b/crates/api_crud/src/post/remove.rs @@ -1,15 +1,13 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{PostResponse, RemovePost}, utils::{check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin}, websocket::{send::send_post_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::{ - community::Community, moderator::{ModRemovePost, ModRemovePostForm}, post::{Post, PostUpdateForm}, }, @@ -52,7 +50,7 @@ impl PerformCrud for RemovePost { // Update the post let post_id = data.post_id; let removed = data.removed; - let updated_post = Post::update( + Post::update( context.pool(), post_id, &PostUpdateForm::builder().removed(Some(removed)).build(), @@ -77,18 +75,6 @@ impl PerformCrud for RemovePost { ) .await?; - // apub updates - let community = Community::read(context.pool(), orig_post.community_id).await?; - let deletable = DeletableObjects::Post(Box::new(updated_post.into())); - send_apub_delete_in_community( - local_user_view.person, - community, - deletable, - data.reason.clone().or_else(|| Some(String::new())), - removed, - context, - ) - .await?; Ok(res) } } diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index 4c3038c87..9337c5952 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -1,6 +1,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{EditPost, PostResponse}, request::fetch_site_data, utils::{ @@ -10,11 +11,6 @@ use lemmy_api_common::{ local_site_to_slur_regex, }, websocket::{send::send_post_ws_message, UserOperationCrud}, - LemmyContext, -}; -use lemmy_apub::protocol::activities::{ - create_or_update::page::CreateOrUpdatePage, - CreateOrUpdateType, }; use lemmy_db_schema::{ source::{ @@ -109,27 +105,15 @@ impl PerformCrud for EditPost { let post_id = data.post_id; let res = Post::update(context.pool(), post_id, &post_form).await; - let updated_post: Post = match res { - Ok(post) => post, - Err(e) => { - let err_type = if e.to_string() == "value too long for type character varying(200)" { - "post_title_too_long" - } else { - "couldnt_update_post" - }; - - return Err(LemmyError::from_error_message(e, err_type)); - } - }; - - // Send apub update - CreateOrUpdatePage::send( - updated_post.into(), - &local_user_view.person.clone().into(), - CreateOrUpdateType::Update, - context, - ) - .await?; + if let Err(e) = res { + let err_type = if e.to_string() == "value too long for type character varying(200)" { + "post_title_too_long" + } else { + "couldnt_update_post" + }; + + return Err(LemmyError::from_error_message(e, err_type)); + } send_post_ws_message( data.post_id, diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index 03d994c08..25c7be467 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -1,22 +1,18 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ - generate_local_apub_endpoint, + context::LemmyContext, private_message::{CreatePrivateMessage, PrivateMessageResponse}, utils::{ check_person_block, + generate_local_apub_endpoint, get_interface_language, get_local_user_view_from_jwt, local_site_to_slur_regex, send_email_to_user, + EndpointType, }, websocket::{send::send_pm_ws_message, UserOperationCrud}, - EndpointType, - LemmyContext, -}; -use lemmy_apub::protocol::activities::{ - create_or_update::chat_message::CreateOrUpdateChatMessage, - CreateOrUpdateType, }; use lemmy_db_schema::{ source::{ @@ -74,7 +70,7 @@ impl PerformCrud for CreatePrivateMessage { &inserted_private_message_id.to_string(), &protocol_and_hostname, )?; - let updated_private_message = PrivateMessage::update( + PrivateMessage::update( context.pool(), inserted_private_message.id, &PrivateMessageUpdateForm::builder() @@ -84,14 +80,6 @@ impl PerformCrud for CreatePrivateMessage { .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_private_message"))?; - CreateOrUpdateChatMessage::send( - updated_private_message.into(), - &local_user_view.person.into(), - CreateOrUpdateType::Create, - context, - ) - .await?; - let res = send_pm_ws_message( inserted_private_message.id, UserOperationCrud::CreatePrivateMessage, diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index ad6b78d3e..4f58065a3 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -1,12 +1,11 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, private_message::{DeletePrivateMessage, PrivateMessageResponse}, utils::get_local_user_view_from_jwt, websocket::{send::send_pm_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_apub::activities::deletion::send_apub_delete_private_message; use lemmy_db_schema::{ source::private_message::{PrivateMessage, PrivateMessageUpdateForm}, traits::Crud, @@ -37,7 +36,7 @@ impl PerformCrud for DeletePrivateMessage { // Doing the update let private_message_id = data.private_message_id; let deleted = data.deleted; - let updated_private_message = PrivateMessage::update( + PrivateMessage::update( context.pool(), private_message_id, &PrivateMessageUpdateForm::builder() @@ -47,15 +46,6 @@ impl PerformCrud for DeletePrivateMessage { .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?; - // Send the apub update - send_apub_delete_private_message( - &local_user_view.person.into(), - updated_private_message, - data.deleted, - context, - ) - .await?; - let op = UserOperationCrud::DeletePrivateMessage; send_pm_ws_message(data.private_message_id, op, websocket_id, context).await } diff --git a/crates/api_crud/src/private_message/read.rs b/crates/api_crud/src/private_message/read.rs index 88bb08300..286802745 100644 --- a/crates/api_crud/src/private_message/read.rs +++ b/crates/api_crud/src/private_message/read.rs @@ -1,9 +1,9 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, private_message::{GetPrivateMessages, PrivateMessagesResponse}, utils::get_local_user_view_from_jwt, - LemmyContext, }; use lemmy_db_schema::traits::DeleteableOrRemoveable; use lemmy_db_views::private_message_view::PrivateMessageQuery; diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index b6e08c9c6..f6f8c8f03 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -1,14 +1,10 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, private_message::{EditPrivateMessage, PrivateMessageResponse}, utils::{get_local_user_view_from_jwt, local_site_to_slur_regex}, websocket::{send::send_pm_ws_message, UserOperationCrud}, - LemmyContext, -}; -use lemmy_apub::protocol::activities::{ - create_or_update::chat_message::CreateOrUpdateChatMessage, - CreateOrUpdateType, }; use lemmy_db_schema::{ source::{ @@ -45,7 +41,7 @@ impl PerformCrud for EditPrivateMessage { // Doing the update let content_slurs_removed = remove_slurs(&data.content, &local_site_to_slur_regex(&local_site)); let private_message_id = data.private_message_id; - let updated_private_message = PrivateMessage::update( + PrivateMessage::update( context.pool(), private_message_id, &PrivateMessageUpdateForm::builder() @@ -56,15 +52,6 @@ impl PerformCrud for EditPrivateMessage { .await .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?; - // Send the apub update - CreateOrUpdateChatMessage::send( - updated_private_message.into(), - &local_user_view.person.into(), - CreateOrUpdateType::Update, - context, - ) - .await?; - let op = UserOperationCrud::EditPrivateMessage; send_pm_ws_message(data.private_message_id, op, websocket_id, context).await } diff --git a/crates/api_crud/src/site/create.rs b/crates/api_crud/src/site/create.rs index 34ac404a9..d04343b0c 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -2,16 +2,16 @@ use crate::PerformCrud; use activitypub_federation::core::signatures::generate_actor_keypair; use actix_web::web::Data; use lemmy_api_common::{ - generate_site_inbox_url, + context::LemmyContext, site::{CreateSite, SiteResponse}, utils::{ + generate_site_inbox_url, get_local_user_view_from_jwt, is_admin, local_site_rate_limit_to_rate_limit_config, local_site_to_slur_regex, site_description_length_check, }, - LemmyContext, }; use lemmy_db_schema::{ newtypes::DbUrl, diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index 8f27bb2ee..55dcd8fb2 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -1,10 +1,10 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{GetSite, GetSiteResponse, MyUserInfo}, utils::{build_federated_instances, get_local_user_settings_view_from_jwt_opt}, websocket::messages::GetUsersOnline, - LemmyContext, }; use lemmy_db_schema::source::{actor_language::SiteLanguage, language::Language, tagline::Tagline}; use lemmy_db_views::structs::{LocalUserDiscussionLanguageView, SiteView}; diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index e738a2513..4a96925ed 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -1,6 +1,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{EditSite, SiteResponse}, utils::{ get_local_user_view_from_jwt, @@ -10,7 +11,6 @@ use lemmy_api_common::{ site_description_length_check, }, websocket::{messages::SendAllMessage, UserOperationCrud}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index 0521ffe0c..34b3b69e4 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -2,20 +2,20 @@ use crate::PerformCrud; use activitypub_federation::core::signatures::generate_actor_keypair; use actix_web::web::Data; use lemmy_api_common::{ - generate_inbox_url, - generate_local_apub_endpoint, - generate_shared_inbox_url, + context::LemmyContext, person::{LoginResponse, Register}, utils::{ + generate_inbox_url, + generate_local_apub_endpoint, + generate_shared_inbox_url, honeypot_check, local_site_to_slur_regex, password_length_check, send_new_applicant_email_to_admins, send_verification_email, + EndpointType, }, websocket::messages::CheckCaptcha, - EndpointType, - LemmyContext, }; use lemmy_db_schema::{ aggregates::structs::PersonAggregates, diff --git a/crates/api_crud/src/user/delete.rs b/crates/api_crud/src/user/delete.rs index 87ad78e44..b49695eac 100644 --- a/crates/api_crud/src/user/delete.rs +++ b/crates/api_crud/src/user/delete.rs @@ -2,11 +2,10 @@ use crate::PerformCrud; use actix_web::web::Data; use bcrypt::verify; use lemmy_api_common::{ + context::LemmyContext, person::{DeleteAccount, DeleteAccountResponse}, - utils::{delete_user_account, get_local_user_view_from_jwt}, - LemmyContext, + utils::get_local_user_view_from_jwt, }; -use lemmy_apub::protocol::activities::deletion::delete_user::DeleteUser; use lemmy_utils::{error::LemmyError, ConnectionId}; #[async_trait::async_trait(?Send)] @@ -33,15 +32,6 @@ impl PerformCrud for DeleteAccount { return Err(LemmyError::from_message("password_incorrect")); } - delete_user_account( - local_user_view.person.id, - context.pool(), - context.settings(), - context.client(), - ) - .await?; - DeleteUser::send(&local_user_view.person.into(), context).await?; - Ok(DeleteAccountResponse {}) } } diff --git a/crates/api_crud/src/user/mod.rs b/crates/api_crud/src/user/mod.rs index 843072411..aeaae9ddd 100644 --- a/crates/api_crud/src/user/mod.rs +++ b/crates/api_crud/src/user/mod.rs @@ -1,3 +1,2 @@ mod create; mod delete; -mod read; diff --git a/crates/apub/src/activities/block/block_user.rs b/crates/apub/src/activities/block/block_user.rs index c77bfde35..b5f03eaf1 100644 --- a/crates/apub/src/activities/block/block_user.rs +++ b/crates/apub/src/activities/block/block_user.rs @@ -24,8 +24,8 @@ use activitystreams_kinds::{activity::BlockType, public}; use anyhow::anyhow; use chrono::NaiveDateTime; use lemmy_api_common::{ + context::LemmyContext, utils::{remove_user_data, remove_user_data_in_community}, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 5a8c48f13..8adc25012 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -1,13 +1,27 @@ use crate::{ - objects::{community::ApubCommunity, instance::ApubSite}, - protocol::objects::{group::Group, instance::Instance}, + objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, + protocol::{ + activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser}, + objects::{group::Group, instance::Instance}, + }, ActorType, + SendActivity, }; use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject}; use chrono::NaiveDateTime; -use lemmy_api_common::LemmyContext; -use lemmy_db_schema::{source::site::Site, utils::DbPool}; -use lemmy_utils::error::LemmyError; +use lemmy_api_common::{ + community::{BanFromCommunity, BanFromCommunityResponse}, + context::LemmyContext, + person::{BanPerson, BanPersonResponse}, + utils::get_local_user_view_from_jwt, +}; +use lemmy_db_schema::{ + source::{community::Community, person::Person, site::Site}, + traits::Crud, + utils::DbPool, +}; +use lemmy_db_views::structs::SiteView; +use lemmy_utils::{error::LemmyError, utils::naive_from_unix}; use serde::Deserialize; use url::Url; @@ -123,3 +137,90 @@ async fn generate_cc(target: &SiteOrCommunity, pool: &DbPool) -> Result SiteOrCommunity::Community(c) => vec![c.actor_id()], }) } + +#[async_trait::async_trait(?Send)] +impl SendActivity for BanPerson { + type Response = BanPersonResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let person = Person::read(context.pool(), request.person_id).await?; + let site = SiteOrCommunity::Site(SiteView::read_local(context.pool()).await?.site.into()); + let expires = request.expires.map(naive_from_unix); + + // if the action affects a local user, federate to other instances + if person.local { + if request.ban { + BlockUser::send( + &site, + &person.into(), + &local_user_view.person.into(), + request.remove_data.unwrap_or(false), + request.reason.clone(), + expires, + context, + ) + .await + } else { + UndoBlockUser::send( + &site, + &person.into(), + &local_user_view.person.into(), + request.reason.clone(), + context, + ) + .await + } + } else { + Ok(()) + } + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for BanFromCommunity { + type Response = BanFromCommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community: ApubCommunity = Community::read(context.pool(), request.community_id) + .await? + .into(); + let banned_person: ApubPerson = Person::read(context.pool(), request.person_id) + .await? + .into(); + let expires = request.expires.map(naive_from_unix); + + if request.ban { + BlockUser::send( + &SiteOrCommunity::Community(community), + &banned_person, + &local_user_view.person.clone().into(), + request.remove_data.unwrap_or(false), + request.reason.clone(), + expires, + context, + ) + .await + } else { + UndoBlockUser::send( + &SiteOrCommunity::Community(community), + &banned_person, + &local_user_view.person.clone().into(), + request.reason.clone(), + context, + ) + .await + } + } +} diff --git a/crates/apub/src/activities/block/undo_block_user.rs b/crates/apub/src/activities/block/undo_block_user.rs index 56f794dc1..315667ac6 100644 --- a/crates/apub/src/activities/block/undo_block_user.rs +++ b/crates/apub/src/activities/block/undo_block_user.rs @@ -19,7 +19,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use activitystreams_kinds::{activity::UndoType, public}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ community::{CommunityPersonBan, CommunityPersonBanForm}, diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index 3718ea680..1bc31b48c 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -10,8 +10,12 @@ use crate::{ activity_lists::AnnouncableActivities, local_instance, objects::{community::ApubCommunity, person::ApubPerson}, - protocol::{activities::community::add_mod::AddMod, InCommunity}, + protocol::{ + activities::community::{add_mod::AddMod, remove_mod::RemoveMod}, + InCommunity, + }, ActorType, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -19,11 +23,16 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::{activity::AddType, public}; -use lemmy_api_common::{generate_moderators_url, LemmyContext}; +use lemmy_api_common::{ + community::{AddModToCommunity, AddModToCommunityResponse}, + context::LemmyContext, + utils::{generate_moderators_url, get_local_user_view_from_jwt}, +}; use lemmy_db_schema::{ source::{ - community::{CommunityModerator, CommunityModeratorForm}, + community::{Community, CommunityModerator, CommunityModeratorForm}, moderator::{ModAddCommunity, ModAddCommunityForm}, + person::Person, }, traits::{Crud, Joinable}, }; @@ -134,3 +143,40 @@ impl ActivityHandler for AddMod { Ok(()) } } + +#[async_trait::async_trait(?Send)] +impl SendActivity for AddModToCommunity { + type Response = AddModToCommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community: ApubCommunity = Community::read(context.pool(), request.community_id) + .await? + .into(); + let updated_mod: ApubPerson = Person::read(context.pool(), request.person_id) + .await? + .into(); + if request.added { + AddMod::send( + &community, + &updated_mod, + &local_user_view.person.into(), + context, + ) + .await + } else { + RemoveMod::send( + &community, + &updated_mod, + &local_user_view.person.into(), + context, + ) + .await + } + } +} diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs index 1ca1aa848..306913aa6 100644 --- a/crates/apub/src/activities/community/announce.rs +++ b/crates/apub/src/activities/community/announce.rs @@ -18,7 +18,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use activitystreams_kinds::{activity::AnnounceType, public}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde_json::Value; use tracing::debug; diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 3d0bb4c3d..4d35c9d56 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -6,7 +6,7 @@ use crate::{ protocol::activities::community::announce::AnnounceActivity, }; use activitypub_federation::{core::object_id::ObjectId, traits::Actor}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::source::person::PersonFollower; use lemmy_utils::error::LemmyError; use url::Url; diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index 855fe7b4e..9bd8c4ec2 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -19,7 +19,7 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::{activity::RemoveType, public}; -use lemmy_api_common::{generate_moderators_url, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::generate_moderators_url}; use lemmy_db_schema::{ source::{ community::{CommunityModerator, CommunityModeratorForm}, diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 2741af7e8..57b1244d1 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -5,6 +5,7 @@ use crate::{ protocol::{activities::community::report::Report, InCommunity}, ActorType, PostOrComment, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -13,10 +14,11 @@ use activitypub_federation::{ }; use activitystreams_kinds::activity::FlagType; use lemmy_api_common::{ - comment::CommentReportResponse, - post::PostReportResponse, + comment::{CommentReportResponse, CreateCommentReport}, + context::LemmyContext, + post::{CreatePostReport, PostReportResponse}, + utils::get_local_user_view_from_jwt, websocket::{messages::SendModRoomMessage, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{ source::{ @@ -29,9 +31,53 @@ use lemmy_db_views::structs::{CommentReportView, PostReportView}; use lemmy_utils::error::LemmyError; use url::Url; +#[async_trait::async_trait(?Send)] +impl SendActivity for CreatePostReport { + type Response = PostReportResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + Report::send( + ObjectId::new(response.post_report_view.post.ap_id.clone()), + &local_user_view.person.into(), + ObjectId::new(response.post_report_view.community.actor_id.clone()), + request.reason.to_string(), + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for CreateCommentReport { + type Response = CommentReportResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + Report::send( + ObjectId::new(response.comment_report_view.comment.ap_id.clone()), + &local_user_view.person.into(), + ObjectId::new(response.comment_report_view.community.actor_id.clone()), + request.reason.to_string(), + context, + ) + .await + } +} + impl Report { #[tracing::instrument(skip_all)] - pub async fn send( + async fn send( object_id: ObjectId, actor: &ApubPerson, community_id: ObjectId, diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index c0d1a2799..969741ef6 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -10,6 +10,7 @@ use crate::{ objects::{community::ApubCommunity, person::ApubPerson}, protocol::{activities::community::update::UpdateCommunity, InCommunity}, ActorType, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -18,13 +19,31 @@ use activitypub_federation::{ }; use activitystreams_kinds::{activity::UpdateType, public}; use lemmy_api_common::{ + community::{CommunityResponse, EditCommunity, HideCommunity}, + context::LemmyContext, + utils::get_local_user_view_from_jwt, websocket::{send::send_community_ws_message, UserOperationCrud}, - LemmyContext, }; use lemmy_db_schema::{source::community::Community, traits::Crud}; use lemmy_utils::error::LemmyError; use url::Url; +#[async_trait::async_trait(?Send)] +impl SendActivity for EditCommunity { + type Response = CommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community = Community::read(context.pool(), request.community_id).await?; + UpdateCommunity::send(community.into(), &local_user_view.person.into(), context).await + } +} + impl UpdateCommunity { #[tracing::instrument(skip_all)] pub async fn send( @@ -115,3 +134,19 @@ impl ActivityHandler for UpdateCommunity { Ok(()) } } + +#[async_trait::async_trait(?Send)] +impl SendActivity for HideCommunity { + type Response = CommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community = Community::read(context.pool(), request.community_id).await?; + UpdateCommunity::send(community.into(), &local_user_view.person.into(), context).await + } +} diff --git a/crates/apub/src/activities/create_or_update/comment.rs b/crates/apub/src/activities/create_or_update/comment.rs index 5def04604..54df09ce6 100644 --- a/crates/apub/src/activities/create_or_update/comment.rs +++ b/crates/apub/src/activities/create_or_update/comment.rs @@ -16,6 +16,7 @@ use crate::{ InCommunity, }, ActorType, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -25,14 +26,17 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use lemmy_api_common::{ + comment::{CommentResponse, CreateComment, EditComment}, + context::LemmyContext, utils::check_post_deleted_or_removed, websocket::{send::send_comment_ws_message, UserOperationCrud}, - LemmyContext, }; use lemmy_db_schema::{ + newtypes::PersonId, source::{ - comment::{CommentLike, CommentLikeForm}, + comment::{Comment, CommentLike, CommentLikeForm}, community::Community, + person::Person, post::Post, }, traits::{Crud, Likeable}, @@ -40,29 +44,67 @@ use lemmy_db_schema::{ use lemmy_utils::error::LemmyError; use url::Url; +#[async_trait::async_trait(?Send)] +impl SendActivity for CreateComment { + type Response = CommentResponse; + + async fn send_activity( + _request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + CreateOrUpdateNote::send( + &response.comment_view.comment, + response.comment_view.creator.id, + CreateOrUpdateType::Create, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for EditComment { + type Response = CommentResponse; + + async fn send_activity( + _request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + CreateOrUpdateNote::send( + &response.comment_view.comment, + response.comment_view.creator.id, + CreateOrUpdateType::Update, + context, + ) + .await + } +} + impl CreateOrUpdateNote { - #[tracing::instrument(skip(comment, actor, kind, context))] - pub async fn send( - comment: ApubComment, - actor: &ApubPerson, + #[tracing::instrument(skip(comment, person_id, kind, context))] + async fn send( + comment: &Comment, + person_id: PersonId, kind: CreateOrUpdateType, context: &LemmyContext, - request_counter: &mut i32, ) -> Result<(), LemmyError> { // TODO: might be helpful to add a comment method to retrieve community directly let post_id = comment.post_id; let post = Post::read(context.pool(), post_id).await?; let community_id = post.community_id; + let person: ApubPerson = Person::read(context.pool(), person_id).await?.into(); let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); let id = generate_activity_id( kind.clone(), &context.settings().get_protocol_and_hostname(), )?; - let note = comment.into_apub(context).await?; + let note = ApubComment(comment.clone()).into_apub(context).await?; let create_or_update = CreateOrUpdateNote { - actor: ObjectId::new(actor.actor_id()), + actor: ObjectId::new(person.actor_id()), to: vec![public()], cc: note.cc.clone(), tag: note.tag.clone(), @@ -88,13 +130,13 @@ impl CreateOrUpdateNote { let mut inboxes = vec![]; for t in tagged_users { let person = t - .dereference(context, local_instance(context).await, request_counter) + .dereference(context, local_instance(context).await, &mut 0) .await?; inboxes.push(person.shared_inbox_or_inbox()); } let activity = AnnouncableActivities::CreateOrUpdateComment(create_or_update); - send_activity_in_community(activity, actor, &community, inboxes, false, context).await + send_activity_in_community(activity, &person, &community, inboxes, false, context).await } } diff --git a/crates/apub/src/activities/create_or_update/mod.rs b/crates/apub/src/activities/create_or_update/mod.rs index b53dd2eb8..60ce6ea34 100644 --- a/crates/apub/src/activities/create_or_update/mod.rs +++ b/crates/apub/src/activities/create_or_update/mod.rs @@ -1,6 +1,6 @@ use crate::{local_instance, objects::person::ApubPerson}; use activitypub_federation::core::object_id::ObjectId; -use lemmy_api_common::{websocket::send::send_local_notifs, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, websocket::send::send_local_notifs}; use lemmy_db_schema::{ newtypes::LocalUserId, source::{comment::Comment, post::Post}, diff --git a/crates/apub/src/activities/create_or_update/post.rs b/crates/apub/src/activities/create_or_update/post.rs index 161b26b9d..92cc70877 100644 --- a/crates/apub/src/activities/create_or_update/post.rs +++ b/crates/apub/src/activities/create_or_update/post.rs @@ -14,6 +14,7 @@ use crate::{ InCommunity, }, ActorType, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -23,19 +24,103 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use lemmy_api_common::{ + context::LemmyContext, + post::{CreatePost, EditPost, LockPost, PostResponse, StickyPost}, + utils::get_local_user_view_from_jwt, websocket::{send::send_post_ws_message, UserOperationCrud}, - LemmyContext, }; use lemmy_db_schema::{ + newtypes::PersonId, source::{ community::Community, - post::{PostLike, PostLikeForm}, + person::Person, + post::{Post, PostLike, PostLikeForm}, }, traits::{Crud, Likeable}, }; use lemmy_utils::error::LemmyError; use url::Url; +#[async_trait::async_trait(?Send)] +impl SendActivity for CreatePost { + type Response = PostResponse; + + async fn send_activity( + _request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + CreateOrUpdatePage::send( + &response.post_view.post, + response.post_view.creator.id, + CreateOrUpdateType::Create, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for EditPost { + type Response = PostResponse; + + async fn send_activity( + _request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + CreateOrUpdatePage::send( + &response.post_view.post, + response.post_view.creator.id, + CreateOrUpdateType::Update, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for LockPost { + type Response = PostResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + CreateOrUpdatePage::send( + &response.post_view.post, + local_user_view.person.id, + CreateOrUpdateType::Update, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for StickyPost { + type Response = PostResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + CreateOrUpdatePage::send( + &response.post_view.post, + local_user_view.person.id, + CreateOrUpdateType::Update, + context, + ) + .await + } +} + impl CreateOrUpdatePage { pub(crate) async fn new( post: ApubPost, @@ -60,19 +145,30 @@ impl CreateOrUpdatePage { } #[tracing::instrument(skip_all)] - pub async fn send( - post: ApubPost, - actor: &ApubPerson, + async fn send( + post: &Post, + person_id: PersonId, kind: CreateOrUpdateType, context: &LemmyContext, ) -> Result<(), LemmyError> { + let post = ApubPost(post.clone()); let community_id = post.community_id; + let person: ApubPerson = Person::read(context.pool(), person_id).await?.into(); let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); - let create_or_update = CreateOrUpdatePage::new(post, actor, &community, kind, context).await?; + let create_or_update = + CreateOrUpdatePage::new(post, &person, &community, kind, context).await?; let is_mod_action = create_or_update.object.is_mod_action(context).await?; let activity = AnnouncableActivities::CreateOrUpdatePost(create_or_update); - send_activity_in_community(activity, actor, &community, vec![], is_mod_action, context).await?; + send_activity_in_community( + activity, + &person, + &community, + vec![], + is_mod_action, + context, + ) + .await?; Ok(()) } } diff --git a/crates/apub/src/activities/create_or_update/private_message.rs b/crates/apub/src/activities/create_or_update/private_message.rs index 431e699ce..071209c34 100644 --- a/crates/apub/src/activities/create_or_update/private_message.rs +++ b/crates/apub/src/activities/create_or_update/private_message.rs @@ -6,6 +6,7 @@ use crate::{ CreateOrUpdateType, }, ActorType, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -14,22 +15,65 @@ use activitypub_federation::{ utils::verify_domains_match, }; use lemmy_api_common::{ + context::LemmyContext, + private_message::{CreatePrivateMessage, EditPrivateMessage, PrivateMessageResponse}, websocket::{send::send_pm_ws_message, UserOperationCrud}, - LemmyContext, }; -use lemmy_db_schema::{source::person::Person, traits::Crud}; +use lemmy_db_schema::{ + newtypes::PersonId, + source::{person::Person, private_message::PrivateMessage}, + traits::Crud, +}; use lemmy_utils::error::LemmyError; use url::Url; +#[async_trait::async_trait(?Send)] +impl SendActivity for CreatePrivateMessage { + type Response = PrivateMessageResponse; + + async fn send_activity( + _request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + CreateOrUpdateChatMessage::send( + &response.private_message_view.private_message, + response.private_message_view.creator.id, + CreateOrUpdateType::Create, + context, + ) + .await + } +} +#[async_trait::async_trait(?Send)] +impl SendActivity for EditPrivateMessage { + type Response = PrivateMessageResponse; + + async fn send_activity( + _request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + CreateOrUpdateChatMessage::send( + &response.private_message_view.private_message, + response.private_message_view.creator.id, + CreateOrUpdateType::Update, + context, + ) + .await + } +} + impl CreateOrUpdateChatMessage { #[tracing::instrument(skip_all)] - pub async fn send( - private_message: ApubPrivateMessage, - actor: &ApubPerson, + async fn send( + private_message: &PrivateMessage, + sender_id: PersonId, kind: CreateOrUpdateType, context: &LemmyContext, ) -> Result<(), LemmyError> { let recipient_id = private_message.recipient_id; + let sender: ApubPerson = Person::read(context.pool(), sender_id).await?.into(); let recipient: ApubPerson = Person::read(context.pool(), recipient_id).await?.into(); let id = generate_activity_id( @@ -38,13 +82,15 @@ impl CreateOrUpdateChatMessage { )?; let create_or_update = CreateOrUpdateChatMessage { id: id.clone(), - actor: ObjectId::new(actor.actor_id()), + actor: ObjectId::new(sender.actor_id()), to: [ObjectId::new(recipient.actor_id())], - object: private_message.into_apub(context).await?, + object: ApubPrivateMessage(private_message.clone()) + .into_apub(context) + .await?, kind, }; let inbox = vec![recipient.shared_inbox_or_inbox()]; - send_lemmy_activity(context, create_or_update, actor, inbox, true).await + send_lemmy_activity(context, create_or_update, &sender, inbox, true).await } } diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index ae93d6e09..138a1fae1 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -10,11 +10,11 @@ use crate::{ use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use activitystreams_kinds::activity::DeleteType; use lemmy_api_common::{ + context::LemmyContext, websocket::{ send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, UserOperationCrud, }, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/apub/src/activities/deletion/delete_user.rs b/crates/apub/src/activities/deletion/delete_user.rs index ffe664d59..4ace431e6 100644 --- a/crates/apub/src/activities/deletion/delete_user.rs +++ b/crates/apub/src/activities/deletion/delete_user.rs @@ -3,6 +3,7 @@ use crate::{ local_instance, objects::{instance::remote_instance_inboxes, person::ApubPerson}, protocol::activities::deletion::delete_user::DeleteUser, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -11,10 +12,54 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::{activity::DeleteType, public}; -use lemmy_api_common::{utils::delete_user_account, LemmyContext}; +use lemmy_api_common::{ + context::LemmyContext, + person::{DeleteAccount, DeleteAccountResponse}, + utils::{delete_user_account, get_local_user_view_from_jwt}, +}; use lemmy_utils::error::LemmyError; use url::Url; +#[async_trait::async_trait(?Send)] +impl SendActivity for DeleteAccount { + type Response = DeleteAccountResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let actor: ApubPerson = local_user_view.person.into(); + delete_user_account( + actor.id, + context.pool(), + context.settings(), + context.client(), + ) + .await?; + + let actor_id = ObjectId::new(actor.actor_id.clone()); + let id = generate_activity_id( + DeleteType::Delete, + &context.settings().get_protocol_and_hostname(), + )?; + let delete = DeleteUser { + actor: actor_id.clone(), + to: vec![public()], + object: actor_id, + kind: DeleteType::Delete, + id: id.clone(), + cc: vec![], + }; + + let inboxes = remote_instance_inboxes(context.pool()).await?; + send_lemmy_activity(context, delete, &actor, inboxes, true).await?; + Ok(()) + } +} + /// This can be separate from Delete activity because it doesn't need to be handled in shared inbox /// (cause instance actor doesn't have shared inbox). #[async_trait::async_trait(?Send)] @@ -60,26 +105,3 @@ impl ActivityHandler for DeleteUser { Ok(()) } } - -impl DeleteUser { - #[tracing::instrument(skip_all)] - pub async fn send(actor: &ApubPerson, context: &LemmyContext) -> Result<(), LemmyError> { - let actor_id = ObjectId::new(actor.actor_id.clone()); - let id = generate_activity_id( - DeleteType::Delete, - &context.settings().get_protocol_and_hostname(), - )?; - let delete = DeleteUser { - actor: actor_id.clone(), - to: vec![public()], - object: actor_id, - kind: DeleteType::Delete, - id: id.clone(), - cc: vec![], - }; - - let inboxes = remote_instance_inboxes(context.pool()).await?; - send_lemmy_activity(context, delete, actor, inboxes, true).await?; - Ok(()) - } -} diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index d05e45021..dae70dc3d 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -21,6 +21,7 @@ use crate::{ InCommunity, }, ActorType, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -29,6 +30,12 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use lemmy_api_common::{ + comment::{CommentResponse, DeleteComment, RemoveComment}, + community::{CommunityResponse, DeleteCommunity, RemoveCommunity}, + context::LemmyContext, + post::{DeletePost, PostResponse, RemovePost}, + private_message::{DeletePrivateMessage, PrivateMessageResponse}, + utils::get_local_user_view_from_jwt, websocket::{ send::{ send_comment_ws_message_simple, @@ -38,7 +45,6 @@ use lemmy_api_common::{ }, UserOperationCrud, }, - LemmyContext, }; use lemmy_db_schema::{ source::{ @@ -58,10 +64,176 @@ pub mod delete; pub mod delete_user; pub mod undo_delete; +#[async_trait::async_trait(?Send)] +impl SendActivity for DeletePost { + type Response = PostResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community = Community::read(context.pool(), response.post_view.community.id).await?; + let deletable = DeletableObjects::Post(Box::new(response.post_view.post.clone().into())); + send_apub_delete_in_community( + local_user_view.person, + community, + deletable, + None, + request.deleted, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for RemovePost { + type Response = PostResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community = Community::read(context.pool(), response.post_view.community.id).await?; + let deletable = DeletableObjects::Post(Box::new(response.post_view.post.clone().into())); + send_apub_delete_in_community( + local_user_view.person, + community, + deletable, + request.reason.clone().or_else(|| Some(String::new())), + request.removed, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for DeleteComment { + type Response = CommentResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let community_id = response.comment_view.community.id; + let community = Community::read(context.pool(), community_id).await?; + let person = Person::read(context.pool(), response.comment_view.creator.id).await?; + let deletable = + DeletableObjects::Comment(Box::new(response.comment_view.comment.clone().into())); + send_apub_delete_in_community(person, community, deletable, None, request.deleted, context) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for RemoveComment { + type Response = CommentResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let comment = Comment::read(context.pool(), request.comment_id).await?; + let community = Community::read(context.pool(), response.comment_view.community.id).await?; + let deletable = DeletableObjects::Comment(Box::new(comment.into())); + send_apub_delete_in_community( + local_user_view.person, + community, + deletable, + request.reason.clone().or_else(|| Some(String::new())), + request.removed, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for DeletePrivateMessage { + type Response = PrivateMessageResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + send_apub_delete_private_message( + &local_user_view.person.into(), + response.private_message_view.private_message.clone(), + request.deleted, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for DeleteCommunity { + type Response = CommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community = Community::read(context.pool(), request.community_id).await?; + let deletable = DeletableObjects::Community(Box::new(community.clone().into())); + send_apub_delete_in_community( + local_user_view.person, + community, + deletable, + None, + request.deleted, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for RemoveCommunity { + type Response = CommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community = Community::read(context.pool(), request.community_id).await?; + let deletable = DeletableObjects::Community(Box::new(community.clone().into())); + send_apub_delete_in_community( + local_user_view.person, + community, + deletable, + request.reason.clone().or_else(|| Some(String::new())), + request.removed, + context, + ) + .await + } +} + /// Parameter `reason` being set indicates that this is a removal by a mod. If its unset, this /// action was done by a normal user. #[tracing::instrument(skip_all)] -pub async fn send_apub_delete_in_community( +async fn send_apub_delete_in_community( actor: Person, community: Community, object: DeletableObjects, @@ -90,7 +262,7 @@ pub async fn send_apub_delete_in_community( } #[tracing::instrument(skip_all)] -pub async fn send_apub_delete_private_message( +async fn send_apub_delete_private_message( actor: &ApubPerson, pm: PrivateMessage, deleted: bool, diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index bc6f9fd14..b3cef3858 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -10,11 +10,11 @@ use crate::{ use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use activitystreams_kinds::activity::UndoType; use lemmy_api_common::{ + context::LemmyContext, websocket::{ send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, UserOperationCrud, }, - LemmyContext, }; use lemmy_db_schema::{ source::{ diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index 880db0d99..6702c8c95 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -13,8 +13,8 @@ use activitypub_federation::{ use activitystreams_kinds::activity::AcceptType; use lemmy_api_common::{ community::CommunityResponse, + context::LemmyContext, websocket::{messages::SendUserRoomMessage, UserOperation}, - LemmyContext, }; use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable}; use lemmy_db_views::structs::LocalUserView; diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 82c0c37a5..62bd24157 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -8,8 +8,13 @@ use crate::{ fetcher::user_or_community::UserOrCommunity, local_instance, objects::{community::ApubCommunity, person::ApubPerson}, - protocol::activities::following::{accept::AcceptFollow, follow::Follow}, + protocol::activities::following::{ + accept::AcceptFollow, + follow::Follow, + undo_follow::UndoFollow, + }, ActorType, + SendActivity, }; use activitypub_federation::{ core::object_id::ObjectId, @@ -17,13 +22,17 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::activity::FollowType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::{ + community::{BlockCommunity, BlockCommunityResponse}, + context::LemmyContext, + utils::get_local_user_view_from_jwt, +}; use lemmy_db_schema::{ source::{ - community::{CommunityFollower, CommunityFollowerForm}, + community::{Community, CommunityFollower, CommunityFollowerForm}, person::{PersonFollower, PersonFollowerForm}, }, - traits::Followable, + traits::{Crud, Followable}, }; use lemmy_utils::error::LemmyError; use url::Url; @@ -132,3 +141,19 @@ impl ActivityHandler for Follow { AcceptFollow::send(self, context, request_counter).await } } + +#[async_trait::async_trait(?Send)] +impl SendActivity for BlockCommunity { + type Response = BlockCommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let community = Community::read(context.pool(), request.community_id).await?; + UndoFollow::send(&local_user_view.person.into(), &community.into(), context).await + } +} diff --git a/crates/apub/src/activities/following/mod.rs b/crates/apub/src/activities/following/mod.rs index 60bdd5f78..e472dc73a 100644 --- a/crates/apub/src/activities/following/mod.rs +++ b/crates/apub/src/activities/following/mod.rs @@ -1,3 +1,41 @@ +use crate::{ + objects::community::ApubCommunity, + protocol::activities::following::{follow::Follow, undo_follow::UndoFollow}, + SendActivity, +}; +use lemmy_api_common::{ + community::{CommunityResponse, FollowCommunity}, + context::LemmyContext, + utils::get_local_user_view_from_jwt, +}; +use lemmy_db_schema::{source::community::Community, traits::Crud}; +use lemmy_utils::error::LemmyError; + pub mod accept; pub mod follow; pub mod undo_follow; + +#[async_trait::async_trait(?Send)] +impl SendActivity for FollowCommunity { + type Response = CommunityResponse; + + async fn send_activity( + request: &Self, + _response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let local_user_view = + get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; + let person = local_user_view.person.clone().into(); + let community: ApubCommunity = Community::read(context.pool(), request.community_id) + .await? + .into(); + if community.local { + Ok(()) + } else if request.follow { + Follow::send(&person, &community, context).await + } else { + UndoFollow::send(&person, &community, context).await + } + } +} diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index 7d48f9f3c..436d8a02e 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -13,7 +13,7 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ community::{CommunityFollower, CommunityFollowerForm}, diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 68a3b535c..2fb5808b7 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -12,7 +12,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use anyhow::anyhow; -use lemmy_api_common::{generate_moderators_url, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::generate_moderators_url}; use lemmy_db_schema::{ newtypes::CommunityId, source::{community::Community, local_site::LocalSite}, @@ -30,6 +30,7 @@ pub mod community; pub mod create_or_update; pub mod deletion; pub mod following; +pub mod unfederated; pub mod voting; /// Checks that the specified Url actually identifies a Person (by fetching it), and that the person diff --git a/crates/apub/src/activities/unfederated.rs b/crates/apub/src/activities/unfederated.rs new file mode 100644 index 000000000..cca3340ed --- /dev/null +++ b/crates/apub/src/activities/unfederated.rs @@ -0,0 +1,351 @@ +use crate::SendActivity; +use lemmy_api_common::{ + comment::{ + CommentReportResponse, + CommentResponse, + GetComment, + GetComments, + GetCommentsResponse, + ListCommentReports, + ListCommentReportsResponse, + ResolveCommentReport, + SaveComment, + }, + community::{ + CommunityResponse, + CreateCommunity, + GetCommunity, + GetCommunityResponse, + ListCommunities, + ListCommunitiesResponse, + TransferCommunity, + }, + person::{ + AddAdmin, + AddAdminResponse, + BannedPersonsResponse, + BlockPerson, + BlockPersonResponse, + ChangePassword, + CommentReplyResponse, + GetBannedPersons, + GetCaptcha, + GetCaptchaResponse, + GetPersonDetails, + GetPersonDetailsResponse, + GetPersonMentions, + GetPersonMentionsResponse, + GetReplies, + GetRepliesResponse, + GetReportCount, + GetReportCountResponse, + GetUnreadCount, + GetUnreadCountResponse, + Login, + LoginResponse, + MarkAllAsRead, + MarkCommentReplyAsRead, + MarkPersonMentionAsRead, + PasswordChangeAfterReset, + PasswordReset, + PasswordResetResponse, + PersonMentionResponse, + Register, + SaveUserSettings, + VerifyEmail, + VerifyEmailResponse, + }, + post::{ + GetPost, + GetPostResponse, + GetPosts, + GetPostsResponse, + GetSiteMetadata, + GetSiteMetadataResponse, + ListPostReports, + ListPostReportsResponse, + MarkPostAsRead, + PostReportResponse, + PostResponse, + ResolvePostReport, + SavePost, + }, + private_message::{ + CreatePrivateMessageReport, + GetPrivateMessages, + ListPrivateMessageReports, + ListPrivateMessageReportsResponse, + MarkPrivateMessageAsRead, + PrivateMessageReportResponse, + PrivateMessageResponse, + PrivateMessagesResponse, + ResolvePrivateMessageReport, + }, + site::{ + ApproveRegistrationApplication, + CreateSite, + EditSite, + GetModlog, + GetModlogResponse, + GetSite, + GetSiteResponse, + GetUnreadRegistrationApplicationCount, + GetUnreadRegistrationApplicationCountResponse, + LeaveAdmin, + ListRegistrationApplications, + ListRegistrationApplicationsResponse, + PurgeComment, + PurgeCommunity, + PurgeItemResponse, + PurgePerson, + PurgePost, + RegistrationApplicationResponse, + ResolveObject, + ResolveObjectResponse, + Search, + SearchResponse, + SiteResponse, + }, + websocket::structs::{ + CommunityJoin, + CommunityJoinResponse, + ModJoin, + ModJoinResponse, + PostJoin, + PostJoinResponse, + UserJoin, + UserJoinResponse, + }, +}; + +impl SendActivity for Register { + type Response = LoginResponse; +} + +impl SendActivity for GetPersonDetails { + type Response = GetPersonDetailsResponse; +} + +impl SendActivity for GetPrivateMessages { + type Response = PrivateMessagesResponse; +} + +impl SendActivity for CreateSite { + type Response = SiteResponse; +} + +impl SendActivity for EditSite { + type Response = SiteResponse; +} + +impl SendActivity for GetSite { + type Response = GetSiteResponse; +} + +impl SendActivity for GetCommunity { + type Response = GetCommunityResponse; +} + +impl SendActivity for ListCommunities { + type Response = ListCommunitiesResponse; +} + +impl SendActivity for CreateCommunity { + type Response = CommunityResponse; +} + +impl SendActivity for GetPost { + type Response = GetPostResponse; +} + +impl SendActivity for GetPosts { + type Response = GetPostsResponse; +} + +impl SendActivity for GetComment { + type Response = CommentResponse; +} + +impl SendActivity for GetComments { + type Response = GetCommentsResponse; +} + +impl SendActivity for Login { + type Response = LoginResponse; +} + +impl SendActivity for GetCaptcha { + type Response = GetCaptchaResponse; +} + +impl SendActivity for GetReplies { + type Response = GetRepliesResponse; +} + +impl SendActivity for AddAdmin { + type Response = AddAdminResponse; +} + +impl SendActivity for GetUnreadRegistrationApplicationCount { + type Response = GetUnreadRegistrationApplicationCountResponse; +} + +impl SendActivity for ListRegistrationApplications { + type Response = ListRegistrationApplicationsResponse; +} + +impl SendActivity for ApproveRegistrationApplication { + type Response = RegistrationApplicationResponse; +} + +impl SendActivity for GetBannedPersons { + type Response = BannedPersonsResponse; +} + +impl SendActivity for BlockPerson { + type Response = BlockPersonResponse; +} + +impl SendActivity for GetPersonMentions { + type Response = GetPersonMentionsResponse; +} + +impl SendActivity for MarkPersonMentionAsRead { + type Response = PersonMentionResponse; +} + +impl SendActivity for MarkCommentReplyAsRead { + type Response = CommentReplyResponse; +} + +impl SendActivity for MarkAllAsRead { + type Response = GetRepliesResponse; +} + +impl SendActivity for PasswordReset { + type Response = PasswordResetResponse; +} + +impl SendActivity for PasswordChangeAfterReset { + type Response = LoginResponse; +} + +impl SendActivity for UserJoin { + type Response = UserJoinResponse; +} + +impl SendActivity for PostJoin { + type Response = PostJoinResponse; +} + +impl SendActivity for CommunityJoin { + type Response = CommunityJoinResponse; +} + +impl SendActivity for ModJoin { + type Response = ModJoinResponse; +} + +impl SendActivity for SaveUserSettings { + type Response = LoginResponse; +} + +impl SendActivity for ChangePassword { + type Response = LoginResponse; +} + +impl SendActivity for GetReportCount { + type Response = GetReportCountResponse; +} + +impl SendActivity for GetUnreadCount { + type Response = GetUnreadCountResponse; +} + +impl SendActivity for VerifyEmail { + type Response = VerifyEmailResponse; +} + +impl SendActivity for MarkPrivateMessageAsRead { + type Response = PrivateMessageResponse; +} + +impl SendActivity for CreatePrivateMessageReport { + type Response = PrivateMessageReportResponse; +} + +impl SendActivity for ResolvePrivateMessageReport { + type Response = PrivateMessageReportResponse; +} + +impl SendActivity for ListPrivateMessageReports { + type Response = ListPrivateMessageReportsResponse; +} + +impl SendActivity for GetModlog { + type Response = GetModlogResponse; +} + +impl SendActivity for PurgePerson { + type Response = PurgeItemResponse; +} + +impl SendActivity for PurgeCommunity { + type Response = PurgeItemResponse; +} + +impl SendActivity for PurgePost { + type Response = PurgeItemResponse; +} + +impl SendActivity for PurgeComment { + type Response = PurgeItemResponse; +} + +impl SendActivity for Search { + type Response = SearchResponse; +} + +impl SendActivity for ResolveObject { + type Response = ResolveObjectResponse; +} + +impl SendActivity for TransferCommunity { + type Response = GetCommunityResponse; +} + +impl SendActivity for LeaveAdmin { + type Response = GetSiteResponse; +} + +impl SendActivity for MarkPostAsRead { + type Response = PostResponse; +} + +impl SendActivity for SavePost { + type Response = PostResponse; +} + +impl SendActivity for ListPostReports { + type Response = ListPostReportsResponse; +} + +impl SendActivity for ResolvePostReport { + type Response = PostReportResponse; +} + +impl SendActivity for GetSiteMetadata { + type Response = GetSiteMetadataResponse; +} + +impl SendActivity for SaveComment { + type Response = CommentResponse; +} + +impl SendActivity for ListCommentReports { + type Response = ListCommentReportsResponse; +} + +impl SendActivity for ResolveCommentReport { + type Response = CommentReportResponse; +} diff --git a/crates/apub/src/activities/voting/mod.rs b/crates/apub/src/activities/voting/mod.rs index a01dcb2ea..4471fbd92 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -1,26 +1,112 @@ use crate::{ + activities::community::send_activity_in_community, + activity_lists::AnnouncableActivities, + fetcher::post_or_comment::PostOrComment, objects::{comment::ApubComment, person::ApubPerson, post::ApubPost}, - protocol::activities::voting::vote::VoteType, + protocol::activities::voting::{ + undo_vote::UndoVote, + vote::{Vote, VoteType}, + }, + SendActivity, }; +use activitypub_federation::core::object_id::ObjectId; use lemmy_api_common::{ + comment::{CommentResponse, CreateCommentLike}, + context::LemmyContext, + post::{CreatePostLike, PostResponse}, + sensitive::Sensitive, + utils::get_local_user_view_from_jwt, websocket::{ send::{send_comment_ws_message_simple, send_post_ws_message}, UserOperation, }, - LemmyContext, }; use lemmy_db_schema::{ + newtypes::CommunityId, source::{ comment::{CommentLike, CommentLikeForm}, + community::Community, + person::Person, post::{PostLike, PostLikeForm}, }, - traits::Likeable, + traits::{Crud, Likeable}, }; use lemmy_utils::error::LemmyError; pub mod undo_vote; pub mod vote; +#[async_trait::async_trait(?Send)] +impl SendActivity for CreatePostLike { + type Response = PostResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let object_id = ObjectId::new(response.post_view.post.ap_id.clone()); + let community_id = response.post_view.community.id; + send_activity( + object_id, + community_id, + request.score, + &request.auth, + context, + ) + .await + } +} + +#[async_trait::async_trait(?Send)] +impl SendActivity for CreateCommentLike { + type Response = CommentResponse; + + async fn send_activity( + request: &Self, + response: &Self::Response, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let object_id = ObjectId::new(response.comment_view.comment.ap_id.clone()); + let community_id = response.comment_view.community.id; + send_activity( + object_id, + community_id, + request.score, + &request.auth, + context, + ) + .await + } +} + +async fn send_activity( + object_id: ObjectId, + community_id: CommunityId, + score: i16, + jwt: &Sensitive, + context: &LemmyContext, +) -> Result<(), LemmyError> { + let community = Community::read(context.pool(), community_id).await?.into(); + let local_user_view = get_local_user_view_from_jwt(jwt, context.pool(), context.secret()).await?; + let actor = Person::read(context.pool(), local_user_view.person.id) + .await? + .into(); + + // score of 1 means upvote, -1 downvote, 0 undo a previous vote + if score != 0 { + let vote = Vote::new(object_id, &actor, &community, score.try_into()?, context)?; + let activity = AnnouncableActivities::Vote(vote); + send_activity_in_community(activity, &actor, &community, vec![], false, context).await + } else { + // Lemmy API doesnt distinguish between Undo/Like and Undo/Dislike, so we hardcode it here. + let vote = Vote::new(object_id, &actor, &community, VoteType::Like, context)?; + let undo_vote = UndoVote::new(vote, &actor, &community, context)?; + let activity = AnnouncableActivities::UndoVote(undo_vote); + send_activity_in_community(activity, &actor, &community, vec![], false, context).await + } +} + #[tracing::instrument(skip_all)] async fn vote_comment( vote_type: &VoteType, diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index dca106ded..7a419e879 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -1,18 +1,13 @@ use crate::{ activities::{ - community::send_activity_in_community, generate_activity_id, verify_person_in_community, voting::{undo_vote_comment, undo_vote_post}, }, - activity_lists::AnnouncableActivities, local_instance, objects::{community::ApubCommunity, person::ApubPerson}, protocol::{ - activities::voting::{ - undo_vote::UndoVote, - vote::{Vote, VoteType}, - }, + activities::voting::{undo_vote::UndoVote, vote::Vote}, InCommunity, }, ActorType, @@ -25,39 +20,27 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::LemmyContext; -use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use url::Url; impl UndoVote { - /// UndoVote has as:Public value in cc field, unlike other activities. This indicates to other - /// software (like GNU social, or presumably Mastodon), that the like actor should not be - /// disclosed. - #[tracing::instrument(skip_all)] - pub async fn send( - object: &PostOrComment, + pub(in crate::activities::voting) fn new( + vote: Vote, actor: &ApubPerson, - community_id: CommunityId, - kind: VoteType, + community: &ApubCommunity, context: &LemmyContext, - ) -> Result<(), LemmyError> { - let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into(); - - let object = Vote::new(object, actor, &community, kind.clone(), context)?; - let id = generate_activity_id( - UndoType::Undo, - &context.settings().get_protocol_and_hostname(), - )?; - let undo_vote = UndoVote { + ) -> Result { + Ok(UndoVote { actor: ObjectId::new(actor.actor_id()), - object, + object: vote, kind: UndoType::Undo, - id: id.clone(), + id: generate_activity_id( + UndoType::Undo, + &context.settings().get_protocol_and_hostname(), + )?, audience: Some(ObjectId::new(community.actor_id())), - }; - let activity = AnnouncableActivities::UndoVote(undo_vote); - send_activity_in_community(activity, actor, &community, vec![], false, context).await + }) } } diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index bc702fd86..e435b6823 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -1,11 +1,9 @@ use crate::{ activities::{ - community::send_activity_in_community, generate_activity_id, verify_person_in_community, voting::{vote_comment, vote_post}, }, - activity_lists::AnnouncableActivities, local_instance, objects::{community::ApubCommunity, person::ApubPerson}, protocol::{ @@ -17,20 +15,14 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use anyhow::anyhow; -use lemmy_api_common::LemmyContext; -use lemmy_db_schema::{ - newtypes::CommunityId, - source::{community::Community, local_site::LocalSite}, - traits::Crud, -}; +use lemmy_api_common::context::LemmyContext; +use lemmy_db_schema::source::local_site::LocalSite; use lemmy_utils::error::LemmyError; use url::Url; -/// Vote has as:Public value in cc field, unlike other activities. This indicates to other software -/// (like GNU social, or presumably Mastodon), that the like actor should not be disclosed. impl Vote { pub(in crate::activities::voting) fn new( - object: &PostOrComment, + object_id: ObjectId, actor: &ApubPerson, community: &ApubCommunity, kind: VoteType, @@ -38,27 +30,12 @@ impl Vote { ) -> Result { Ok(Vote { actor: ObjectId::new(actor.actor_id()), - object: ObjectId::new(object.ap_id()), + object: object_id, kind: kind.clone(), id: generate_activity_id(kind, &context.settings().get_protocol_and_hostname())?, audience: Some(ObjectId::new(community.actor_id())), }) } - - #[tracing::instrument(skip_all)] - pub async fn send( - object: &PostOrComment, - actor: &ApubPerson, - community_id: CommunityId, - kind: VoteType, - context: &LemmyContext, - ) -> Result<(), LemmyError> { - let community = Community::read(context.pool(), community_id).await?.into(); - let vote = Vote::new(object, actor, &community, kind, context)?; - - let activity = AnnouncableActivities::Vote(vote); - send_activity_in_community(activity, actor, &community, vec![], false, context).await - } } #[async_trait::async_trait(?Send)] diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index fa343d8ae..6e1771127 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -24,7 +24,7 @@ use crate::{ }, }; use activitypub_federation::{data::Data, deser::context::WithContext, traits::ActivityHandler}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/api_crud/src/comment/list.rs b/crates/apub/src/api/list_comments.rs similarity index 94% rename from crates/api_crud/src/comment/list.rs rename to crates/apub/src/api/list_comments.rs index 3e7444bf7..c4af6900a 100644 --- a/crates/api_crud/src/comment/list.rs +++ b/crates/apub/src/api/list_comments.rs @@ -1,15 +1,18 @@ -use crate::PerformCrud; +use crate::{ + api::PerformApub, + fetcher::resolve_actor_identifier, + objects::community::ApubCommunity, +}; use actix_web::web::Data; use lemmy_api_common::{ comment::{GetComments, GetCommentsResponse}, + context::LemmyContext, utils::{ check_private_instance, get_local_user_view_from_jwt_opt, listing_type_with_site_default, }, - LemmyContext, }; -use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity}; use lemmy_db_schema::{ source::{comment::Comment, community::Community, local_site::LocalSite}, traits::{Crud, DeleteableOrRemoveable}, @@ -18,7 +21,7 @@ use lemmy_db_views::comment_view::CommentQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; #[async_trait::async_trait(?Send)] -impl PerformCrud for GetComments { +impl PerformApub for GetComments { type Response = GetCommentsResponse; #[tracing::instrument(skip(context, _websocket_id))] diff --git a/crates/api_crud/src/post/list.rs b/crates/apub/src/api/list_posts.rs similarity index 93% rename from crates/api_crud/src/post/list.rs rename to crates/apub/src/api/list_posts.rs index 42944cada..7a1f815c7 100644 --- a/crates/api_crud/src/post/list.rs +++ b/crates/apub/src/api/list_posts.rs @@ -1,15 +1,18 @@ -use crate::PerformCrud; +use crate::{ + api::PerformApub, + fetcher::resolve_actor_identifier, + objects::community::ApubCommunity, +}; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{GetPosts, GetPostsResponse}, utils::{ check_private_instance, get_local_user_view_from_jwt_opt, listing_type_with_site_default, }, - LemmyContext, }; -use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity}; use lemmy_db_schema::{ source::{community::Community, local_site::LocalSite}, traits::DeleteableOrRemoveable, @@ -18,7 +21,7 @@ use lemmy_db_views::post_view::PostQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; #[async_trait::async_trait(?Send)] -impl PerformCrud for GetPosts { +impl PerformApub for GetPosts { type Response = GetPostsResponse; #[tracing::instrument(skip(context, _websocket_id))] diff --git a/crates/apub/src/api/mod.rs b/crates/apub/src/api/mod.rs new file mode 100644 index 000000000..233f72f02 --- /dev/null +++ b/crates/apub/src/api/mod.rs @@ -0,0 +1,21 @@ +use actix_web::web::Data; +use lemmy_api_common::context::LemmyContext; +use lemmy_utils::{error::LemmyError, ConnectionId}; + +mod list_comments; +mod list_posts; +mod read_community; +mod read_person; +mod resolve_object; +mod search; + +#[async_trait::async_trait(?Send)] +pub trait PerformApub { + type Response: serde::ser::Serialize + Send; + + async fn perform( + &self, + context: &Data, + websocket_id: Option, + ) -> Result; +} diff --git a/crates/api_crud/src/community/read.rs b/crates/apub/src/api/read_community.rs similarity index 92% rename from crates/api_crud/src/community/read.rs rename to crates/apub/src/api/read_community.rs index a008f7865..b1615d7d7 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/apub/src/api/read_community.rs @@ -1,14 +1,14 @@ -use crate::PerformCrud; +use crate::{ + api::PerformApub, + fetcher::resolve_actor_identifier, + objects::community::ApubCommunity, +}; use actix_web::web::Data; use lemmy_api_common::{ community::{GetCommunity, GetCommunityResponse}, + context::LemmyContext, utils::{check_private_instance, get_local_user_view_from_jwt_opt}, websocket::messages::GetCommunityUsersOnline, - LemmyContext, -}; -use lemmy_apub::{ - fetcher::resolve_actor_identifier, - objects::{community::ApubCommunity, instance::instance_actor_id_from_url}, }; use lemmy_db_schema::{ impls::actor_language::default_post_language, @@ -24,7 +24,7 @@ use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView}; use lemmy_utils::{error::LemmyError, ConnectionId}; #[async_trait::async_trait(?Send)] -impl PerformCrud for GetCommunity { +impl PerformApub for GetCommunity { type Response = GetCommunityResponse; #[tracing::instrument(skip(context, _websocket_id))] @@ -78,7 +78,8 @@ impl PerformCrud for GetCommunity { .await .unwrap_or(1); - let site_id = instance_actor_id_from_url(community_view.community.actor_id.clone().into()); + let site_id = + Site::instance_actor_id_from_url(community_view.community.actor_id.clone().into()); let mut site = Site::read_from_apub_id(context.pool(), site_id).await?; // no need to include metadata for local site (its already available through other endpoints). // this also prevents us from leaking the federation private key. diff --git a/crates/api_crud/src/user/read.rs b/crates/apub/src/api/read_person.rs similarity index 95% rename from crates/api_crud/src/user/read.rs rename to crates/apub/src/api/read_person.rs index b7b155a74..514bcfccc 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/apub/src/api/read_person.rs @@ -1,11 +1,10 @@ -use crate::PerformCrud; +use crate::{api::PerformApub, fetcher::resolve_actor_identifier, objects::person::ApubPerson}; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetPersonDetails, GetPersonDetailsResponse}, utils::{check_private_instance, get_local_user_view_from_jwt_opt}, - LemmyContext, }; -use lemmy_apub::{fetcher::resolve_actor_identifier, objects::person::ApubPerson}; use lemmy_db_schema::{ source::{local_site::LocalSite, person::Person}, utils::post_to_comment_sort_type, @@ -15,7 +14,7 @@ use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonViewSafe}; use lemmy_utils::{error::LemmyError, ConnectionId}; #[async_trait::async_trait(?Send)] -impl PerformCrud for GetPersonDetails { +impl PerformApub for GetPersonDetails { type Response = GetPersonDetailsResponse; #[tracing::instrument(skip(self, context, _websocket_id))] diff --git a/crates/api/src/site/resolve_object.rs b/crates/apub/src/api/resolve_object.rs similarity index 93% rename from crates/api/src/site/resolve_object.rs rename to crates/apub/src/api/resolve_object.rs index 47aa248e7..c179ed582 100644 --- a/crates/api/src/site/resolve_object.rs +++ b/crates/apub/src/api/resolve_object.rs @@ -1,19 +1,21 @@ -use crate::Perform; +use crate::{ + api::PerformApub, + fetcher::search::{search_query_to_object_id, SearchableObjects}, +}; use actix_web::web::Data; use diesel::NotFound; use lemmy_api_common::{ + context::LemmyContext, site::{ResolveObject, ResolveObjectResponse}, utils::{check_private_instance, get_local_user_view_from_jwt_opt}, - LemmyContext, }; -use lemmy_apub::fetcher::search::{search_query_to_object_id, SearchableObjects}; use lemmy_db_schema::{newtypes::PersonId, source::local_site::LocalSite, utils::DbPool}; use lemmy_db_views::structs::{CommentView, PostView}; use lemmy_db_views_actor::structs::{CommunityView, PersonViewSafe}; use lemmy_utils::{error::LemmyError, ConnectionId}; #[async_trait::async_trait(?Send)] -impl Perform for ResolveObject { +impl PerformApub for ResolveObject { type Response = ResolveObjectResponse; #[tracing::instrument(skip(context, _websocket_id))] diff --git a/crates/api/src/site/search.rs b/crates/apub/src/api/search.rs similarity index 97% rename from crates/api/src/site/search.rs rename to crates/apub/src/api/search.rs index 1033f92e6..cad41c549 100644 --- a/crates/api/src/site/search.rs +++ b/crates/apub/src/api/search.rs @@ -1,11 +1,14 @@ -use crate::Perform; +use crate::{ + api::PerformApub, + fetcher::resolve_actor_identifier, + objects::community::ApubCommunity, +}; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, site::{Search, SearchResponse}, utils::{check_private_instance, get_local_user_view_from_jwt_opt}, - LemmyContext, }; -use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity}; use lemmy_db_schema::{ source::{community::Community, local_site::LocalSite}, traits::DeleteableOrRemoveable, @@ -17,7 +20,7 @@ use lemmy_db_views_actor::{community_view::CommunityQuery, person_view::PersonQu use lemmy_utils::{error::LemmyError, ConnectionId}; #[async_trait::async_trait(?Send)] -impl Perform for Search { +impl PerformApub for Search { type Response = SearchResponse; #[tracing::instrument(skip(context, _websocket_id))] diff --git a/crates/apub/src/collections/community_moderators.rs b/crates/apub/src/collections/community_moderators.rs index aa38f8bee..9616ddb30 100644 --- a/crates/apub/src/collections/community_moderators.rs +++ b/crates/apub/src/collections/community_moderators.rs @@ -11,7 +11,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::collection::OrderedCollectionType; use chrono::NaiveDateTime; -use lemmy_api_common::generate_moderators_url; +use lemmy_api_common::utils::generate_moderators_url; use lemmy_db_schema::{ source::community::{CommunityModerator, CommunityModeratorForm}, traits::Joinable, diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index 44685430e..a16fbd02b 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -19,7 +19,7 @@ use activitypub_federation::{ use activitystreams_kinds::collection::OrderedCollectionType; use chrono::NaiveDateTime; use futures::future::join_all; -use lemmy_api_common::generate_outbox_url; +use lemmy_api_common::utils::generate_outbox_url; use lemmy_db_schema::{ source::{person::Person, post::Post}, traits::Crud, diff --git a/crates/apub/src/collections/mod.rs b/crates/apub/src/collections/mod.rs index 4c27beb41..40bdf1206 100644 --- a/crates/apub/src/collections/mod.rs +++ b/crates/apub/src/collections/mod.rs @@ -1,5 +1,5 @@ use crate::objects::community::ApubCommunity; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; pub(crate) mod community_moderators; pub(crate) mod community_outbox; diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index 563989241..0ce4dd8f6 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -1,7 +1,7 @@ use crate::{fetcher::webfinger::webfinger_resolve_actor, ActorType}; use activitypub_federation::traits::ApubObject; use itertools::Itertools; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::traits::ApubActor; use lemmy_utils::error::LemmyError; diff --git a/crates/apub/src/fetcher/post_or_comment.rs b/crates/apub/src/fetcher/post_or_comment.rs index b44d9f16f..68e176b01 100644 --- a/crates/apub/src/fetcher/post_or_comment.rs +++ b/crates/apub/src/fetcher/post_or_comment.rs @@ -7,7 +7,7 @@ use crate::{ }; use activitypub_federation::traits::ApubObject; use chrono::NaiveDateTime; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, post::Post}, traits::Crud, @@ -97,16 +97,6 @@ impl ApubObject for PostOrComment { } } -impl PostOrComment { - pub(crate) fn ap_id(&self) -> Url { - match self { - PostOrComment::Post(p) => p.ap_id.clone(), - PostOrComment::Comment(c) => c.ap_id.clone(), - } - .into() - } -} - #[async_trait::async_trait(?Send)] impl InCommunity for PostOrComment { async fn community( diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index 95b47f5e4..ffc2c9611 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject}; use chrono::NaiveDateTime; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::Deserialize; use url::Url; @@ -15,7 +15,7 @@ use url::Url; /// ObjectId directly, or a webfinger identifier (@user@example.com or !community@example.com) /// which gets resolved to an URL. #[tracing::instrument(skip_all)] -pub async fn search_query_to_object_id( +pub(crate) async fn search_query_to_object_id( query: &str, local_only: bool, context: &LemmyContext, @@ -54,7 +54,7 @@ pub async fn search_query_to_object_id( /// The types of ActivityPub objects that can be fetched directly by searching for their ID. #[derive(Debug)] -pub enum SearchableObjects { +pub(crate) enum SearchableObjects { Person(ApubPerson), Community(ApubCommunity), Post(ApubPost), @@ -63,7 +63,7 @@ pub enum SearchableObjects { #[derive(Deserialize)] #[serde(untagged)] -pub enum SearchableApubTypes { +pub(crate) enum SearchableApubTypes { Group(Group), Person(Person), Page(Page), diff --git a/crates/apub/src/fetcher/user_or_community.rs b/crates/apub/src/fetcher/user_or_community.rs index 14fc5c344..3af86be1a 100644 --- a/crates/apub/src/fetcher/user_or_community.rs +++ b/crates/apub/src/fetcher/user_or_community.rs @@ -5,7 +5,7 @@ use crate::{ }; use activitypub_federation::traits::{Actor, ApubObject}; use chrono::NaiveDateTime; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/fetcher/webfinger.rs b/crates/apub/src/fetcher/webfinger.rs index 3ec6fcf81..4746736eb 100644 --- a/crates/apub/src/fetcher/webfinger.rs +++ b/crates/apub/src/fetcher/webfinger.rs @@ -2,7 +2,7 @@ use crate::{local_instance, ActorType, FEDERATION_HTTP_FETCH_LIMIT}; use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject}; use anyhow::anyhow; use itertools::Itertools; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::newtypes::DbUrl; use lemmy_utils::{error::LemmyError, WebfingerResponse}; use tracing::debug; @@ -10,7 +10,6 @@ use url::Url; /// Turns a person id like `@name@example.com` into an apub ID, like `https://example.com/user/name`, /// using webfinger. -#[tracing::instrument(skip_all)] pub(crate) async fn webfinger_resolve_actor( identifier: &str, local_only: bool, diff --git a/crates/apub/src/http/comment.rs b/crates/apub/src/http/comment.rs index fbadd42ba..5e7de7e25 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -5,7 +5,7 @@ use crate::{ use activitypub_federation::traits::ApubObject; use actix_web::{web, web::Path, HttpResponse}; use diesel::result::Error::NotFound; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{newtypes::CommentId, source::comment::Comment, traits::Crud}; use lemmy_utils::error::LemmyError; use serde::Deserialize; diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 487ad5512..74809509f 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -16,7 +16,7 @@ use activitypub_federation::{ traits::ApubObject, }; use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_api_common::{generate_outbox_url, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url}; use lemmy_db_schema::{source::community::Community, traits::ApubActor}; use lemmy_utils::error::LemmyError; use serde::Deserialize; diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index c4602c337..726834c00 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -15,7 +15,7 @@ use activitypub_federation::{ }; use actix_web::{web, HttpRequest, HttpResponse}; use http::StatusCode; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::source::activity::Activity; use lemmy_utils::error::LemmyError; use once_cell::sync::OnceCell; diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 0e838fe13..6a1bc5b35 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -7,7 +7,7 @@ use crate::{ }; use activitypub_federation::{deser::context::WithContext, traits::ApubObject}; use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_api_common::{generate_outbox_url, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url}; use lemmy_db_schema::{source::person::Person, traits::ApubActor}; use lemmy_utils::error::LemmyError; use serde::Deserialize; diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index 85a4406f5..bea5da3a4 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -5,7 +5,7 @@ use crate::{ use activitypub_federation::traits::ApubObject; use actix_web::{web, HttpResponse}; use diesel::result::Error::NotFound; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{newtypes::PostId, source::post::Post, traits::Crud}; use lemmy_utils::error::LemmyError; use serde::Deserialize; diff --git a/crates/apub/src/http/site.rs b/crates/apub/src/http/site.rs index 7a945ac72..fe6c34f63 100644 --- a/crates/apub/src/http/site.rs +++ b/crates/apub/src/http/site.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::{deser::context::WithContext, traits::ApubObject}; use actix_web::{web, HttpRequest, HttpResponse}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_views::structs::SiteView; use lemmy_utils::error::LemmyError; use url::Url; diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 92ae014b1..0908a1f4f 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -7,7 +7,7 @@ use activitypub_federation::{ UrlVerifier, }; use async_trait::async_trait; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{activity::Activity, instance::Instance, local_site::LocalSite}, utils::DbPool, @@ -19,6 +19,7 @@ use url::Url; pub mod activities; pub(crate) mod activity_lists; +pub mod api; pub(crate) mod collections; pub mod fetcher; pub mod http; @@ -216,3 +217,16 @@ pub trait ActorType: Actor + ApubObject { PublicKey::new_main_key(self.actor_id(), self.public_key().to_string()) } } + +#[async_trait::async_trait(?Send)] +pub trait SendActivity { + type Response; + + async fn send_activity( + _request: &Self, + _response: &Self::Response, + _context: &LemmyContext, + ) -> Result<(), LemmyError> { + Ok(()) + } +} diff --git a/crates/apub/src/mentions.rs b/crates/apub/src/mentions.rs index ae7d9b6c1..559078942 100644 --- a/crates/apub/src/mentions.rs +++ b/crates/apub/src/mentions.rs @@ -5,7 +5,7 @@ use crate::{ }; use activitypub_federation::core::object_id::ObjectId; use activitystreams_kinds::link::MentionType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{comment::Comment, person::Person, post::Post}, traits::Crud, diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index a4c6ef737..ab11b00d8 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -20,7 +20,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::{object::NoteType, public}; use chrono::NaiveDateTime; -use lemmy_api_common::{utils::local_site_opt_to_slur_regex, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentInsertForm, CommentUpdateForm}, @@ -39,7 +39,7 @@ use std::ops::Deref; use url::Url; #[derive(Clone, Debug)] -pub struct ApubComment(Comment); +pub struct ApubComment(pub(crate) Comment); impl Deref for ApubComment { type Target = Comment; diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index d8c1596ae..b309d25fc 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -18,7 +18,10 @@ use activitypub_federation::{ use activitystreams_kinds::actor::GroupType; use chrono::NaiveDateTime; use itertools::Itertools; -use lemmy_api_common::{generate_moderators_url, generate_outbox_url, LemmyContext}; +use lemmy_api_common::{ + context::LemmyContext, + utils::{generate_moderators_url, generate_outbox_url}, +}; use lemmy_db_schema::{ source::{ actor_language::CommunityLanguage, diff --git a/crates/apub/src/objects/instance.rs b/crates/apub/src/objects/instance.rs index 18e9d9f25..5ec4fe909 100644 --- a/crates/apub/src/objects/instance.rs +++ b/crates/apub/src/objects/instance.rs @@ -20,7 +20,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use chrono::NaiveDateTime; -use lemmy_api_common::{utils::local_site_opt_to_slur_regex, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex}; use lemmy_db_schema::{ source::{ actor_language::SiteLanguage, @@ -176,15 +176,6 @@ impl Actor for ApubSite { } } -/// Instance actor is at the root path, so we simply need to clear the path and other unnecessary -/// parts of the url. -pub fn instance_actor_id_from_url(mut url: Url) -> Url { - url.set_fragment(None); - url.set_path(""); - url.set_query(None); - url -} - /// try to fetch the instance actor (to make things like instance rules available) pub(in crate::objects) async fn fetch_instance_actor_for_object( object_id: Url, @@ -192,7 +183,7 @@ pub(in crate::objects) async fn fetch_instance_actor_for_object( request_counter: &mut i32, ) { // try to fetch the instance actor (to make things like instance rules available) - let instance_id = instance_actor_id_from_url(object_id); + let instance_id = Site::instance_actor_id_from_url(object_id); let site = ObjectId::::new(instance_id.clone()) .dereference(context, local_instance(context).await, request_counter) .await; diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index 1bf621fca..58e1f23f5 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -57,9 +57,9 @@ pub(crate) mod tests { use actix::Actor; use anyhow::anyhow; use lemmy_api_common::{ + context::LemmyContext, request::build_user_agent, websocket::chat_server::ChatServer, - LemmyContext, }; use lemmy_db_schema::{source::secret::Secret, utils::build_db_pool_for_tests}; use lemmy_utils::{ @@ -113,6 +113,7 @@ pub(crate) mod tests { pool.clone(), |_, _, _, _| Box::pin(x()), |_, _, _, _| Box::pin(x()), + |_, _, _, _| Box::pin(x()), client.clone(), settings.clone(), secret.clone(), diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 236f3edf3..2017b605c 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -18,7 +18,10 @@ use activitypub_federation::{ utils::verify_domains_match, }; use chrono::NaiveDateTime; -use lemmy_api_common::{generate_outbox_url, utils::local_site_opt_to_slur_regex, LemmyContext}; +use lemmy_api_common::{ + context::LemmyContext, + utils::{generate_outbox_url, local_site_opt_to_slur_regex}, +}; use lemmy_db_schema::{ source::{ instance::Instance, diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index f79e3055a..afe025ce2 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -23,9 +23,9 @@ use activitypub_federation::{ use activitystreams_kinds::public; use chrono::NaiveDateTime; use lemmy_api_common::{ + context::LemmyContext, request::fetch_site_data, utils::local_site_opt_to_slur_regex, - LemmyContext, }; use lemmy_db_schema::{ self, @@ -46,7 +46,7 @@ use std::ops::Deref; use url::Url; #[derive(Clone, Debug)] -pub struct ApubPost(Post); +pub struct ApubPost(pub(crate) Post); impl Deref for ApubPost { type Target = Post; diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index f4807076b..4d8c70076 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -15,7 +15,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use chrono::NaiveDateTime; -use lemmy_api_common::{utils::check_person_block, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::check_person_block}; use lemmy_db_schema::{ source::{ person::Person, @@ -31,7 +31,7 @@ use std::ops::Deref; use url::Url; #[derive(Clone, Debug)] -pub struct ApubPrivateMessage(PrivateMessage); +pub struct ApubPrivateMessage(pub(crate) PrivateMessage); impl Deref for ApubPrivateMessage { type Target = PrivateMessage; diff --git a/crates/apub/src/protocol/activities/block/block_user.rs b/crates/apub/src/protocol/activities/block/block_user.rs index 364fe9b9f..3ac040ced 100644 --- a/crates/apub/src/protocol/activities/block/block_user.rs +++ b/crates/apub/src/protocol/activities/block/block_user.rs @@ -8,7 +8,7 @@ use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserial use activitystreams_kinds::activity::BlockType; use anyhow::anyhow; use chrono::{DateTime, FixedOffset}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; diff --git a/crates/apub/src/protocol/activities/block/undo_block_user.rs b/crates/apub/src/protocol/activities/block/undo_block_user.rs index 9646315ff..d818af9de 100644 --- a/crates/apub/src/protocol/activities/block/undo_block_user.rs +++ b/crates/apub/src/protocol/activities/block/undo_block_user.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; diff --git a/crates/apub/src/protocol/activities/community/add_mod.rs b/crates/apub/src/protocol/activities/community/add_mod.rs index c8ea5daa9..22fc07fcb 100644 --- a/crates/apub/src/protocol/activities/community/add_mod.rs +++ b/crates/apub/src/protocol/activities/community/add_mod.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::AddType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/activities/community/remove_mod.rs b/crates/apub/src/protocol/activities/community/remove_mod.rs index 57d9c1bca..ce46fb920 100644 --- a/crates/apub/src/protocol/activities/community/remove_mod.rs +++ b/crates/apub/src/protocol/activities/community/remove_mod.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::RemoveType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index a66e08b05..0a1ef650f 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -7,7 +7,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one}; use activitystreams_kinds::activity::FlagType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/activities/community/update.rs b/crates/apub/src/protocol/activities/community/update.rs index 8bf39a826..9a2f1f481 100644 --- a/crates/apub/src/protocol/activities/community/update.rs +++ b/crates/apub/src/protocol/activities/community/update.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::UpdateType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/activities/create_or_update/note.rs b/crates/apub/src/protocol/activities/create_or_update/note.rs index a952811be..dfa1dbe9f 100644 --- a/crates/apub/src/protocol/activities/create_or_update/note.rs +++ b/crates/apub/src/protocol/activities/create_or_update/note.rs @@ -6,7 +6,7 @@ use crate::{ protocol::{activities::CreateOrUpdateType, objects::note::Note, InCommunity}, }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{source::community::Community, traits::Crud}; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; diff --git a/crates/apub/src/protocol/activities/create_or_update/page.rs b/crates/apub/src/protocol/activities/create_or_update/page.rs index 9d45ae0bf..2c15d9f90 100644 --- a/crates/apub/src/protocol/activities/create_or_update/page.rs +++ b/crates/apub/src/protocol/activities/create_or_update/page.rs @@ -5,7 +5,7 @@ use crate::{ protocol::{activities::CreateOrUpdateType, objects::page::Page, InCommunity}, }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/activities/deletion/delete.rs b/crates/apub/src/protocol/activities/deletion/delete.rs index 8a0c1b0bd..d92ac2456 100644 --- a/crates/apub/src/protocol/activities/deletion/delete.rs +++ b/crates/apub/src/protocol/activities/deletion/delete.rs @@ -7,7 +7,7 @@ use crate::{ use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::DeleteType; use anyhow::anyhow; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, post::Post}, traits::Crud, diff --git a/crates/apub/src/protocol/activities/deletion/undo_delete.rs b/crates/apub/src/protocol/activities/deletion/undo_delete.rs index 0e2c0f982..d5249ba9a 100644 --- a/crates/apub/src/protocol/activities/deletion/undo_delete.rs +++ b/crates/apub/src/protocol/activities/deletion/undo_delete.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; diff --git a/crates/apub/src/protocol/activities/voting/undo_vote.rs b/crates/apub/src/protocol/activities/voting/undo_vote.rs index 7c23036c6..0973c76a8 100644 --- a/crates/apub/src/protocol/activities/voting/undo_vote.rs +++ b/crates/apub/src/protocol/activities/voting/undo_vote.rs @@ -6,7 +6,7 @@ use crate::{ }; use activitypub_federation::core::object_id::ObjectId; use activitystreams_kinds::activity::UndoType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/activities/voting/vote.rs b/crates/apub/src/protocol/activities/voting/vote.rs index a88aa3da9..2a09a45ea 100644 --- a/crates/apub/src/protocol/activities/voting/vote.rs +++ b/crates/apub/src/protocol/activities/voting/vote.rs @@ -6,7 +6,7 @@ use crate::{ protocol::InCommunity, }; use activitypub_federation::core::object_id::ObjectId; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; diff --git a/crates/apub/src/protocol/collections/group_followers.rs b/crates/apub/src/protocol/collections/group_followers.rs index 23ee169d4..b9cf85182 100644 --- a/crates/apub/src/protocol/collections/group_followers.rs +++ b/crates/apub/src/protocol/collections/group_followers.rs @@ -1,5 +1,5 @@ use activitystreams_kinds::collection::CollectionType; -use lemmy_api_common::{generate_followers_url, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::generate_followers_url}; use lemmy_db_schema::source::community::Community; use lemmy_db_views_actor::structs::CommunityFollowerView; use lemmy_utils::error::LemmyError; diff --git a/crates/apub/src/protocol/mod.rs b/crates/apub/src/protocol/mod.rs index 16bdb1b29..ef0f2a875 100644 --- a/crates/apub/src/protocol/mod.rs +++ b/crates/apub/src/protocol/mod.rs @@ -1,7 +1,7 @@ use crate::{local_instance, objects::community::ApubCommunity}; use activitypub_federation::{deser::values::MediaTypeMarkdown, utils::fetch_object_http}; use activitystreams_kinds::object::ImageType; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::newtypes::DbUrl; use lemmy_utils::error::LemmyError; use serde::{de::DeserializeOwned, Deserialize, Serialize}; diff --git a/crates/apub/src/protocol/objects/group.rs b/crates/apub/src/protocol/objects/group.rs index 316af1a8d..03f71a348 100644 --- a/crates/apub/src/protocol/objects/group.rs +++ b/crates/apub/src/protocol/objects/group.rs @@ -19,7 +19,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::actor::GroupType; use chrono::{DateTime, FixedOffset}; -use lemmy_api_common::{utils::local_site_opt_to_slur_regex, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex}; use lemmy_db_schema::{ newtypes::InstanceId, source::community::{CommunityInsertForm, CommunityUpdateForm}, diff --git a/crates/apub/src/protocol/objects/note.rs b/crates/apub/src/protocol/objects/note.rs index f8263d874..f561c313d 100644 --- a/crates/apub/src/protocol/objects/note.rs +++ b/crates/apub/src/protocol/objects/note.rs @@ -15,7 +15,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::object::NoteType; use chrono::{DateTime, FixedOffset}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, post::Post}, traits::Crud, diff --git a/crates/apub/src/protocol/objects/page.rs b/crates/apub/src/protocol/objects/page.rs index 1ff12bc29..a62fb8e57 100644 --- a/crates/apub/src/protocol/objects/page.rs +++ b/crates/apub/src/protocol/objects/page.rs @@ -20,7 +20,7 @@ use activitystreams_kinds::{ }; use chrono::{DateTime, FixedOffset}; use itertools::Itertools; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::newtypes::DbUrl; use lemmy_utils::error::LemmyError; use serde::{Deserialize, Serialize}; diff --git a/crates/db_schema/src/impls/site.rs b/crates/db_schema/src/impls/site.rs index 42d384eb9..96f8a2f05 100644 --- a/crates/db_schema/src/impls/site.rs +++ b/crates/db_schema/src/impls/site.rs @@ -75,4 +75,13 @@ impl Site { let conn = &mut get_conn(pool).await?; site.order_by(id).offset(1).get_results::(conn).await } + + /// Instance actor is at the root path, so we simply need to clear the path and other unnecessary + /// parts of the url. + pub fn instance_actor_id_from_url(mut url: Url) -> Url { + url.set_fragment(None); + url.set_path(""); + url.set_query(None); + url + } } diff --git a/crates/routes/Cargo.toml b/crates/routes/Cargo.toml index c5349a20a..bc2b573e5 100644 --- a/crates/routes/Cargo.toml +++ b/crates/routes/Cargo.toml @@ -16,7 +16,7 @@ lemmy_utils = { workspace = true } lemmy_db_views = { workspace = true } lemmy_db_views_actor = { workspace = true } lemmy_db_schema = { workspace = true } -lemmy_api_common = { workspace = true } +lemmy_api_common = { workspace = true, features = ["full"] } diesel = { workspace = true } actix-web = { workspace = true } anyhow = { workspace = true } diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 72181bf6a..594bf1153 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -1,7 +1,7 @@ use actix_web::{error::ErrorBadRequest, web, Error, HttpRequest, HttpResponse, Result}; use anyhow::anyhow; use chrono::{DateTime, NaiveDateTime, Utc}; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ newtypes::LocalUserId, source::{community::Community, local_user::LocalUser, person::Person}, diff --git a/crates/routes/src/images.rs b/crates/routes/src/images.rs index 6e839e214..0b1f6fbdd 100644 --- a/crates/routes/src/images.rs +++ b/crates/routes/src/images.rs @@ -11,7 +11,7 @@ use actix_web::{ HttpResponse, }; use futures::stream::{Stream, StreamExt}; -use lemmy_api_common::{utils::get_local_user_view_from_jwt, LemmyContext}; +use lemmy_api_common::{context::LemmyContext, utils::get_local_user_view_from_jwt}; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_utils::{claims::Claims, rate_limit::RateLimitCell, REQWEST_TIMEOUT}; use reqwest::Body; diff --git a/crates/routes/src/nodeinfo.rs b/crates/routes/src/nodeinfo.rs index 3a8b41859..13786e3b6 100644 --- a/crates/routes/src/nodeinfo.rs +++ b/crates/routes/src/nodeinfo.rs @@ -1,6 +1,6 @@ use actix_web::{error::ErrorBadRequest, web, Error, HttpResponse, Result}; use anyhow::anyhow; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_views::structs::SiteView; use lemmy_utils::{error::LemmyError, version}; use serde::{Deserialize, Serialize}; diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs index 68482a8d1..9056ea632 100644 --- a/crates/routes/src/webfinger.rs +++ b/crates/routes/src/webfinger.rs @@ -1,6 +1,6 @@ use actix_web::{web, web::Query, HttpResponse}; use anyhow::Context; -use lemmy_api_common::LemmyContext; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, person::Person}, traits::ApubActor, diff --git a/src/api_routes.rs b/src/api_routes.rs index 626857c69..77e5c27d7 100644 --- a/src/api_routes.rs +++ b/src/api_routes.rs @@ -28,6 +28,7 @@ use lemmy_api_common::{ RemoveCommunity, TransferCommunity, }, + context::LemmyContext, person::{ AddAdmin, BanPerson, @@ -96,13 +97,18 @@ use lemmy_api_common::{ }, websocket::{ routes::chat_route, + serialize_websocket_message, structs::{CommunityJoin, ModJoin, PostJoin, UserJoin}, + UserOperation, + UserOperationApub, + UserOperationCrud, }, - LemmyContext, }; use lemmy_api_crud::PerformCrud; -use lemmy_utils::rate_limit::RateLimitCell; +use lemmy_apub::{api::PerformApub, SendActivity}; +use lemmy_utils::{error::LemmyError, rate_limit::RateLimitCell, ConnectionId}; use serde::Deserialize; +use std::result; pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { cfg.service( @@ -126,12 +132,12 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { .service( web::resource("/search") .wrap(rate_limit.search()) - .route(web::get().to(route_get::)), + .route(web::get().to(route_get_apub::)), ) .service( web::resource("/resolve_object") .wrap(rate_limit.message()) - .route(web::get().to(route_get::)), + .route(web::get().to(route_get_apub::)), ) // Community .service( @@ -143,7 +149,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { .service( web::scope("/community") .wrap(rate_limit.message()) - .route("", web::get().to(route_get_crud::)) + .route("", web::get().to(route_get_apub::)) .route("", web::put().to(route_post_crud::)) .route("/hide", web::put().to(route_post::)) .route("/list", web::get().to(route_get_crud::)) @@ -185,7 +191,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { ) .route("/lock", web::post().to(route_post::)) .route("/sticky", web::post().to(route_post::)) - .route("/list", web::get().to(route_get_crud::)) + .route("/list", web::get().to(route_get_apub::)) .route("/like", web::post().to(route_post::)) .route("/save", web::put().to(route_post::)) .route("/join", web::post().to(route_post::)) @@ -221,7 +227,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { ) .route("/like", web::post().to(route_post::)) .route("/save", web::put().to(route_post::)) - .route("/list", web::get().to(route_get_crud::)) + .route("/list", web::get().to(route_get_apub::)) .route("/report", web::post().to(route_post::)) .route( "/report/resolve", @@ -279,7 +285,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { .service( web::scope("/user") .wrap(rate_limit.message()) - .route("", web::get().to(route_get_crud::)) + .route("", web::get().to(route_get_apub::)) .route("/mention", web::get().to(route_get::)) .route( "/mention/mark_as_read", @@ -352,19 +358,21 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { ); } -async fn perform( - data: Request, +async fn perform<'a, Data>( + data: Data, context: web::Data, ) -> Result where - Request: Perform, - Request: Send + 'static, + Data: Perform + + SendActivity::Response> + + Clone + + Deserialize<'a> + + Send + + 'static, { - let res = data - .perform(&context, None) - .await - .map(|json| HttpResponse::Ok().json(json))?; - Ok(res) + let res = data.perform(&context, None).await?; + SendActivity::send_activity(&data, &res, &context).await?; + Ok(HttpResponse::Ok().json(res)) } async fn route_get<'a, Data>( @@ -372,34 +380,63 @@ async fn route_get<'a, Data>( context: web::Data, ) -> Result where - Data: Deserialize<'a> + Send + 'static + Perform, + Data: Perform + + SendActivity::Response> + + Clone + + Deserialize<'a> + + Send + + 'static, { perform::(data.0, context).await } +async fn route_get_apub<'a, Data>( + data: web::Query, + context: web::Data, +) -> Result +where + Data: PerformApub + + SendActivity::Response> + + Clone + + Deserialize<'a> + + Send + + 'static, +{ + let res = data.perform(&context, None).await?; + SendActivity::send_activity(&data.0, &res, &context).await?; + Ok(HttpResponse::Ok().json(res)) +} + async fn route_post<'a, Data>( data: web::Json, context: web::Data, ) -> Result where - Data: Deserialize<'a> + Send + 'static + Perform, + Data: Perform + + SendActivity::Response> + + Clone + + Deserialize<'a> + + Send + + 'static, { perform::(data.0, context).await } -async fn perform_crud( - data: Request, +async fn perform_crud<'a, Data>( + data: Data, context: web::Data, ) -> Result where - Request: PerformCrud, - Request: Send + 'static, + Data: PerformCrud + + SendActivity::Response> + + Clone + + Deserialize<'a> + + Send + + 'static, { - let res = data - .perform(&context, None) - .await - .map(|json| HttpResponse::Ok().json(json))?; - Ok(res) + let res = data.perform(&context, None).await?; + SendActivity::send_activity(&data, &res, &context).await?; + Ok(HttpResponse::Ok().json(res)) } async fn route_get_crud<'a, Data>( @@ -407,7 +444,12 @@ async fn route_get_crud<'a, Data>( context: web::Data, ) -> Result where - Data: Deserialize<'a> + Send + 'static + PerformCrud, + Data: PerformCrud + + SendActivity::Response> + + Clone + + Deserialize<'a> + + Send + + 'static, { perform_crud::(data.0, context).await } @@ -417,7 +459,340 @@ async fn route_post_crud<'a, Data>( context: web::Data, ) -> Result where - Data: Deserialize<'a> + Send + 'static + PerformCrud, + Data: PerformCrud + + SendActivity::Response> + + Clone + + Deserialize<'a> + + Send + + 'static, { perform_crud::(data.0, context).await } + +pub async fn match_websocket_operation_crud( + context: LemmyContext, + id: ConnectionId, + op: UserOperationCrud, + data: &str, +) -> result::Result { + match op { + // User ops + UserOperationCrud::Register => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::DeleteAccount => { + do_websocket_operation_crud::(context, id, op, data).await + } + + // Private Message ops + UserOperationCrud::CreatePrivateMessage => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::EditPrivateMessage => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::DeletePrivateMessage => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::GetPrivateMessages => { + do_websocket_operation_crud::(context, id, op, data).await + } + + // Site ops + UserOperationCrud::CreateSite => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::EditSite => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::GetSite => { + do_websocket_operation_crud::(context, id, op, data).await + } + + // Community ops + UserOperationCrud::ListCommunities => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::CreateCommunity => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::EditCommunity => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::DeleteCommunity => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::RemoveCommunity => { + do_websocket_operation_crud::(context, id, op, data).await + } + + // Post ops + UserOperationCrud::CreatePost => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::GetPost => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::EditPost => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::DeletePost => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::RemovePost => { + do_websocket_operation_crud::(context, id, op, data).await + } + + // Comment ops + UserOperationCrud::CreateComment => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::EditComment => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::DeleteComment => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::RemoveComment => { + do_websocket_operation_crud::(context, id, op, data).await + } + UserOperationCrud::GetComment => { + do_websocket_operation_crud::(context, id, op, data).await + } + } +} + +async fn do_websocket_operation_crud<'a, 'b, Data>( + context: LemmyContext, + id: ConnectionId, + op: UserOperationCrud, + data: &str, +) -> result::Result +where + Data: PerformCrud + SendActivity::Response>, + for<'de> Data: Deserialize<'de>, +{ + let parsed_data: Data = serde_json::from_str(data)?; + let res = parsed_data + .perform(&web::Data::new(context.clone()), Some(id)) + .await?; + SendActivity::send_activity(&parsed_data, &res, &context).await?; + serialize_websocket_message(&op, &res) +} + +pub async fn match_websocket_operation_apub( + context: LemmyContext, + id: ConnectionId, + op: UserOperationApub, + data: &str, +) -> result::Result { + match op { + UserOperationApub::GetPersonDetails => { + do_websocket_operation_apub::(context, id, op, data).await + } + UserOperationApub::GetCommunity => { + do_websocket_operation_apub::(context, id, op, data).await + } + UserOperationApub::GetComments => { + do_websocket_operation_apub::(context, id, op, data).await + } + UserOperationApub::GetPosts => { + do_websocket_operation_apub::(context, id, op, data).await + } + UserOperationApub::ResolveObject => { + do_websocket_operation_apub::(context, id, op, data).await + } + UserOperationApub::Search => do_websocket_operation_apub::(context, id, op, data).await, + } +} + +async fn do_websocket_operation_apub<'a, 'b, Data>( + context: LemmyContext, + id: ConnectionId, + op: UserOperationApub, + data: &str, +) -> result::Result +where + Data: PerformApub + SendActivity::Response>, + for<'de> Data: Deserialize<'de>, +{ + let parsed_data: Data = serde_json::from_str(data)?; + let res = parsed_data + .perform(&web::Data::new(context.clone()), Some(id)) + .await?; + SendActivity::send_activity(&parsed_data, &res, &context).await?; + serialize_websocket_message(&op, &res) +} + +pub async fn match_websocket_operation( + context: LemmyContext, + id: ConnectionId, + op: UserOperation, + data: &str, +) -> result::Result { + match op { + // User ops + UserOperation::Login => do_websocket_operation::(context, id, op, data).await, + UserOperation::GetCaptcha => do_websocket_operation::(context, id, op, data).await, + UserOperation::GetReplies => do_websocket_operation::(context, id, op, data).await, + UserOperation::AddAdmin => do_websocket_operation::(context, id, op, data).await, + UserOperation::GetUnreadRegistrationApplicationCount => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ListRegistrationApplications => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ApproveRegistrationApplication => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::BanPerson => do_websocket_operation::(context, id, op, data).await, + UserOperation::GetBannedPersons => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::BlockPerson => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::GetPersonMentions => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::MarkPersonMentionAsRead => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::MarkCommentReplyAsRead => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::MarkAllAsRead => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::PasswordReset => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::PasswordChange => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::UserJoin => do_websocket_operation::(context, id, op, data).await, + UserOperation::PostJoin => do_websocket_operation::(context, id, op, data).await, + UserOperation::CommunityJoin => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ModJoin => do_websocket_operation::(context, id, op, data).await, + UserOperation::SaveUserSettings => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ChangePassword => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::GetReportCount => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::GetUnreadCount => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::VerifyEmail => { + do_websocket_operation::(context, id, op, data).await + } + + // Private Message ops + UserOperation::MarkPrivateMessageAsRead => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::CreatePrivateMessageReport => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ResolvePrivateMessageReport => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ListPrivateMessageReports => { + do_websocket_operation::(context, id, op, data).await + } + + // Site ops + UserOperation::GetModlog => do_websocket_operation::(context, id, op, data).await, + UserOperation::PurgePerson => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::PurgeCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::PurgePost => do_websocket_operation::(context, id, op, data).await, + UserOperation::PurgeComment => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::TransferCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::LeaveAdmin => do_websocket_operation::(context, id, op, data).await, + + // Community ops + UserOperation::FollowCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::BlockCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::BanFromCommunity => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::AddModToCommunity => { + do_websocket_operation::(context, id, op, data).await + } + + // Post ops + UserOperation::LockPost => do_websocket_operation::(context, id, op, data).await, + UserOperation::StickyPost => do_websocket_operation::(context, id, op, data).await, + UserOperation::CreatePostLike => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::MarkPostAsRead => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::SavePost => do_websocket_operation::(context, id, op, data).await, + UserOperation::CreatePostReport => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ListPostReports => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ResolvePostReport => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::GetSiteMetadata => { + do_websocket_operation::(context, id, op, data).await + } + + // Comment ops + UserOperation::SaveComment => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::CreateCommentLike => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::CreateCommentReport => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ListCommentReports => { + do_websocket_operation::(context, id, op, data).await + } + UserOperation::ResolveCommentReport => { + do_websocket_operation::(context, id, op, data).await + } + } +} + +async fn do_websocket_operation<'a, 'b, Data>( + context: LemmyContext, + id: ConnectionId, + op: UserOperation, + data: &str, +) -> result::Result +where + Data: Perform + SendActivity::Response>, + for<'de> Data: Deserialize<'de>, +{ + let parsed_data: Data = serde_json::from_str(data)?; + let res = parsed_data + .perform(&web::Data::new(context.clone()), Some(id)) + .await?; + SendActivity::send_activity(&parsed_data, &res, &context).await?; + serialize_websocket_message(&op, &res) +} diff --git a/src/code_migrations.rs b/src/code_migrations.rs index 0c9fecf69..89933a15e 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -9,13 +9,15 @@ use diesel::{ }; use diesel_async::RunQueryDsl; use lemmy_api_common::{ - generate_followers_url, - generate_inbox_url, - generate_local_apub_endpoint, - generate_shared_inbox_url, - generate_site_inbox_url, lemmy_db_views::structs::SiteView, - EndpointType, + utils::{ + generate_followers_url, + generate_inbox_url, + generate_local_apub_endpoint, + generate_shared_inbox_url, + generate_site_inbox_url, + EndpointType, + }, }; use lemmy_db_schema::{ source::{ diff --git a/src/main.rs b/src/main.rs index e4b8e8e32..c60c1823a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,8 @@ use actix::prelude::*; use actix_web::{middleware, web::Data, App, HttpServer, Result}; use diesel_migrations::EmbeddedMigrations; use doku::json::{AutoComments, CommentsStyle, Formatting, ObjectsStyle}; -use lemmy_api::match_websocket_operation; use lemmy_api_common::{ + context::LemmyContext, lemmy_db_views::structs::SiteView, request::build_user_agent, utils::{ @@ -14,9 +14,7 @@ use lemmy_api_common::{ local_site_rate_limit_to_rate_limit_config, }, websocket::chat_server::ChatServer, - LemmyContext, }; -use lemmy_api_crud::match_websocket_operation_crud; use lemmy_db_schema::{ source::secret::Secret, utils::{build_db_pool, get_database_url, run_migrations}, @@ -24,6 +22,11 @@ use lemmy_db_schema::{ use lemmy_routes::{feeds, images, nodeinfo, webfinger}; use lemmy_server::{ api_routes, + api_routes::{ + match_websocket_operation, + match_websocket_operation_apub, + match_websocket_operation_crud, + }, code_migrations::run_advanced_migrations, init_logging, root_span_builder::QuieterRootSpanBuilder, @@ -136,6 +139,7 @@ async fn main() -> Result<(), LemmyError> { pool.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)), + |c, i, o, d| Box::pin(match_websocket_operation_apub(c, i, o, d)), client.clone(), settings.clone(), secret.clone(),