diff --git a/Cargo.lock b/Cargo.lock index c083fba9d..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,13 +2043,11 @@ dependencies = [ "chrono", "diesel", "lemmy_api_common", - "lemmy_apub", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", "lemmy_db_views_moderator", "lemmy_utils", - "lemmy_websocket", "serde", "serde_json", "serial_test", @@ -2063,8 +2060,12 @@ dependencies = [ name = "lemmy_api_common" version = "0.16.5" dependencies = [ + "actix", "actix-rt", "actix-web", + "actix-web-actors", + "anyhow", + "background-jobs", "chrono", "diesel", "encoding", @@ -2073,13 +2074,20 @@ dependencies = [ "lemmy_db_views_actor", "lemmy_db_views_moderator", "lemmy_utils", + "opentelemetry 0.17.0", "percent-encoding", + "rand 0.8.5", "regex", "reqwest", "reqwest-middleware", "rosetta-i18n", "serde", + "serde_json", + "strum", + "strum_macros", + "tokio", "tracing", + "tracing-opentelemetry 0.17.4", "url", "webpage", ] @@ -2093,12 +2101,10 @@ dependencies = [ "async-trait", "bcrypt", "lemmy_api_common", - "lemmy_apub", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", "lemmy_utils", - "lemmy_websocket", "serde", "serde_json", "tracing", @@ -2131,7 +2137,6 @@ dependencies = [ "lemmy_db_views", "lemmy_db_views_actor", "lemmy_utils", - "lemmy_websocket", "once_cell", "reqwest", "reqwest-middleware", @@ -2223,12 +2228,10 @@ dependencies = [ "diesel", "futures", "lemmy_api_common", - "lemmy_apub", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", "lemmy_utils", - "lemmy_websocket", "once_cell", "reqwest", "reqwest-middleware", @@ -2260,7 +2263,6 @@ dependencies = [ "lemmy_db_schema", "lemmy_routes", "lemmy_utils", - "lemmy_websocket", "opentelemetry 0.17.0", "opentelemetry-otlp", "parking_lot", @@ -2269,6 +2271,7 @@ dependencies = [ "reqwest-retry", "reqwest-tracing", "serde", + "serde_json", "tracing", "tracing-actix-web", "tracing-error", @@ -2317,34 +2320,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "lemmy_websocket" -version = "0.16.5" -dependencies = [ - "actix", - "actix-web", - "actix-web-actors", - "anyhow", - "background-jobs", - "chrono", - "diesel", - "lemmy_api_common", - "lemmy_db_schema", - "lemmy_db_views", - "lemmy_db_views_actor", - "lemmy_utils", - "opentelemetry 0.17.0", - "rand 0.8.5", - "reqwest-middleware", - "serde", - "serde_json", - "strum", - "strum_macros", - "tokio", - "tracing", - "tracing-opentelemetry 0.17.4", -] - [[package]] name = "lettre" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index 67e85b27b..e83f0c837 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,6 @@ members = [ "crates/db_views", "crates/db_views_actor", "crates/db_views_actor", - "crates/websocket", "crates/routes" ] @@ -56,7 +55,6 @@ lemmy_apub = { version = "=0.16.5", path = "./crates/apub" } lemmy_utils = { version = "=0.16.5", path = "./crates/utils" } lemmy_db_schema = { version = "=0.16.5", path = "./crates/db_schema" } lemmy_api_common = { version = "=0.16.5", path = "./crates/api_common" } -lemmy_websocket = { version = "=0.16.5", path = "./crates/websocket" } lemmy_routes = { version = "=0.16.5", path = "./crates/routes" } lemmy_db_views = { version = "=0.16.5", path = "./crates/db_views" } lemmy_db_views_actor = { version = "=0.16.5", path = "./crates/db_views_actor" } @@ -116,7 +114,6 @@ lemmy_apub = { workspace = true } lemmy_utils = { workspace = true } lemmy_db_schema = { workspace = true } lemmy_api_common = { workspace = true } -lemmy_websocket = { workspace = true } lemmy_routes = { workspace = true } activitypub_federation = { workspace = true } diesel = { workspace = true } @@ -138,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 b707545b6..f7f1b0bf3 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -14,15 +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"] } -lemmy_websocket = { workspace = true } -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 6ca87f3cf..fba61ed13 100644 --- a/crates/api/src/comment/like.rs +++ b/crates/api/src/comment/like.rs @@ -2,14 +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}, -}; -use lemmy_apub::{ - fetcher::post_or_comment::PostOrComment, - protocol::activities::voting::{ - undo_vote::UndoVote, - vote::{Vote, VoteType}, - }, + websocket::{send::send_comment_ws_message, UserOperation}, }; use lemmy_db_schema::{ newtypes::LocalUserId, @@ -22,8 +17,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::{CommentView, LocalUserView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperation}; -use std::convert::TryInto; #[async_trait::async_trait(?Send)] impl Perform for CreateCommentLike { @@ -77,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 647f0ed53..03051f6cc 100644 --- a/crates/api/src/comment/save.rs +++ b/crates/api/src/comment/save.rs @@ -2,6 +2,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, SaveComment}, + context::LemmyContext, utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ @@ -10,7 +11,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::CommentView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for SaveComment { diff --git a/crates/api/src/comment_report/create.rs b/crates/api/src/comment_report/create.rs index 2533aba1c..bf3fec0a1 100644 --- a/crates/api/src/comment_report/create.rs +++ b/crates/api/src/comment_report/create.rs @@ -1,11 +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}, }; -use lemmy_apub::protocol::activities::community::report::Report; use lemmy_db_schema::{ source::{ comment_report::{CommentReport, CommentReportForm}, @@ -15,7 +15,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::{CommentReportView, CommentView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; /// Creates a comment report and notifies the moderators of the community #[async_trait::async_trait(?Send)] @@ -66,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 4a9041e99..8aa3fcbcd 100644 --- a/crates/api/src/comment_report/list.rs +++ b/crates/api/src/comment_report/list.rs @@ -2,11 +2,11 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ comment::{ListCommentReports, ListCommentReportsResponse}, + context::LemmyContext, utils::get_local_user_view_from_jwt, }; use lemmy_db_views::comment_report_view::CommentReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; /// Lists comment reports for a community if an id is supplied /// or returns all comment reports for communities a user moderates diff --git a/crates/api/src/comment_report/resolve.rs b/crates/api/src/comment_report/resolve.rs index 8055e9484..9df11fc23 100644 --- a/crates/api/src/comment_report/resolve.rs +++ b/crates/api/src/comment_report/resolve.rs @@ -2,12 +2,13 @@ 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}, }; use lemmy_db_schema::{source::comment_report::CommentReport, traits::Reportable}; use lemmy_db_views::structs::CommentReportView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; /// Resolves or unresolves a comment report and notifies the moderators of the community #[async_trait::async_trait(?Send)] diff --git a/crates/api/src/community/add_mod.rs b/crates/api/src/community/add_mod.rs index ff54edda7..ce3082f71 100644 --- a/crates/api/src/community/add_mod.rs +++ b/crates/api/src/community/add_mod.rs @@ -2,23 +2,19 @@ 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}, -}; -use lemmy_apub::{ - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::activities::community::{add_mod::AddMod, remove_mod::RemoveMod}, + websocket::{messages::SendCommunityRoomMessage, UserOperation}, }; use lemmy_db_schema::{ source::{ community::{Community, CommunityModerator, CommunityModeratorForm}, moderator::{ModAddCommunity, ModAddCommunityForm}, - person::Person, }, traits::{Crud, Joinable}, }; use lemmy_db_views_actor::structs::CommunityModeratorView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for AddModToCommunity { @@ -68,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 7b0897ad8..fb5e7fcfe 100644 --- a/crates/api/src/community/ban.rs +++ b/crates/api/src/community/ban.rs @@ -2,30 +2,24 @@ 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}, -}; -use lemmy_apub::{ - activities::block::SiteOrCommunity, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser}, + websocket::{messages::SendCommunityRoomMessage, UserOperation}, }; use lemmy_db_schema::{ source::{ community::{ - Community, CommunityFollower, CommunityFollowerForm, CommunityPersonBan, CommunityPersonBanForm, }, moderator::{ModBanFromCommunity, ModBanFromCommunityForm}, - person::Person, }, traits::{Bannable, Crud, Followable}, }; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, utils::naive_from_unix, ConnectionId}; -use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for BanFromCommunity { @@ -55,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 @@ -73,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 840d17665..914b5238e 100644 --- a/crates/api/src/community/block.rs +++ b/crates/api/src/community/block.rs @@ -2,19 +2,18 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ community::{BlockCommunity, BlockCommunityResponse}, + context::LemmyContext, utils::get_local_user_view_from_jwt, }; -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}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for BlockCommunity { @@ -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 fbabebc2c..dedfc9712 100644 --- a/crates/api/src/community/follow.rs +++ b/crates/api/src/community/follow.rs @@ -2,22 +2,15 @@ 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}, }; -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}, traits::{Crud, Followable}, }; use lemmy_db_views_actor::structs::CommunityView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for FollowCommunity { @@ -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 111a89d01..94ce7d745 100644 --- a/crates/api/src/community/hide.rs +++ b/crates/api/src/community/hide.rs @@ -2,9 +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}, }; -use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ source::{ community::{Community, CommunityUpdateForm}, @@ -13,7 +14,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl Perform for HideCommunity { @@ -44,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 5da0d8e3e..7ca174e4c 100644 --- a/crates/api/src/community/transfer.rs +++ b/crates/api/src/community/transfer.rs @@ -3,6 +3,7 @@ use actix_web::web::Data; use anyhow::Context; use lemmy_api_common::{ community::{GetCommunityResponse, TransferCommunity}, + context::LemmyContext, utils::get_local_user_view_from_jwt, }; use lemmy_db_schema::{ @@ -14,7 +15,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView, PersonViewSafe}; use lemmy_utils::{error::LemmyError, location_info, ConnectionId}; -use lemmy_websocket::LemmyContext; // TODO: we dont do anything for federation here, it should be updated the next time the community // gets fetched. i hope we can get rid of the community creator role soon. diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index dbff533ea..5904a9b9b 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,77 +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::{CommunityJoin, ModJoin, PostJoin, UserJoin}, -}; +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 lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation}; -use serde::Deserialize; mod comment; mod comment_report; @@ -95,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 ceca80f90..78357f0c5 100644 --- a/crates/api/src/local_user/add_admin.rs +++ b/crates/api/src/local_user/add_admin.rs @@ -1,8 +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}, }; use lemmy_db_schema::{ source::{ @@ -13,7 +15,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for AddAdmin { diff --git a/crates/api/src/local_user/ban_person.rs b/crates/api/src/local_user/ban_person.rs index 2482e408e..0bb252349 100644 --- a/crates/api/src/local_user/ban_person.rs +++ b/crates/api/src/local_user/ban_person.rs @@ -1,12 +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}, -}; -use lemmy_apub::{ - activities::block::SiteOrCommunity, - protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser}, + websocket::{messages::SendAllMessage, UserOperation}, }; use lemmy_db_schema::{ source::{ @@ -15,10 +13,8 @@ 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}; -use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for BanPerson { @@ -78,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 44bd668f7..b57ecd551 100644 --- a/crates/api/src/local_user/block.rs +++ b/crates/api/src/local_user/block.rs @@ -1,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{BlockPerson, BlockPersonResponse}, utils::get_local_user_view_from_jwt, }; @@ -10,7 +11,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for BlockPerson { diff --git a/crates/api/src/local_user/change_password.rs b/crates/api/src/local_user/change_password.rs index 38fac32b5..2d0fd30e5 100644 --- a/crates/api/src/local_user/change_password.rs +++ b/crates/api/src/local_user/change_password.rs @@ -2,12 +2,12 @@ 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}, }; use lemmy_db_schema::source::local_user::LocalUser; use lemmy_utils::{claims::Claims, error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for ChangePassword { 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 3ac48252e..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,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{LoginResponse, PasswordChangeAfterReset}, utils::password_length_check, }; @@ -10,7 +11,6 @@ use lemmy_db_schema::source::{ }; use lemmy_db_views::structs::SiteView; use lemmy_utils::{claims::Claims, error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for PasswordChangeAfterReset { diff --git a/crates/api/src/local_user/get_captcha.rs b/crates/api/src/local_user/get_captcha.rs index 3d1b88845..50a2bdba2 100644 --- a/crates/api/src/local_user/get_captcha.rs +++ b/crates/api/src/local_user/get_captcha.rs @@ -2,10 +2,13 @@ use crate::{captcha_as_wav_base64, Perform}; use actix_web::web::Data; use captcha::{gen, Difficulty}; use chrono::Duration; -use lemmy_api_common::person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse}; +use lemmy_api_common::{ + context::LemmyContext, + person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse}, + websocket::messages::CaptchaItem, +}; use lemmy_db_schema::{source::local_site::LocalSite, utils::naive_now}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::CaptchaItem, LemmyContext}; #[async_trait::async_trait(?Send)] impl Perform for GetCaptcha { diff --git a/crates/api/src/local_user/list_banned.rs b/crates/api/src/local_user/list_banned.rs index 16df72ccc..60eb32b35 100644 --- a/crates/api/src/local_user/list_banned.rs +++ b/crates/api/src/local_user/list_banned.rs @@ -1,12 +1,12 @@ 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}, }; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for GetBannedPersons { diff --git a/crates/api/src/local_user/login.rs b/crates/api/src/local_user/login.rs index 613543877..c60c0dcdf 100644 --- a/crates/api/src/local_user/login.rs +++ b/crates/api/src/local_user/login.rs @@ -2,13 +2,13 @@ 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}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::{claims::Claims, error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for Login { diff --git a/crates/api/src/local_user/notifications/list_mentions.rs b/crates/api/src/local_user/notifications/list_mentions.rs index d231f7184..c03e9d167 100644 --- a/crates/api/src/local_user/notifications/list_mentions.rs +++ b/crates/api/src/local_user/notifications/list_mentions.rs @@ -1,12 +1,12 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetPersonMentions, GetPersonMentionsResponse}, utils::get_local_user_view_from_jwt, }; use lemmy_db_views_actor::person_mention_view::PersonMentionQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for GetPersonMentions { diff --git a/crates/api/src/local_user/notifications/list_replies.rs b/crates/api/src/local_user/notifications/list_replies.rs index 102229985..585db5e95 100644 --- a/crates/api/src/local_user/notifications/list_replies.rs +++ b/crates/api/src/local_user/notifications/list_replies.rs @@ -1,12 +1,12 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetReplies, GetRepliesResponse}, utils::get_local_user_view_from_jwt, }; use lemmy_db_views_actor::comment_reply_view::CommentReplyQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for GetReplies { 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 3b8ad0f44..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,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetRepliesResponse, MarkAllAsRead}, utils::get_local_user_view_from_jwt, }; @@ -10,7 +11,6 @@ use lemmy_db_schema::source::{ private_message::PrivateMessage, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for MarkAllAsRead { 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 c42e294a8..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,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{MarkPersonMentionAsRead, PersonMentionResponse}, utils::get_local_user_view_from_jwt, }; @@ -10,7 +11,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views_actor::structs::PersonMentionView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for MarkPersonMentionAsRead { 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 2ec5fd806..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,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{CommentReplyResponse, MarkCommentReplyAsRead}, utils::get_local_user_view_from_jwt, }; @@ -10,7 +11,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views_actor::structs::CommentReplyView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for MarkCommentReplyAsRead { diff --git a/crates/api/src/local_user/notifications/unread_count.rs b/crates/api/src/local_user/notifications/unread_count.rs index 47d826fdd..715ccd286 100644 --- a/crates/api/src/local_user/notifications/unread_count.rs +++ b/crates/api/src/local_user/notifications/unread_count.rs @@ -1,13 +1,13 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetUnreadCount, GetUnreadCountResponse}, utils::get_local_user_view_from_jwt, }; use lemmy_db_views::structs::PrivateMessageView; use lemmy_db_views_actor::structs::{CommentReplyView, PersonMentionView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for GetUnreadCount { diff --git a/crates/api/src/local_user/report_count.rs b/crates/api/src/local_user/report_count.rs index 1372e4caa..b59a06490 100644 --- a/crates/api/src/local_user/report_count.rs +++ b/crates/api/src/local_user/report_count.rs @@ -1,12 +1,12 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{GetReportCount, GetReportCountResponse}, utils::get_local_user_view_from_jwt, }; use lemmy_db_views::structs::{CommentReportView, PostReportView, PrivateMessageReportView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for GetReportCount { diff --git a/crates/api/src/local_user/reset_password.rs b/crates/api/src/local_user/reset_password.rs index 078d55ec3..5d0e9d88b 100644 --- a/crates/api/src/local_user/reset_password.rs +++ b/crates/api/src/local_user/reset_password.rs @@ -1,12 +1,12 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{PasswordReset, PasswordResetResponse}, utils::send_password_reset_email, }; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for PasswordReset { diff --git a/crates/api/src/local_user/save_settings.rs b/crates/api/src/local_user/save_settings.rs index 4aa3a7437..6672a67b0 100644 --- a/crates/api/src/local_user/save_settings.rs +++ b/crates/api/src/local_user/save_settings.rs @@ -1,6 +1,7 @@ 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}, }; @@ -20,7 +21,6 @@ use lemmy_utils::{ utils::{is_valid_display_name, is_valid_matrix_id}, ConnectionId, }; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for SaveUserSettings { diff --git a/crates/api/src/local_user/verify_email.rs b/crates/api/src/local_user/verify_email.rs index 73db4bea5..fb82b716b 100644 --- a/crates/api/src/local_user/verify_email.rs +++ b/crates/api/src/local_user/verify_email.rs @@ -1,6 +1,7 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, person::{VerifyEmail, VerifyEmailResponse}, utils::send_email_verification_success, }; @@ -13,7 +14,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for VerifyEmail { diff --git a/crates/api/src/post/get_link_metadata.rs b/crates/api/src/post/get_link_metadata.rs index 54e2cfe7c..eaf111eba 100644 --- a/crates/api/src/post/get_link_metadata.rs +++ b/crates/api/src/post/get_link_metadata.rs @@ -1,11 +1,11 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{GetSiteMetadata, GetSiteMetadataResponse}, request::fetch_site_metadata, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for GetSiteMetadata { diff --git a/crates/api/src/post/like.rs b/crates/api/src/post/like.rs index ec2edc33e..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, @@ -9,14 +10,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, mark_post_as_read, }, -}; -use lemmy_apub::{ - fetcher::post_or_comment::PostOrComment, - objects::post::ApubPost, - protocol::activities::voting::{ - undo_vote::UndoVote, - vote::{Vote, VoteType}, - }, + websocket::{send::send_post_ws_message, UserOperation}, }; use lemmy_db_schema::{ source::{ @@ -26,7 +20,6 @@ use lemmy_db_schema::{ traits::{Crud, Likeable}, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for CreatePostLike { @@ -48,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?; @@ -64,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 { @@ -74,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 ae726ee92..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, @@ -8,10 +9,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, is_mod_or_admin, }, -}; -use lemmy_apub::{ - objects::post::ApubPost, - protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType}, + websocket::{send::send_post_ws_message, UserOperation}, }; use lemmy_db_schema::{ source::{ @@ -21,7 +19,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for LockPost { @@ -59,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 { @@ -75,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 18f86521c..9fdf01b12 100644 --- a/crates/api/src/post/mark_read.rs +++ b/crates/api/src/post/mark_read.rs @@ -1,12 +1,12 @@ 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}, }; use lemmy_db_views::structs::PostView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for MarkPostAsRead { diff --git a/crates/api/src/post/save.rs b/crates/api/src/post/save.rs index 0a240f9eb..b36f844b6 100644 --- a/crates/api/src/post/save.rs +++ b/crates/api/src/post/save.rs @@ -1,6 +1,7 @@ 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}, }; @@ -10,7 +11,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::PostView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for SavePost { diff --git a/crates/api/src/post/sticky.rs b/crates/api/src/post/sticky.rs index 384ba52d6..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, @@ -8,10 +9,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, is_mod_or_admin, }, -}; -use lemmy_apub::{ - objects::post::ApubPost, - protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType}, + websocket::{send::send_post_ws_message, UserOperation}, }; use lemmy_db_schema::{ source::{ @@ -21,7 +19,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for StickyPost { @@ -59,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 { @@ -76,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 ca4113a3b..71be43623 100644 --- a/crates/api/src/post_report/create.rs +++ b/crates/api/src/post_report/create.rs @@ -1,11 +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}, }; -use lemmy_apub::protocol::activities::community::report::Report; use lemmy_db_schema::{ source::{ local_site::LocalSite, @@ -15,7 +15,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::{PostReportView, PostView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; /// Creates a post report and notifies the moderators of the community #[async_trait::async_trait(?Send)] @@ -66,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 7a79f04b7..2feed7ed2 100644 --- a/crates/api/src/post_report/list.rs +++ b/crates/api/src/post_report/list.rs @@ -1,12 +1,12 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, post::{ListPostReports, ListPostReportsResponse}, utils::get_local_user_view_from_jwt, }; use lemmy_db_views::post_report_view::PostReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; /// Lists post reports for a community if an id is supplied /// or returns all post reports for communities a user moderates diff --git a/crates/api/src/post_report/resolve.rs b/crates/api/src/post_report/resolve.rs index 687bdcce1..0e2b9e16a 100644 --- a/crates/api/src/post_report/resolve.rs +++ b/crates/api/src/post_report/resolve.rs @@ -1,13 +1,14 @@ 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}, }; use lemmy_db_schema::{source::post_report::PostReport, traits::Reportable}; use lemmy_db_views::structs::PostReportView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; /// Resolves or unresolves a post report and notifies the moderators of the community #[async_trait::async_trait(?Send)] diff --git a/crates/api/src/private_message/mark_read.rs b/crates/api/src/private_message/mark_read.rs index 0b7bb676a..9c3c3d8ae 100644 --- a/crates/api/src/private_message/mark_read.rs +++ b/crates/api/src/private_message/mark_read.rs @@ -1,15 +1,16 @@ 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}, }; use lemmy_db_schema::{ source::private_message::{PrivateMessage, PrivateMessageUpdateForm}, traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for MarkPrivateMessageAsRead { diff --git a/crates/api/src/private_message_report/create.rs b/crates/api/src/private_message_report/create.rs index 490fd55bf..66875c614 100644 --- a/crates/api/src/private_message_report/create.rs +++ b/crates/api/src/private_message_report/create.rs @@ -1,8 +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}, }; use lemmy_db_schema::{ newtypes::CommunityId, @@ -15,7 +17,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::PrivateMessageReportView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for CreatePrivateMessageReport { diff --git a/crates/api/src/private_message_report/list.rs b/crates/api/src/private_message_report/list.rs index 0279cb83b..98c2d9269 100644 --- a/crates/api/src/private_message_report/list.rs +++ b/crates/api/src/private_message_report/list.rs @@ -1,12 +1,12 @@ 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}, }; use lemmy_db_views::private_message_report_view::PrivateMessageReportQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for ListPrivateMessageReports { diff --git a/crates/api/src/private_message_report/resolve.rs b/crates/api/src/private_message_report/resolve.rs index a7af798ad..2a3f677ad 100644 --- a/crates/api/src/private_message_report/resolve.rs +++ b/crates/api/src/private_message_report/resolve.rs @@ -1,8 +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}, }; use lemmy_db_schema::{ newtypes::CommunityId, @@ -11,7 +13,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::PrivateMessageReportView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; #[async_trait::async_trait(?Send)] impl Perform for ResolvePrivateMessageReport { diff --git a/crates/api/src/site/leave_admin.rs b/crates/api/src/site/leave_admin.rs index 4a6687b32..7a75db51d 100644 --- a/crates/api/src/site/leave_admin.rs +++ b/crates/api/src/site/leave_admin.rs @@ -1,6 +1,7 @@ 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}, }; @@ -17,7 +18,6 @@ use lemmy_db_schema::{ use lemmy_db_views::structs::SiteView; use lemmy_db_views_actor::structs::PersonViewSafe; use lemmy_utils::{error::LemmyError, version, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for LeaveAdmin { 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 f1ab9f45c..5e1c71a70 100644 --- a/crates/api/src/site/mod_log.rs +++ b/crates/api/src/site/mod_log.rs @@ -1,6 +1,7 @@ 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}, }; @@ -28,7 +29,6 @@ use lemmy_db_views_moderator::structs::{ ModlogListParams, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; use ModlogActionType::*; #[async_trait::async_trait(?Send)] diff --git a/crates/api/src/site/purge/comment.rs b/crates/api/src/site/purge/comment.rs index d5a11216f..71d2c7889 100644 --- a/crates/api/src/site/purge/comment.rs +++ b/crates/api/src/site/purge/comment.rs @@ -1,6 +1,7 @@ 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}, }; @@ -12,7 +13,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for PurgeComment { diff --git a/crates/api/src/site/purge/community.rs b/crates/api/src/site/purge/community.rs index 74373d81f..e3a673b74 100644 --- a/crates/api/src/site/purge/community.rs +++ b/crates/api/src/site/purge/community.rs @@ -1,6 +1,7 @@ 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}, @@ -13,7 +14,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for PurgeCommunity { diff --git a/crates/api/src/site/purge/person.rs b/crates/api/src/site/purge/person.rs index f5aad6e1d..658e50b6d 100644 --- a/crates/api/src/site/purge/person.rs +++ b/crates/api/src/site/purge/person.rs @@ -1,6 +1,7 @@ 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}, @@ -13,7 +14,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for PurgePerson { diff --git a/crates/api/src/site/purge/post.rs b/crates/api/src/site/purge/post.rs index ee5adf723..aa2e74839 100644 --- a/crates/api/src/site/purge/post.rs +++ b/crates/api/src/site/purge/post.rs @@ -1,6 +1,7 @@ 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}, @@ -13,7 +14,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for PurgePost { diff --git a/crates/api/src/site/registration_applications/approve.rs b/crates/api/src/site/registration_applications/approve.rs index bb1252598..61a686899 100644 --- a/crates/api/src/site/registration_applications/approve.rs +++ b/crates/api/src/site/registration_applications/approve.rs @@ -1,6 +1,7 @@ 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}, }; @@ -14,7 +15,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for ApproveRegistrationApplication { diff --git a/crates/api/src/site/registration_applications/list.rs b/crates/api/src/site/registration_applications/list.rs index 3d9ed326e..7be2e2e8e 100644 --- a/crates/api/src/site/registration_applications/list.rs +++ b/crates/api/src/site/registration_applications/list.rs @@ -1,13 +1,13 @@ 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}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::registration_application_view::RegistrationApplicationQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; /// Lists registration applications, filterable by undenied only. #[async_trait::async_trait(?Send)] diff --git a/crates/api/src/site/registration_applications/unread_count.rs b/crates/api/src/site/registration_applications/unread_count.rs index 7fb8906af..fe33d17c8 100644 --- a/crates/api/src/site/registration_applications/unread_count.rs +++ b/crates/api/src/site/registration_applications/unread_count.rs @@ -1,13 +1,13 @@ 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}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::RegistrationApplicationView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl Perform for GetUnreadRegistrationApplicationCount { diff --git a/crates/api/src/websocket.rs b/crates/api/src/websocket.rs index 391b84e0d..ca755bde9 100644 --- a/crates/api/src/websocket.rs +++ b/crates/api/src/websocket.rs @@ -1,23 +1,23 @@ use crate::Perform; use actix_web::web::Data; use lemmy_api_common::{ + context::LemmyContext, utils::get_local_user_view_from_jwt, websocket::{ - CommunityJoin, - CommunityJoinResponse, - ModJoin, - ModJoinResponse, - PostJoin, - PostJoinResponse, - UserJoin, - UserJoinResponse, + messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom}, + structs::{ + CommunityJoin, + CommunityJoinResponse, + ModJoin, + ModJoinResponse, + PostJoin, + PostJoinResponse, + UserJoin, + UserJoinResponse, + }, }, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{ - messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom}, - LemmyContext, -}; #[async_trait::async_trait(?Send)] impl Perform for UserJoin { diff --git a/crates/api_common/Cargo.toml b/crates/api_common/Cargo.toml index bfbaa8e25..a4c80da52 100644 --- a/crates/api_common/Cargo.toml +++ b/crates/api_common/Cargo.toml @@ -36,6 +36,17 @@ rosetta-i18n = { workspace = true, optional = true } percent-encoding = { workspace = true, optional = true } webpage = { version = "1.4.0", default-features = false, features = ["serde"], optional = true } encoding = { version = "0.2.33", optional = true } +rand = { workspace = true } +serde_json = { workspace = true } +actix = { workspace = true } +anyhow = { workspace = true } +tokio = { workspace = true } +strum = { workspace = true } +strum_macros = { workspace = true } +opentelemetry = { workspace = true } +tracing-opentelemetry = { workspace = true } +actix-web-actors = { version = "4.1.0", default-features = false } +background-jobs = "0.13.0" [dev-dependencies] actix-rt = { workspace = true } 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 ef907f88a..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,8 +11,11 @@ pub mod sensitive; pub mod site; #[cfg(feature = "full")] pub mod utils; +#[cfg(feature = "full")] pub mod websocket; +#[macro_use] +extern crate strum_macros; pub extern crate lemmy_db_schema; pub extern crate lemmy_db_views; pub extern crate lemmy_db_views_actor; 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/websocket/src/chat_server.rs b/crates/api_common/src/websocket/chat_server.rs similarity index 90% rename from crates/websocket/src/chat_server.rs rename to crates/api_common/src/websocket/chat_server.rs index 8577e0429..b669a4fd3 100644 --- a/crates/websocket/src/chat_server.rs +++ b/crates/api_common/src/websocket/chat_server.rs @@ -1,14 +1,18 @@ use crate::{ - messages::{CaptchaItem, StandardMessage, WsMessage}, - serialize_websocket_message, - LemmyContext, - OperationType, - UserOperation, - UserOperationCrud, + comment::CommentResponse, + context::LemmyContext, + post::PostResponse, + websocket::{ + messages::{CaptchaItem, StandardMessage, WsMessage}, + serialize_websocket_message, + OperationType, + UserOperation, + UserOperationApub, + UserOperationCrud, + }, }; use actix::prelude::*; use anyhow::Context as acontext; -use lemmy_api_common::{comment::CommentResponse, post::PostResponse}; use lemmy_db_schema::{ newtypes::{CommunityId, LocalUserId, PostId}, source::secret::Secret, @@ -47,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 { @@ -81,6 +92,7 @@ pub struct ChatServer { message_handler: MessageHandlerType, message_handler_crud: MessageHandlerCrudType, + message_handler_apub: MessageHandlerApubType, /// An HTTP Client client: ClientWithMiddleware, @@ -102,6 +114,7 @@ impl ChatServer { pool: DbPool, message_handler: MessageHandlerType, message_handler_crud: MessageHandlerCrudType, + message_handler_apub: MessageHandlerApubType, client: ClientWithMiddleware, settings: Settings, secret: Secret, @@ -118,6 +131,7 @@ impl ChatServer { captchas: Vec::new(), message_handler, message_handler_crud, + message_handler_apub, client, settings, secret, @@ -450,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)?; @@ -479,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/websocket/src/handlers.rs b/crates/api_common/src/websocket/handlers.rs similarity index 99% rename from crates/websocket/src/handlers.rs rename to crates/api_common/src/websocket/handlers.rs index 90ef01a4b..6f3d164c9 100644 --- a/crates/websocket/src/handlers.rs +++ b/crates/api_common/src/websocket/handlers.rs @@ -1,4 +1,4 @@ -use crate::{ +use crate::websocket::{ chat_server::{ChatServer, SessionInfo}, messages::{ CaptchaItem, diff --git a/crates/websocket/src/messages.rs b/crates/api_common/src/websocket/messages.rs similarity index 97% rename from crates/websocket/src/messages.rs rename to crates/api_common/src/websocket/messages.rs index 21b6ac4b7..f81124161 100644 --- a/crates/websocket/src/messages.rs +++ b/crates/api_common/src/websocket/messages.rs @@ -1,6 +1,5 @@ -use crate::UserOperation; +use crate::{comment::CommentResponse, post::PostResponse, websocket::UserOperation}; use actix::{prelude::*, Recipient}; -use lemmy_api_common::{comment::CommentResponse, post::PostResponse}; use lemmy_db_schema::newtypes::{CommunityId, LocalUserId, PostId}; use lemmy_utils::{ConnectionId, IpAddr}; use serde::{Deserialize, Serialize}; diff --git a/crates/websocket/src/lib.rs b/crates/api_common/src/websocket/mod.rs similarity index 58% rename from crates/websocket/src/lib.rs rename to crates/api_common/src/websocket/mod.rs index e73e784e2..430027cfa 100644 --- a/crates/websocket/src/lib.rs +++ b/crates/api_common/src/websocket/mod.rs @@ -1,15 +1,4 @@ -#[macro_use] -extern crate strum_macros; - -use crate::chat_server::ChatServer; -use actix::Addr; -use lemmy_db_schema::{source::secret::Secret, utils::DbPool}; -use lemmy_utils::{ - error::LemmyError, - rate_limit::RateLimitCell, - settings::{structs::Settings, SETTINGS}, -}; -use reqwest_middleware::ClientWithMiddleware; +use lemmy_utils::error::LemmyError; use serde::Serialize; pub mod chat_server; @@ -17,66 +6,7 @@ pub mod handlers; pub mod messages; pub mod routes; pub mod send; - -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 mod structs; #[derive(Serialize)] struct WebsocketResponse { @@ -133,8 +63,6 @@ pub enum UserOperation { ApproveRegistrationApplication, BanPerson, GetBannedPersons, - Search, - ResolveObject, MarkAllAsRead, SaveUserSettings, TransferCommunity, @@ -168,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, @@ -197,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/websocket/src/routes.rs b/crates/api_common/src/websocket/routes.rs similarity index 97% rename from crates/websocket/src/routes.rs rename to crates/api_common/src/websocket/routes.rs index a3b1b0460..936dc9998 100644 --- a/crates/websocket/src/routes.rs +++ b/crates/api_common/src/websocket/routes.rs @@ -1,7 +1,9 @@ use crate::{ - chat_server::ChatServer, - messages::{Connect, Disconnect, StandardMessage, WsMessage}, - LemmyContext, + context::LemmyContext, + websocket::{ + chat_server::ChatServer, + messages::{Connect, Disconnect, StandardMessage, WsMessage}, + }, }; use actix::prelude::*; use actix_web::{web, Error, HttpRequest, HttpResponse}; diff --git a/crates/websocket/src/send.rs b/crates/api_common/src/websocket/send.rs similarity index 98% rename from crates/websocket/src/send.rs rename to crates/api_common/src/websocket/send.rs index 2793534f4..cd53955f9 100644 --- a/crates/websocket/src/send.rs +++ b/crates/api_common/src/websocket/send.rs @@ -1,14 +1,14 @@ use crate::{ - messages::{SendComment, SendCommunityRoomMessage, SendPost, SendUserRoomMessage}, - LemmyContext, - OperationType, -}; -use lemmy_api_common::{ comment::CommentResponse, community::CommunityResponse, + context::LemmyContext, post::PostResponse, private_message::PrivateMessageResponse, utils::{check_person_block, get_interface_language, send_email_to_user}, + websocket::{ + messages::{SendComment, SendCommunityRoomMessage, SendPost, SendUserRoomMessage}, + OperationType, + }, }; use lemmy_db_schema::{ newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId}, diff --git a/crates/api_common/src/websocket.rs b/crates/api_common/src/websocket/structs.rs similarity index 100% rename from crates/api_common/src/websocket.rs rename to crates/api_common/src/websocket/structs.rs diff --git a/crates/api_crud/Cargo.toml b/crates/api_crud/Cargo.toml index b4f68a8df..2d1774463 100644 --- a/crates/api_crud/Cargo.toml +++ b/crates/api_crud/Cargo.toml @@ -9,13 +9,11 @@ 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"] } lemmy_db_views_actor = { workspace = true, features = ["full"] } lemmy_api_common = { workspace = true, features = ["full"] } -lemmy_websocket = { workspace = true } activitypub_federation = { workspace = true } bcrypt = { workspace = true } serde_json = { workspace = true } diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index f027b0fe2..8c61a0444 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -2,20 +2,21 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ comment::{CommentResponse, CreateComment}, + 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, }, -}; -use lemmy_apub::{ - generate_local_apub_endpoint, - objects::comment::ApubComment, - protocol::activities::{create_or_update::note::CreateOrUpdateNote, CreateOrUpdateType}, - EndpointType, }; use lemmy_db_schema::{ source::{ @@ -32,11 +33,6 @@ use lemmy_utils::{ utils::{remove_slurs, scrape_text_for_mentions}, ConnectionId, }; -use lemmy_websocket::{ - send::{send_comment_ws_message, send_local_notifs}, - LemmyContext, - UserOperationCrud, -}; #[async_trait::async_trait(?Send)] impl PerformCrud for CreateComment { @@ -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 549d2f366..211d04776 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -2,24 +2,22 @@ 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, + }, }; -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, }; use lemmy_db_views::structs::CommentView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{ - send::{send_comment_ws_message, send_local_notifs}, - LemmyContext, - UserOperationCrud, -}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeleteComment { @@ -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 7d5779ffe..c0136f06c 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -2,12 +2,12 @@ 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}, }; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_db_views::structs::CommentView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl PerformCrud for GetComment { diff --git a/crates/api_crud/src/comment/remove.rs b/crates/api_crud/src/comment/remove.rs index c1e581e0c..1032f54c9 100644 --- a/crates/api_crud/src/comment/remove.rs +++ b/crates/api_crud/src/comment/remove.rs @@ -2,13 +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, + }, }; -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, }, @@ -16,11 +19,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::CommentView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{ - send::{send_comment_ws_message, send_local_notifs}, - LemmyContext, - UserOperationCrud, -}; #[async_trait::async_trait(?Send)] impl PerformCrud for RemoveComment { @@ -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 0d89acc29..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, @@ -10,10 +11,10 @@ use lemmy_api_common::{ is_mod_or_admin, local_site_to_slur_regex, }, -}; -use lemmy_apub::protocol::activities::{ - create_or_update::note::CreateOrUpdateNote, - CreateOrUpdateType, + websocket::{ + send::{send_comment_ws_message, send_local_notifs}, + UserOperationCrud, + }, }; use lemmy_db_schema::{ source::{ @@ -29,11 +30,6 @@ use lemmy_utils::{ utils::{remove_slurs, scrape_text_for_mentions}, ConnectionId, }; -use lemmy_websocket::{ - send::{send_comment_ws_message, send_local_notifs}, - LemmyContext, - UserOperationCrud, -}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditComment { @@ -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 437671eef..cf894edbd 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -1,17 +1,19 @@ 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}, - utils::{get_local_user_view_from_jwt, is_admin, local_site_to_slur_regex}, -}; -use lemmy_apub::{ - generate_followers_url, - generate_inbox_url, - generate_local_apub_endpoint, - generate_shared_inbox_url, - objects::community::ApubCommunity, - EndpointType, + 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_db_schema::{ source::community::{ @@ -22,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; @@ -32,7 +34,6 @@ use lemmy_utils::{ utils::{check_slurs, check_slurs_opt, is_valid_actor_name}, ConnectionId, }; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl PerformCrud for CreateCommunity { @@ -75,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 41f14b527..84de55477 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -2,16 +2,16 @@ 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}, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::community::{Community, CommunityUpdateForm}, traits::Crud, }; use lemmy_db_views_actor::structs::CommunityModeratorView; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeleteCommunity { @@ -40,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() @@ -59,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 37a9d88a4..4d2e7046f 100644 --- a/crates/api_crud/src/community/list.rs +++ b/crates/api_crud/src/community/list.rs @@ -2,12 +2,12 @@ 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}, }; use lemmy_db_schema::{source::local_site::LocalSite, traits::DeleteableOrRemoveable}; use lemmy_db_views_actor::community_view::CommunityQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl PerformCrud for ListCommunities { 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 1977f5cd1..215b39cf4 100644 --- a/crates/api_crud/src/community/remove.rs +++ b/crates/api_crud/src/community/remove.rs @@ -2,9 +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}, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::{ community::{Community, CommunityUpdateForm}, @@ -13,7 +14,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::{error::LemmyError, utils::naive_from_unix, ConnectionId}; -use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for RemoveCommunity { @@ -35,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() @@ -65,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 8e60b3f88..9059a4a6f 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -2,9 +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}, }; -use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ newtypes::PersonId, source::{ @@ -17,7 +18,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views_actor::structs::CommunityModeratorView; use lemmy_utils::{error::LemmyError, utils::check_slurs_opt, ConnectionId}; -use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditCommunity { @@ -73,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 b50d3cd27..d37dfbee2 100644 --- a/crates/api_crud/src/lib.rs +++ b/crates/api_crud/src/lib.rs @@ -1,27 +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}, -}; +use actix_web::web::Data; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperationCrud}; -use serde::Deserialize; mod comment; mod community; @@ -40,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 cad8b28e2..af62135e2 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -1,22 +1,20 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ + 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, }, -}; -use lemmy_apub::{ - generate_local_apub_endpoint, - objects::post::ApubPost, - protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType}, - EndpointType, + websocket::{send::send_post_ws_message, UserOperationCrud}, }; use lemmy_db_schema::{ impls::actor_language::default_post_language, @@ -34,7 +32,6 @@ use lemmy_utils::{ utils::{check_slurs, check_slurs_opt, clean_url_params, is_valid_post_title}, ConnectionId, }; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; use tracing::{warn, Instrument}; use url::Url; use webmention::{Webmention, WebmentionError}; @@ -173,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 a0b930084..57e5adb15 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -1,19 +1,16 @@ 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}, }; -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}; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeletePost { @@ -53,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(), @@ -69,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 5e2582a07..c6747c5e8 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -1,8 +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, }; use lemmy_db_schema::{ aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm}, @@ -12,7 +14,6 @@ use lemmy_db_schema::{ use lemmy_db_views::structs::PostView; use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext}; #[async_trait::async_trait(?Send)] impl PerformCrud for GetPost { diff --git a/crates/api_crud/src/post/remove.rs b/crates/api_crud/src/post/remove.rs index b062bc653..66af2ca95 100644 --- a/crates/api_crud/src/post/remove.rs +++ b/crates/api_crud/src/post/remove.rs @@ -1,20 +1,19 @@ 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}, }; -use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects}; use lemmy_db_schema::{ source::{ - community::Community, moderator::{ModRemovePost, ModRemovePostForm}, post::{Post, PostUpdateForm}, }, traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for RemovePost { @@ -51,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(), @@ -76,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 11b566bc9..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::{ @@ -9,10 +10,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, local_site_to_slur_regex, }, -}; -use lemmy_apub::protocol::activities::{ - create_or_update::page::CreateOrUpdatePage, - CreateOrUpdateType, + websocket::{send::send_post_ws_message, UserOperationCrud}, }; use lemmy_db_schema::{ source::{ @@ -28,7 +26,6 @@ use lemmy_utils::{ utils::{check_slurs_opt, clean_url_params, is_valid_post_title}, ConnectionId, }; -use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditPost { @@ -108,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 35bc09e22..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::{ + 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, }, -}; -use lemmy_apub::{ - generate_local_apub_endpoint, - protocol::activities::{ - create_or_update::chat_message::CreateOrUpdateChatMessage, - CreateOrUpdateType, - }, - EndpointType, + websocket::{send::send_pm_ws_message, UserOperationCrud}, }; use lemmy_db_schema::{ source::{ @@ -27,7 +23,6 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::LocalUserView; use lemmy_utils::{error::LemmyError, utils::remove_slurs, ConnectionId}; -use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for CreatePrivateMessage { @@ -75,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() @@ -85,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 51cded6d1..4f58065a3 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -1,16 +1,16 @@ 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}, }; -use lemmy_apub::activities::deletion::send_apub_delete_private_message; use lemmy_db_schema::{ source::private_message::{PrivateMessage, PrivateMessageUpdateForm}, traits::Crud, }; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeletePrivateMessage { @@ -36,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() @@ -46,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 f0741398e..286802745 100644 --- a/crates/api_crud/src/private_message/read.rs +++ b/crates/api_crud/src/private_message/read.rs @@ -1,13 +1,13 @@ 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, }; use lemmy_db_schema::traits::DeleteableOrRemoveable; use lemmy_db_views::private_message_view::PrivateMessageQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl PerformCrud for GetPrivateMessages { diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index 5f79735e9..f6f8c8f03 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -1,12 +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}, -}; -use lemmy_apub::protocol::activities::{ - create_or_update::chat_message::CreateOrUpdateChatMessage, - CreateOrUpdateType, + websocket::{send::send_pm_ws_message, UserOperationCrud}, }; use lemmy_db_schema::{ source::{ @@ -17,7 +15,6 @@ use lemmy_db_schema::{ utils::naive_now, }; use lemmy_utils::{error::LemmyError, utils::remove_slurs, ConnectionId}; -use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditPrivateMessage { @@ -44,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() @@ -55,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 8b2b9c18b..d04343b0c 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -2,8 +2,10 @@ use crate::PerformCrud; use activitypub_federation::core::signatures::generate_actor_keypair; use actix_web::web::Data; use lemmy_api_common::{ + 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, @@ -11,7 +13,6 @@ use lemmy_api_common::{ site_description_length_check, }, }; -use lemmy_apub::generate_site_inbox_url; use lemmy_db_schema::{ newtypes::DbUrl, source::{ @@ -28,7 +29,6 @@ use lemmy_utils::{ utils::{check_application_question, check_slurs, check_slurs_opt}, ConnectionId, }; -use lemmy_websocket::LemmyContext; use url::Url; #[async_trait::async_trait(?Send)] diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index dbf64c6c3..55dcd8fb2 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -1,8 +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, }; use lemmy_db_schema::source::{actor_language::SiteLanguage, language::Language, tagline::Tagline}; use lemmy_db_views::structs::{LocalUserDiscussionLanguageView, SiteView}; @@ -14,7 +16,6 @@ use lemmy_db_views_actor::structs::{ PersonViewSafe, }; use lemmy_utils::{error::LemmyError, version, ConnectionId}; -use lemmy_websocket::{messages::GetUsersOnline, LemmyContext}; #[async_trait::async_trait(?Send)] impl PerformCrud for GetSite { diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index 07e965823..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, @@ -9,6 +10,7 @@ use lemmy_api_common::{ local_site_to_slur_regex, site_description_length_check, }, + websocket::{messages::SendAllMessage, UserOperationCrud}, }; use lemmy_db_schema::{ source::{ @@ -31,7 +33,6 @@ use lemmy_utils::{ utils::{check_application_question, check_slurs_opt}, ConnectionId, }; -use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperationCrud}; use std::str::FromStr; #[async_trait::async_trait(?Send)] diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index d1b5fbc3e..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::{ + 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, }, -}; -use lemmy_apub::{ - generate_inbox_url, - generate_local_apub_endpoint, - generate_shared_inbox_url, - EndpointType, + websocket::messages::CheckCaptcha, }; use lemmy_db_schema::{ aggregates::structs::PersonAggregates, @@ -33,7 +33,6 @@ use lemmy_utils::{ utils::{check_slurs, check_slurs_opt, is_valid_actor_name}, ConnectionId, }; -use lemmy_websocket::{messages::CheckCaptcha, LemmyContext}; #[async_trait::async_trait(?Send)] impl PerformCrud for Register { diff --git a/crates/api_crud/src/user/delete.rs b/crates/api_crud/src/user/delete.rs index 594747673..b49695eac 100644 --- a/crates/api_crud/src/user/delete.rs +++ b/crates/api_crud/src/user/delete.rs @@ -2,12 +2,11 @@ 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}, + utils::get_local_user_view_from_jwt, }; -use lemmy_apub::protocol::activities::deletion::delete_user::DeleteUser; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl PerformCrud for DeleteAccount { @@ -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/Cargo.toml b/crates/apub/Cargo.toml index c2a8827eb..720fa5937 100644 --- a/crates/apub/Cargo.toml +++ b/crates/apub/Cargo.toml @@ -19,7 +19,6 @@ lemmy_db_schema = { workspace = true, features = ["full"] } lemmy_db_views = { workspace = true, features = ["full"] } lemmy_db_views_actor = { workspace = true, features = ["full"] } lemmy_api_common = { workspace = true, features = ["full"] } -lemmy_websocket = { workspace = true } activitypub_federation = { workspace = true } diesel = { workspace = true } chrono = { workspace = true } diff --git a/crates/apub/src/activities/block/block_user.rs b/crates/apub/src/activities/block/block_user.rs index 1d726e7ce..b5f03eaf1 100644 --- a/crates/apub/src/activities/block/block_user.rs +++ b/crates/apub/src/activities/block/block_user.rs @@ -23,7 +23,10 @@ use activitypub_federation::{ use activitystreams_kinds::{activity::BlockType, public}; use anyhow::anyhow; use chrono::NaiveDateTime; -use lemmy_api_common::utils::{remove_user_data, remove_user_data_in_community}; +use lemmy_api_common::{ + context::LemmyContext, + utils::{remove_user_data, remove_user_data_in_community}, +}; use lemmy_db_schema::{ source::{ community::{ @@ -38,7 +41,6 @@ use lemmy_db_schema::{ traits::{Bannable, Crud, Followable}, }; use lemmy_utils::{error::LemmyError, utils::convert_datetime}; -use lemmy_websocket::LemmyContext; use url::Url; impl BlockUser { diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index bc2ea77f0..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_db_schema::{source::site::Site, utils::DbPool}; -use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; +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 eb54f5e48..315667ac6 100644 --- a/crates/apub/src/activities/block/undo_block_user.rs +++ b/crates/apub/src/activities/block/undo_block_user.rs @@ -19,6 +19,7 @@ use activitypub_federation::{ utils::verify_domains_match, }; use activitystreams_kinds::{activity::UndoType, public}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ community::{CommunityPersonBan, CommunityPersonBanForm}, @@ -28,7 +29,6 @@ use lemmy_db_schema::{ traits::{Bannable, Crud}, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use url::Url; impl UndoBlockUser { diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index c212cfe14..1bc31b48c 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -8,11 +8,14 @@ use crate::{ verify_person_in_community, }, activity_lists::AnnouncableActivities, - generate_moderators_url, 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, @@ -20,15 +23,20 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::{activity::AddType, public}; +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}, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use url::Url; impl AddMod { @@ -135,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 b6c31af5d..306913aa6 100644 --- a/crates/apub/src/activities/community/announce.rs +++ b/crates/apub/src/activities/community/announce.rs @@ -18,8 +18,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler}; use activitystreams_kinds::{activity::AnnounceType, public}; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde_json::Value; use tracing::debug; use url::Url; diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index a7b35595e..4d35c9d56 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -6,9 +6,9 @@ use crate::{ protocol::activities::community::announce::AnnounceActivity, }; use activitypub_federation::{core::object_id::ObjectId, traits::Actor}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::source::person::PersonFollower; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use url::Url; pub mod add_mod; diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index 3934df3b1..9bd8c4ec2 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -8,7 +8,6 @@ use crate::{ verify_person_in_community, }, activity_lists::AnnouncableActivities, - generate_moderators_url, local_instance, objects::{community::ApubCommunity, person::ApubPerson}, protocol::{activities::community::remove_mod::RemoveMod, InCommunity}, @@ -20,6 +19,7 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::{activity::RemoveType, public}; +use lemmy_api_common::{context::LemmyContext, utils::generate_moderators_url}; use lemmy_db_schema::{ source::{ community::{CommunityModerator, CommunityModeratorForm}, @@ -28,7 +28,6 @@ use lemmy_db_schema::{ traits::{Crud, Joinable}, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use url::Url; impl RemoveMod { diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 440a8ebbb..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, @@ -12,7 +13,13 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::activity::FlagType; -use lemmy_api_common::{comment::CommentReportResponse, post::PostReportResponse}; +use lemmy_api_common::{ + comment::{CommentReportResponse, CreateCommentReport}, + context::LemmyContext, + post::{CreatePostReport, PostReportResponse}, + utils::get_local_user_view_from_jwt, + websocket::{messages::SendModRoomMessage, UserOperation}, +}; use lemmy_db_schema::{ source::{ comment_report::{CommentReport, CommentReportForm}, @@ -22,12 +29,55 @@ use lemmy_db_schema::{ }; use lemmy_db_views::structs::{CommentReportView, PostReportView}; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}; 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 f41f2d47c..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, @@ -17,11 +18,32 @@ use activitypub_federation::{ traits::{ActivityHandler, ApubObject}, }; 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}, +}; use lemmy_db_schema::{source::community::Community, traits::Crud}; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; 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( @@ -112,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 a4b60ad4d..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, @@ -24,42 +25,86 @@ use activitypub_federation::{ utils::verify_domains_match, }; use activitystreams_kinds::public; -use lemmy_api_common::utils::check_post_deleted_or_removed; +use lemmy_api_common::{ + comment::{CommentResponse, CreateComment, EditComment}, + context::LemmyContext, + utils::check_post_deleted_or_removed, + websocket::{send::send_comment_ws_message, UserOperationCrud}, +}; use lemmy_db_schema::{ + newtypes::PersonId, source::{ - comment::{CommentLike, CommentLikeForm}, + comment::{Comment, CommentLike, CommentLikeForm}, community::Community, + person::Person, post::Post, }, traits::{Crud, Likeable}, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; 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(), @@ -85,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 2c68ad80f..60ce6ea34 100644 --- a/crates/apub/src/activities/create_or_update/mod.rs +++ b/crates/apub/src/activities/create_or_update/mod.rs @@ -1,12 +1,12 @@ use crate::{local_instance, objects::person::ApubPerson}; use activitypub_federation::core::object_id::ObjectId; +use lemmy_api_common::{context::LemmyContext, websocket::send::send_local_notifs}; use lemmy_db_schema::{ newtypes::LocalUserId, source::{comment::Comment, post::Post}, traits::Crud, }; use lemmy_utils::{error::LemmyError, utils::scrape_text_for_mentions}; -use lemmy_websocket::{send::send_local_notifs, LemmyContext}; pub mod comment; pub mod post; diff --git a/crates/apub/src/activities/create_or_update/post.rs b/crates/apub/src/activities/create_or_update/post.rs index abe9be1a6..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, @@ -22,17 +23,104 @@ use activitypub_federation::{ utils::{verify_domains_match, verify_urls_match}, }; 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}, +}; 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 lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; 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, @@ -57,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 eb310ce9c..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, @@ -13,20 +14,66 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor, ApubObject}, utils::verify_domains_match, }; -use lemmy_db_schema::{source::person::Person, traits::Crud}; +use lemmy_api_common::{ + context::LemmyContext, + private_message::{CreatePrivateMessage, EditPrivateMessage, PrivateMessageResponse}, + websocket::{send::send_pm_ws_message, UserOperationCrud}, +}; +use lemmy_db_schema::{ + newtypes::PersonId, + source::{person::Person, private_message::PrivateMessage}, + traits::Crud, +}; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; 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( @@ -35,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 8298a6fe0..138a1fae1 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -9,6 +9,13 @@ 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, + }, +}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, @@ -26,11 +33,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{ - send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, - LemmyContext, - UserOperationCrud, -}; use url::Url; #[async_trait::async_trait(?Send)] diff --git a/crates/apub/src/activities/deletion/delete_user.rs b/crates/apub/src/activities/deletion/delete_user.rs index 08d9d3959..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,11 +12,54 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::{activity::DeleteType, public}; -use lemmy_api_common::utils::delete_user_account; +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 lemmy_websocket::LemmyContext; 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)] @@ -61,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 bf4b920a8..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, @@ -28,6 +29,23 @@ use activitypub_federation::{ utils::verify_domains_match, }; 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, + send_community_ws_message, + send_pm_ws_message, + send_post_ws_message, + }, + UserOperationCrud, + }, +}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, @@ -39,16 +57,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{ - send::{ - send_comment_ws_message_simple, - send_community_ws_message, - send_pm_ws_message, - send_post_ws_message, - }, - LemmyContext, - UserOperationCrud, -}; use std::ops::Deref; use url::Url; @@ -56,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, @@ -88,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 8b845400e..b3cef3858 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -9,6 +9,13 @@ 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, + }, +}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentUpdateForm}, @@ -26,11 +33,6 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{ - send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, - LemmyContext, - UserOperationCrud, -}; use url::Url; #[async_trait::async_trait(?Send)] diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index 5a8baa4c7..6702c8c95 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -11,12 +11,15 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::activity::AcceptType; -use lemmy_api_common::community::CommunityResponse; +use lemmy_api_common::{ + community::CommunityResponse, + context::LemmyContext, + websocket::{messages::SendUserRoomMessage, UserOperation}, +}; use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable}; use lemmy_db_views::structs::LocalUserView; use lemmy_db_views_actor::structs::CommunityView; use lemmy_utils::error::LemmyError; -use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; use url::Url; impl AcceptFollow { diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 867eb2913..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,15 +22,19 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use activitystreams_kinds::activity::FollowType; +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 lemmy_websocket::LemmyContext; use url::Url; impl Follow { @@ -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 012ebfb90..436d8a02e 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -13,6 +13,7 @@ use activitypub_federation::{ utils::verify_urls_match, }; use activitystreams_kinds::activity::UndoType; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ community::{CommunityFollower, CommunityFollowerForm}, @@ -21,7 +22,6 @@ use lemmy_db_schema::{ traits::Followable, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use url::Url; impl UndoFollow { diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index c38eadcda..2fb5808b7 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -1,5 +1,4 @@ use crate::{ - generate_moderators_url, insert_activity, local_instance, objects::{community::ApubCommunity, person::ApubPerson}, @@ -13,13 +12,13 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use anyhow::anyhow; +use lemmy_api_common::{context::LemmyContext, utils::generate_moderators_url}; use lemmy_db_schema::{ newtypes::CommunityId, source::{community::Community, local_site::LocalSite}, }; use lemmy_db_views_actor::structs::{CommunityPersonBanView, CommunityView}; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::Serialize; use std::ops::Deref; use tracing::info; @@ -31,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 bff67efee..4471fbd92 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -1,24 +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, + }, }; 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; -use lemmy_websocket::{ - send::{send_comment_ws_message_simple, send_post_ws_message}, - LemmyContext, - UserOperation, -}; 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 20c9432cd..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_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 f8d44ed98..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_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 lemmy_websocket::LemmyContext; 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 fa8eece38..6e1771127 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -24,8 +24,8 @@ use crate::{ }, }; use activitypub_federation::{data::Data, deser::context::WithContext, traits::ActivityHandler}; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 93% rename from crates/api_crud/src/comment/list.rs rename to crates/apub/src/api/list_comments.rs index afee451a3..c4af6900a 100644 --- a/crates/api_crud/src/comment/list.rs +++ b/crates/apub/src/api/list_comments.rs @@ -1,24 +1,27 @@ -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, }, }; -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}, }; use lemmy_db_views::comment_view::CommentQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[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 bf4086e47..7a1f815c7 100644 --- a/crates/api_crud/src/post/list.rs +++ b/crates/apub/src/api/list_posts.rs @@ -1,6 +1,11 @@ -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, @@ -8,17 +13,15 @@ use lemmy_api_common::{ listing_type_with_site_default, }, }; -use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity}; use lemmy_db_schema::{ source::{community::Community, local_site::LocalSite}, traits::DeleteableOrRemoveable, }; use lemmy_db_views::post_view::PostQuery; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[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 91% rename from crates/api_crud/src/community/read.rs rename to crates/apub/src/api/read_community.rs index 1b3e5ff48..b1615d7d7 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/apub/src/api/read_community.rs @@ -1,12 +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}, -}; -use lemmy_apub::{ - fetcher::resolve_actor_identifier, - objects::{community::ApubCommunity, instance::instance_actor_id_from_url}, + websocket::messages::GetCommunityUsersOnline, }; use lemmy_db_schema::{ impls::actor_language::default_post_language, @@ -20,10 +22,9 @@ use lemmy_db_schema::{ }; use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::GetCommunityUsersOnline, LemmyContext}; #[async_trait::async_trait(?Send)] -impl PerformCrud for GetCommunity { +impl PerformApub for GetCommunity { type Response = GetCommunityResponse; #[tracing::instrument(skip(context, _websocket_id))] @@ -77,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 ccf5189cd..514bcfccc 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/apub/src/api/read_person.rs @@ -1,10 +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}, }; -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, @@ -12,10 +12,9 @@ use lemmy_db_schema::{ use lemmy_db_views::{comment_view::CommentQuery, post_view::PostQuery}; use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonViewSafe}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[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 0e59c6835..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}, }; -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}; -use lemmy_websocket::LemmyContext; #[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 5d813fcfd..cad41c549 100644 --- a/crates/api/src/site/search.rs +++ b/crates/apub/src/api/search.rs @@ -1,10 +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}, }; -use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity}; use lemmy_db_schema::{ source::{community::Community, local_site::LocalSite}, traits::DeleteableOrRemoveable, @@ -14,10 +18,9 @@ use lemmy_db_schema::{ use lemmy_db_views::{comment_view::CommentQuery, post_view::PostQuery}; use lemmy_db_views_actor::{community_view::CommunityQuery, person_view::PersonQuery}; use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::LemmyContext; #[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 b75753708..9616ddb30 100644 --- a/crates/apub/src/collections/community_moderators.rs +++ b/crates/apub/src/collections/community_moderators.rs @@ -1,6 +1,5 @@ use crate::{ collections::CommunityContext, - generate_moderators_url, local_instance, objects::person::ApubPerson, protocol::collections::group_moderators::GroupModerators, @@ -12,6 +11,7 @@ use activitypub_federation::{ }; use activitystreams_kinds::collection::OrderedCollectionType; use chrono::NaiveDateTime; +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 c7742de72..a16fbd02b 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -1,7 +1,6 @@ use crate::{ activity_lists::AnnouncableActivities, collections::CommunityContext, - generate_outbox_url, objects::post::ApubPost, protocol::{ activities::{ @@ -20,6 +19,7 @@ use activitypub_federation::{ use activitystreams_kinds::collection::OrderedCollectionType; use chrono::NaiveDateTime; use futures::future::join_all; +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 e2a274a01..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_websocket::LemmyContext; +use lemmy_api_common::context::LemmyContext; pub(crate) mod community_moderators; pub(crate) mod community_outbox; diff --git a/crates/apub/src/fetcher/deletable_apub_object.rs b/crates/apub/src/fetcher/deletable_apub_object.rs index c84ebabbc..0eae410c6 100644 --- a/crates/apub/src/fetcher/deletable_apub_object.rs +++ b/crates/apub/src/fetcher/deletable_apub_object.rs @@ -13,7 +13,7 @@ use lemmy_db_schema::source::{ site::Site, }; use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; +use lemmy_api_common::LemmyContext; // TODO: merge this trait with ApubObject (means that db_schema needs to depend on apub_lib) #[async_trait::async_trait(?Send)] diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index d98bb8e4d..0ce4dd8f6 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -1,9 +1,9 @@ use crate::{fetcher::webfinger::webfinger_resolve_actor, ActorType}; use activitypub_federation::traits::ApubObject; use itertools::Itertools; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::traits::ApubActor; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; pub mod post_or_comment; pub mod search; diff --git a/crates/apub/src/fetcher/post_or_comment.rs b/crates/apub/src/fetcher/post_or_comment.rs index d2d0b91f6..68e176b01 100644 --- a/crates/apub/src/fetcher/post_or_comment.rs +++ b/crates/apub/src/fetcher/post_or_comment.rs @@ -7,12 +7,12 @@ use crate::{ }; use activitypub_federation::traits::ApubObject; use chrono::NaiveDateTime; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, post::Post}, traits::Crud, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::Deserialize; use url::Url; @@ -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 1daccd3a4..ffc2c9611 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -6,8 +6,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, traits::ApubObject}; use chrono::NaiveDateTime; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 156f5e83a..3af86be1a 100644 --- a/crates/apub/src/fetcher/user_or_community.rs +++ b/crates/apub/src/fetcher/user_or_community.rs @@ -5,8 +5,8 @@ use crate::{ }; use activitypub_federation::traits::{Actor, ApubObject}; use chrono::NaiveDateTime; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/fetcher/webfinger.rs b/crates/apub/src/fetcher/webfinger.rs index 8e97d7d07..4746736eb 100644 --- a/crates/apub/src/fetcher/webfinger.rs +++ b/crates/apub/src/fetcher/webfinger.rs @@ -2,30 +2,14 @@ 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::context::LemmyContext; use lemmy_db_schema::newtypes::DbUrl; -use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; +use lemmy_utils::{error::LemmyError, WebfingerResponse}; use tracing::debug; use url::Url; -#[derive(Serialize, Deserialize, Debug)] -pub struct WebfingerLink { - pub rel: Option, - #[serde(rename = "type")] - pub kind: Option, - pub href: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WebfingerResponse { - pub subject: String, - pub links: Vec, -} - /// 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 498a23c8a..5e7de7e25 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -5,9 +5,9 @@ use crate::{ use activitypub_federation::traits::ApubObject; use actix_web::{web, web::Path, HttpResponse}; use diesel::result::Error::NotFound; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{newtypes::CommentId, source::comment::Comment, traits::Crud}; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::Deserialize; #[derive(Deserialize)] diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 8b860f573..74809509f 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -5,7 +5,6 @@ use crate::{ community_outbox::ApubCommunityOutbox, CommunityContext, }, - generate_outbox_url, http::{create_apub_response, create_apub_tombstone_response, receive_lemmy_activity}, local_instance, objects::{community::ApubCommunity, person::ApubPerson}, @@ -17,9 +16,9 @@ use activitypub_federation::{ traits::ApubObject, }; use actix_web::{web, HttpRequest, HttpResponse}; +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 lemmy_websocket::LemmyContext; use serde::Deserialize; #[derive(Deserialize)] diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index f351ea4f0..726834c00 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -15,9 +15,9 @@ use activitypub_federation::{ }; use actix_web::{web, HttpRequest, HttpResponse}; use http::StatusCode; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::source::activity::Activity; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use once_cell::sync::OnceCell; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde_json::Value; diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 0ca31bd5c..6a1bc5b35 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -1,16 +1,15 @@ use crate::{ activity_lists::PersonInboxActivitiesWithAnnouncable, fetcher::user_or_community::UserOrCommunity, - generate_outbox_url, http::{create_apub_response, create_apub_tombstone_response, receive_lemmy_activity}, objects::person::ApubPerson, protocol::collections::empty_outbox::EmptyOutbox, }; use activitypub_federation::{deser::context::WithContext, traits::ApubObject}; use actix_web::{web, HttpRequest, HttpResponse}; +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 lemmy_websocket::LemmyContext; use serde::Deserialize; #[derive(Deserialize)] diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index 5da69fb45..bea5da3a4 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -5,9 +5,9 @@ use crate::{ use activitypub_federation::traits::ApubObject; use actix_web::{web, HttpResponse}; use diesel::result::Error::NotFound; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{newtypes::PostId, source::post::Post, traits::Crud}; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::Deserialize; #[derive(Deserialize)] diff --git a/crates/apub/src/http/site.rs b/crates/apub/src/http/site.rs index 201fc5b3a..fe6c34f63 100644 --- a/crates/apub/src/http/site.rs +++ b/crates/apub/src/http/site.rs @@ -6,9 +6,9 @@ use crate::{ }; use activitypub_federation::{deser::context::WithContext, traits::ApubObject}; use actix_web::{web, HttpRequest, HttpResponse}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_views::structs::SiteView; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use url::Url; pub(crate) async fn get_apub_site_http( diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index f5d8d3565..0908a1f4f 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -6,21 +6,20 @@ use activitypub_federation::{ LocalInstance, UrlVerifier, }; -use anyhow::Context; use async_trait::async_trait; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ - newtypes::DbUrl, source::{activity::Activity, instance::Instance, local_site::LocalSite}, utils::DbPool, }; -use lemmy_utils::{error::LemmyError, location_info, settings::structs::Settings}; -use lemmy_websocket::LemmyContext; +use lemmy_utils::{error::LemmyError, settings::structs::Settings}; use once_cell::sync::Lazy; use tokio::sync::OnceCell; -use url::{ParseError, Url}; +use url::Url; pub mod activities; pub(crate) mod activity_lists; +pub mod api; pub(crate) mod collections; pub mod fetcher; pub mod http; @@ -193,68 +192,6 @@ pub(crate) fn check_apub_id_valid_with_strictness( Ok(()) } -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()) -} - -fn generate_moderators_url(community_id: &DbUrl) -> Result { - Ok(Url::parse(&format!("{}/moderators", community_id))?.into()) -} - /// Store a sent or received activity in the database, for logging purposes. These records are not /// persistent. #[tracing::instrument(skip(pool))] @@ -280,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 8e24270d0..559078942 100644 --- a/crates/apub/src/mentions.rs +++ b/crates/apub/src/mentions.rs @@ -5,6 +5,7 @@ use crate::{ }; use activitypub_federation::core::object_id::ObjectId; use activitystreams_kinds::link::MentionType; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{comment::Comment, person::Person, post::Post}, traits::Crud, @@ -14,7 +15,6 @@ use lemmy_utils::{ error::LemmyError, utils::{scrape_text_for_mentions, MentionData}, }; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_json::Value; use url::Url; diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index df20700fb..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; +use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex}; use lemmy_db_schema::{ source::{ comment::{Comment, CommentInsertForm, CommentUpdateForm}, @@ -35,12 +35,11 @@ use lemmy_utils::{ error::LemmyError, utils::{convert_datetime, markdown_to_html, remove_slurs}, }; -use lemmy_websocket::LemmyContext; 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 aefc7edb2..b309d25fc 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -2,8 +2,6 @@ use crate::{ check_apub_id_valid_with_strictness, collections::{community_moderators::ApubCommunityModerators, CommunityContext}, fetch_local_site_data, - generate_moderators_url, - generate_outbox_url, local_instance, objects::instance::fetch_instance_actor_for_object, protocol::{ @@ -20,6 +18,10 @@ use activitypub_federation::{ use activitystreams_kinds::actor::GroupType; use chrono::NaiveDateTime; use itertools::Itertools; +use lemmy_api_common::{ + context::LemmyContext, + utils::{generate_moderators_url, generate_outbox_url}, +}; use lemmy_db_schema::{ source::{ actor_language::CommunityLanguage, @@ -33,7 +35,6 @@ use lemmy_utils::{ error::LemmyError, utils::{convert_datetime, markdown_to_html}, }; -use lemmy_websocket::LemmyContext; use std::ops::Deref; use tracing::debug; use url::Url; diff --git a/crates/apub/src/objects/instance.rs b/crates/apub/src/objects/instance.rs index 9f33ee518..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; +use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex}; use lemmy_db_schema::{ source::{ actor_language::SiteLanguage, @@ -34,7 +34,6 @@ use lemmy_utils::{ error::LemmyError, utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html}, }; -use lemmy_websocket::LemmyContext; use std::ops::Deref; use tracing::debug; use url::Url; @@ -177,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, @@ -193,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 5098d0b2b..58e1f23f5 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -56,14 +56,17 @@ pub(crate) fn verify_is_remote_object(id: &Url, settings: &Settings) -> Result<( pub(crate) mod tests { use actix::Actor; use anyhow::anyhow; - use lemmy_api_common::request::build_user_agent; + use lemmy_api_common::{ + context::LemmyContext, + request::build_user_agent, + websocket::chat_server::ChatServer, + }; use lemmy_db_schema::{source::secret::Secret, utils::build_db_pool_for_tests}; use lemmy_utils::{ error::LemmyError, rate_limit::{RateLimitCell, RateLimitConfig}, settings::SETTINGS, }; - use lemmy_websocket::{chat_server::ChatServer, LemmyContext}; use reqwest::{Client, Request, Response}; use reqwest_middleware::{ClientBuilder, Middleware, Next}; use task_local_extensions::Extensions; @@ -110,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 fb450557d..2017b605c 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -1,7 +1,6 @@ use crate::{ check_apub_id_valid_with_strictness, fetch_local_site_data, - generate_outbox_url, objects::{instance::fetch_instance_actor_for_object, read_from_string_or_source_opt}, protocol::{ objects::{ @@ -19,7 +18,10 @@ use activitypub_federation::{ utils::verify_domains_match, }; use chrono::NaiveDateTime; -use lemmy_api_common::utils::local_site_opt_to_slur_regex; +use lemmy_api_common::{ + context::LemmyContext, + utils::{generate_outbox_url, local_site_opt_to_slur_regex}, +}; use lemmy_db_schema::{ source::{ instance::Instance, @@ -32,7 +34,6 @@ use lemmy_utils::{ error::LemmyError, utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html}, }; -use lemmy_websocket::LemmyContext; use std::ops::Deref; use url::Url; diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index b7d38e347..afe025ce2 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -22,7 +22,11 @@ use activitypub_federation::{ }; use activitystreams_kinds::public; use chrono::NaiveDateTime; -use lemmy_api_common::{request::fetch_site_data, utils::local_site_opt_to_slur_regex}; +use lemmy_api_common::{ + context::LemmyContext, + request::fetch_site_data, + utils::local_site_opt_to_slur_regex, +}; use lemmy_db_schema::{ self, source::{ @@ -38,12 +42,11 @@ use lemmy_utils::{ error::LemmyError, utils::{check_slurs, convert_datetime, markdown_to_html, remove_slurs}, }; -use lemmy_websocket::LemmyContext; 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 47a9c5d13..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; +use lemmy_api_common::{context::LemmyContext, utils::check_person_block}; use lemmy_db_schema::{ source::{ person::Person, @@ -27,12 +27,11 @@ use lemmy_utils::{ error::LemmyError, utils::{convert_datetime, markdown_to_html}, }; -use lemmy_websocket::LemmyContext; 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 91467a96c..3ac040ced 100644 --- a/crates/apub/src/protocol/activities/block/block_user.rs +++ b/crates/apub/src/protocol/activities/block/block_user.rs @@ -8,8 +8,8 @@ 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::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use url::Url; 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 ade126eec..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,8 +6,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::UndoType; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use url::Url; diff --git a/crates/apub/src/protocol/activities/community/add_mod.rs b/crates/apub/src/protocol/activities/community/add_mod.rs index f23fcbae0..22fc07fcb 100644 --- a/crates/apub/src/protocol/activities/community/add_mod.rs +++ b/crates/apub/src/protocol/activities/community/add_mod.rs @@ -6,8 +6,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::AddType; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 2ee744b7f..ce46fb920 100644 --- a/crates/apub/src/protocol/activities/community/remove_mod.rs +++ b/crates/apub/src/protocol/activities/community/remove_mod.rs @@ -6,8 +6,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::RemoveType; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 34738c56a..0a1ef650f 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -7,8 +7,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one}; use activitystreams_kinds::activity::FlagType; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 f534f2369..9a2f1f481 100644 --- a/crates/apub/src/protocol/activities/community/update.rs +++ b/crates/apub/src/protocol/activities/community/update.rs @@ -6,8 +6,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::UpdateType; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 0de7161f4..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,9 +6,9 @@ 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::context::LemmyContext; use lemmy_db_schema::{source::community::Community, traits::Crud}; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use url::Url; 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 b0311b5ff..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,8 +5,8 @@ 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::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 f5ae40d8a..d92ac2456 100644 --- a/crates/apub/src/protocol/activities/deletion/delete.rs +++ b/crates/apub/src/protocol/activities/deletion/delete.rs @@ -7,12 +7,12 @@ 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::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, post::Post}, traits::Crud, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use url::Url; diff --git a/crates/apub/src/protocol/activities/deletion/undo_delete.rs b/crates/apub/src/protocol/activities/deletion/undo_delete.rs index c4946850a..d5249ba9a 100644 --- a/crates/apub/src/protocol/activities/deletion/undo_delete.rs +++ b/crates/apub/src/protocol/activities/deletion/undo_delete.rs @@ -6,8 +6,8 @@ use crate::{ }; use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many}; use activitystreams_kinds::activity::UndoType; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use url::Url; diff --git a/crates/apub/src/protocol/activities/voting/undo_vote.rs b/crates/apub/src/protocol/activities/voting/undo_vote.rs index 1d17cf158..0973c76a8 100644 --- a/crates/apub/src/protocol/activities/voting/undo_vote.rs +++ b/crates/apub/src/protocol/activities/voting/undo_vote.rs @@ -6,8 +6,8 @@ use crate::{ }; use activitypub_federation::core::object_id::ObjectId; use activitystreams_kinds::activity::UndoType; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; 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 5da9b791c..2a09a45ea 100644 --- a/crates/apub/src/protocol/activities/voting/vote.rs +++ b/crates/apub/src/protocol/activities/voting/vote.rs @@ -6,8 +6,8 @@ use crate::{ protocol::InCommunity, }; use activitypub_federation::core::object_id::ObjectId; +use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; use strum_macros::Display; diff --git a/crates/apub/src/protocol/collections/group_followers.rs b/crates/apub/src/protocol/collections/group_followers.rs index ac1ef2285..b9cf85182 100644 --- a/crates/apub/src/protocol/collections/group_followers.rs +++ b/crates/apub/src/protocol/collections/group_followers.rs @@ -1,9 +1,8 @@ -use crate::generate_followers_url; use activitystreams_kinds::collection::CollectionType; +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; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/apub/src/protocol/mod.rs b/crates/apub/src/protocol/mod.rs index a65e74da2..ef0f2a875 100644 --- a/crates/apub/src/protocol/mod.rs +++ b/crates/apub/src/protocol/mod.rs @@ -1,9 +1,9 @@ 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::context::LemmyContext; use lemmy_db_schema::newtypes::DbUrl; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use url::Url; diff --git a/crates/apub/src/protocol/objects/group.rs b/crates/apub/src/protocol/objects/group.rs index 564aed169..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; +use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex}; use lemmy_db_schema::{ newtypes::InstanceId, source::community::{CommunityInsertForm, CommunityUpdateForm}, @@ -29,7 +29,6 @@ use lemmy_utils::{ error::LemmyError, utils::{check_slurs, check_slurs_opt}, }; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use url::Url; diff --git a/crates/apub/src/protocol/objects/note.rs b/crates/apub/src/protocol/objects/note.rs index 21f7bcf38..f561c313d 100644 --- a/crates/apub/src/protocol/objects/note.rs +++ b/crates/apub/src/protocol/objects/note.rs @@ -15,12 +15,12 @@ use activitypub_federation::{ }; use activitystreams_kinds::object::NoteType; use chrono::{DateTime, FixedOffset}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, post::Post}, traits::Crud, }; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use std::ops::Deref; diff --git a/crates/apub/src/protocol/objects/page.rs b/crates/apub/src/protocol/objects/page.rs index b25e1d97c..a62fb8e57 100644 --- a/crates/apub/src/protocol/objects/page.rs +++ b/crates/apub/src/protocol/objects/page.rs @@ -20,9 +20,9 @@ use activitystreams_kinds::{ }; use chrono::{DateTime, FixedOffset}; use itertools::Itertools; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::newtypes::DbUrl; use lemmy_utils::error::LemmyError; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; use url::Url; 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 cbcd259c0..bc2b573e5 100644 --- a/crates/routes/Cargo.toml +++ b/crates/routes/Cargo.toml @@ -13,12 +13,10 @@ doctest = false [dependencies] lemmy_utils = { workspace = true } -lemmy_websocket = { workspace = true } lemmy_db_views = { workspace = true } lemmy_db_views_actor = { workspace = true } lemmy_db_schema = { workspace = true } -lemmy_api_common = { workspace = true } -lemmy_apub = { 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 436148b96..594bf1153 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -1,6 +1,7 @@ use actix_web::{error::ErrorBadRequest, web, Error, HttpRequest, HttpResponse, Result}; use anyhow::anyhow; use chrono::{DateTime, NaiveDateTime, Utc}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ newtypes::LocalUserId, source::{community::Community, local_user::LocalUser, person::Person}, @@ -20,7 +21,6 @@ use lemmy_db_views_actor::{ structs::{CommentReplyView, PersonMentionView}, }; use lemmy_utils::{claims::Claims, error::LemmyError, utils::markdown_to_html}; -use lemmy_websocket::LemmyContext; use once_cell::sync::Lazy; use rss::{ extension::dublincore::DublinCoreExtensionBuilder, diff --git a/crates/routes/src/images.rs b/crates/routes/src/images.rs index 716b18be8..0b1f6fbdd 100644 --- a/crates/routes/src/images.rs +++ b/crates/routes/src/images.rs @@ -11,10 +11,9 @@ use actix_web::{ HttpResponse, }; use futures::stream::{Stream, StreamExt}; -use lemmy_api_common::utils::get_local_user_view_from_jwt; +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 lemmy_websocket::LemmyContext; use reqwest::Body; use reqwest_middleware::{ClientWithMiddleware, RequestBuilder}; use serde::{Deserialize, Serialize}; diff --git a/crates/routes/src/nodeinfo.rs b/crates/routes/src/nodeinfo.rs index 9c3a32402..13786e3b6 100644 --- a/crates/routes/src/nodeinfo.rs +++ b/crates/routes/src/nodeinfo.rs @@ -1,8 +1,8 @@ use actix_web::{error::ErrorBadRequest, web, Error, HttpResponse, Result}; use anyhow::anyhow; +use lemmy_api_common::context::LemmyContext; use lemmy_db_views::structs::SiteView; use lemmy_utils::{error::LemmyError, version}; -use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use url::Url; diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs index 113959769..9056ea632 100644 --- a/crates/routes/src/webfinger.rs +++ b/crates/routes/src/webfinger.rs @@ -1,12 +1,11 @@ use actix_web::{web, web::Query, HttpResponse}; use anyhow::Context; -use lemmy_apub::fetcher::webfinger::{WebfingerLink, WebfingerResponse}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{community::Community, person::Person}, traits::ApubActor, }; -use lemmy_utils::{error::LemmyError, location_info}; -use lemmy_websocket::LemmyContext; +use lemmy_utils::{error::LemmyError, location_info, WebfingerLink, WebfingerResponse}; use serde::Deserialize; use url::Url; diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index beaf173ba..eeb588439 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -16,7 +16,9 @@ mod test; pub mod utils; pub mod version; +use serde::{Deserialize, Serialize}; use std::{fmt, time::Duration}; +use url::Url; pub type ConnectionId = usize; @@ -31,6 +33,20 @@ impl fmt::Display for IpAddr { } } +#[derive(Serialize, Deserialize, Debug)] +pub struct WebfingerLink { + pub rel: Option, + #[serde(rename = "type")] + pub kind: Option, + pub href: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct WebfingerResponse { + pub subject: String, + pub links: Vec, +} + #[macro_export] macro_rules! location_info { () => { diff --git a/crates/websocket/Cargo.toml b/crates/websocket/Cargo.toml deleted file mode 100644 index 829b759af..000000000 --- a/crates/websocket/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "lemmy_websocket" -version.workspace = true -edition.workspace = true -description.workspace = true -license.workspace = true -homepage.workspace = true -documentation.workspace = true -repository.workspace = true - -[lib] -name = "lemmy_websocket" -path = "src/lib.rs" -doctest = false - -[dependencies] -lemmy_utils = { workspace = true } -lemmy_api_common = { workspace = true, features = ["full"] } -lemmy_db_schema = { workspace = true, features = ["full"] } -lemmy_db_views = { workspace = true, features = ["full"] } -lemmy_db_views_actor = { workspace = true, features = ["full"] } -reqwest-middleware = { workspace = true } -tracing = { workspace = true } -rand = { workspace = true } -serde = { workspace = true } -serde_json = { workspace = true } -actix = { workspace = true } -anyhow = { workspace = true } -diesel = { workspace = true } -tokio = { workspace = true } -strum = { workspace = true } -strum_macros = { workspace = true } -chrono = { workspace = true } -actix-web = { workspace = true } -opentelemetry = { workspace = true } -tracing-opentelemetry = { workspace = true } -actix-web-actors = { version = "4.1.0", default-features = false } -background-jobs = "0.13.0" diff --git a/src/api_routes.rs b/src/api_routes.rs index 82a73f884..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, @@ -94,12 +95,20 @@ use lemmy_api_common::{ ResolveObject, Search, }, - websocket::{CommunityJoin, ModJoin, PostJoin, UserJoin}, + websocket::{ + routes::chat_route, + serialize_websocket_message, + structs::{CommunityJoin, ModJoin, PostJoin, UserJoin}, + UserOperation, + UserOperationApub, + UserOperationCrud, + }, }; use lemmy_api_crud::PerformCrud; -use lemmy_utils::rate_limit::RateLimitCell; -use lemmy_websocket::{routes::chat_route, LemmyContext}; +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( @@ -123,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( @@ -140,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::)) @@ -182,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::)) @@ -218,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", @@ -276,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", @@ -349,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>( @@ -369,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>( @@ -404,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 } @@ -414,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 bcbebb503..89933a15e 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -8,14 +8,16 @@ use diesel::{ TextExpressionMethods, }; use diesel_async::RunQueryDsl; -use lemmy_api_common::lemmy_db_views::structs::SiteView; -use lemmy_apub::{ - generate_followers_url, - generate_inbox_url, - generate_local_apub_endpoint, - generate_shared_inbox_url, - generate_site_inbox_url, - EndpointType, +use lemmy_api_common::{ + lemmy_db_views::structs::SiteView, + 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 728b3d370..c60c1823a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,16 +5,16 @@ 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::{ check_private_instance_and_federation_enabled, local_site_rate_limit_to_rate_limit_config, }, + websocket::chat_server::ChatServer, }; -use lemmy_api_crud::match_websocket_operation_crud; use lemmy_db_schema::{ source::secret::Secret, utils::{build_db_pool, get_database_url, run_migrations}, @@ -22,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, @@ -32,7 +37,6 @@ use lemmy_utils::{ rate_limit::RateLimitCell, settings::{structs::Settings, SETTINGS}, }; -use lemmy_websocket::{chat_server::ChatServer, LemmyContext}; use reqwest::Client; use reqwest_middleware::ClientBuilder; use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware}; @@ -135,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(),