diff --git a/Cargo.lock b/Cargo.lock index f3848fe6d..be38a4626 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "8f27d075294830fcab6f66e320dab524bc6d048f4a151698e153205559113772" [[package]] name = "activitypub_federation" -version = "0.7.0-beta.4" +version = "0.7.0-beta.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fb4c19ede0a628977cdc5d1ec7d1fb3e3e3e5e9de955bd0d5fed0c8cd5260d" +checksum = "e58f584c183501d7865b18d8b94c9477f750051ce99d54a399a2f4180667574c" dependencies = [ "activitystreams-kinds", "actix-web", @@ -4056,7 +4056,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.0", + "windows-targets 0.52.6", ] [[package]] @@ -7976,29 +7976,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - [[package]] name = "windows-threading" version = "0.1.0" @@ -8020,12 +8004,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -8038,12 +8016,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -8056,24 +8028,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -8086,12 +8046,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -8104,12 +8058,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -8122,12 +8070,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -8140,12 +8082,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" version = "0.7.10" diff --git a/Cargo.toml b/Cargo.toml index 24a011311..a7ab1ab36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -140,7 +140,7 @@ lemmy_db_views_reports = { version = "=1.0.0-alpha.5", path = "./crates/db_views lemmy_db_views_search_combined = { version = "=1.0.0-alpha.5", path = "./crates/db_views/search_combined" } lemmy_db_views_site = { version = "=1.0.0-alpha.5", path = "./crates/db_views/site" } lemmy_db_views_vote = { version = "=1.0.0-alpha.5", path = "./crates/db_views/vote" } -activitypub_federation = { version = "0.7.0-beta.4", default-features = false, features = [ +activitypub_federation = { version = "0.7.0-beta.5", default-features = false, features = [ "actix-web", ] } diesel = { version = "2.2.10", features = [ diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml index d4583d0ec..5b43f1c59 100644 --- a/crates/apub/Cargo.toml +++ b/crates/apub/Cargo.toml @@ -18,6 +18,9 @@ doctest = false [lints] workspace = true +[features] +full = [] + [dependencies] lemmy_db_views_comment = { workspace = true, features = ["full"] } lemmy_db_views_community = { workspace = true, features = ["full"] } diff --git a/crates/apub/src/activities/block/block_user.rs b/crates/apub/src/activities/block/block_user.rs index cf6e1ab32..a7fdfa702 100644 --- a/crates/apub/src/activities/block/block_user.rs +++ b/crates/apub/src/activities/block/block_user.rs @@ -13,7 +13,7 @@ use crate::{ use activitypub_federation::{ config::Data, kinds::activity::BlockType, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use chrono::{DateTime, Utc}; use lemmy_api_utils::{ @@ -48,11 +48,11 @@ impl BlockUser { ) -> LemmyResult { let to = to(target)?; Ok(BlockUser { - actor: mod_.id().into(), + actor: mod_.id().clone().into(), to, - object: user.id().into(), + object: user.id().clone().into(), cc: generate_cc(target, &mut context.pool()).await?, - target: target.id(), + target: target.id().clone().into(), kind: BlockType::Block, remove_data, summary: reason, @@ -82,11 +82,11 @@ impl BlockUser { .await?; match target { - SiteOrCommunity::Site(_) => { + SiteOrCommunity::Left(_) => { let inboxes = ActivitySendTargets::to_all_instances(); send_lemmy_activity(context, block, mod_, inboxes, false).await } - SiteOrCommunity::Community(c) => { + SiteOrCommunity::Right(c) => { let activity = AnnouncableActivities::BlockUser(block); let inboxes = ActivitySendTargets::to_inbox(user.shared_inbox_or_inbox()); send_activity_in_community(activity, mod_, c, inboxes, true, context).await @@ -96,7 +96,7 @@ impl BlockUser { } #[async_trait::async_trait] -impl ActivityHandler for BlockUser { +impl Activity for BlockUser { type DataType = LemmyContext; type Error = LemmyError; @@ -110,10 +110,10 @@ impl ActivityHandler for BlockUser { async fn verify(&self, context: &Data) -> LemmyResult<()> { match self.target.dereference(context).await? { - SiteOrCommunity::Site(_site) => { + SiteOrCommunity::Left(_site) => { verify_is_public(&self.to, &self.cc)?; } - SiteOrCommunity::Community(community) => { + SiteOrCommunity::Right(community) => { verify_visibility(&self.to, &self.cc, &community)?; verify_person_in_community(&self.actor, &community, context).await?; verify_mod_action(&self.actor, &community, context).await?; @@ -130,7 +130,7 @@ impl ActivityHandler for BlockUser { let reason = self.summary; let pool = &mut context.pool(); match target { - SiteOrCommunity::Site(site) => { + SiteOrCommunity::Left(site) => { let form = InstanceBanForm::new(blocked_person.id, site.instance_id, expires_at); InstanceActions::ban(pool, &form).await?; @@ -155,7 +155,7 @@ impl ActivityHandler for BlockUser { }; ModBan::create(&mut context.pool(), &form).await?; } - SiteOrCommunity::Community(community) => { + SiteOrCommunity::Right(community) => { let community_user_ban_form = CommunityPersonBanForm { ban_expires_at: Some(expires_at), ..CommunityPersonBanForm::new(community.id, blocked_person.id) diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 4892fc509..407f9d8a0 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -1,15 +1,9 @@ use crate::protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser}; -use activitypub_federation::{ - config::Data, - fetch::object_id::ObjectId, - kinds::public, - traits::{Actor, Object}, -}; -use chrono::{DateTime, Utc}; +use activitypub_federation::{config::Data, kinds::public, traits::Object}; +use either::Either; use lemmy_api_utils::{context::LemmyContext, utils::check_expire_time}; use lemmy_apub_objects::{ objects::{community::ApubCommunity, instance::ApubSite}, - protocol::{group::Group, instance::Instance}, utils::functions::generate_to, }; use lemmy_db_schema::{ @@ -19,106 +13,22 @@ use lemmy_db_schema::{ utils::DbPool, }; use lemmy_db_views_community::api::BanFromCommunity; -use lemmy_utils::error::{LemmyError, LemmyResult}; -use serde::Deserialize; +use lemmy_utils::error::LemmyResult; use url::Url; pub mod block_user; pub mod undo_block_user; -#[derive(Clone, Debug)] -pub enum SiteOrCommunity { - Site(ApubSite), - Community(ApubCommunity), -} -#[derive(Deserialize)] -#[serde(untagged)] -pub enum InstanceOrGroup { - Instance(Box), - Group(Box), -} - -#[async_trait::async_trait] -impl Object for SiteOrCommunity { - type DataType = LemmyContext; - type Kind = InstanceOrGroup; - type Error = LemmyError; - - fn last_refreshed_at(&self) -> Option> { - Some(match self { - SiteOrCommunity::Site(i) => i.last_refreshed_at, - SiteOrCommunity::Community(c) => c.last_refreshed_at, - }) - } - - async fn read_from_id(object_id: Url, data: &Data) -> LemmyResult> - where - Self: Sized, - { - let site = ApubSite::read_from_id(object_id.clone(), data).await?; - Ok(match site { - Some(o) => Some(SiteOrCommunity::Site(o)), - None => ApubCommunity::read_from_id(object_id, data) - .await? - .map(SiteOrCommunity::Community), - }) - } - - async fn delete(self, data: &Data) -> LemmyResult<()> { - match self { - SiteOrCommunity::Site(i) => i.delete(data).await, - SiteOrCommunity::Community(c) => c.delete(data).await, - } - } - - async fn into_json(self, data: &Data) -> LemmyResult { - Ok(match self { - SiteOrCommunity::Site(i) => InstanceOrGroup::Instance(Box::new(i.into_json(data).await?)), - SiteOrCommunity::Community(c) => InstanceOrGroup::Group(Box::new(c.into_json(data).await?)), - }) - } - - async fn verify( - apub: &Self::Kind, - expected_domain: &Url, - data: &Data, - ) -> LemmyResult<()> { - match apub { - InstanceOrGroup::Instance(i) => ApubSite::verify(i, expected_domain, data).await, - InstanceOrGroup::Group(g) => ApubCommunity::verify(g, expected_domain, data).await, - } - } - - async fn from_json(apub: Self::Kind, data: &Data) -> LemmyResult - where - Self: Sized, - { - Ok(match apub { - InstanceOrGroup::Instance(p) => SiteOrCommunity::Site(ApubSite::from_json(*p, data).await?), - InstanceOrGroup::Group(n) => { - SiteOrCommunity::Community(ApubCommunity::from_json(*n, data).await?) - } - }) - } -} - -impl SiteOrCommunity { - fn id(&self) -> ObjectId { - match self { - SiteOrCommunity::Site(s) => ObjectId::from(s.ap_id.clone()), - SiteOrCommunity::Community(c) => ObjectId::from(c.ap_id.clone()), - } - } -} +pub type SiteOrCommunity = Either; async fn generate_cc(target: &SiteOrCommunity, pool: &mut DbPool<'_>) -> LemmyResult> { Ok(match target { - SiteOrCommunity::Site(_) => Site::read_remote_sites(pool) + SiteOrCommunity::Left(_) => Site::read_remote_sites(pool) .await? .into_iter() .map(|s| s.ap_id.into()) .collect(), - SiteOrCommunity::Community(c) => vec![c.id()], + SiteOrCommunity::Right(c) => vec![c.id().clone()], }) } @@ -131,7 +41,7 @@ pub(crate) async fn send_ban_from_site( expires: Option, context: Data, ) -> LemmyResult<()> { - let site = SiteOrCommunity::Site(Site::read_local(&mut context.pool()).await?.into()); + let site = SiteOrCommunity::Left(Site::read_local(&mut context.pool()).await?.into()); let expires = check_expire_time(expires)?; if ban { @@ -172,7 +82,7 @@ pub(crate) async fn send_ban_from_community( if data.ban { BlockUser::send( - &SiteOrCommunity::Community(community), + &SiteOrCommunity::Right(community), &banned_person.into(), &mod_.into(), data.remove_or_restore_data.unwrap_or(false), @@ -183,7 +93,7 @@ pub(crate) async fn send_ban_from_community( .await } else { UndoBlockUser::send( - &SiteOrCommunity::Community(community), + &SiteOrCommunity::Right(community), &banned_person.into(), &mod_.into(), data.remove_or_restore_data.unwrap_or(false), @@ -195,7 +105,7 @@ pub(crate) async fn send_ban_from_community( } fn to(target: &SiteOrCommunity) -> LemmyResult> { - Ok(if let SiteOrCommunity::Community(c) = target { + Ok(if let SiteOrCommunity::Right(c) = target { generate_to(c)? } else { vec![public()] diff --git a/crates/apub/src/activities/block/undo_block_user.rs b/crates/apub/src/activities/block/undo_block_user.rs index 2509ccd7f..90ccdd883 100644 --- a/crates/apub/src/activities/block/undo_block_user.rs +++ b/crates/apub/src/activities/block/undo_block_user.rs @@ -13,7 +13,7 @@ use activitypub_federation::{ config::Data, kinds::activity::UndoType, protocol::verification::verify_domains_match, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use lemmy_api_utils::{ context::LemmyContext, @@ -49,7 +49,7 @@ impl UndoBlockUser { let id = generate_activity_id(UndoType::Undo, context)?; let undo = UndoBlockUser { - actor: mod_.id().into(), + actor: mod_.id().clone().into(), to, object: block, cc: generate_cc(target, &mut context.pool()).await?, @@ -60,11 +60,11 @@ impl UndoBlockUser { let mut inboxes = ActivitySendTargets::to_inbox(user.shared_inbox_or_inbox()); match target { - SiteOrCommunity::Site(_) => { + SiteOrCommunity::Left(_) => { inboxes.set_all_instances(); send_lemmy_activity(context, undo, mod_, inboxes, false).await } - SiteOrCommunity::Community(c) => { + SiteOrCommunity::Right(c) => { let activity = AnnouncableActivities::UndoBlockUser(undo); send_activity_in_community(activity, mod_, c, inboxes, true, context).await } @@ -73,7 +73,7 @@ impl UndoBlockUser { } #[async_trait::async_trait] -impl ActivityHandler for UndoBlockUser { +impl Activity for UndoBlockUser { type DataType = LemmyContext; type Error = LemmyError; @@ -97,7 +97,7 @@ impl ActivityHandler for UndoBlockUser { let blocked_person = self.object.object.dereference(context).await?; let pool = &mut context.pool(); match self.object.target.dereference(context).await? { - SiteOrCommunity::Site(site) => { + SiteOrCommunity::Left(site) => { verify_is_public(&self.to, &self.cc)?; let form = InstanceBanForm::new(blocked_person.id, site.instance_id, expires_at); InstanceActions::unban(pool, &form).await?; @@ -123,7 +123,7 @@ impl ActivityHandler for UndoBlockUser { }; ModBan::create(&mut context.pool(), &form).await?; } - SiteOrCommunity::Community(community) => { + SiteOrCommunity::Right(community) => { verify_visibility(&self.to, &self.cc, &community)?; let community_user_ban_form = CommunityPersonBanForm::new(community.id, blocked_person.id); CommunityActions::unban(&mut context.pool(), &community_user_ban_form).await?; diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs index f2b0152ff..f24bdd677 100644 --- a/crates/apub/src/activities/community/announce.rs +++ b/crates/apub/src/activities/community/announce.rs @@ -9,7 +9,7 @@ use crate::{ use activitypub_federation::{ config::Data, kinds::activity::AnnounceType, - traits::{ActivityHandler, Actor}, + traits::{Activity, Object}, }; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::{ @@ -25,7 +25,7 @@ use serde_json::Value; use url::Url; #[async_trait::async_trait] -impl ActivityHandler for RawAnnouncableActivities { +impl Activity for RawAnnouncableActivities { type DataType = LemmyContext; type Error = LemmyError; @@ -70,6 +70,12 @@ impl ActivityHandler for RawAnnouncableActivities { } } +impl Id for RawAnnouncableActivities { + fn id(&self) -> &Url { + &self.id + } +} + impl AnnounceActivity { pub(crate) fn new( object: RawAnnouncableActivities, @@ -84,7 +90,7 @@ impl AnnounceActivity { let id = generate_announce_activity_id(inner_kind, &context.settings().get_protocol_and_hostname())?; Ok(AnnounceActivity { - actor: community.id().into(), + actor: community.id().clone().into(), to: generate_to(community)?, object: IdOrNestedObject::NestedObject(object), cc: community @@ -129,7 +135,7 @@ impl AnnounceActivity { } #[async_trait::async_trait] -impl ActivityHandler for AnnounceActivity { +impl Activity for AnnounceActivity { type DataType = LemmyContext; type Error = LemmyError; @@ -163,12 +169,6 @@ impl ActivityHandler for AnnounceActivity { } } -impl Id for RawAnnouncableActivities { - fn object_id(&self) -> &Url { - ActivityHandler::id(self) - } -} - impl TryFrom for AnnouncableActivities { type Error = serde_json::error::Error; diff --git a/crates/apub/src/activities/community/collection_add.rs b/crates/apub/src/activities/community/collection_add.rs index cef1b5700..549de124e 100644 --- a/crates/apub/src/activities/community/collection_add.rs +++ b/crates/apub/src/activities/community/collection_add.rs @@ -10,7 +10,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::activity::AddType, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use lemmy_api_utils::{ context::LemmyContext, @@ -47,11 +47,11 @@ impl CollectionAdd { ) -> LemmyResult<()> { let id = generate_activity_id(AddType::Add, context)?; let add = CollectionAdd { - actor: actor.id().into(), + actor: actor.id().clone().into(), to: generate_to(community)?, - object: added_mod.id(), + object: added_mod.id().clone(), target: generate_moderators_url(&community.ap_id)?.into(), - cc: vec![community.id()], + cc: vec![community.id().clone()], kind: AddType::Add, id: id.clone(), }; @@ -69,11 +69,11 @@ impl CollectionAdd { ) -> LemmyResult<()> { let id = generate_activity_id(AddType::Add, context)?; let add = CollectionAdd { - actor: actor.id().into(), + actor: actor.id().clone().into(), to: generate_to(community)?, object: featured_post.ap_id.clone().into(), target: generate_featured_url(&community.ap_id)?.into(), - cc: vec![community.id()], + cc: vec![community.id().clone()], kind: AddType::Add, id: id.clone(), }; @@ -91,7 +91,7 @@ impl CollectionAdd { } #[async_trait::async_trait] -impl ActivityHandler for CollectionAdd { +impl Activity for CollectionAdd { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/community/collection_remove.rs b/crates/apub/src/activities/community/collection_remove.rs index 3af2c7235..9d0685e07 100644 --- a/crates/apub/src/activities/community/collection_remove.rs +++ b/crates/apub/src/activities/community/collection_remove.rs @@ -7,7 +7,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::activity::RemoveType, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use lemmy_api_utils::{ context::LemmyContext, @@ -42,12 +42,12 @@ impl CollectionRemove { ) -> LemmyResult<()> { let id = generate_activity_id(RemoveType::Remove, context)?; let remove = CollectionRemove { - actor: actor.id().into(), + actor: actor.id().clone().into(), to: generate_to(community)?, - object: removed_mod.id(), + object: removed_mod.id().clone(), target: generate_moderators_url(&community.ap_id)?.into(), id: id.clone(), - cc: vec![community.id()], + cc: vec![community.id().clone()], kind: RemoveType::Remove, }; @@ -64,11 +64,11 @@ impl CollectionRemove { ) -> LemmyResult<()> { let id = generate_activity_id(RemoveType::Remove, context)?; let remove = CollectionRemove { - actor: actor.id().into(), + actor: actor.id().clone().into(), to: generate_to(community)?, object: featured_post.ap_id.clone().into(), target: generate_featured_url(&community.ap_id)?.into(), - cc: vec![community.id()], + cc: vec![community.id().clone()], kind: RemoveType::Remove, id: id.clone(), }; @@ -86,7 +86,7 @@ impl CollectionRemove { } #[async_trait::async_trait] -impl ActivityHandler for CollectionRemove { +impl Activity for CollectionRemove { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/community/lock_page.rs b/crates/apub/src/activities/community/lock_page.rs index 829c4b3fe..b40ea46bb 100644 --- a/crates/apub/src/activities/community/lock_page.rs +++ b/crates/apub/src/activities/community/lock_page.rs @@ -12,7 +12,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::activity::UndoType, - traits::ActivityHandler, + traits::Activity, }; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::{ @@ -36,7 +36,7 @@ use lemmy_utils::error::{LemmyError, LemmyResult}; use url::Url; #[async_trait::async_trait] -impl ActivityHandler for LockPage { +impl Activity for LockPage { type DataType = LemmyContext; type Error = LemmyError; @@ -80,7 +80,7 @@ impl ActivityHandler for LockPage { } #[async_trait::async_trait] -impl ActivityHandler for UndoLockPage { +impl Activity for UndoLockPage { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 6696d1614..0a4299717 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -11,7 +11,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::activity::FlagType, - traits::{ActivityHandler, Actor}, + traits::{Activity, Object}, }; use either::Either; use lemmy_api_utils::{ @@ -54,8 +54,8 @@ impl Report { let kind = FlagType::Flag; let id = generate_activity_id(kind.clone(), context)?; Ok(Report { - actor: actor.id().into(), - to: [receiver.id().into()], + actor: actor.id().clone().into(), + to: [receiver.id().clone().into()], object: ReportObject::Lemmy(object_id.clone()), summary: reason, content: None, @@ -79,7 +79,7 @@ impl Report { } #[async_trait::async_trait] -impl ActivityHandler for Report { +impl Activity for Report { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index 9ad7c0fa1..19379bcde 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -12,7 +12,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, protocol::verification::verify_urls_match, - traits::{ActivityHandler, Actor}, + traits::{Activity, Object}, }; use either::Either; use lemmy_api_utils::context::LemmyContext; @@ -49,8 +49,8 @@ impl ResolveReport { let id = generate_activity_id(kind.clone(), &context)?; let object = Report::new(&object_id, report_creator, receiver, None, &context)?; let resolve = ResolveReport { - actor: actor.id().into(), - to: [receiver.id().into()], + actor: actor.id().clone().into(), + to: [receiver.id().clone().into()], object, kind, id: id.clone(), @@ -62,7 +62,7 @@ impl ResolveReport { } #[async_trait::async_trait] -impl ActivityHandler for ResolveReport { +impl Activity for ResolveReport { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index 839949adf..28c3cce74 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -11,7 +11,7 @@ use crate::{ use activitypub_federation::{ config::Data, kinds::{activity::UpdateType, public}, - traits::{ActivityHandler, Actor, Object}, + traits::{Activity, Object}, }; use either::Either; use lemmy_api_utils::context::LemmyContext; @@ -44,10 +44,10 @@ pub(crate) async fn send_update_community( let actor: ApubPerson = actor.into(); let id = generate_activity_id(UpdateType::Update, &context)?; let update = Update { - actor: actor.id().into(), + actor: actor.id().clone().into(), to: generate_to(&community)?, object: Either::Left(community.clone().into_json(&context).await?), - cc: vec![community.id()], + cc: vec![community.id().clone()], kind: UpdateType::Update, id: id.clone(), }; @@ -73,7 +73,7 @@ pub(crate) async fn send_update_multi_community( let actor: ApubPerson = actor.into(); let id = generate_activity_id(UpdateType::Update, &context)?; let update = Update { - actor: actor.id().into(), + actor: actor.id().clone().into(), to: vec![multi.ap_id.clone().into(), public()], object: Either::Right(multi.clone().into_json(&context).await?), cc: vec![], @@ -88,7 +88,7 @@ pub(crate) async fn send_update_multi_community( } #[async_trait::async_trait] -impl ActivityHandler for Update { +impl Activity for Update { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/create_or_update/comment.rs b/crates/apub/src/activities/create_or_update/comment.rs index afb98e722..6ddaee396 100644 --- a/crates/apub/src/activities/create_or_update/comment.rs +++ b/crates/apub/src/activities/create_or_update/comment.rs @@ -11,7 +11,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, protocol::verification::{verify_domains_match, verify_urls_match}, - traits::{ActivityHandler, Actor, Object}, + traits::{Activity, Actor, Object}, }; use lemmy_api_utils::{ build_response::send_local_notifs, @@ -65,7 +65,7 @@ impl CreateOrUpdateNote { let note = ApubComment(comment).into_json(&context).await?; let create_or_update = CreateOrUpdateNote { - actor: person.id().into(), + actor: person.id().clone().into(), to: generate_to(&community)?, cc: note.cc.clone(), tag: note.tag.clone(), @@ -103,7 +103,7 @@ impl CreateOrUpdateNote { } #[async_trait::async_trait] -impl ActivityHandler for CreateOrUpdateNote { +impl Activity for CreateOrUpdateNote { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/create_or_update/note_wrapper.rs b/crates/apub/src/activities/create_or_update/note_wrapper.rs index 5cc0a4106..6ae9cb8e0 100644 --- a/crates/apub/src/activities/create_or_update/note_wrapper.rs +++ b/crates/apub/src/activities/create_or_update/note_wrapper.rs @@ -3,7 +3,7 @@ use crate::protocol::activities::create_or_update::{ note_wrapper::CreateOrUpdateNoteWrapper, private_message::CreateOrUpdatePrivateMessage, }; -use activitypub_federation::{config::Data, traits::ActivityHandler}; +use activitypub_federation::{config::Data, traits::Activity}; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::{objects::community::ApubCommunity, utils::protocol::InCommunity}; use lemmy_utils::error::{LemmyError, LemmyResult}; @@ -14,7 +14,7 @@ use url::Url; /// makes it difficult to distinguish them. This wrapper handles receiving of both types, and /// routes them to the correct handler. #[async_trait::async_trait] -impl ActivityHandler for CreateOrUpdateNoteWrapper { +impl Activity for CreateOrUpdateNoteWrapper { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/create_or_update/post.rs b/crates/apub/src/activities/create_or_update/post.rs index b30c11d6f..a60eaa95b 100644 --- a/crates/apub/src/activities/create_or_update/post.rs +++ b/crates/apub/src/activities/create_or_update/post.rs @@ -10,7 +10,7 @@ use crate::{ use activitypub_federation::{ config::Data, protocol::verification::{verify_domains_match, verify_urls_match}, - traits::{ActivityHandler, Actor, Object}, + traits::{Activity, Object}, }; use lemmy_api_utils::{build_response::send_local_notifs, context::LemmyContext}; use lemmy_apub_objects::{ @@ -47,10 +47,10 @@ impl CreateOrUpdatePage { ) -> LemmyResult { let id = generate_activity_id(kind.clone(), context)?; Ok(CreateOrUpdatePage { - actor: actor.id().into(), + actor: actor.id().clone().into(), to: generate_to(community)?, object: post.into_json(context).await?, - cc: vec![community.id()], + cc: vec![community.id().clone()], kind, id: id.clone(), }) @@ -85,7 +85,7 @@ impl CreateOrUpdatePage { } #[async_trait::async_trait] -impl ActivityHandler for CreateOrUpdatePage { +impl Activity for CreateOrUpdatePage { type DataType = LemmyContext; type Error = LemmyError; 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 7f565a6c8..dab98be74 100644 --- a/crates/apub/src/activities/create_or_update/private_message.rs +++ b/crates/apub/src/activities/create_or_update/private_message.rs @@ -8,7 +8,7 @@ use crate::{ use activitypub_federation::{ config::Data, protocol::verification::{verify_domains_match, verify_urls_match}, - traits::{ActivityHandler, Actor, Object}, + traits::{Activity, Actor, Object}, }; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::objects::{person::ApubPerson, private_message::ApubPrivateMessage}; @@ -28,8 +28,8 @@ pub(crate) async fn send_create_or_update_pm( let id = generate_activity_id(kind.clone(), &context)?; let create_or_update = CreateOrUpdatePrivateMessage { id: id.clone(), - actor: actor.id().into(), - to: [recipient.id().into()], + actor: actor.id().clone().into(), + to: [recipient.id().clone().into()], object: ApubPrivateMessage(pm_view.private_message.clone()) .into_json(&context) .await?, @@ -40,7 +40,7 @@ pub(crate) async fn send_create_or_update_pm( } #[async_trait::async_trait] -impl ActivityHandler for CreateOrUpdatePrivateMessage { +impl Activity for CreateOrUpdatePrivateMessage { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index 02b20dd2b..46caf0856 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -5,7 +5,7 @@ use crate::{ }, protocol::{activities::deletion::delete::Delete, IdOrNestedObject}, }; -use activitypub_federation::{config::Data, kinds::activity::DeleteType, traits::ActivityHandler}; +use activitypub_federation::{config::Data, kinds::activity::DeleteType, traits::Activity}; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::objects::person::ApubPerson; use lemmy_db_schema::{ @@ -31,7 +31,7 @@ use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResul use url::Url; #[async_trait::async_trait] -impl ActivityHandler for Delete { +impl Activity for Delete { type DataType = LemmyContext; type Error = LemmyError; @@ -91,7 +91,7 @@ impl Delete { Ok(Delete { actor: actor.ap_id.clone().into(), to, - object: IdOrNestedObject::Id(object.id()), + object: IdOrNestedObject::Id(object.id().clone()), cc: cc.into_iter().collect(), kind: DeleteType::Delete, summary, diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index 158bfeaae..e76a645a7 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -93,10 +93,24 @@ pub(crate) async fn send_apub_delete_private_message( let deletable = DeletableObjects::PrivateMessage(pm.into()); let inbox = ActivitySendTargets::to_inbox(recipient.shared_inbox_or_inbox()); if deleted { - let delete: Delete = Delete::new(actor, deletable, vec![recipient.id()], None, None, &context)?; + let delete: Delete = Delete::new( + actor, + deletable, + vec![recipient.id().clone()], + None, + None, + &context, + )?; send_lemmy_activity(&context, delete, actor, inbox, true).await?; } else { - let undo = UndoDelete::new(actor, deletable, vec![recipient.id()], None, None, &context)?; + let undo = UndoDelete::new( + actor, + deletable, + vec![recipient.id().clone()], + None, + None, + &context, + )?; send_lemmy_activity(&context, undo, actor, inbox, true).await?; }; Ok(()) @@ -150,13 +164,13 @@ impl DeletableObjects { Err(diesel::NotFound.into()) } - pub(crate) fn id(&self) -> Url { + pub(crate) fn id(&self) -> &Url { match self { DeletableObjects::Community(c) => c.id(), DeletableObjects::Person(p) => p.id(), - DeletableObjects::Comment(c) => c.ap_id.clone().into(), - DeletableObjects::Post(p) => p.ap_id.clone().into(), - DeletableObjects::PrivateMessage(p) => p.ap_id.clone().into(), + DeletableObjects::Comment(c) => c.ap_id.inner(), + DeletableObjects::Post(p) => p.ap_id.inner(), + DeletableObjects::PrivateMessage(p) => p.ap_id.inner(), } } } diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index 8273df4d3..e4dae2e4c 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -5,7 +5,7 @@ use crate::{ }, protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete}, }; -use activitypub_federation::{config::Data, kinds::activity::UndoType, traits::ActivityHandler}; +use activitypub_federation::{config::Data, kinds::activity::UndoType, traits::Activity}; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::objects::person::ApubPerson; use lemmy_db_schema::{ @@ -28,7 +28,7 @@ use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResul use url::Url; #[async_trait::async_trait] -impl ActivityHandler for UndoDelete { +impl Activity for UndoDelete { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index 1bf7529d1..386ce1d3d 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -6,7 +6,7 @@ use activitypub_federation::{ config::Data, kinds::activity::AcceptType, protocol::verification::verify_urls_match, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use lemmy_api_utils::context::LemmyContext; use lemmy_db_schema::{ @@ -21,8 +21,8 @@ impl AcceptFollow { let target = follow.object.dereference_local(context).await?; let person = follow.actor.clone().dereference(context).await?; let accept = AcceptFollow { - actor: target.id().into(), - to: Some([person.id().into()]), + actor: target.id().clone().into(), + to: Some([person.id().clone().into()]), object: follow, kind: AcceptType::Accept, id: generate_activity_id(AcceptType::Accept, context)?, @@ -34,7 +34,7 @@ impl AcceptFollow { /// Handle accepted follows #[async_trait::async_trait] -impl ActivityHandler for AcceptFollow { +impl Activity for AcceptFollow { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 08a334ede..f5b048ba0 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -6,7 +6,7 @@ use activitypub_federation::{ config::Data, kinds::activity::FollowType, protocol::verification::verify_urls_match, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use either::Either::*; use lemmy_api_utils::context::LemmyContext; @@ -35,9 +35,9 @@ impl Follow { context: &Data, ) -> LemmyResult { Ok(Follow { - actor: actor.id().into(), - object: target.id().into(), - to: Some([target.id().into()]), + actor: actor.id().clone().into(), + object: target.id().clone().into(), + to: Some([target.id().clone().into()]), kind: FollowType::Follow, id: generate_activity_id(FollowType::Follow, context)?, }) @@ -55,7 +55,7 @@ impl Follow { } #[async_trait::async_trait] -impl ActivityHandler for Follow { +impl Activity for Follow { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/following/mod.rs b/crates/apub/src/activities/following/mod.rs index d511001ae..5cc4a2ac6 100644 --- a/crates/apub/src/activities/following/mod.rs +++ b/crates/apub/src/activities/following/mod.rs @@ -5,7 +5,7 @@ use crate::protocol::activities::following::{ reject::RejectFollow, undo_follow::UndoFollow, }; -use activitypub_federation::{config::Data, kinds::activity::FollowType, traits::ActivityHandler}; +use activitypub_federation::{config::Data, kinds::activity::FollowType, traits::Activity}; use either::Either::*; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::objects::{person::ApubPerson, CommunityOrMulti, UserOrCommunityOrMulti}; @@ -60,14 +60,14 @@ pub async fn send_accept_or_reject_follow( } /// Wrapper type which is needed because we cant implement ActorT for Either. -async fn send_activity_from_user_or_community_or_multi( +async fn send_activity_from_user_or_community_or_multi( context: &Data, - activity: Activity, + activity: A, target: UserOrCommunityOrMulti, send_targets: ActivitySendTargets, ) -> LemmyResult<()> where - Activity: ActivityHandler + Serialize + Send + Sync + Clone + ActivityHandler, + A: Activity + Serialize + Send + Sync + Clone + Activity, { match target { Left(user) => send_lemmy_activity(context, activity, &user, send_targets, true).await, diff --git a/crates/apub/src/activities/following/reject.rs b/crates/apub/src/activities/following/reject.rs index 05154d201..fe23e6355 100644 --- a/crates/apub/src/activities/following/reject.rs +++ b/crates/apub/src/activities/following/reject.rs @@ -7,7 +7,7 @@ use activitypub_federation::{ config::Data, kinds::activity::RejectType, protocol::verification::verify_urls_match, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use lemmy_api_utils::context::LemmyContext; use lemmy_db_schema::{ @@ -22,8 +22,8 @@ impl RejectFollow { let user_or_community = follow.object.dereference_local(context).await?; let person = follow.actor.clone().dereference(context).await?; let reject = RejectFollow { - actor: user_or_community.id().into(), - to: Some([person.id().into()]), + actor: user_or_community.id().clone().into(), + to: Some([person.id().clone().into()]), object: follow, kind: RejectType::Reject, id: generate_activity_id(RejectType::Reject, context)?, @@ -35,7 +35,7 @@ impl RejectFollow { /// Handle rejected follows #[async_trait::async_trait] -impl ActivityHandler for RejectFollow { +impl Activity for RejectFollow { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index b33dd6e8a..5d80e8e34 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -6,7 +6,7 @@ use activitypub_federation::{ config::Data, kinds::activity::UndoType, protocol::verification::verify_urls_match, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor, Object}, }; use either::Either::*; use lemmy_api_utils::context::LemmyContext; @@ -31,8 +31,8 @@ impl UndoFollow { ) -> LemmyResult<()> { let object = Follow::new(actor, target, context)?; let undo = UndoFollow { - actor: actor.id().into(), - to: Some([target.id().into()]), + actor: actor.id().clone().into(), + to: Some([target.id().clone().into()]), object, kind: UndoType::Undo, id: generate_activity_id(UndoType::Undo, context)?, @@ -43,7 +43,7 @@ impl UndoFollow { } #[async_trait::async_trait] -impl ActivityHandler for UndoFollow { +impl Activity for UndoFollow { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index cacffe50f..667c1be64 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -26,7 +26,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::activity::AnnounceType, - traits::{ActivityHandler, Actor}, + traits::{Activity, Actor}, }; use either::Either; use following::send_accept_or_reject_follow; @@ -137,15 +137,15 @@ fn generate_announce_activity_id( Url::parse(&id) } -async fn send_lemmy_activity( +async fn send_lemmy_activity( data: &Data, - activity: Activity, + activity: A, actor: &ActorT, send_targets: ActivitySendTargets, sensitive: bool, ) -> LemmyResult<()> where - Activity: ActivityHandler + Serialize + Send + Sync + Clone + ActivityHandler, + A: Activity + Serialize + Send + Sync + Clone + Activity, ActorT: Actor + GetActorType, { info!("Saving outgoing activity to queue {}", activity.id()); @@ -162,7 +162,7 @@ where send_all_instances: send_targets.all_instances, send_community_followers_of: send_targets.community_followers_of.map(|e| e.0), actor_type: actor.actor_type(), - actor_apub_id: actor.id().into(), + actor_apub_id: actor.id().clone().into(), }; SentActivity::create(&mut data.pool(), form).await?; diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index bffe148d8..78ed8e508 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -9,7 +9,7 @@ use activitypub_federation::{ config::Data, kinds::activity::UndoType, protocol::verification::verify_urls_match, - traits::{ActivityHandler, Actor}, + traits::{Activity, Object}, }; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::{ @@ -26,7 +26,7 @@ impl UndoVote { context: &Data, ) -> LemmyResult { Ok(UndoVote { - actor: actor.id().into(), + actor: actor.id().clone().into(), object: vote, kind: UndoType::Undo, id: generate_activity_id(UndoType::Undo, context)?, @@ -35,7 +35,7 @@ impl UndoVote { } #[async_trait::async_trait] -impl ActivityHandler for UndoVote { +impl Activity for UndoVote { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index 13ab47eb9..c0fb99fa8 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -8,7 +8,7 @@ use crate::{ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, - traits::{ActivityHandler, Actor}, + traits::{Activity, Object}, }; use lemmy_api_utils::{context::LemmyContext, utils::check_bot_account}; use lemmy_apub_objects::{ @@ -28,7 +28,7 @@ impl Vote { context: &Data, ) -> LemmyResult { Ok(Vote { - actor: actor.id().into(), + actor: actor.id().clone().into(), object: object_id, kind: kind.clone(), id: generate_activity_id(kind, context)?, @@ -37,7 +37,7 @@ impl Vote { } #[async_trait::async_trait] -impl ActivityHandler for Vote { +impl Activity for Vote { type DataType = LemmyContext; type Error = LemmyError; diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index e2edfc7aa..f8011fa28 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -19,7 +19,7 @@ use crate::protocol::activities::{ }, voting::{undo_vote::UndoVote, vote::Vote}, }; -use activitypub_federation::{config::Data, traits::ActivityHandler}; +use activitypub_federation::{config::Data, traits::Activity}; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::{ objects::community::ApubCommunity, @@ -37,7 +37,7 @@ use url::Url; /// are handled correctly. #[derive(Debug, Deserialize, Serialize, Clone)] #[serde(untagged)] -#[enum_delegate::implement(ActivityHandler)] +#[enum_delegate::implement(Activity)] pub(crate) enum SharedInboxActivities { Follow(Follow), AcceptFollow(AcceptFollow), @@ -52,7 +52,7 @@ pub(crate) enum SharedInboxActivities { #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(untagged)] -#[enum_delegate::implement(ActivityHandler)] +#[enum_delegate::implement(Activity)] pub enum AnnouncableActivities { CreateOrUpdateNoteWrapper(CreateOrUpdateNoteWrapper), CreateOrUpdatePost(CreateOrUpdatePage), diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index fd767c5ba..3495e728f 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -13,7 +13,7 @@ use activitypub_federation::{ config::Data, kinds::collection::OrderedCollectionType, protocol::verification::verify_domains_match, - traits::{ActivityHandler, Collection}, + traits::{Activity, Collection}, }; use futures::future::join_all; use lemmy_api_utils::{context::LemmyContext, utils::generate_outbox_url}; diff --git a/crates/apub/src/http/comment.rs b/crates/apub/src/http/comment.rs index c7a4d197e..f7776bec9 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -1,5 +1,4 @@ use super::check_community_content_fetchable; -use crate::http::{create_apub_response, create_apub_tombstone_response, redirect_remote_object}; use activitypub_federation::{config::Data, traits::Object}; use actix_web::{web::Path, HttpRequest, HttpResponse}; use lemmy_api_utils::context::LemmyContext; @@ -9,7 +8,7 @@ use lemmy_db_schema::{ source::{comment::Comment, community::Community, post::Post}, traits::Crud, }; -use lemmy_utils::error::LemmyResult; +use lemmy_utils::{error::LemmyResult, FEDERATION_CONTEXT}; use serde::Deserialize; #[derive(Deserialize)] @@ -30,11 +29,5 @@ pub(crate) async fn get_apub_comment( let community = Community::read(&mut context.pool(), post.community_id).await?; check_community_content_fetchable(&community, &request, &context).await?; - if !comment.local { - Ok(redirect_remote_object(&comment.ap_id)) - } else if !comment.deleted && !comment.removed { - create_apub_response(&comment.into_json(&context).await?) - } else { - create_apub_tombstone_response(comment.ap_id.clone()) - } + comment.http_response(&FEDERATION_CONTEXT, &context).await } diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index e0d12492d..bac64220a 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -7,10 +7,10 @@ use crate::{ community_outbox::ApubCommunityOutbox, }, fetcher::get_instance_id, - http::{check_community_fetchable, create_apub_response, create_apub_tombstone_response}, + http::check_community_fetchable, }; use activitypub_federation::{ - actix_web::signing_actor, + actix_web::{response::create_http_response, signing_actor}, config::Data, fetch::object_id::ObjectId, traits::{Collection, Object}, @@ -33,7 +33,10 @@ use lemmy_db_schema::{ }; use lemmy_db_schema_file::enums::CommunityVisibility; use lemmy_db_views_community_follower::CommunityFollowerView; -use lemmy_utils::error::{LemmyErrorType, LemmyResult}; +use lemmy_utils::{ + error::{LemmyErrorType, LemmyResult}, + FEDERATION_CONTEXT, +}; use serde::Deserialize; #[derive(Deserialize, Clone)] @@ -57,13 +60,9 @@ pub(crate) async fn get_apub_community_http( .ok_or(LemmyErrorType::NotFound)? .into(); - if community.deleted || community.removed { - return create_apub_tombstone_response(community.ap_id.clone()); - } check_community_fetchable(&community)?; - let apub = community.into_json(&context).await?; - create_apub_response(&apub) + community.http_response(&FEDERATION_CONTEXT, &context).await } /// Returns an empty followers collection, only populating the size (for privacy). @@ -81,7 +80,7 @@ pub(crate) async fn get_apub_community_followers( } check_community_fetchable(&community)?; let followers = ApubCommunityFollower::read_local(&community.into(), &context).await?; - create_apub_response(&followers) + Ok(create_http_response(followers, &FEDERATION_CONTEXT)?) } /// Checks if a given actor follows the private community. Returns status 200 if true. @@ -132,7 +131,7 @@ pub(crate) async fn get_apub_community_outbox( .into(); check_community_content_fetchable(&community, &request, &context).await?; let outbox = ApubCommunityOutbox::read_local(&community, &context).await?; - create_apub_response(&outbox) + Ok(create_http_response(outbox, &FEDERATION_CONTEXT)?) } pub(crate) async fn get_apub_community_moderators( @@ -146,7 +145,7 @@ pub(crate) async fn get_apub_community_moderators( .into(); check_community_fetchable(&community)?; let moderators = ApubCommunityModerators::read_local(&community, &context).await?; - create_apub_response(&moderators) + Ok(create_http_response(moderators, &FEDERATION_CONTEXT)?) } /// Returns collection of featured (stickied) posts. @@ -162,7 +161,7 @@ pub(crate) async fn get_apub_community_featured( .into(); check_community_content_fetchable(&community, &request, &context).await?; let featured = ApubCommunityFeatured::read_local(&community, &context).await?; - create_apub_response(&featured) + Ok(create_http_response(featured, &FEDERATION_CONTEXT)?) } #[derive(Deserialize)] @@ -179,7 +178,7 @@ pub(crate) async fn get_apub_person_multi_community( .await? .into(); - create_apub_response(&multi.into_json(&context).await?) + multi.http_response(&FEDERATION_CONTEXT, &context).await } pub(crate) async fn get_apub_person_multi_community_follows( @@ -191,15 +190,16 @@ pub(crate) async fn get_apub_person_multi_community_follows( .into(); let collection = ApubFeedCollection::read_local(&multi, &context).await?; - create_apub_response(&collection) + Ok(create_http_response(collection, &FEDERATION_CONTEXT)?) } #[cfg(test)] pub(crate) mod tests { use super::*; + use activitypub_federation::protocol::tombstone::Tombstone; use actix_web::{body::to_bytes, test::TestRequest}; - use lemmy_apub_objects::protocol::{group::Group, tombstone::Tombstone}; + use lemmy_apub_objects::protocol::group::Group; use lemmy_db_schema::{ source::{ community::CommunityInsertForm, @@ -211,6 +211,7 @@ pub(crate) mod tests { }; use serde::de::DeserializeOwned; use serial_test::serial; + use url::Url; async fn init( deleted: bool, @@ -221,6 +222,7 @@ pub(crate) mod tests { let community_form = CommunityInsertForm { deleted: Some(deleted), + ap_id: Some(Url::parse("http://lemmy-alpha")?.into()), visibility: Some(visibility), ..CommunityInsertForm::new( data.instance.id, @@ -308,7 +310,6 @@ pub(crate) mod tests { let res = get_apub_community_outbox(path, context.clone(), request).await; assert!(res.is_err()); - //Community::delete(&mut context.pool(), community.id).await?; data.delete(&mut context.pool()).await?; Ok(()) } diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index 3b86fd896..7f24d128e 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -2,30 +2,22 @@ use crate::{activity_lists::SharedInboxActivities, fetcher::get_instance_id}; use activitypub_federation::{ actix_web::{ inbox::{receive_activity_with_hook, ReceiveActivityHook}, + response::create_http_response, signing_actor, }, config::Data, - protocol::context::WithContext, - traits::{ActivityHandler, Actor}, - FEDERATION_CONTENT_TYPE, + traits::{Activity, Object}, }; use actix_web::{ - http::header::VARY, web::{self, Bytes}, HttpRequest, HttpResponse, }; use lemmy_api_utils::{context::LemmyContext, plugins::plugin_hook_after}; -use lemmy_apub_objects::{ - objects::{SiteOrMultiOrCommunityOrUser, UserOrCommunity}, - protocol::tombstone::Tombstone, -}; -use lemmy_db_schema::{ - newtypes::DbUrl, - source::{ - activity::{ReceivedActivity, SentActivity}, - community::Community, - }, +use lemmy_apub_objects::objects::{SiteOrMultiOrCommunityOrUser, UserOrCommunity}; +use lemmy_db_schema::source::{ + activity::{ReceivedActivity, SentActivity}, + community::Community, }; use lemmy_db_schema_file::enums::CommunityVisibility; use lemmy_db_views_community_follower::CommunityFollowerView; @@ -33,8 +25,8 @@ use lemmy_utils::{ error::{FederationError, LemmyErrorExt, LemmyErrorType, LemmyResult}, FEDERATION_CONTEXT, }; -use serde::{Deserialize, Serialize}; -use std::{ops::Deref, time::Duration}; +use serde::Deserialize; +use std::time::Duration; use tokio::time::timeout; use tracing::debug; use url::Url; @@ -91,46 +83,6 @@ impl ReceiveActivityHook f } } -/// Convert the data to json and turn it into an HTTP Response with the correct ActivityPub -/// headers. -/// -/// actix-web doesn't allow pretty-print for json so we need to do this manually. -fn create_apub_response(data: &T) -> LemmyResult -where - T: Serialize, -{ - let json = serde_json::to_string_pretty(&WithContext::new(data, FEDERATION_CONTEXT.clone()))?; - - Ok( - HttpResponse::Ok() - .content_type(FEDERATION_CONTENT_TYPE) - .insert_header((VARY, "Accept")) - .body(json), - ) -} - -fn create_apub_tombstone_response>(id: T) -> LemmyResult { - let tombstone = Tombstone::new(id.into()); - let json = serde_json::to_string_pretty(&WithContext::new( - tombstone, - FEDERATION_CONTEXT.deref().clone(), - ))?; - - Ok( - HttpResponse::Gone() - .content_type(FEDERATION_CONTENT_TYPE) - .status(actix_web::http::StatusCode::GONE) - .insert_header((VARY, "Accept")) - .body(json), - ) -} - -fn redirect_remote_object(url: &DbUrl) -> HttpResponse { - let mut res = HttpResponse::PermanentRedirect(); - res.insert_header((actix_web::http::header::LOCATION, url.as_str())); - res.finish() -} - #[derive(Deserialize)] pub struct ActivityQuery { type_: String, @@ -140,7 +92,7 @@ pub struct ActivityQuery { /// Return the ActivityPub json representation of a local activity over HTTP. pub(crate) async fn get_activity( info: web::Path, - context: web::Data, + context: Data, ) -> LemmyResult { let settings = context.settings(); let activity_id = Url::parse(&format!( @@ -156,13 +108,12 @@ pub(crate) async fn get_activity( if sensitive { Ok(HttpResponse::Forbidden().finish()) } else { - create_apub_response(&activity.data) + Ok(create_http_response(&activity.data, &FEDERATION_CONTEXT)?) } } /// Ensure that the community is public and not removed/deleted. fn check_community_fetchable(community: &Community) -> LemmyResult<()> { - check_community_removed_or_deleted(community)?; if !community.visibility.can_federate() { return Err(LemmyErrorType::NotFound.into()); } @@ -176,7 +127,6 @@ async fn check_community_content_fetchable( context: &Data, ) -> LemmyResult<()> { use CommunityVisibility::*; - check_community_removed_or_deleted(community)?; match community.visibility { Public | Unlisted => Ok(()), Private => { @@ -207,10 +157,3 @@ async fn check_community_content_fetchable( LocalOnlyPublic | LocalOnlyPrivate => Err(LemmyErrorType::NotFound.into()), } } - -fn check_community_removed_or_deleted(community: &Community) -> LemmyResult<()> { - if community.deleted || community.removed { - Err(LemmyErrorType::Deleted)? - } - Ok(()) -} diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index c91530ba0..55319481d 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -1,13 +1,17 @@ -use crate::{ - http::{create_apub_response, create_apub_tombstone_response}, - protocol::collections::empty_outbox::EmptyOutbox, +use crate::protocol::collections::empty_outbox::EmptyOutbox; +use activitypub_federation::{ + actix_web::response::create_http_response, + config::Data, + traits::Object, }; -use activitypub_federation::{config::Data, traits::Object}; use actix_web::{web::Path, HttpResponse}; use lemmy_api_utils::{context::LemmyContext, utils::generate_outbox_url}; use lemmy_apub_objects::objects::person::ApubPerson; use lemmy_db_schema::{source::person::Person, traits::ApubActor}; -use lemmy_utils::error::{LemmyErrorType, LemmyResult}; +use lemmy_utils::{ + error::{LemmyErrorType, LemmyResult}, + FEDERATION_CONTEXT, +}; use serde::Deserialize; #[derive(Deserialize)] @@ -21,19 +25,13 @@ pub(crate) async fn get_apub_person_http( context: Data, ) -> LemmyResult { let user_name = info.into_inner().user_name; - // TODO: this needs to be able to read deleted persons, so that it can send tombstones + // This needs to be able to read deleted persons, so that it can send tombstones let person: ApubPerson = Person::read_from_name(&mut context.pool(), &user_name, true) .await? .ok_or(LemmyErrorType::NotFound)? .into(); - if !person.deleted { - let apub = person.into_json(&context).await?; - - create_apub_response(&apub) - } else { - create_apub_tombstone_response(person.ap_id.clone()) - } + person.http_response(&FEDERATION_CONTEXT, &context).await } pub(crate) async fn get_apub_person_outbox( @@ -45,5 +43,5 @@ pub(crate) async fn get_apub_person_outbox( .ok_or(LemmyErrorType::NotFound)?; let outbox_id = generate_outbox_url(&person.ap_id)?.into(); let outbox = EmptyOutbox::new(outbox_id)?; - create_apub_response(&outbox) + Ok(create_http_response(outbox, &FEDERATION_CONTEXT)?) } diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index 73ce1b91d..3b494c874 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -1,5 +1,4 @@ use super::check_community_content_fetchable; -use crate::http::{create_apub_response, create_apub_tombstone_response, redirect_remote_object}; use activitypub_federation::{config::Data, traits::Object}; use actix_web::{web, HttpRequest, HttpResponse}; use lemmy_api_utils::context::LemmyContext; @@ -9,7 +8,7 @@ use lemmy_db_schema::{ source::{community::Community, post::Post}, traits::Crud, }; -use lemmy_utils::error::LemmyResult; +use lemmy_utils::{error::LemmyResult, FEDERATION_CONTEXT}; use serde::Deserialize; #[derive(Deserialize)] @@ -30,11 +29,5 @@ pub(crate) async fn get_apub_post( check_community_content_fetchable(&community, &request, &context).await?; - if !post.local { - Ok(redirect_remote_object(&post.ap_id)) - } else if !post.deleted && !post.removed { - create_apub_response(&post.into_json(&context).await?) - } else { - create_apub_tombstone_response(post.ap_id.clone()) - } + post.http_response(&FEDERATION_CONTEXT, &context).await } diff --git a/crates/apub/src/http/site.rs b/crates/apub/src/http/site.rs index f950acc01..c1e0e28e4 100644 --- a/crates/apub/src/http/site.rs +++ b/crates/apub/src/http/site.rs @@ -1,17 +1,20 @@ -use crate::{http::create_apub_response, protocol::collections::empty_outbox::EmptyOutbox}; -use activitypub_federation::{config::Data, traits::Object}; +use crate::protocol::collections::empty_outbox::EmptyOutbox; +use activitypub_federation::{ + actix_web::response::create_http_response, + config::Data, + traits::Object, +}; use actix_web::HttpResponse; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::objects::instance::ApubSite; use lemmy_db_schema::source::site::Site; -use lemmy_utils::error::LemmyResult; +use lemmy_utils::{error::LemmyResult, FEDERATION_CONTEXT}; use url::Url; pub(crate) async fn get_apub_site_http(context: Data) -> LemmyResult { let site: ApubSite = Site::read_local(&mut context.pool()).await?.into(); - let apub = site.into_json(&context).await?; - create_apub_response(&apub) + site.http_response(&FEDERATION_CONTEXT, &context).await } pub(crate) async fn get_apub_site_outbox(context: Data) -> LemmyResult { @@ -20,5 +23,5 @@ pub(crate) async fn get_apub_site_outbox(context: Data) -> LemmyRe context.settings().get_protocol_and_hostname() ); let outbox = EmptyOutbox::new(Url::parse(&outbox_id)?)?; - create_apub_response(&outbox) + Ok(create_http_response(outbox, &FEDERATION_CONTEXT)?) } diff --git a/crates/apub/src/protocol/activities/block/block_user.rs b/crates/apub/src/protocol/activities/block/block_user.rs index 6e6d3c352..21cd922c6 100644 --- a/crates/apub/src/protocol/activities/block/block_user.rs +++ b/crates/apub/src/protocol/activities/block/block_user.rs @@ -44,8 +44,8 @@ impl InCommunity for BlockUser { async fn community(&self, context: &Data) -> LemmyResult { let target = self.target.dereference(context).await?; let community = match target { - SiteOrCommunity::Community(c) => c, - SiteOrCommunity::Site(_) => return Err(anyhow!("activity is not in community").into()), + SiteOrCommunity::Right(c) => c, + SiteOrCommunity::Left(_) => return Err(anyhow!("activity is not in community").into()), }; Ok(community) } diff --git a/crates/apub/src/protocol/activities/deletion/delete.rs b/crates/apub/src/protocol/activities/deletion/delete.rs index 0cf60631e..270986a61 100644 --- a/crates/apub/src/protocol/activities/deletion/delete.rs +++ b/crates/apub/src/protocol/activities/deletion/delete.rs @@ -3,13 +3,12 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::activity::DeleteType, - protocol::helpers::deserialize_one_or_many, + protocol::{helpers::deserialize_one_or_many, tombstone::Tombstone}, }; use anyhow::anyhow; use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::{ objects::{community::ApubCommunity, person::ApubPerson}, - protocol::tombstone::Tombstone, utils::protocol::InCommunity, }; use lemmy_db_schema::{ diff --git a/crates/apub/src/protocol/mod.rs b/crates/apub/src/protocol/mod.rs index 8fa8561ed..fed3362c4 100644 --- a/crates/apub/src/protocol/mod.rs +++ b/crates/apub/src/protocol/mod.rs @@ -3,16 +3,11 @@ use lemmy_api_utils::context::LemmyContext; use lemmy_apub_objects::utils::protocol::Id; use lemmy_utils::error::LemmyResult; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::collections::HashMap; use url::Url; pub mod activities; pub(crate) mod collections; -#[derive(Clone, Debug, Default, Deserialize, Serialize)] -#[serde(transparent)] -pub struct Unparsed(HashMap); - #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(untagged)] pub(crate) enum IdOrNestedObject { @@ -24,7 +19,7 @@ impl IdOrNestedObject { pub(crate) fn id(&self) -> &Url { match self { IdOrNestedObject::Id(i) => i, - IdOrNestedObject::NestedObject(n) => n.object_id(), + IdOrNestedObject::NestedObject(n) => n.id(), } } pub(crate) async fn object(self, context: &Data) -> LemmyResult { diff --git a/crates/apub_objects/Cargo.toml b/crates/apub_objects/Cargo.toml index 50641161d..77f231117 100644 --- a/crates/apub_objects/Cargo.toml +++ b/crates/apub_objects/Cargo.toml @@ -18,6 +18,9 @@ doctest = false [lints] workspace = true +[features] +full = [] + [dependencies] lemmy_db_views_community_moderator = { workspace = true, features = ["full"] } lemmy_db_views_community_person_ban = { workspace = true, features = ["full"] } @@ -25,7 +28,7 @@ lemmy_db_views_local_user = { workspace = true, features = ["full"] } lemmy_db_views_site = { workspace = true, features = ["full"] } lemmy_utils = { workspace = true, features = ["full"] } lemmy_db_schema = { workspace = true, features = ["full"] } -lemmy_api_utils = { workspace = true } +lemmy_api_utils = { workspace = true, features = ["full"] } activitypub_federation = { workspace = true } lemmy_db_schema_file = { workspace = true } chrono = { workspace = true } diff --git a/crates/apub_objects/src/objects/comment.rs b/crates/apub_objects/src/objects/comment.rs index 906b9a77d..3a3b7094b 100644 --- a/crates/apub_objects/src/objects/comment.rs +++ b/crates/apub_objects/src/objects/comment.rs @@ -74,8 +74,8 @@ impl Object for ApubComment { type Kind = Note; type Error = LemmyError; - fn last_refreshed_at(&self) -> Option> { - None + fn id(&self) -> &Url { + self.ap_id.inner() } async fn read_from_id( @@ -100,6 +100,10 @@ impl Object for ApubComment { Ok(()) } + fn is_deleted(&self) -> bool { + self.removed || self.deleted + } + async fn into_json(self, context: &Data) -> LemmyResult { let creator_id = self.creator_id; let creator = Person::read(&mut context.pool(), creator_id).await?; @@ -113,7 +117,7 @@ impl Object for ApubComment { let parent_comment = Comment::read(&mut context.pool(), comment_id).await?; parent_comment.ap_id.into() } else { - post.ap_id.into() + post.ap_id.clone().into() }; let language = Some(LanguageTag::new_single(self.language_id, &mut context.pool()).await?); let maa = collect_non_local_mentions(&self, context).await?; diff --git a/crates/apub_objects/src/objects/community.rs b/crates/apub_objects/src/objects/community.rs index f5a1c721e..badb3a3d4 100644 --- a/crates/apub_objects/src/objects/community.rs +++ b/crates/apub_objects/src/objects/community.rs @@ -81,6 +81,10 @@ impl Object for ApubCommunity { type Kind = Group; type Error = LemmyError; + fn id(&self) -> &Url { + self.ap_id.inner() + } + fn last_refreshed_at(&self) -> Option> { Some(self.last_refreshed_at) } @@ -105,6 +109,10 @@ impl Object for ApubCommunity { Ok(()) } + fn is_deleted(&self) -> bool { + self.removed || self.deleted + } + async fn into_json(self, data: &Data) -> LemmyResult { let community_id = self.id; let langs = CommunityLanguage::read(&mut data.pool(), community_id).await?; @@ -112,7 +120,7 @@ impl Object for ApubCommunity { let group = Group { kind: GroupType::Group, - id: self.id().into(), + id: self.id().clone().into(), preferred_username: self.name.clone(), name: Some(self.title.clone()), content: self.sidebar.as_ref().map(|d| markdown_to_html(d)), @@ -243,10 +251,6 @@ impl Object for ApubCommunity { } impl Actor for ApubCommunity { - fn id(&self) -> Url { - self.ap_id.inner().clone() - } - fn public_key_pem(&self) -> &str { &self.public_key } diff --git a/crates/apub_objects/src/objects/instance.rs b/crates/apub_objects/src/objects/instance.rs index 5fe066586..c71d2a0bd 100644 --- a/crates/apub_objects/src/objects/instance.rs +++ b/crates/apub_objects/src/objects/instance.rs @@ -69,6 +69,10 @@ impl Object for ApubSite { type Kind = Instance; type Error = LemmyError; + fn id(&self) -> &Url { + self.ap_id.inner() + } + fn last_refreshed_at(&self) -> Option> { Some(self.last_refreshed_at) } @@ -92,7 +96,7 @@ impl Object for ApubSite { let instance = Instance { kind: ApplicationType::Application, - id: self.id().into(), + id: self.id().clone().into(), name: self.name.clone(), preferred_username: Some(data.domain().to_string()), content: self.sidebar.as_ref().map(|d| markdown_to_html(d)), @@ -169,10 +173,6 @@ impl Object for ApubSite { } impl Actor for ApubSite { - fn id(&self) -> Url { - self.ap_id.inner().clone() - } - fn public_key_pem(&self) -> &str { &self.public_key } diff --git a/crates/apub_objects/src/objects/multi_community.rs b/crates/apub_objects/src/objects/multi_community.rs index 67e2e0334..3f3c779d1 100644 --- a/crates/apub_objects/src/objects/multi_community.rs +++ b/crates/apub_objects/src/objects/multi_community.rs @@ -43,6 +43,10 @@ impl Object for ApubMultiCommunity { type Kind = Feed; type Error = LemmyError; + fn id(&self) -> &Url { + self.ap_id.inner() + } + fn last_refreshed_at(&self) -> Option> { Some(self.last_refreshed_at) } @@ -62,6 +66,10 @@ impl Object for ApubMultiCommunity { Err(LemmyErrorType::NotFound.into()) } + fn is_deleted(&self) -> bool { + self.deleted + } + async fn into_json(self, context: &Data) -> LemmyResult { let site_view = SiteView::read_local(&mut context.pool()).await?; let site = ApubSite(site_view.site.clone()); @@ -115,10 +123,6 @@ impl Object for ApubMultiCommunity { } impl Actor for ApubMultiCommunity { - fn id(&self) -> Url { - self.ap_id.inner().clone() - } - fn public_key_pem(&self) -> &str { &self.public_key } diff --git a/crates/apub_objects/src/objects/person.rs b/crates/apub_objects/src/objects/person.rs index 9651cfcfb..a5d1bb65e 100644 --- a/crates/apub_objects/src/objects/person.rs +++ b/crates/apub_objects/src/objects/person.rs @@ -65,6 +65,10 @@ impl Object for ApubPerson { type Kind = Person; type Error = LemmyError; + fn id(&self) -> &Url { + self.ap_id.inner() + } + fn last_refreshed_at(&self) -> Option> { Some(self.last_refreshed_at) } @@ -89,6 +93,10 @@ impl Object for ApubPerson { Ok(()) } + fn is_deleted(&self) -> bool { + self.deleted + } + async fn into_json(self, _context: &Data) -> LemmyResult { let kind = if self.bot_account { UserTypes::Service @@ -181,10 +189,6 @@ impl Object for ApubPerson { } impl Actor for ApubPerson { - fn id(&self) -> Url { - self.ap_id.inner().clone() - } - fn public_key_pem(&self) -> &str { &self.public_key } diff --git a/crates/apub_objects/src/objects/post.rs b/crates/apub_objects/src/objects/post.rs index da7bc52e7..19e184f21 100644 --- a/crates/apub_objects/src/objects/post.rs +++ b/crates/apub_objects/src/objects/post.rs @@ -27,7 +27,7 @@ use activitypub_federation::{ traits::Object, }; use anyhow::anyhow; -use chrono::{DateTime, Utc}; +use chrono::Utc; use html2text::{from_read_with_decorator, render::TrivialDecorator}; use lemmy_api_utils::{ context::LemmyContext, @@ -82,8 +82,8 @@ impl Object for ApubPost { type Kind = Page; type Error = LemmyError; - fn last_refreshed_at(&self) -> Option> { - None + fn id(&self) -> &Url { + self.ap_id.inner() } async fn read_from_id( @@ -108,6 +108,10 @@ impl Object for ApubPost { Ok(()) } + fn is_deleted(&self) -> bool { + self.removed || self.deleted + } + // Turn a Lemmy post into an ActivityPub page that can be sent out over the network. async fn into_json(self, context: &Data) -> LemmyResult { diff --git a/crates/apub_objects/src/objects/private_message.rs b/crates/apub_objects/src/objects/private_message.rs index 43b384809..05f5ee576 100644 --- a/crates/apub_objects/src/objects/private_message.rs +++ b/crates/apub_objects/src/objects/private_message.rs @@ -14,7 +14,7 @@ use activitypub_federation::{ }, traits::Object, }; -use chrono::{DateTime, Utc}; +use chrono::Utc; use lemmy_api_utils::{ context::LemmyContext, plugins::{plugin_hook_after, plugin_hook_before}, @@ -59,8 +59,8 @@ impl Object for ApubPrivateMessage { type Kind = PrivateMessage; type Error = LemmyError; - fn last_refreshed_at(&self) -> Option> { - None + fn id(&self) -> &Url { + self.ap_id.inner() } async fn read_from_id( @@ -79,6 +79,10 @@ impl Object for ApubPrivateMessage { Err(LemmyErrorType::NotFound.into()) } + fn is_deleted(&self) -> bool { + self.removed || self.deleted + } + async fn into_json(self, context: &Data) -> LemmyResult { let creator_id = self.creator_id; let creator = Person::read(&mut context.pool(), creator_id).await?; diff --git a/crates/apub_objects/src/protocol/mod.rs b/crates/apub_objects/src/protocol/mod.rs index e59e00c9f..455da45ac 100644 --- a/crates/apub_objects/src/protocol/mod.rs +++ b/crates/apub_objects/src/protocol/mod.rs @@ -5,7 +5,6 @@ pub mod note; pub mod page; pub mod person; pub mod private_message; -pub mod tombstone; #[cfg(test)] mod tests { @@ -16,9 +15,9 @@ mod tests { page::Page, person::Person, private_message::PrivateMessage, - tombstone::Tombstone, }; use crate::utils::test::{test_json, test_parse_lemmy_item}; + use activitypub_federation::protocol::tombstone::Tombstone; use lemmy_utils::error::LemmyResult; #[test] diff --git a/crates/apub_objects/src/protocol/page.rs b/crates/apub_objects/src/protocol/page.rs index b1a281178..cb1af79bd 100644 --- a/crates/apub_objects/src/protocol/page.rs +++ b/crates/apub_objects/src/protocol/page.rs @@ -20,7 +20,7 @@ use activitypub_federation::{ helpers::{deserialize_one_or_many, deserialize_skip_error}, values::MediaTypeMarkdownOrHtml, }, - traits::{ActivityHandler, Object}, + traits::{Activity, Object}, }; use chrono::{DateTime, Utc}; use itertools::Itertools; @@ -200,7 +200,7 @@ impl Attachment { // Used for community outbox, so that it can be compatible with Pleroma/Mastodon. #[async_trait::async_trait] -impl ActivityHandler for Page { +impl Activity for Page { type DataType = LemmyContext; type Error = LemmyError; fn id(&self) -> &Url { diff --git a/crates/apub_objects/src/utils/mentions.rs b/crates/apub_objects/src/utils/mentions.rs index 9b751153f..3489f6c46 100644 --- a/crates/apub_objects/src/utils/mentions.rs +++ b/crates/apub_objects/src/utils/mentions.rs @@ -3,7 +3,7 @@ use activitypub_federation::{ config::Data, fetch::webfinger::webfinger_resolve_actor, kinds::link::MentionType, - traits::Actor, + traits::Object, }; use lemmy_api_utils::context::LemmyContext; use lemmy_db_schema::{ @@ -47,7 +47,7 @@ pub async fn collect_non_local_mentions( context: &Data, ) -> LemmyResult { let parent_creator = get_comment_parent_creator(&mut context.pool(), comment).await?; - let mut addressed_ccs: Vec = vec![parent_creator.id()]; + let mut addressed_ccs: Vec = vec![parent_creator.id().clone()]; // Add the mention tag let parent_creator_tag = Mention { @@ -77,7 +77,7 @@ pub async fn collect_non_local_mentions( addressed_ccs.push(person.ap_id.to_string().parse()?); let mention_tag = Mention { - href: person.id(), + href: person.id().clone(), name: Some(mention.full_name()), kind: MentionType::Mention, }; diff --git a/crates/apub_objects/src/utils/protocol.rs b/crates/apub_objects/src/utils/protocol.rs index 6ca2eba12..a64f9b8df 100644 --- a/crates/apub_objects/src/utils/protocol.rs +++ b/crates/apub_objects/src/utils/protocol.rs @@ -3,7 +3,7 @@ use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::object::ImageType, - protocol::values::MediaTypeMarkdown, + protocol::{tombstone::Tombstone, values::MediaTypeMarkdown}, }; use lemmy_api_utils::context::LemmyContext; use lemmy_db_schema::{ @@ -198,5 +198,11 @@ pub struct Endpoints { } pub trait Id { - fn object_id(&self) -> &Url; + fn id(&self) -> &Url; +} + +impl Id for Tombstone { + fn id(&self) -> &Url { + &self.id + } } diff --git a/crates/federate/src/send.rs b/crates/federate/src/send.rs index 73815d6fc..5441513ca 100644 --- a/crates/federate/src/send.rs +++ b/crates/federate/src/send.rs @@ -3,7 +3,7 @@ use activitypub_federation::{ activity_sending::SendActivityTask, config::Data, protocol::context::WithContext, - traits::ActivityHandler, + traits::Activity, }; use anyhow::{Context, Result}; use chrono::{DateTime, Utc}; @@ -166,7 +166,7 @@ struct DummyActivity { } #[async_trait::async_trait] -impl ActivityHandler for DummyActivity { +impl Activity for DummyActivity { type DataType = LemmyContext; type Error = LemmyError;