From 4e840a9527b10ee5bfb37a30384d056d44db6547 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Sun, 15 Aug 2021 00:33:01 +0200 Subject: [PATCH] Rewrite remaining activities --- crates/api/src/community.rs | 33 ++-- crates/api_crud/src/community/update.rs | 6 +- .../apub/src/activities/community/add_mod.rs | 48 ++++- .../apub/src/activities/community/announce.rs | 5 +- .../src/activities/community/block_user.rs | 61 +++++- crates/apub/src/activities/community/mod.rs | 1 + .../remove.rs => community/remove_mod.rs} | 50 ++++- .../activities/community/undo_block_user.rs | 47 ++++- .../apub/src/activities/community/update.rs | 43 ++++- crates/apub/src/activities/mod.rs | 2 +- crates/apub/src/activities/removal/mod.rs | 2 - crates/apub/src/activities/send/community.rs | 177 +----------------- .../activities/{removal => }/undo_remove.rs | 2 +- crates/apub/src/activity_queue.rs | 146 +-------------- crates/apub/src/http/inbox_enums.rs | 3 +- crates/apub/src/lib.rs | 36 ---- crates/apub_lib/src/lib.rs | 7 - 17 files changed, 252 insertions(+), 417 deletions(-) rename crates/apub/src/activities/{removal/remove.rs => community/remove_mod.rs} (65%) delete mode 100644 crates/apub/src/activities/removal/mod.rs rename crates/apub/src/activities/{removal => }/undo_remove.rs (97%) diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index 0ca4ac47a..3d6f3e896 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -8,12 +8,14 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, is_mod_or_admin, }; -use lemmy_apub::{ - activities::following::{ - follow::FollowCommunity as FollowCommunityApub, - undo::UndoFollowCommunity, +use lemmy_apub::activities::{ + community::{ + add_mod::AddMod, + block_user::BlockUserFromCommunity, + remove_mod::RemoveMod, + undo_block_user::UndoBlockUserFromCommunity, }, - CommunityType, + following::{follow::FollowCommunity as FollowCommunityApub, undo::UndoFollowCommunity}, }; use lemmy_db_queries::{ source::{comment::Comment_, community::CommunityModerator_, post::Post_}, @@ -157,17 +159,20 @@ impl Perform for BanFromCommunity { .await? .ok(); - community - .send_block_user(&local_user_view.person, banned_person, context) + BlockUserFromCommunity::send(&community, &banned_person, &local_user_view.person, context) .await?; } else { let unban = move |conn: &'_ _| CommunityPersonBan::unban(conn, &community_user_ban_form); if blocking(context.pool(), unban).await?.is_err() { return Err(ApiError::err("community_user_already_banned").into()); } - community - .send_undo_block_user(&local_user_view.person, banned_person, context) - .await?; + UndoBlockUserFromCommunity::send( + &community, + &banned_person, + &local_user_view.person, + context, + ) + .await?; } // Remove/Restore their data if that's desired @@ -294,13 +299,9 @@ impl Perform for AddModToCommunity { }) .await??; if data.added { - community - .send_add_mod(&local_user_view.person, updated_mod, context) - .await?; + AddMod::send(&community, &updated_mod, &local_user_view.person, context).await?; } else { - community - .send_remove_mod(&local_user_view.person, updated_mod, context) - .await?; + RemoveMod::send(&community, &updated_mod, &local_user_view.person, context).await?; } // Note: in case a remote mod is added, this returns the old moderators list, it will only get diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 2a99c76db..2196c57b7 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -5,7 +5,7 @@ use lemmy_api_common::{ community::{CommunityResponse, EditCommunity}, get_local_user_view_from_jwt, }; -use lemmy_apub::CommunityType; +use lemmy_apub::activities::community::update::UpdateCommunity; use lemmy_db_queries::{diesel_option_overwrite_to_url, Crud}; use lemmy_db_schema::{ naive_now, @@ -69,9 +69,7 @@ impl PerformCrud for EditCommunity { .await? .map_err(|_| ApiError::err("couldnt_update_community"))?; - updated_community - .send_update(local_user_view.person.to_owned(), context) - .await?; + UpdateCommunity::send(&updated_community, &local_user_view.person, context).await?; let op = UserOperationCrud::EditCommunity; send_community_ws_message(data.community_id, op, websocket_id, None, context).await diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index db6d369a1..bd7cfbadd 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -1,18 +1,26 @@ use crate::{ activities::{ + community::announce::AnnouncableActivities, + generate_activity_id, verify_activity, verify_add_remove_moderator_target, verify_mod_action, verify_person_in_community, }, + activity_queue::send_to_community_new, + extensions::context::lemmy_context, fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, - CommunityType, + generate_moderators_url, + ActorType, }; -use activitystreams::{activity::kind::AddType, base::AnyBase}; +use activitystreams::activity::kind::AddType; use lemmy_api_common::blocking; use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler}; use lemmy_db_queries::{source::community::CommunityModerator_, Joinable}; -use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm}; +use lemmy_db_schema::source::{ + community::{Community, CommunityModerator, CommunityModeratorForm}, + person::Person, +}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -30,6 +38,34 @@ pub struct AddMod { common: ActivityCommonFields, } +impl AddMod { + pub async fn send( + community: &Community, + added_mod: &Person, + actor: &Person, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let id = generate_activity_id(AddType::Add)?; + let add = AddMod { + to: PublicUrl::Public, + object: added_mod.actor_id(), + target: generate_moderators_url(&community.actor_id)?.into(), + cc: [community.actor_id()], + kind: AddType::Add, + common: ActivityCommonFields { + context: lemmy_context(), + id: id.clone(), + actor: actor.actor_id(), + unparsed: Default::default(), + }, + }; + + let activity = AnnouncableActivities::AddMod(add); + let inboxes = vec![added_mod.get_shared_inbox_or_inbox_url()]; + send_to_community_new(activity, &id, actor, community, inboxes, context).await + } +} + #[async_trait::async_trait(?Send)] impl ActivityHandler for AddMod { async fn verify( @@ -70,12 +106,6 @@ impl ActivityHandler for AddMod { }) .await??; } - if community.local { - let anybase = AnyBase::from_arbitrary_json(serde_json::to_string(&self)?)?; - community - .send_announce(anybase, Some(self.object.clone()), context) - .await?; - } // TODO: send websocket notification about added mod Ok(()) } diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs index 734fed00e..06c895a05 100644 --- a/crates/apub/src/activities/community/announce.rs +++ b/crates/apub/src/activities/community/announce.rs @@ -5,12 +5,14 @@ use crate::{ add_mod::AddMod, block_user::BlockUserFromCommunity, list_community_follower_inboxes, + remove_mod::RemoveMod, undo_block_user::UndoBlockUserFromCommunity, + update::UpdateCommunity, }, deletion::{delete::Delete, undo_delete::UndoDelete}, generate_activity_id, post::create_or_update::CreateOrUpdatePost, - removal::{remove::RemoveMod, undo_remove::UndoRemovePostCommentOrCommunity}, + undo_remove::UndoRemovePostCommentOrCommunity, verify_activity, verify_community, voting::{undo_vote::UndoVote, vote::Vote}, @@ -40,6 +42,7 @@ pub enum AnnouncableActivities { Delete(Delete), UndoDelete(UndoDelete), UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity), + UpdateCommunity(Box), BlockUserFromCommunity(BlockUserFromCommunity), UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), AddMod(AddMod), diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs index bf362c482..d725c35da 100644 --- a/crates/apub/src/activities/community/block_user.rs +++ b/crates/apub/src/activities/community/block_user.rs @@ -1,16 +1,29 @@ use crate::{ - activities::{verify_activity, verify_mod_action, verify_person_in_community}, + activities::{ + community::announce::AnnouncableActivities, + generate_activity_id, + verify_activity, + verify_mod_action, + verify_person_in_community, + }, + activity_queue::send_to_community_new, + extensions::context::lemmy_context, fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, + ActorType, }; use activitystreams::activity::kind::BlockType; use lemmy_api_common::blocking; use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler}; use lemmy_db_queries::{Bannable, Followable}; -use lemmy_db_schema::source::community::{ - CommunityFollower, - CommunityFollowerForm, - CommunityPersonBan, - CommunityPersonBanForm, +use lemmy_db_schema::source::{ + community::{ + Community, + CommunityFollower, + CommunityFollowerForm, + CommunityPersonBan, + CommunityPersonBanForm, + }, + person::Person, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -28,6 +41,42 @@ pub struct BlockUserFromCommunity { common: ActivityCommonFields, } +impl BlockUserFromCommunity { + pub(in crate::activities::community) fn new( + id: Url, + community: &Community, + target: &Person, + actor: &Person, + ) -> BlockUserFromCommunity { + BlockUserFromCommunity { + to: PublicUrl::Public, + object: target.actor_id(), + cc: [community.actor_id()], + kind: BlockType::Block, + common: ActivityCommonFields { + context: lemmy_context(), + id, + actor: actor.actor_id(), + unparsed: Default::default(), + }, + } + } + + pub async fn send( + community: &Community, + target: &Person, + actor: &Person, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let id = generate_activity_id(BlockType::Block)?; + let block = BlockUserFromCommunity::new(id.clone(), community, target, actor); + + let activity = AnnouncableActivities::BlockUserFromCommunity(block); + let inboxes = vec![target.get_shared_inbox_or_inbox_url()]; + send_to_community_new(activity, &id, actor, community, inboxes, context).await + } +} + #[async_trait::async_trait(?Send)] impl ActivityHandler for BlockUserFromCommunity { async fn verify( diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 49cf9615f..ba80ff4ad 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -8,6 +8,7 @@ use url::Url; pub mod add_mod; pub mod announce; pub mod block_user; +pub mod remove_mod; pub mod undo_block_user; pub mod update; diff --git a/crates/apub/src/activities/removal/remove.rs b/crates/apub/src/activities/community/remove_mod.rs similarity index 65% rename from crates/apub/src/activities/removal/remove.rs rename to crates/apub/src/activities/community/remove_mod.rs index 1bd6e0a03..9ca0082fd 100644 --- a/crates/apub/src/activities/removal/remove.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -1,19 +1,27 @@ use crate::{ activities::{ + community::announce::AnnouncableActivities, deletion::{delete::receive_remove_action, verify_delete_activity}, + generate_activity_id, verify_activity, verify_add_remove_moderator_target, verify_mod_action, verify_person_in_community, }, + activity_queue::send_to_community_new, + extensions::context::lemmy_context, fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, - CommunityType, + generate_moderators_url, + ActorType, }; -use activitystreams::{activity::kind::RemoveType, base::AnyBase}; +use activitystreams::activity::kind::RemoveType; use lemmy_api_common::blocking; use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler}; use lemmy_db_queries::Joinable; -use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm}; +use lemmy_db_schema::source::{ + community::{Community, CommunityModerator, CommunityModeratorForm}, + person::Person, +}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -22,16 +30,44 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct RemoveMod { to: PublicUrl, - pub(in crate::activities::removal) object: Url, + pub(in crate::activities) object: Url, cc: [Url; 1], #[serde(rename = "type")] kind: RemoveType, // if target is set, this is means remove mod from community - pub(in crate::activities::removal) target: Option, + pub(in crate::activities) target: Option, #[serde(flatten)] common: ActivityCommonFields, } +impl RemoveMod { + pub async fn send( + community: &Community, + removed_mod: &Person, + actor: &Person, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let id = generate_activity_id(RemoveType::Remove)?; + let remove = RemoveMod { + to: PublicUrl::Public, + object: removed_mod.actor_id(), + target: Some(generate_moderators_url(&community.actor_id)?.into()), + cc: [community.actor_id()], + kind: RemoveType::Remove, + common: ActivityCommonFields { + context: lemmy_context(), + id: id.clone(), + actor: actor.actor_id(), + unparsed: Default::default(), + }, + }; + + let activity = AnnouncableActivities::RemoveMod(remove); + let inboxes = vec![removed_mod.get_shared_inbox_or_inbox_url()]; + send_to_community_new(activity, &id, actor, community, inboxes, context).await + } +} + #[async_trait::async_trait(?Send)] impl ActivityHandler for RemoveMod { async fn verify( @@ -77,10 +113,6 @@ impl ActivityHandler for RemoveMod { CommunityModerator::leave(conn, &form) }) .await??; - let anybase = AnyBase::from_arbitrary_json(serde_json::to_string(&self)?)?; - community - .send_announce(anybase, Some(self.object.clone()), context) - .await?; // TODO: send websocket notification about removed mod Ok(()) } else { diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs index 514c90ccd..0afe77c36 100644 --- a/crates/apub/src/activities/community/undo_block_user.rs +++ b/crates/apub/src/activities/community/undo_block_user.rs @@ -1,17 +1,24 @@ use crate::{ activities::{ - community::block_user::BlockUserFromCommunity, + community::{announce::AnnouncableActivities, block_user::BlockUserFromCommunity}, + generate_activity_id, verify_activity, verify_mod_action, verify_person_in_community, }, + activity_queue::send_to_community_new, + extensions::context::lemmy_context, fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person}, + ActorType, }; -use activitystreams::activity::kind::UndoType; +use activitystreams::activity::kind::{BlockType, UndoType}; use lemmy_api_common::blocking; use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler}; use lemmy_db_queries::Bannable; -use lemmy_db_schema::source::community::{CommunityPersonBan, CommunityPersonBanForm}; +use lemmy_db_schema::source::{ + community::{Community, CommunityPersonBan, CommunityPersonBanForm}, + person::Person, +}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -28,6 +35,40 @@ pub struct UndoBlockUserFromCommunity { common: ActivityCommonFields, } +impl UndoBlockUserFromCommunity { + pub async fn send( + community: &Community, + target: &Person, + actor: &Person, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let block = BlockUserFromCommunity::new( + generate_activity_id(BlockType::Block)?, + community, + target, + actor, + ); + + let id = generate_activity_id(UndoType::Undo)?; + let undo = UndoBlockUserFromCommunity { + to: PublicUrl::Public, + object: block, + cc: [community.actor_id()], + kind: UndoType::Undo, + common: ActivityCommonFields { + context: lemmy_context(), + id: id.clone(), + actor: actor.actor_id(), + unparsed: Default::default(), + }, + }; + + let activity = AnnouncableActivities::UndoBlockUserFromCommunity(undo); + let inboxes = vec![target.get_shared_inbox_or_inbox_url()]; + send_to_community_new(activity, &id, actor, community, inboxes, context).await + } +} + #[async_trait::async_trait(?Send)] impl ActivityHandler for UndoBlockUserFromCommunity { async fn verify( diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index d38d722bf..3b60981e3 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -1,12 +1,24 @@ use crate::{ - activities::{verify_activity, verify_mod_action, verify_person_in_community}, - objects::community::Group, + activities::{ + community::announce::AnnouncableActivities, + generate_activity_id, + verify_activity, + verify_mod_action, + verify_person_in_community, + }, + activity_queue::send_to_community_new, + extensions::context::lemmy_context, + objects::{community::Group, ToApub}, + ActorType, }; use activitystreams::activity::kind::UpdateType; use lemmy_api_common::blocking; use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler}; use lemmy_db_queries::{ApubObject, Crud}; -use lemmy_db_schema::source::community::{Community, CommunityForm}; +use lemmy_db_schema::source::{ + community::{Community, CommunityForm}, + person::Person, +}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; use url::Url; @@ -25,6 +37,31 @@ pub struct UpdateCommunity { common: ActivityCommonFields, } +impl UpdateCommunity { + pub async fn send( + community: &Community, + actor: &Person, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let id = generate_activity_id(UpdateType::Update)?; + let update = UpdateCommunity { + to: PublicUrl::Public, + object: community.to_apub(context.pool()).await?, + cc: [community.actor_id()], + kind: UpdateType::Update, + common: ActivityCommonFields { + context: lemmy_context(), + id: id.clone(), + actor: actor.actor_id(), + unparsed: Default::default(), + }, + }; + + let activity = AnnouncableActivities::UpdateCommunity(Box::new(update)); + send_to_community_new(activity, &id, actor, community, vec![], context).await + } +} + #[async_trait::async_trait(?Send)] impl ActivityHandler for UpdateCommunity { async fn verify( diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index afbad6c8b..8d44bcc11 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -26,8 +26,8 @@ pub mod deletion; pub mod following; pub mod post; pub mod private_message; -pub mod removal; pub mod send; +pub mod undo_remove; pub mod voting; #[derive(Clone, Debug, ToString, Deserialize, Serialize)] diff --git a/crates/apub/src/activities/removal/mod.rs b/crates/apub/src/activities/removal/mod.rs deleted file mode 100644 index 01c031dd7..000000000 --- a/crates/apub/src/activities/removal/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod remove; -pub mod undo_remove; diff --git a/crates/apub/src/activities/send/community.rs b/crates/apub/src/activities/send/community.rs index a103f95c6..29aa9dba8 100644 --- a/crates/apub/src/activities/send/community.rs +++ b/crates/apub/src/activities/send/community.rs @@ -1,38 +1,10 @@ -use crate::{ - activities::generate_activity_id, - activity_queue::{send_to_community, send_to_community_followers}, - check_is_apub_id_valid, - extensions::context::lemmy_context, - fetcher::get_or_fetch_and_upsert_actor, - generate_moderators_url, - insert_activity, - objects::ToApub, - ActorType, - CommunityType, -}; -use activitystreams::{ - activity::{ - kind::{AddType, AnnounceType, BlockType, RemoveType, UndoType, UpdateType}, - Add, - Announce, - Block, - OptTargetRefExt, - Remove, - Undo, - Update, - }, - base::{AnyBase, BaseExt, ExtendsExt}, - object::ObjectExt, - public, -}; -use anyhow::Context; +use crate::{check_is_apub_id_valid, ActorType, CommunityType}; use itertools::Itertools; use lemmy_api_common::blocking; use lemmy_db_queries::DbPool; -use lemmy_db_schema::source::{community::Community, person::Person}; +use lemmy_db_schema::source::community::Community; use lemmy_db_views_actor::community_follower_view::CommunityFollowerView; -use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; -use lemmy_websocket::LemmyContext; +use lemmy_utils::LemmyError; use url::Url; impl ActorType for Community { @@ -67,71 +39,6 @@ impl CommunityType for Community { self.followers_url.clone().into() } - /// If a remote community is updated by a local mod, send the updated info to the community's - /// instance. - async fn send_update(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError> { - if self.local { - // Do nothing, other instances will automatically refetch the community - } else { - let mut update = Update::new( - mod_.actor_id(), - AnyBase::from_arbitrary_json(self.to_apub(context.pool()).await?)?, - ); - update - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(UpdateType::Update)?) - .set_to(public()) - .set_many_ccs(vec![self.actor_id()]); - send_to_community(update, &mod_, self, None, context).await?; - } - Ok(()) - } - - /// Wraps an activity sent to the community in an announce, and then sends the announce to all - /// community followers. - /// - /// If we are announcing a local activity, it hasn't been stored in the database yet, and we need - /// to do it here, so that it can be fetched by ID. Remote activities are inserted into DB in the - /// inbox. - /// - /// If the `object` of the announced activity is an actor, the actor ID needs to be passed as - /// `object_actor`, so that the announce can be delivered to that user. - async fn send_announce( - &self, - activity: AnyBase, - object_actor: Option, - context: &LemmyContext, - ) -> Result<(), LemmyError> { - let inner_id = activity.id().context(location_info!())?; - if inner_id.domain() == Some(&Settings::get().get_hostname_without_port()?) { - insert_activity(inner_id, activity.clone(), true, false, context.pool()).await?; - } - - let mut ccs = vec![self.followers_url()]; - let mut object_actor_inbox: Option = None; - if let Some(actor_id) = object_actor { - // Ignore errors, maybe its not actually an actor - // TODO: should pass the actual request counter in, but that seems complicated - let actor = get_or_fetch_and_upsert_actor(&actor_id, context, &mut 0) - .await - .ok(); - if let Some(actor) = actor { - ccs.push(actor_id); - object_actor_inbox = Some(actor.get_shared_inbox_or_inbox_url()); - } - } - let mut announce = Announce::new(self.actor_id(), activity); - announce - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(AnnounceType::Announce)?) - .set_to(public()) - .set_many_ccs(ccs); - - send_to_community_followers(announce, self, object_actor_inbox, context).await?; - - Ok(()) - } - /// For a given community, returns the inboxes of all followers. async fn get_follower_inboxes(&self, pool: &DbPool) -> Result, LemmyError> { let id = self.id; @@ -152,82 +59,4 @@ impl CommunityType for Community { Ok(inboxes) } - - async fn send_add_mod( - &self, - actor: &Person, - added_mod: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError> { - let mut add = Add::new(actor.actor_id(), added_mod.actor_id()); - add - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(AddType::Add)?) - .set_to(public()) - .set_many_ccs(vec![self.actor_id()]) - .set_target(generate_moderators_url(&self.actor_id)?.into_inner()); - - send_to_community(add, actor, self, Some(added_mod.actor_id()), context).await?; - Ok(()) - } - - async fn send_remove_mod( - &self, - actor: &Person, - removed_mod: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError> { - let mut remove = Remove::new(actor.actor_id(), removed_mod.actor_id()); - remove - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(RemoveType::Remove)?) - .set_to(public()) - .set_many_ccs(vec![self.actor_id()]) - .set_target(generate_moderators_url(&self.actor_id)?.into_inner()); - - send_to_community(remove, actor, self, Some(removed_mod.actor_id()), context).await?; - Ok(()) - } - - async fn send_block_user( - &self, - actor: &Person, - blocked_user: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError> { - let mut block = Block::new(actor.actor_id(), blocked_user.actor_id()); - block - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(BlockType::Block)?) - .set_to(public()) - .set_many_ccs(vec![self.actor_id()]); - - send_to_community(block, actor, self, Some(blocked_user.actor_id()), context).await?; - Ok(()) - } - - async fn send_undo_block_user( - &self, - actor: &Person, - unblocked_user: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError> { - let mut block = Block::new(actor.actor_id(), unblocked_user.actor_id()); - block - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(BlockType::Block)?) - .set_to(public()) - .set_many_ccs(vec![self.actor_id()]); - - // Undo that fake activity - let mut undo = Undo::new(actor.actor_id(), block.into_any_base()?); - undo - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(UndoType::Undo)?) - .set_to(public()) - .set_many_ccs(vec![self.actor_id()]); - - send_to_community(undo, actor, self, Some(unblocked_user.actor_id()), context).await?; - Ok(()) - } } diff --git a/crates/apub/src/activities/removal/undo_remove.rs b/crates/apub/src/activities/undo_remove.rs similarity index 97% rename from crates/apub/src/activities/removal/undo_remove.rs rename to crates/apub/src/activities/undo_remove.rs index e2c7ef76f..6518cd5f6 100644 --- a/crates/apub/src/activities/removal/undo_remove.rs +++ b/crates/apub/src/activities/undo_remove.rs @@ -1,6 +1,6 @@ use crate::activities::{ + community::remove_mod::RemoveMod, deletion::{undo_delete::UndoDelete, verify_delete_activity}, - removal::remove::RemoveMod, verify_activity, }; use activitystreams::activity::kind::UndoType; diff --git a/crates/apub/src/activity_queue.rs b/crates/apub/src/activity_queue.rs index 48cccc612..01959c7d7 100644 --- a/crates/apub/src/activity_queue.rs +++ b/crates/apub/src/activity_queue.rs @@ -1,16 +1,10 @@ use crate::{ activities::community::announce::{AnnouncableActivities, AnnounceActivity}, - check_is_apub_id_valid, extensions::signatures::sign_and_send, insert_activity, ActorType, - CommunityType, APUB_JSON_CONTENT_TYPE, }; -use activitystreams::{ - base::{BaseExt, Extends, ExtendsExt}, - object::AsObject, -}; use anyhow::{anyhow, Context, Error}; use background_jobs::{ create_server, @@ -21,95 +15,15 @@ use background_jobs::{ QueueHandle, WorkerConfig, }; -use itertools::Itertools; -use lemmy_db_schema::source::{community::Community, person::Person}; +use lemmy_db_schema::source::community::Community; use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; -use log::{debug, info, warn}; +use log::{info, warn}; use reqwest::Client; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, env, fmt::Debug, future::Future, pin::Pin}; use url::Url; -/// From a local community, send activity to all remote followers. -/// -/// * `activity` the apub activity to send -/// * `community` the sending community -/// * `extra_inbox` actor inbox which should receive the activity, in addition to followers -pub(crate) async fn send_to_community_followers( - activity: T, - community: &Community, - extra_inbox: Option, - context: &LemmyContext, -) -> Result<(), LemmyError> -where - T: AsObject + Extends + Debug + BaseExt, - Kind: Serialize, - >::Error: From + Send + Sync + 'static, -{ - let extra_inbox: Vec = extra_inbox.into_iter().collect(); - let follower_inboxes: Vec = vec![ - community.get_follower_inboxes(context.pool()).await?, - extra_inbox, - ] - .iter() - .flatten() - .unique() - .filter(|inbox| inbox.host_str() != Some(&Settings::get().hostname)) - .filter(|inbox| check_is_apub_id_valid(inbox, false).is_ok()) - .map(|inbox| inbox.to_owned()) - .collect(); - debug!( - "Sending activity {:?} to followers of {}", - &activity.id_unchecked().map(ToString::to_string), - &community.actor_id - ); - - send_activity_internal(context, activity, community, follower_inboxes, true, false).await?; - - Ok(()) -} - -/// Sends an activity from a local person to a remote community. -/// -/// * `activity` the activity to send -/// * `creator` the creator of the activity -/// * `community` the destination community -/// * `object_actor` if the object of the activity is an actor, it should be passed here so it can -/// be sent directly to the actor -/// -pub(crate) async fn send_to_community( - activity: T, - creator: &Person, - community: &Community, - object_actor: Option, - context: &LemmyContext, -) -> Result<(), LemmyError> -where - T: AsObject + Extends + Debug + BaseExt, - Kind: Serialize, - >::Error: From + Send + Sync + 'static, -{ - // if this is a local community, we need to do an announce from the community instead - if community.local { - community - .send_announce(activity.into_any_base()?, object_actor, context) - .await?; - } else { - let inbox = community.get_shared_inbox_or_inbox_url(); - check_is_apub_id_valid(&inbox, false)?; - debug!( - "Sending activity {:?} to community {}", - &activity.id_unchecked().map(ToString::to_string), - &community.actor_id - ); - // dont send to object_actor here, as that is responsibility of the community itself - send_activity_internal(context, activity, creator, vec![inbox], true, false).await?; - } - - Ok(()) -} - pub(crate) async fn send_to_community_new( activity: AnnouncableActivities, activity_id: &Url, @@ -184,62 +98,6 @@ where Ok(()) } -/// Create new `SendActivityTasks`, which will deliver the given activity to inboxes, as well as -/// handling signing and retrying failed deliveres. -/// -/// The caller of this function needs to remove any blocked domains from `to`, -/// using `check_is_apub_id_valid()`. -async fn send_activity_internal( - context: &LemmyContext, - activity: T, - actor: &dyn ActorType, - inboxes: Vec, - insert_into_db: bool, - sensitive: bool, -) -> Result<(), LemmyError> -where - T: AsObject + Extends + Debug, - Kind: Serialize, - >::Error: From + Send + Sync + 'static, -{ - if !Settings::get().federation.enabled || inboxes.is_empty() { - return Ok(()); - } - - // Don't send anything to ourselves - let hostname = Settings::get().get_hostname_without_port()?; - let inboxes: Vec<&Url> = inboxes - .iter() - .filter(|i| i.domain().expect("valid inbox url") != hostname) - .collect(); - - let activity = activity.into_any_base()?; - let serialised_activity = serde_json::to_string(&activity)?; - - // This is necessary because send_comment and send_comment_mentions - // might send the same ap_id - if insert_into_db { - let id = activity.id().context(location_info!())?; - insert_activity(id, activity.clone(), true, sensitive, context.pool()).await?; - } - - for i in inboxes { - let message = SendActivityTask { - activity: serialised_activity.to_owned(), - inbox: i.to_owned(), - actor_id: actor.actor_id(), - private_key: actor.private_key().context(location_info!())?, - }; - if env::var("LEMMY_TEST_SEND_SYNC").is_ok() { - do_send(message, &Client::default()).await?; - } else { - context.activity_queue.queue::(message)?; - } - } - - Ok(()) -} - #[derive(Clone, Debug, Deserialize, Serialize)] struct SendActivityTask { activity: String, diff --git a/crates/apub/src/http/inbox_enums.rs b/crates/apub/src/http/inbox_enums.rs index 1ed210bb5..e3726e95e 100644 --- a/crates/apub/src/http/inbox_enums.rs +++ b/crates/apub/src/http/inbox_enums.rs @@ -4,6 +4,7 @@ use crate::activities::{ add_mod::AddMod, announce::AnnounceActivity, block_user::BlockUserFromCommunity, + remove_mod::RemoveMod, undo_block_user::UndoBlockUserFromCommunity, update::UpdateCommunity, }, @@ -15,7 +16,7 @@ use crate::activities::{ delete::DeletePrivateMessage, undo_delete::UndoDeletePrivateMessage, }, - removal::{remove::RemoveMod, undo_remove::UndoRemovePostCommentOrCommunity}, + undo_remove::UndoRemovePostCommentOrCommunity, voting::{undo_vote::UndoVote, vote::Vote}, }; use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler}; diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 477143009..839e7d148 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -10,7 +10,6 @@ pub mod migrations; pub mod objects; use crate::extensions::signatures::PublicKey; -use activitystreams::base::AnyBase; use anyhow::{anyhow, Context}; use diesel::NotFound; use lemmy_api_common::blocking; @@ -139,41 +138,6 @@ trait ActorType { pub trait CommunityType { fn followers_url(&self) -> Url; async fn get_follower_inboxes(&self, pool: &DbPool) -> Result, LemmyError>; - - async fn send_update(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError>; - - async fn send_announce( - &self, - activity: AnyBase, - object: Option, - context: &LemmyContext, - ) -> Result<(), LemmyError>; - - async fn send_add_mod( - &self, - actor: &Person, - added_mod: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError>; - async fn send_remove_mod( - &self, - actor: &Person, - removed_mod: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError>; - - async fn send_block_user( - &self, - actor: &Person, - blocked_user: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError>; - async fn send_undo_block_user( - &self, - actor: &Person, - blocked_user: Person, - context: &LemmyContext, - ) -> Result<(), LemmyError>; } pub enum EndpointType { diff --git a/crates/apub_lib/src/lib.rs b/crates/apub_lib/src/lib.rs index df73d5e8f..15267db71 100644 --- a/crates/apub_lib/src/lib.rs +++ b/crates/apub_lib/src/lib.rs @@ -53,13 +53,6 @@ pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), LemmyError> { Ok(()) } -pub fn verify_domains_match_opt(a: &Url, b: Option<&Url>) -> Result<(), LemmyError> { - if let Some(b2) = b { - return verify_domains_match(a, b2); - } - Ok(()) -} - pub fn verify_urls_match(a: &Url, b: &Url) -> Result<(), LemmyError> { if a != b { return Err(DomainError.into());