From d67cb191b511895b6ccd63d9fa3a4153faeb1064 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 10 Mar 2025 20:06:27 -0700 Subject: [PATCH 01/32] add calls to submit_activity and use SiteOrCommunity --- crates/api/src/reports/community_report/create.rs | 10 +++++++++- crates/api/src/reports/community_report/resolve.rs | 10 ++++++++++ crates/api_common/src/send_activity.rs | 4 ++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/crates/api/src/reports/community_report/create.rs b/crates/api/src/reports/community_report/create.rs index 71338d2d13..3221613917 100644 --- a/crates/api/src/reports/community_report/create.rs +++ b/crates/api/src/reports/community_report/create.rs @@ -63,7 +63,15 @@ pub async fn create_community_report( .await?; } - // TODO: consider federating this + ActivityChannel::submit_activity( + SendActivityData::CreateReport { + object_id: community_view.community.ap_id.inner().clone(), + actor: local_user_view.person, + target: SiteOrCommunity::Site(todo!()), + reason: data.reason.clone(), + }, + &context, + )?; Ok(Json(CommunityReportResponse { community_report_view, diff --git a/crates/api/src/reports/community_report/resolve.rs b/crates/api/src/reports/community_report/resolve.rs index 73fe1c80b1..7e2fc519a6 100644 --- a/crates/api/src/reports/community_report/resolve.rs +++ b/crates/api/src/reports/community_report/resolve.rs @@ -30,6 +30,16 @@ pub async fn resolve_community_report( let community_report_view = CommunityReportView::read(&mut context.pool(), report_id, person_id).await?; + ActivityChannel::submit_activity( + SendActivityData::SendResolveReport { + object_id: community_report_view.community.ap_id.inner().clone(), + actor: local_user_view.person, + report_creator: report.creator, + community: SiteOrCommunity::Site(todo!()), + }, + &context, + )?; + Ok(Json(CommunityReportResponse { community_report_view, })) diff --git a/crates/api_common/src/send_activity.rs b/crates/api_common/src/send_activity.rs index fdefbaac0f..8dcf398f73 100644 --- a/crates/api_common/src/send_activity.rs +++ b/crates/api_common/src/send_activity.rs @@ -96,14 +96,14 @@ pub enum SendActivityData { CreateReport { object_id: Url, actor: Person, - community: Community, + target: SiteOrCommunity, reason: String, }, SendResolveReport { object_id: Url, actor: Person, report_creator: Person, - community: Community, + target: SiteOrCommunity, }, } From 97f9ba02f98de5dd8d5c6649b1ef277d04e104ef Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Thu, 13 Mar 2025 21:49:20 -0700 Subject: [PATCH 02/32] add send_activity imports --- crates/api/src/reports/community_report/create.rs | 1 + crates/api/src/reports/community_report/resolve.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/api/src/reports/community_report/create.rs b/crates/api/src/reports/community_report/create.rs index 9a35f39b1e..3e3c17f544 100644 --- a/crates/api/src/reports/community_report/create.rs +++ b/crates/api/src/reports/community_report/create.rs @@ -3,6 +3,7 @@ use actix_web::web::{Data, Json}; use lemmy_api_common::{ context::LemmyContext, reports::community::{CommunityReportResponse, CreateCommunityReport}, + send_activity::{ActivityChannel, SendActivityData}, utils::{send_new_report_email_to_admins, slur_regex}, }; use lemmy_db_schema::{ diff --git a/crates/api/src/reports/community_report/resolve.rs b/crates/api/src/reports/community_report/resolve.rs index dc26756daf..eff0a55510 100644 --- a/crates/api/src/reports/community_report/resolve.rs +++ b/crates/api/src/reports/community_report/resolve.rs @@ -2,6 +2,7 @@ use actix_web::web::{Data, Json}; use lemmy_api_common::{ context::LemmyContext, reports::community::{CommunityReportResponse, ResolveCommunityReport}, + send_activity::{ActivityChannel, SendActivityData}, utils::is_admin, }; use lemmy_db_schema::{source::community_report::CommunityReport, traits::Reportable}; From eb46faae98ab8e21f745c163a3000e19fd51f432 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Fri, 14 Mar 2025 20:23:50 -0700 Subject: [PATCH 03/32] use separate CreateReportToSite and SendResolveReportToSite variants --- .../api/src/reports/community_report/create.rs | 8 +++++--- .../api/src/reports/community_report/resolve.rs | 16 ++++++++++++---- crates/api_common/src/send_activity.rs | 17 +++++++++++++++-- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/crates/api/src/reports/community_report/create.rs b/crates/api/src/reports/community_report/create.rs index 3e3c17f544..b83127a92c 100644 --- a/crates/api/src/reports/community_report/create.rs +++ b/crates/api/src/reports/community_report/create.rs @@ -11,6 +11,7 @@ use lemmy_db_schema::{ community::Community, community_report::{CommunityReport, CommunityReportForm}, local_site::LocalSite, + site::Site, }, traits::{Crud, Reportable}, }; @@ -29,6 +30,7 @@ pub async fn create_community_report( let person_id = local_user_view.person.id; let community_id = data.community_id; let community = Community::read(&mut context.pool(), community_id).await?; + let site = Site::read_from_instance_id(&mut context.pool(), community.instance_id).await?; let report_form = CommunityReportForm { creator_id: person_id, @@ -63,10 +65,10 @@ pub async fn create_community_report( } ActivityChannel::submit_activity( - SendActivityData::CreateReport { - object_id: community_view.community.ap_id.inner().clone(), + SendActivityData::CreateReportToSite { + object_id: community.ap_id.inner().clone(), actor: local_user_view.person, - target: SiteOrCommunity::Site(todo!()), + site, reason: data.reason.clone(), }, &context, diff --git a/crates/api/src/reports/community_report/resolve.rs b/crates/api/src/reports/community_report/resolve.rs index eff0a55510..e2217e013d 100644 --- a/crates/api/src/reports/community_report/resolve.rs +++ b/crates/api/src/reports/community_report/resolve.rs @@ -5,7 +5,10 @@ use lemmy_api_common::{ send_activity::{ActivityChannel, SendActivityData}, utils::is_admin, }; -use lemmy_db_schema::{source::community_report::CommunityReport, traits::Reportable}; +use lemmy_db_schema::{ + source::{community_report::CommunityReport, site::Site}, + traits::Reportable, +}; use lemmy_db_views::structs::{CommunityReportView, LocalUserView}; use lemmy_utils::error::LemmyResult; @@ -26,13 +29,18 @@ pub async fn resolve_community_report( let community_report_view = CommunityReportView::read(&mut context.pool(), report_id, person_id).await?; + let site = Site::read_from_instance_id( + &mut context.pool(), + community_report_view.community.instance_id, + ) + .await?; ActivityChannel::submit_activity( - SendActivityData::SendResolveReport { + SendActivityData::SendResolveReportToSite { object_id: community_report_view.community.ap_id.inner().clone(), actor: local_user_view.person, - report_creator: report.creator, - community: SiteOrCommunity::Site(todo!()), + report_creator: community_report_view.creator, + site, }, &context, )?; diff --git a/crates/api_common/src/send_activity.rs b/crates/api_common/src/send_activity.rs index 8dcf398f73..28d3f5c9d7 100644 --- a/crates/api_common/src/send_activity.rs +++ b/crates/api_common/src/send_activity.rs @@ -9,6 +9,7 @@ use lemmy_db_schema::{ person::Person, post::Post, private_message::PrivateMessage, + site::Site, }, }; use lemmy_db_views::structs::PrivateMessageView; @@ -96,14 +97,26 @@ pub enum SendActivityData { CreateReport { object_id: Url, actor: Person, - target: SiteOrCommunity, + community: Community, reason: String, }, SendResolveReport { object_id: Url, actor: Person, report_creator: Person, - target: SiteOrCommunity, + community: Community, + }, + CreateReportToSite { + object_id: Url, + actor: Person, + site: Site, + reason: String, + }, + SendResolveReportToSite { + object_id: Url, + actor: Person, + report_creator: Person, + site: Site, }, } From 8df24fb3291ab6342fa18956372e7f00692d7124 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Fri, 14 Mar 2025 20:43:32 -0700 Subject: [PATCH 04/32] fix api compile errors --- crates/api/src/reports/community_report/create.rs | 3 ++- crates/api/src/reports/community_report/resolve.rs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/api/src/reports/community_report/create.rs b/crates/api/src/reports/community_report/create.rs index b83127a92c..557c6f4fb2 100644 --- a/crates/api/src/reports/community_report/create.rs +++ b/crates/api/src/reports/community_report/create.rs @@ -1,5 +1,6 @@ use crate::check_report_reason; -use actix_web::web::{Data, Json}; +use activitypub_federation::config::Data; +use actix_web::web::Json; use lemmy_api_common::{ context::LemmyContext, reports::community::{CommunityReportResponse, CreateCommunityReport}, diff --git a/crates/api/src/reports/community_report/resolve.rs b/crates/api/src/reports/community_report/resolve.rs index e2217e013d..97b1c32b10 100644 --- a/crates/api/src/reports/community_report/resolve.rs +++ b/crates/api/src/reports/community_report/resolve.rs @@ -1,4 +1,5 @@ -use actix_web::web::{Data, Json}; +use activitypub_federation::config::Data; +use actix_web::web::Json; use lemmy_api_common::{ context::LemmyContext, reports::community::{CommunityReportResponse, ResolveCommunityReport}, @@ -39,7 +40,7 @@ pub async fn resolve_community_report( SendActivityData::SendResolveReportToSite { object_id: community_report_view.community.ap_id.inner().clone(), actor: local_user_view.person, - report_creator: community_report_view.creator, + report_creator: community_report_view.creator.clone(), site, }, &context, From 580151cc2ba9d52c806be9742bb439c04e1e8da6 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Sun, 16 Mar 2025 09:16:19 -0700 Subject: [PATCH 05/32] allow apub Report struct to represent community report --- crates/apub/src/fetcher/mod.rs | 1 + crates/apub/src/fetcher/report.rs | 8 ++++++++ crates/apub/src/protocol/activities/community/report.rs | 7 ++++--- 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 crates/apub/src/fetcher/report.rs diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index a6b2f24ca8..afc9163fbd 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -12,6 +12,7 @@ use lemmy_utils::error::{LemmyError, LemmyResult}; pub(crate) mod markdown_links; pub mod post_or_comment; +pub(crate) mod report; pub mod search; pub mod site_or_community_or_user; pub mod user_or_community; diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs new file mode 100644 index 0000000000..09df1d7037 --- /dev/null +++ b/crates/apub/src/fetcher/report.rs @@ -0,0 +1,8 @@ +use crate::{fetcher::post_or_comment::PostOrComment, objects::community::ApubCommunity}; + +/// The types of ActivityPub objects that reports can be created for. +#[derive(Debug)] +pub(crate) enum ReportableObjects { + PostOrComment(PostOrComment), + Community(ApubCommunity), +} diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 35b379b93c..1377f15b78 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -1,5 +1,6 @@ use crate::{ - fetcher::post_or_comment::PostOrComment, + activities::block::SiteOrCommunity, + fetcher::{post_or_comment::PostOrComment, report::ReportableObjects}, objects::{community::ApubCommunity, person::ApubPerson}, protocol::InCommunity, }; @@ -19,7 +20,7 @@ use url::Url; pub struct Report { pub(crate) actor: ObjectId, #[serde(deserialize_with = "deserialize_one")] - pub(crate) to: [ObjectId; 1], + pub(crate) to: [ObjectId; 1], pub(crate) object: ReportObject, /// Report reason as sent by Lemmy pub(crate) summary: Option, @@ -43,7 +44,7 @@ impl Report { #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(untagged)] pub(crate) enum ReportObject { - Lemmy(ObjectId), + Lemmy(ObjectId), /// Mastodon sends an array containing user id and one or more post ids Mastodon(Vec), } From 7b4604cc343e378b9008fcdd8a7b11d823b94814 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Sun, 16 Mar 2025 18:25:50 -0700 Subject: [PATCH 06/32] change argument types of Report::new, Report::send, and report_inboxes --- crates/apub/src/activities/community/mod.rs | 19 ++++++++++------ .../apub/src/activities/community/report.rs | 22 ++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 623b459911..778446e0e7 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -1,7 +1,7 @@ use crate::{ - activities::send_lemmy_activity, + activities::{block::SiteOrCommunity, send_lemmy_activity}, activity_lists::AnnouncableActivities, - fetcher::post_or_comment::PostOrComment, + fetcher::{post_or_comment::PostOrComment, report::ReportableObjects}, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::community::announce::AnnounceActivity, }; @@ -79,12 +79,16 @@ pub(crate) async fn send_activity_in_community( } async fn report_inboxes( - object_id: ObjectId, - community: &ApubCommunity, + object_id: ObjectId, + receiver: &SiteOrCommunity, context: &Data, ) -> LemmyResult { // send report to the community where object was posted - let mut inboxes = ActivitySendTargets::to_inbox(community.shared_inbox_or_inbox()); + let mut inboxes = ActivitySendTargets::to_inbox(receiver.shared_inbox_or_inbox()); + + let SiteOrCommunity::Community(community) = receiver else { + return Ok(inboxes); + }; if community.local { // send to all moderators @@ -96,8 +100,9 @@ async fn report_inboxes( // also send report to user's home instance if possible let object_creator_id = match object_id.dereference_local(context).await? { - PostOrComment::Post(p) => p.creator_id, - PostOrComment::Comment(c) => c.creator_id, + ReportableObjects::PostOrComment(PostOrComment::Post(p)) => p.creator_id, + ReportableObjects::PostOrComment(PostOrComment::Comment(c)) => c.creator_id, + _ => return Ok(inboxes), }; let object_creator = Person::read(&mut context.pool(), object_creator_id).await?; let object_creator_site: Option = diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index f0eced013b..0335d5111e 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -1,7 +1,13 @@ use super::report_inboxes; use crate::{ - activities::{generate_activity_id, send_lemmy_activity, verify_person_in_community}, + activities::{ + block::SiteOrCommunity, + generate_activity_id, + send_lemmy_activity, + verify_person_in_community, + }, activity_lists::AnnouncableActivities, + fetcher::report::ReportableObjects, insert_received_activity, objects::{community::ApubCommunity, person::ApubPerson}, protocol::{ @@ -35,9 +41,9 @@ use url::Url; impl Report { pub(crate) fn new( - object_id: &ObjectId, + object_id: &ObjectId, actor: &ApubPerson, - community: &ApubCommunity, + receiver: &SiteOrCommunity, reason: Option, context: &Data, ) -> LemmyResult { @@ -48,7 +54,7 @@ impl Report { )?; Ok(Report { actor: actor.id().into(), - to: [community.id().into()], + to: [receiver.id().into()], object: ReportObject::Lemmy(object_id.clone()), summary: reason, content: None, @@ -58,14 +64,14 @@ impl Report { } pub(crate) async fn send( - object_id: ObjectId, + object_id: ObjectId, actor: &ApubPerson, - community: &ApubCommunity, + receiver: &SiteOrCommunity, reason: String, context: Data, ) -> LemmyResult<()> { - let report = Self::new(&object_id, actor, community, Some(reason), &context)?; - let inboxes = report_inboxes(object_id, community, &context).await?; + let report = Self::new(&object_id, actor, receiver, Some(reason), &context)?; + let inboxes = report_inboxes(object_id, receiver, &context).await?; send_lemmy_activity(&context, report, actor, inboxes, false).await } From 9446e8a1b2200d51a9f7a2964950b5d7f2bb8b8c Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Sun, 16 Mar 2025 19:30:03 -0700 Subject: [PATCH 07/32] impl Object for ReportableObjects --- crates/apub/src/fetcher/report.rs | 79 ++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs index 09df1d7037..415c21c370 100644 --- a/crates/apub/src/fetcher/report.rs +++ b/crates/apub/src/fetcher/report.rs @@ -1,4 +1,14 @@ -use crate::{fetcher::post_or_comment::PostOrComment, objects::community::ApubCommunity}; +use crate::{ + fetcher::post_or_comment::{PageOrNote, PostOrComment}, + objects::community::ApubCommunity, + protocol::objects::group::Group, +}; +use activitypub_federation::{config::Data, traits::Object}; +use chrono::{DateTime, Utc}; +use lemmy_api_common::context::LemmyContext; +use lemmy_utils::error::{LemmyError, LemmyResult}; +use reqwest::Url; +use serde::Deserialize; /// The types of ActivityPub objects that reports can be created for. #[derive(Debug)] @@ -6,3 +16,70 @@ pub(crate) enum ReportableObjects { PostOrComment(PostOrComment), Community(ApubCommunity), } + +#[derive(Deserialize)] +#[serde(untagged)] +pub(crate) enum ReportableKinds { + PageOrNote(PageOrNote), + Group(Group), +} + +#[async_trait::async_trait] +impl Object for ReportableObjects { + type DataType = LemmyContext; + type Kind = ReportableKinds; + type Error = LemmyError; + + fn last_refreshed_at(&self) -> Option> { + match self { + ReportableObjects::PostOrComment(p) => p.last_refreshed_at(), + ReportableObjects::Community(c) => c.last_refreshed_at(), + } + } + + async fn read_from_id(object_id: Url, data: &Data) -> LemmyResult> { + let community = ApubCommunity::read_from_id(object_id.clone(), data).await?; + Ok(match community { + Some(o) => Some(ReportableObjects::Community(o)), + None => PostOrComment::read_from_id(object_id, data) + .await? + .map(ReportableObjects::PostOrComment), + }) + } + + async fn delete(self, data: &Data) -> LemmyResult<()> { + match self { + ReportableObjects::PostOrComment(p) => p.delete(data).await, + ReportableObjects::Community(c) => c.delete(data).await, + } + } + + async fn into_json(self, data: &Data) -> LemmyResult { + Ok(match self { + ReportableObjects::PostOrComment(p) => ReportableKinds::PageOrNote(p.into_json(data).await?), + ReportableObjects::Community(c) => ReportableKinds::Group(c.into_json(data).await?), + }) + } + + async fn verify( + apub: &Self::Kind, + expected_domain: &Url, + data: &Data, + ) -> LemmyResult<()> { + match apub { + ReportableKinds::PageOrNote(p) => PostOrComment::verify(p, expected_domain, data).await, + ReportableKinds::Group(g) => ApubCommunity::verify(g, expected_domain, data).await, + } + } + + async fn from_json(apub: Self::Kind, data: &Data) -> LemmyResult { + Ok(match apub { + ReportableKinds::PageOrNote(p) => { + ReportableObjects::PostOrComment(PostOrComment::from_json(p, data).await?) + } + ReportableKinds::Group(g) => { + ReportableObjects::Community(ApubCommunity::from_json(g, data).await?) + } + }) + } +} From b7ad0639bf048923e2078cc0a3813ffd43d0a50e Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Sun, 16 Mar 2025 20:24:34 -0700 Subject: [PATCH 08/32] impl Actor for SiteOrCommunity --- crates/apub/src/activities/block/mod.rs | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 0d635e09d2..795f02b1ad 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -107,6 +107,43 @@ impl Object for SiteOrCommunity { } } +impl Actor for SiteOrCommunity { + fn id(&self) -> Url { + match self { + SiteOrCommunity::Site(u) => u.id(), + SiteOrCommunity::Community(c) => c.id(), + } + } + + fn public_key_pem(&self) -> &str { + match self { + SiteOrCommunity::Site(p) => p.public_key_pem(), + SiteOrCommunity::Community(p) => p.public_key_pem(), + } + } + + fn private_key_pem(&self) -> Option { + match self { + SiteOrCommunity::Site(p) => p.private_key_pem(), + SiteOrCommunity::Community(p) => p.private_key_pem(), + } + } + + fn inbox(&self) -> Url { + match self { + SiteOrCommunity::Site(u) => u.inbox(), + SiteOrCommunity::Community(c) => c.inbox(), + } + } + + fn shared_inbox(&self) -> Option { + match self { + SiteOrCommunity::Site(u) => u.shared_inbox(), + SiteOrCommunity::Community(c) => c.shared_inbox(), + } + } +} + impl SiteOrCommunity { fn id(&self) -> ObjectId { match self { From 298019758dee75c83a011ed269b1842618ac796a Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 11:51:37 -0700 Subject: [PATCH 09/32] change return types of ReportObject::dereference and ReportObject::object_id --- crates/apub/src/protocol/activities/community/report.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 1377f15b78..9f1e0a27d8 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -53,7 +53,7 @@ impl ReportObject { pub(crate) async fn dereference( &self, context: &Data, - ) -> LemmyResult { + ) -> LemmyResult { match self { ReportObject::Lemmy(l) => l.dereference(context).await, ReportObject::Mastodon(objects) => { @@ -73,13 +73,13 @@ impl ReportObject { pub(crate) async fn object_id( &self, context: &Data, - ) -> LemmyResult> { + ) -> LemmyResult> { match self { ReportObject::Lemmy(l) => Ok(l.clone()), ReportObject::Mastodon(objects) => { for o in objects { // Same logic as above, but return the ID and not the object itself. - let deref = ObjectId::::from(o.clone()) + let deref = ObjectId::::from(o.clone()) .dereference(context) .await; if deref.is_ok() { From 8561dd0ef15413b856406022dd421483ffa8b531 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 12:10:17 -0700 Subject: [PATCH 10/32] Add verify_person_in_site_or_community --- crates/apub/src/activities/mod.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 28470cde3f..c4ce4aa793 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -30,6 +30,7 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use anyhow::anyhow; +use block::SiteOrCommunity; use following::send_accept_or_reject_follow; use lemmy_api_common::{ context::LemmyContext, @@ -90,6 +91,27 @@ pub(crate) async fn verify_person_in_community( CommunityPersonBanView::check(&mut context.pool(), person_id, community_id).await } +/// Fetches the person and community or site to verify their type, then checks if person is banned +/// from local site or community. +pub(crate) async fn verify_person_in_site_or_community( + person_id: &ObjectId, + site_or_community: &SiteOrCommunity, + context: &Data, +) -> LemmyResult<()> { + let person = person_id.dereference(context).await?; + if person.banned { + Err(FederationError::PersonIsBannedFromSite( + person.ap_id.to_string(), + ))? + } + if let SiteOrCommunity::Community(community) = site_or_community { + let person_id = person.id; + let community_id = community.id; + CommunityPersonBanView::check(&mut context.pool(), person_id, community_id).await?; + } + Ok(()) +} + /// Verify that mod action in community was performed by a moderator. /// /// * `mod_id` - Activitypub ID of the mod or admin who performed the action From f2fa0ed18c03cb91920a30cb083ba898064651a4 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 12:52:14 -0700 Subject: [PATCH 11/32] replace Report::community with Report::recipient to return either site or community, and add SiteOrCommunity::local_community --- crates/apub/src/activities/block/mod.rs | 7 ++++++ crates/apub/src/activities/community/mod.rs | 6 +---- .../apub/src/activities/community/report.rs | 16 ++++++------ .../activities/community/resolve_report.rs | 17 +++++++------ crates/apub/src/activities/mod.rs | 25 ++++++++++++++++++- crates/apub/src/activity_lists.rs | 11 ++++++-- .../protocol/activities/community/report.rs | 15 +++++------ .../activities/community/resolve_report.rs | 10 +++++--- 8 files changed, 73 insertions(+), 34 deletions(-) diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 795f02b1ad..8baa82f6c8 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -151,6 +151,13 @@ impl SiteOrCommunity { SiteOrCommunity::Community(c) => ObjectId::from(c.ap_id.clone()), } } + + pub(crate) fn local_community(&self) -> Option<&ApubCommunity> { + match self { + SiteOrCommunity::Community(c) if c.local => Some(c), + _ => None, + } + } } async fn generate_cc(target: &SiteOrCommunity, pool: &mut DbPool<'_>) -> LemmyResult> { diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 778446e0e7..99fee5eb81 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -86,11 +86,7 @@ async fn report_inboxes( // send report to the community where object was posted let mut inboxes = ActivitySendTargets::to_inbox(receiver.shared_inbox_or_inbox()); - let SiteOrCommunity::Community(community) = receiver else { - return Ok(inboxes); - }; - - if community.local { + if let Some(community) = receiver.local_community() { // send to all moderators let moderators = CommunityModeratorView::for_community(&mut context.pool(), community.id).await?; diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 0335d5111e..c319ad1b61 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -4,7 +4,7 @@ use crate::{ block::SiteOrCommunity, generate_activity_id, send_lemmy_activity, - verify_person_in_community, + verify_person_in_site_or_community, }, activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, @@ -91,8 +91,8 @@ impl ActivityHandler for Report { } async fn verify(&self, context: &Data) -> LemmyResult<()> { - let community = self.community(context).await?; - verify_person_in_community(&self.actor, &community, context).await?; + let recipient = self.recipient(context).await?; + verify_person_in_site_or_community(&self.actor, &recipient, context).await?; Ok(()) } @@ -129,14 +129,14 @@ impl ActivityHandler for Report { } }; - let community = self.community(context).await?; - if community.local { + let recipient = self.recipient(context).await?; + if let Some(community) = recipient.local_community() { // forward to remote mods let object_id = self.object.object_id(context).await?; let announce = AnnouncableActivities::Report(self); - let announce = AnnounceActivity::new(announce.try_into()?, &community, context)?; - let inboxes = report_inboxes(object_id, &community, context).await?; - send_lemmy_activity(context, announce, &community, inboxes.clone(), false).await?; + let announce = AnnounceActivity::new(announce.try_into()?, community, context)?; + let inboxes = report_inboxes(object_id, &recipient, context).await?; + send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?; } Ok(()) diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index e59e1fea66..39fd8359ec 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -5,6 +5,7 @@ use crate::{ send_lemmy_activity, verify_mod_action, verify_person_in_community, + verify_person_in_site_or_community, }, activity_lists::AnnouncableActivities, insert_received_activity, @@ -75,10 +76,10 @@ impl ActivityHandler for ResolveReport { async fn verify(&self, context: &Data) -> LemmyResult<()> { self.object.verify(context).await?; - let community = self.community(context).await?; - verify_person_in_community(&self.actor, &community, context).await?; + let recipient = self.recipient(context).await?; + verify_person_in_site_or_community(&self.actor, &recipient, context).await?; verify_urls_match(self.to[0].inner(), self.object.to[0].inner())?; - verify_mod_action(&self.actor, &community, context).await?; + verify_mod_action(&self.actor, &recipient, context).await?; Ok(()) } @@ -95,14 +96,14 @@ impl ActivityHandler for ResolveReport { } }; - let community = self.community(context).await?; - if community.local { + let recipient = self.recipient(context).await?; + if let Some(community) = recipient.local_community() { // forward to remote mods let object_id = self.object.object.object_id(context).await?; let announce = AnnouncableActivities::ResolveReport(self); - let announce = AnnounceActivity::new(announce.try_into()?, &community, context)?; - let inboxes = report_inboxes(object_id, &community, context).await?; - send_lemmy_activity(context, announce, &community, inboxes.clone(), false).await?; + let announce = AnnounceActivity::new(announce.try_into()?, community, context)?; + let inboxes = report_inboxes(object_id, &recipient, context).await?; + send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?; } Ok(()) diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index c4ce4aa793..ddc21a6901 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -35,16 +35,18 @@ use following::send_accept_or_reject_follow; use lemmy_api_common::{ context::LemmyContext, send_activity::{ActivityChannel, SendActivityData}, + utils::is_admin, }; use lemmy_db_schema::{ source::{ activity::{ActivitySendTargets, ActorType, SentActivity, SentActivityForm}, community::Community, + site::Site, }, traits::Crud, CommunityVisibility, }; -use lemmy_db_views::structs::{CommunityPersonBanView, CommunityView}; +use lemmy_db_views::structs::{CommunityPersonBanView, CommunityView, LocalUserView}; use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult}; use serde::Serialize; use tracing::info; @@ -133,6 +135,27 @@ pub(crate) async fn verify_mod_action( CommunityView::check_is_mod_or_admin(&mut context.pool(), mod_.id, community.id).await } +/// Verify that admin action was performed by an admin. +/// +/// * `mod_id` - Activitypub ID of the admin who performed the action +/// * `site` - The site that the person should be an admin of +pub(crate) async fn verify_admin_action( + admin_id: &ObjectId, + site: &Site, + context: &Data, +) -> LemmyResult<()> { + // admin action comes from the correct instance, so it was presumably done + // by an instance admin. + // TODO: federate instance admin status and check it here + if admin_id.inner().domain() == site.ap_id.domain() { + return Ok(()); + } + + let admin = admin_id.dereference(context).await?; + let local_user_view = LocalUserView::read_person(&mut context.pool(), admin.id).await?; + is_admin(&local_user_view) +} + pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> { if ![to, cc].iter().any(|set| set.contains(&public())) { Err(FederationError::ObjectIsNotPublic)? diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index 849e27fb6b..9578f433aa 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -1,4 +1,5 @@ use crate::{ + activities::block::SiteOrCommunity, objects::community::ApubCommunity, protocol::{ activities::{ @@ -92,8 +93,14 @@ impl InCommunity for AnnouncableActivities { CollectionRemove(a) => a.community(context).await, LockPost(a) => a.community(context).await, UndoLockPost(a) => a.community(context).await, - Report(a) => a.community(context).await, - ResolveReport(a) => a.community(context).await, + Report(a) => match a.recipient(context).await? { + SiteOrCommunity::Site(_) => Err(LemmyErrorType::NotFound.into()), + SiteOrCommunity::Community(c) => Ok(c), + }, + ResolveReport(a) => match a.recipient(context).await? { + SiteOrCommunity::Site(_) => Err(LemmyErrorType::NotFound.into()), + SiteOrCommunity::Community(c) => Ok(c), + }, Page(_) => Err(LemmyErrorType::NotFound.into()), } } diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 9f1e0a27d8..08d753c79e 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -39,6 +39,14 @@ impl Report { .or(self.content.clone()) .ok_or(LemmyErrorType::NotFound.into()) } + + pub(crate) async fn recipient( + &self, + context: &Data, + ) -> LemmyResult { + let recipient = self.to[0].dereference(context).await?; + Ok(recipient) + } } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -91,10 +99,3 @@ impl ReportObject { } } } - -impl InCommunity for Report { - async fn community(&self, context: &Data) -> LemmyResult { - let community = self.to[0].dereference(context).await?; - Ok(community) - } -} diff --git a/crates/apub/src/protocol/activities/community/resolve_report.rs b/crates/apub/src/protocol/activities/community/resolve_report.rs index c15753476c..ea989c4907 100644 --- a/crates/apub/src/protocol/activities/community/resolve_report.rs +++ b/crates/apub/src/protocol/activities/community/resolve_report.rs @@ -1,5 +1,6 @@ use super::report::Report; use crate::{ + activities::block::SiteOrCommunity, objects::{community::ApubCommunity, person::ApubPerson}, protocol::InCommunity, }; @@ -31,8 +32,11 @@ pub struct ResolveReport { pub(crate) id: Url, } -impl InCommunity for ResolveReport { - async fn community(&self, context: &Data) -> LemmyResult { - self.object.community(context).await +impl ResolveReport { + pub(crate) async fn recipient( + &self, + context: &Data, + ) -> LemmyResult { + self.object.recipient(context).await } } From 8e18194ee8da3926ca079b92d9c83b1992b45772 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 15:10:56 -0700 Subject: [PATCH 12/32] fix Report::receive --- .../apub/src/activities/community/report.rs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index c319ad1b61..a33ff23df8 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -27,11 +27,16 @@ use activitypub_federation::{ }; use lemmy_api_common::{ context::LemmyContext, - utils::{check_comment_deleted_or_removed, check_post_deleted_or_removed}, + utils::{ + check_comment_deleted_or_removed, + check_community_deleted_removed, + check_post_deleted_or_removed, + }, }; use lemmy_db_schema::{ source::{ comment_report::{CommentReport, CommentReportForm}, + community_report::{CommunityReport, CommunityReportForm}, post_report::{PostReport, PostReportForm}, }, traits::Reportable, @@ -101,7 +106,7 @@ impl ActivityHandler for Report { let actor = self.actor.dereference(context).await?; let reason = self.reason()?; match self.object.dereference(context).await? { - PostOrComment::Post(post) => { + ReportableObjects::PostOrComment(PostOrComment::Post(post)) => { check_post_deleted_or_removed(&post)?; let report_form = PostReportForm { @@ -115,7 +120,7 @@ impl ActivityHandler for Report { }; PostReport::report(&mut context.pool(), &report_form).await?; } - PostOrComment::Comment(comment) => { + ReportableObjects::PostOrComment(PostOrComment::Comment(comment)) => { check_comment_deleted_or_removed(&comment)?; let report_form = CommentReportForm { @@ -127,6 +132,21 @@ impl ActivityHandler for Report { }; CommentReport::report(&mut context.pool(), &report_form).await?; } + ReportableObjects::Community(community) => { + check_community_deleted_removed(&community)?; + let report_form = CommunityReportForm { + creator_id: actor.id, + community_id: community.id, + reason, + original_community_name: community.name.clone(), + original_community_title: community.title.clone(), + original_community_banner: community.banner.clone(), + original_community_icon: community.icon.clone(), + original_community_description: community.description.clone(), + original_community_sidebar: community.sidebar.clone(), + }; + CommunityReport::report(&mut context.pool(), &report_form).await?; + } }; let recipient = self.recipient(context).await?; From 43a671d77cae23e9dafee97bdeb04ce36945225b Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 17:10:23 -0700 Subject: [PATCH 13/32] fix ResolveReport::send --- .../apub/src/activities/community/resolve_report.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index 39fd8359ec..dcafeda3f6 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -1,6 +1,7 @@ use super::report_inboxes; use crate::{ activities::{ + block::SiteOrCommunity, generate_activity_id, send_lemmy_activity, verify_mod_action, @@ -8,6 +9,7 @@ use crate::{ verify_person_in_site_or_community, }, activity_lists::AnnouncableActivities, + fetcher::report::ReportableObjects, insert_received_activity, objects::{community::ApubCommunity, person::ApubPerson}, protocol::{ @@ -36,10 +38,10 @@ use url::Url; impl ResolveReport { pub(crate) async fn send( - object_id: ObjectId, + object_id: ObjectId, actor: &ApubPerson, report_creator: &ApubPerson, - community: &ApubCommunity, + receiver: &SiteOrCommunity, context: Data, ) -> LemmyResult<()> { let kind = ResolveType::Resolve; @@ -47,15 +49,15 @@ impl ResolveReport { kind.clone(), &context.settings().get_protocol_and_hostname(), )?; - let object = Report::new(&object_id, report_creator, community, None, &context)?; + let object = Report::new(&object_id, report_creator, receiver, None, &context)?; let resolve = ResolveReport { actor: actor.id().into(), - to: [community.id().into()], + to: [receiver.id().into()], object, kind, id: id.clone(), }; - let inboxes = report_inboxes(object_id, community, &context).await?; + let inboxes = report_inboxes(object_id, receiver, &context).await?; send_lemmy_activity(&context, resolve, actor, inboxes, false).await } From bba086928db22b8804d61dca14210310b10b647f Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 17:18:27 -0700 Subject: [PATCH 14/32] fix ResolveReport --- .../src/activities/community/resolve_report.rs | 17 +++++++++++++---- crates/apub/src/activities/mod.rs | 11 +++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index dcafeda3f6..a808ab3bf9 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -5,6 +5,7 @@ use crate::{ generate_activity_id, send_lemmy_activity, verify_mod_action, + verify_mod_or_admin_action, verify_person_in_community, verify_person_in_site_or_community, }, @@ -30,7 +31,11 @@ use activitypub_federation::{ }; use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ - source::{comment_report::CommentReport, post_report::PostReport}, + source::{ + comment_report::CommentReport, + community_report::CommunityReport, + post_report::PostReport, + }, traits::Reportable, }; use lemmy_utils::error::{LemmyError, LemmyResult}; @@ -81,7 +86,7 @@ impl ActivityHandler for ResolveReport { let recipient = self.recipient(context).await?; verify_person_in_site_or_community(&self.actor, &recipient, context).await?; verify_urls_match(self.to[0].inner(), self.object.to[0].inner())?; - verify_mod_action(&self.actor, &recipient, context).await?; + verify_mod_or_admin_action(&self.actor, &recipient, context).await?; Ok(()) } @@ -90,12 +95,16 @@ impl ActivityHandler for ResolveReport { let reporter = self.object.actor.dereference(context).await?; let actor = self.actor.dereference(context).await?; match self.object.object.dereference(context).await? { - PostOrComment::Post(post) => { + ReportableObjects::PostOrComment(PostOrComment::Post(post)) => { PostReport::resolve_apub(&mut context.pool(), post.id, reporter.id, actor.id).await?; } - PostOrComment::Comment(comment) => { + ReportableObjects::PostOrComment(PostOrComment::Comment(comment)) => { CommentReport::resolve_apub(&mut context.pool(), comment.id, reporter.id, actor.id).await?; } + ReportableObjects::Community(community) => { + CommunityReport::resolve_apub(&mut context.pool(), community.id, reporter.id, actor.id) + .await?; + } }; let recipient = self.recipient(context).await?; diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index ddc21a6901..0d1cbb3686 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -156,6 +156,17 @@ pub(crate) async fn verify_admin_action( is_admin(&local_user_view) } +pub(crate) async fn verify_mod_or_admin_action( + person_id: &ObjectId, + site_or_community: &SiteOrCommunity, + context: &Data, +) -> LemmyResult<()> { + match site_or_community { + SiteOrCommunity::Site(site) => verify_admin_action(person_id, site, context).await, + SiteOrCommunity::Community(community) => verify_mod_action(person_id, community, context).await, + } +} + pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> { if ![to, cc].iter().any(|set| set.contains(&public())) { Err(FederationError::ObjectIsNotPublic)? From a851ffd18bb97f618723fdd49900da4d65d11a53 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 17:21:36 -0700 Subject: [PATCH 15/32] fix match_outgoing_activities --- crates/apub/src/activities/mod.rs | 34 +++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 0d1cbb3686..adc9499007 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -437,7 +437,7 @@ pub async fn match_outgoing_activities( Report::send( ObjectId::from(object_id), &actor.into(), - &community.into(), + &SiteOrCommunity::Community(community.into()), reason, context, ) @@ -453,7 +453,37 @@ pub async fn match_outgoing_activities( ObjectId::from(object_id), &actor.into(), &report_creator.into(), - &community.into(), + &SiteOrCommunity::Community(community.into()), + context, + ) + .await + } + CreateReportToSite { + object_id, + actor, + site, + reason, + } => { + Report::send( + ObjectId::from(object_id), + &actor.into(), + &SiteOrCommunity::Site(site.into()), + reason, + context, + ) + .await + } + SendResolveReportToSite { + object_id, + actor, + report_creator, + site, + } => { + ResolveReport::send( + ObjectId::from(object_id), + &actor.into(), + &report_creator.into(), + &SiteOrCommunity::Site(site.into()), context, ) .await From 6c8c22f964318c4b408187b1701bb9e0f6aab1ae Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 17:27:56 -0700 Subject: [PATCH 16/32] replace recipient with receiver --- crates/apub/src/activities/community/report.rs | 10 +++++----- .../apub/src/activities/community/resolve_report.rs | 12 ++++++------ crates/apub/src/activity_lists.rs | 4 ++-- .../apub/src/protocol/activities/community/report.rs | 6 +++--- .../protocol/activities/community/resolve_report.rs | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index a33ff23df8..297a139e6e 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -96,8 +96,8 @@ impl ActivityHandler for Report { } async fn verify(&self, context: &Data) -> LemmyResult<()> { - let recipient = self.recipient(context).await?; - verify_person_in_site_or_community(&self.actor, &recipient, context).await?; + let receiver = self.receiver(context).await?; + verify_person_in_site_or_community(&self.actor, &receiver, context).await?; Ok(()) } @@ -149,13 +149,13 @@ impl ActivityHandler for Report { } }; - let recipient = self.recipient(context).await?; - if let Some(community) = recipient.local_community() { + let receiver = self.receiver(context).await?; + if let Some(community) = receiver.local_community() { // forward to remote mods let object_id = self.object.object_id(context).await?; let announce = AnnouncableActivities::Report(self); let announce = AnnounceActivity::new(announce.try_into()?, community, context)?; - let inboxes = report_inboxes(object_id, &recipient, context).await?; + let inboxes = report_inboxes(object_id, &receiver, context).await?; send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?; } diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index a808ab3bf9..32703d3725 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -83,10 +83,10 @@ impl ActivityHandler for ResolveReport { async fn verify(&self, context: &Data) -> LemmyResult<()> { self.object.verify(context).await?; - let recipient = self.recipient(context).await?; - verify_person_in_site_or_community(&self.actor, &recipient, context).await?; + let receiver = self.receiver(context).await?; + verify_person_in_site_or_community(&self.actor, &receiver, context).await?; verify_urls_match(self.to[0].inner(), self.object.to[0].inner())?; - verify_mod_or_admin_action(&self.actor, &recipient, context).await?; + verify_mod_or_admin_action(&self.actor, &receiver, context).await?; Ok(()) } @@ -107,13 +107,13 @@ impl ActivityHandler for ResolveReport { } }; - let recipient = self.recipient(context).await?; - if let Some(community) = recipient.local_community() { + let receiver = self.receiver(context).await?; + if let Some(community) = receiver.local_community() { // forward to remote mods let object_id = self.object.object.object_id(context).await?; let announce = AnnouncableActivities::ResolveReport(self); let announce = AnnounceActivity::new(announce.try_into()?, community, context)?; - let inboxes = report_inboxes(object_id, &recipient, context).await?; + let inboxes = report_inboxes(object_id, &receiver, context).await?; send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?; } diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index 9578f433aa..c38c17f221 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -93,11 +93,11 @@ impl InCommunity for AnnouncableActivities { CollectionRemove(a) => a.community(context).await, LockPost(a) => a.community(context).await, UndoLockPost(a) => a.community(context).await, - Report(a) => match a.recipient(context).await? { + Report(a) => match a.receiver(context).await? { SiteOrCommunity::Site(_) => Err(LemmyErrorType::NotFound.into()), SiteOrCommunity::Community(c) => Ok(c), }, - ResolveReport(a) => match a.recipient(context).await? { + ResolveReport(a) => match a.receiver(context).await? { SiteOrCommunity::Site(_) => Err(LemmyErrorType::NotFound.into()), SiteOrCommunity::Community(c) => Ok(c), }, diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 08d753c79e..6c504ea7bd 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -40,12 +40,12 @@ impl Report { .ok_or(LemmyErrorType::NotFound.into()) } - pub(crate) async fn recipient( + pub(crate) async fn receiver( &self, context: &Data, ) -> LemmyResult { - let recipient = self.to[0].dereference(context).await?; - Ok(recipient) + let receiver = self.to[0].dereference(context).await?; + Ok(receiver) } } diff --git a/crates/apub/src/protocol/activities/community/resolve_report.rs b/crates/apub/src/protocol/activities/community/resolve_report.rs index ea989c4907..dc446026f9 100644 --- a/crates/apub/src/protocol/activities/community/resolve_report.rs +++ b/crates/apub/src/protocol/activities/community/resolve_report.rs @@ -33,10 +33,10 @@ pub struct ResolveReport { } impl ResolveReport { - pub(crate) async fn recipient( + pub(crate) async fn receiver( &self, context: &Data, ) -> LemmyResult { - self.object.recipient(context).await + self.object.receiver(context).await } } From 137e96619ec925af651565449cb89115d479ff0a Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 17 Mar 2025 20:28:55 -0700 Subject: [PATCH 17/32] lint --- crates/apub/src/activities/community/report.rs | 11 ++++------- .../src/activities/community/resolve_report.rs | 15 +++++---------- crates/apub/src/fetcher/report.rs | 6 +++--- .../src/protocol/activities/community/report.rs | 5 ++--- .../activities/community/resolve_report.rs | 1 - 5 files changed, 14 insertions(+), 24 deletions(-) diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 297a139e6e..1faf81d5ca 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -9,13 +9,10 @@ use crate::{ activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, insert_received_activity, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::{ - activities::community::{ - announce::AnnounceActivity, - report::{Report, ReportObject}, - }, - InCommunity, + objects::person::ApubPerson, + protocol::activities::community::{ + announce::AnnounceActivity, + report::{Report, ReportObject}, }, PostOrComment, }; diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index 32703d3725..116052ec76 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -4,22 +4,17 @@ use crate::{ block::SiteOrCommunity, generate_activity_id, send_lemmy_activity, - verify_mod_action, verify_mod_or_admin_action, - verify_person_in_community, verify_person_in_site_or_community, }, activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, insert_received_activity, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::{ - activities::community::{ - announce::AnnounceActivity, - report::Report, - resolve_report::{ResolveReport, ResolveType}, - }, - InCommunity, + objects::person::ApubPerson, + protocol::activities::community::{ + announce::AnnounceActivity, + report::Report, + resolve_report::{ResolveReport, ResolveType}, }, PostOrComment, }; diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs index 415c21c370..10deaf92d9 100644 --- a/crates/apub/src/fetcher/report.rs +++ b/crates/apub/src/fetcher/report.rs @@ -21,7 +21,7 @@ pub(crate) enum ReportableObjects { #[serde(untagged)] pub(crate) enum ReportableKinds { PageOrNote(PageOrNote), - Group(Group), + Group(Box), } #[async_trait::async_trait] @@ -57,7 +57,7 @@ impl Object for ReportableObjects { async fn into_json(self, data: &Data) -> LemmyResult { Ok(match self { ReportableObjects::PostOrComment(p) => ReportableKinds::PageOrNote(p.into_json(data).await?), - ReportableObjects::Community(c) => ReportableKinds::Group(c.into_json(data).await?), + ReportableObjects::Community(c) => ReportableKinds::Group(Box::new(c.into_json(data).await?)), }) } @@ -78,7 +78,7 @@ impl Object for ReportableObjects { ReportableObjects::PostOrComment(PostOrComment::from_json(p, data).await?) } ReportableKinds::Group(g) => { - ReportableObjects::Community(ApubCommunity::from_json(g, data).await?) + ReportableObjects::Community(ApubCommunity::from_json(*g, data).await?) } }) } diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 6c504ea7bd..81a083a93a 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -1,8 +1,7 @@ use crate::{ activities::block::SiteOrCommunity, - fetcher::{post_or_comment::PostOrComment, report::ReportableObjects}, - objects::{community::ApubCommunity, person::ApubPerson}, - protocol::InCommunity, + fetcher::report::ReportableObjects, + objects::person::ApubPerson, }; use activitypub_federation::{ config::Data, diff --git a/crates/apub/src/protocol/activities/community/resolve_report.rs b/crates/apub/src/protocol/activities/community/resolve_report.rs index dc446026f9..11b9b9ee3a 100644 --- a/crates/apub/src/protocol/activities/community/resolve_report.rs +++ b/crates/apub/src/protocol/activities/community/resolve_report.rs @@ -2,7 +2,6 @@ use super::report::Report; use crate::{ activities::block::SiteOrCommunity, objects::{community::ApubCommunity, person::ApubPerson}, - protocol::InCommunity, }; use activitypub_federation::{ config::Data, From 3d30d7eba6f8e1bd018989cde97578970de874fb Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Tue, 25 Mar 2025 09:22:36 -0700 Subject: [PATCH 18/32] update cargo.toml files --- Cargo.lock | 10 ++++++---- Cargo.toml | 3 ++- crates/apub/Cargo.toml | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca6fc1374b..063fd6087c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "8f27d075294830fcab6f66e320dab524bc6d048f4a151698e153205559113772" [[package]] name = "activitypub_federation" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8c76cad52a3d0f637f1f4ba06d96ac63c92512082f6a1ca86145b66a0a5371" +checksum = "a29981dfc22318f8e8c5246ce4067b62b344e5d045ae2e34e086d1514eb1c9b0" dependencies = [ "activitystreams-kinds", "actix-web", @@ -22,6 +22,7 @@ dependencies = [ "chrono", "derive_builder", "dyn-clone", + "either", "enum_delegate", "futures", "futures-core", @@ -1461,9 +1462,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elementtree" @@ -2672,6 +2673,7 @@ dependencies = [ "async-trait", "chrono", "diesel", + "either", "enum_delegate", "futures", "html2md", diff --git a/Cargo.toml b/Cargo.toml index 7023a64525..aff3321d98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,7 +88,7 @@ lemmy_api_common = { version = "=1.0.0-alpha.3", path = "./crates/api_common" } lemmy_routes = { version = "=1.0.0-alpha.3", path = "./crates/routes" } lemmy_db_views = { version = "=1.0.0-alpha.3", path = "./crates/db_views" } lemmy_federate = { version = "=1.0.0-alpha.3", path = "./crates/federate" } -activitypub_federation = { version = "0.6.3", default-features = false, features = [ +activitypub_federation = { version = "0.6.4", default-features = false, features = [ "actix-web", ] } diesel = "2.2.7" @@ -156,6 +156,7 @@ clap = { version = "4.5.29", features = ["derive", "env"] } pretty_assertions = "1.4.1" derive-new = "0.7.0" tuplex = "0.1.2" +either = "1.15.0" [dependencies] lemmy_api = { workspace = true } diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml index 27a9a3d3c3..0822603c50 100644 --- a/crates/apub/Cargo.toml +++ b/crates/apub/Cargo.toml @@ -45,6 +45,7 @@ html2text = "0.14.0" stringreader = "0.1.1" enum_delegate = "0.2.0" semver = "1.0.25" +either = { workspace = true } [dev-dependencies] serial_test = { workspace = true } From 8208c8a8b138edc7b4e280d6dea85769f3bce8f5 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Tue, 25 Mar 2025 09:22:54 -0700 Subject: [PATCH 19/32] start removing new custom enums --- crates/apub/src/activities/block/mod.rs | 44 ----------- crates/apub/src/activities/community/mod.rs | 10 ++- .../apub/src/activities/community/report.rs | 7 +- .../activities/community/resolve_report.rs | 3 +- crates/apub/src/activities/mod.rs | 5 +- crates/apub/src/fetcher/report.rs | 75 +------------------ 6 files changed, 20 insertions(+), 124 deletions(-) diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 8baa82f6c8..0d635e09d2 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -107,43 +107,6 @@ impl Object for SiteOrCommunity { } } -impl Actor for SiteOrCommunity { - fn id(&self) -> Url { - match self { - SiteOrCommunity::Site(u) => u.id(), - SiteOrCommunity::Community(c) => c.id(), - } - } - - fn public_key_pem(&self) -> &str { - match self { - SiteOrCommunity::Site(p) => p.public_key_pem(), - SiteOrCommunity::Community(p) => p.public_key_pem(), - } - } - - fn private_key_pem(&self) -> Option { - match self { - SiteOrCommunity::Site(p) => p.private_key_pem(), - SiteOrCommunity::Community(p) => p.private_key_pem(), - } - } - - fn inbox(&self) -> Url { - match self { - SiteOrCommunity::Site(u) => u.inbox(), - SiteOrCommunity::Community(c) => c.inbox(), - } - } - - fn shared_inbox(&self) -> Option { - match self { - SiteOrCommunity::Site(u) => u.shared_inbox(), - SiteOrCommunity::Community(c) => c.shared_inbox(), - } - } -} - impl SiteOrCommunity { fn id(&self) -> ObjectId { match self { @@ -151,13 +114,6 @@ impl SiteOrCommunity { SiteOrCommunity::Community(c) => ObjectId::from(c.ap_id.clone()), } } - - pub(crate) fn local_community(&self) -> Option<&ApubCommunity> { - match self { - SiteOrCommunity::Community(c) if c.local => Some(c), - _ => None, - } - } } async fn generate_cc(target: &SiteOrCommunity, pool: &mut DbPool<'_>) -> LemmyResult> { diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 99fee5eb81..197c43890d 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -6,6 +6,7 @@ use crate::{ protocol::activities::community::announce::AnnounceActivity, }; use activitypub_federation::{config::Data, fetch::object_id::ObjectId, traits::Actor}; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ @@ -80,7 +81,7 @@ pub(crate) async fn send_activity_in_community( async fn report_inboxes( object_id: ObjectId, - receiver: &SiteOrCommunity, + receiver: Either<&ApubSite, &ApubCommunity>, context: &Data, ) -> LemmyResult { // send report to the community where object was posted @@ -112,3 +113,10 @@ async fn report_inboxes( } Ok(inboxes) } + +async fn local_community(site_or_community: Either<&ApubSite, &ApubCommunity>) -> Option<&ApubCommunity> { + match site_or_community { + Either::Right(c) if c.local => Some(c), + _ => None, + } +} diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 1faf81d5ca..190aedac24 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -9,7 +9,7 @@ use crate::{ activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, insert_received_activity, - objects::person::ApubPerson, + objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::community::{ announce::AnnounceActivity, report::{Report, ReportObject}, @@ -22,6 +22,7 @@ use activitypub_federation::{ kinds::activity::FlagType, traits::{ActivityHandler, Actor}, }; +use either::Either; use lemmy_api_common::{ context::LemmyContext, utils::{ @@ -45,7 +46,7 @@ impl Report { pub(crate) fn new( object_id: &ObjectId, actor: &ApubPerson, - receiver: &SiteOrCommunity, + receiver: Either<&ApubSite, &ApubCommunity>, reason: Option, context: &Data, ) -> LemmyResult { @@ -68,7 +69,7 @@ impl Report { pub(crate) async fn send( object_id: ObjectId, actor: &ApubPerson, - receiver: &SiteOrCommunity, + receiver: Either<&ApubSite, &ApubCommunity>, reason: String, context: Data, ) -> LemmyResult<()> { diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index 116052ec76..f503db88a6 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -24,6 +24,7 @@ use activitypub_federation::{ protocol::verification::verify_urls_match, traits::{ActivityHandler, Actor}, }; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ @@ -41,7 +42,7 @@ impl ResolveReport { object_id: ObjectId, actor: &ApubPerson, report_creator: &ApubPerson, - receiver: &SiteOrCommunity, + receiver: Either<&ApubSite, &ApubCommunity>, context: Data, ) -> LemmyResult<()> { let kind = ResolveType::Resolve; diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index f4ff543594..fe812031fa 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -30,6 +30,7 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use block::SiteOrCommunity; +use either::Either; use following::send_accept_or_reject_follow; use lemmy_api_common::{ context::LemmyContext, @@ -95,7 +96,7 @@ pub(crate) async fn verify_person_in_community( /// from local site or community. pub(crate) async fn verify_person_in_site_or_community( person_id: &ObjectId, - site_or_community: &SiteOrCommunity, + site_or_community: Either<&ApubSite, &ApubCommunity>, context: &Data, ) -> LemmyResult<()> { let person = person_id.dereference(context).await?; @@ -156,7 +157,7 @@ pub(crate) async fn verify_admin_action( pub(crate) async fn verify_mod_or_admin_action( person_id: &ObjectId, - site_or_community: &SiteOrCommunity, + site_or_community: Either<&ApubSite, &ApubCommunity>, context: &Data, ) -> LemmyResult<()> { match site_or_community { diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs index 10deaf92d9..5f190e9c9c 100644 --- a/crates/apub/src/fetcher/report.rs +++ b/crates/apub/src/fetcher/report.rs @@ -1,6 +1,6 @@ use crate::{ fetcher::post_or_comment::{PageOrNote, PostOrComment}, - objects::community::ApubCommunity, + objects::{comment::ApubComment, community::ApubCommunity, post::ApubPost}, protocol::objects::group::Group, }; use activitypub_federation::{config::Data, traits::Object}; @@ -11,75 +11,4 @@ use reqwest::Url; use serde::Deserialize; /// The types of ActivityPub objects that reports can be created for. -#[derive(Debug)] -pub(crate) enum ReportableObjects { - PostOrComment(PostOrComment), - Community(ApubCommunity), -} - -#[derive(Deserialize)] -#[serde(untagged)] -pub(crate) enum ReportableKinds { - PageOrNote(PageOrNote), - Group(Box), -} - -#[async_trait::async_trait] -impl Object for ReportableObjects { - type DataType = LemmyContext; - type Kind = ReportableKinds; - type Error = LemmyError; - - fn last_refreshed_at(&self) -> Option> { - match self { - ReportableObjects::PostOrComment(p) => p.last_refreshed_at(), - ReportableObjects::Community(c) => c.last_refreshed_at(), - } - } - - async fn read_from_id(object_id: Url, data: &Data) -> LemmyResult> { - let community = ApubCommunity::read_from_id(object_id.clone(), data).await?; - Ok(match community { - Some(o) => Some(ReportableObjects::Community(o)), - None => PostOrComment::read_from_id(object_id, data) - .await? - .map(ReportableObjects::PostOrComment), - }) - } - - async fn delete(self, data: &Data) -> LemmyResult<()> { - match self { - ReportableObjects::PostOrComment(p) => p.delete(data).await, - ReportableObjects::Community(c) => c.delete(data).await, - } - } - - async fn into_json(self, data: &Data) -> LemmyResult { - Ok(match self { - ReportableObjects::PostOrComment(p) => ReportableKinds::PageOrNote(p.into_json(data).await?), - ReportableObjects::Community(c) => ReportableKinds::Group(Box::new(c.into_json(data).await?)), - }) - } - - async fn verify( - apub: &Self::Kind, - expected_domain: &Url, - data: &Data, - ) -> LemmyResult<()> { - match apub { - ReportableKinds::PageOrNote(p) => PostOrComment::verify(p, expected_domain, data).await, - ReportableKinds::Group(g) => ApubCommunity::verify(g, expected_domain, data).await, - } - } - - async fn from_json(apub: Self::Kind, data: &Data) -> LemmyResult { - Ok(match apub { - ReportableKinds::PageOrNote(p) => { - ReportableObjects::PostOrComment(PostOrComment::from_json(p, data).await?) - } - ReportableKinds::Group(g) => { - ReportableObjects::Community(ApubCommunity::from_json(*g, data).await?) - } - }) - } -} +pub(crate) type ReportableObjects = Either; From fcea7f74984248023425ce3cd935142a7e53b509 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Tue, 25 Mar 2025 09:23:00 -0700 Subject: [PATCH 20/32] Revert "start removing new custom enums" This reverts commit 8208c8a8b138edc7b4e280d6dea85769f3bce8f5. --- crates/apub/src/activities/block/mod.rs | 44 +++++++++++ crates/apub/src/activities/community/mod.rs | 10 +-- .../apub/src/activities/community/report.rs | 7 +- .../activities/community/resolve_report.rs | 3 +- crates/apub/src/activities/mod.rs | 5 +- crates/apub/src/fetcher/report.rs | 75 ++++++++++++++++++- 6 files changed, 124 insertions(+), 20 deletions(-) diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 0d635e09d2..8baa82f6c8 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -107,6 +107,43 @@ impl Object for SiteOrCommunity { } } +impl Actor for SiteOrCommunity { + fn id(&self) -> Url { + match self { + SiteOrCommunity::Site(u) => u.id(), + SiteOrCommunity::Community(c) => c.id(), + } + } + + fn public_key_pem(&self) -> &str { + match self { + SiteOrCommunity::Site(p) => p.public_key_pem(), + SiteOrCommunity::Community(p) => p.public_key_pem(), + } + } + + fn private_key_pem(&self) -> Option { + match self { + SiteOrCommunity::Site(p) => p.private_key_pem(), + SiteOrCommunity::Community(p) => p.private_key_pem(), + } + } + + fn inbox(&self) -> Url { + match self { + SiteOrCommunity::Site(u) => u.inbox(), + SiteOrCommunity::Community(c) => c.inbox(), + } + } + + fn shared_inbox(&self) -> Option { + match self { + SiteOrCommunity::Site(u) => u.shared_inbox(), + SiteOrCommunity::Community(c) => c.shared_inbox(), + } + } +} + impl SiteOrCommunity { fn id(&self) -> ObjectId { match self { @@ -114,6 +151,13 @@ impl SiteOrCommunity { SiteOrCommunity::Community(c) => ObjectId::from(c.ap_id.clone()), } } + + pub(crate) fn local_community(&self) -> Option<&ApubCommunity> { + match self { + SiteOrCommunity::Community(c) if c.local => Some(c), + _ => None, + } + } } async fn generate_cc(target: &SiteOrCommunity, pool: &mut DbPool<'_>) -> LemmyResult> { diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 197c43890d..99fee5eb81 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -6,7 +6,6 @@ use crate::{ protocol::activities::community::announce::AnnounceActivity, }; use activitypub_federation::{config::Data, fetch::object_id::ObjectId, traits::Actor}; -use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ @@ -81,7 +80,7 @@ pub(crate) async fn send_activity_in_community( async fn report_inboxes( object_id: ObjectId, - receiver: Either<&ApubSite, &ApubCommunity>, + receiver: &SiteOrCommunity, context: &Data, ) -> LemmyResult { // send report to the community where object was posted @@ -113,10 +112,3 @@ async fn report_inboxes( } Ok(inboxes) } - -async fn local_community(site_or_community: Either<&ApubSite, &ApubCommunity>) -> Option<&ApubCommunity> { - match site_or_community { - Either::Right(c) if c.local => Some(c), - _ => None, - } -} diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 190aedac24..1faf81d5ca 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -9,7 +9,7 @@ use crate::{ activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, insert_received_activity, - objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, + objects::person::ApubPerson, protocol::activities::community::{ announce::AnnounceActivity, report::{Report, ReportObject}, @@ -22,7 +22,6 @@ use activitypub_federation::{ kinds::activity::FlagType, traits::{ActivityHandler, Actor}, }; -use either::Either; use lemmy_api_common::{ context::LemmyContext, utils::{ @@ -46,7 +45,7 @@ impl Report { pub(crate) fn new( object_id: &ObjectId, actor: &ApubPerson, - receiver: Either<&ApubSite, &ApubCommunity>, + receiver: &SiteOrCommunity, reason: Option, context: &Data, ) -> LemmyResult { @@ -69,7 +68,7 @@ impl Report { pub(crate) async fn send( object_id: ObjectId, actor: &ApubPerson, - receiver: Either<&ApubSite, &ApubCommunity>, + receiver: &SiteOrCommunity, reason: String, context: Data, ) -> LemmyResult<()> { diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index f503db88a6..116052ec76 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -24,7 +24,6 @@ use activitypub_federation::{ protocol::verification::verify_urls_match, traits::{ActivityHandler, Actor}, }; -use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ @@ -42,7 +41,7 @@ impl ResolveReport { object_id: ObjectId, actor: &ApubPerson, report_creator: &ApubPerson, - receiver: Either<&ApubSite, &ApubCommunity>, + receiver: &SiteOrCommunity, context: Data, ) -> LemmyResult<()> { let kind = ResolveType::Resolve; diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index fe812031fa..f4ff543594 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -30,7 +30,6 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use block::SiteOrCommunity; -use either::Either; use following::send_accept_or_reject_follow; use lemmy_api_common::{ context::LemmyContext, @@ -96,7 +95,7 @@ pub(crate) async fn verify_person_in_community( /// from local site or community. pub(crate) async fn verify_person_in_site_or_community( person_id: &ObjectId, - site_or_community: Either<&ApubSite, &ApubCommunity>, + site_or_community: &SiteOrCommunity, context: &Data, ) -> LemmyResult<()> { let person = person_id.dereference(context).await?; @@ -157,7 +156,7 @@ pub(crate) async fn verify_admin_action( pub(crate) async fn verify_mod_or_admin_action( person_id: &ObjectId, - site_or_community: Either<&ApubSite, &ApubCommunity>, + site_or_community: &SiteOrCommunity, context: &Data, ) -> LemmyResult<()> { match site_or_community { diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs index 5f190e9c9c..10deaf92d9 100644 --- a/crates/apub/src/fetcher/report.rs +++ b/crates/apub/src/fetcher/report.rs @@ -1,6 +1,6 @@ use crate::{ fetcher::post_or_comment::{PageOrNote, PostOrComment}, - objects::{comment::ApubComment, community::ApubCommunity, post::ApubPost}, + objects::community::ApubCommunity, protocol::objects::group::Group, }; use activitypub_federation::{config::Data, traits::Object}; @@ -11,4 +11,75 @@ use reqwest::Url; use serde::Deserialize; /// The types of ActivityPub objects that reports can be created for. -pub(crate) type ReportableObjects = Either; +#[derive(Debug)] +pub(crate) enum ReportableObjects { + PostOrComment(PostOrComment), + Community(ApubCommunity), +} + +#[derive(Deserialize)] +#[serde(untagged)] +pub(crate) enum ReportableKinds { + PageOrNote(PageOrNote), + Group(Box), +} + +#[async_trait::async_trait] +impl Object for ReportableObjects { + type DataType = LemmyContext; + type Kind = ReportableKinds; + type Error = LemmyError; + + fn last_refreshed_at(&self) -> Option> { + match self { + ReportableObjects::PostOrComment(p) => p.last_refreshed_at(), + ReportableObjects::Community(c) => c.last_refreshed_at(), + } + } + + async fn read_from_id(object_id: Url, data: &Data) -> LemmyResult> { + let community = ApubCommunity::read_from_id(object_id.clone(), data).await?; + Ok(match community { + Some(o) => Some(ReportableObjects::Community(o)), + None => PostOrComment::read_from_id(object_id, data) + .await? + .map(ReportableObjects::PostOrComment), + }) + } + + async fn delete(self, data: &Data) -> LemmyResult<()> { + match self { + ReportableObjects::PostOrComment(p) => p.delete(data).await, + ReportableObjects::Community(c) => c.delete(data).await, + } + } + + async fn into_json(self, data: &Data) -> LemmyResult { + Ok(match self { + ReportableObjects::PostOrComment(p) => ReportableKinds::PageOrNote(p.into_json(data).await?), + ReportableObjects::Community(c) => ReportableKinds::Group(Box::new(c.into_json(data).await?)), + }) + } + + async fn verify( + apub: &Self::Kind, + expected_domain: &Url, + data: &Data, + ) -> LemmyResult<()> { + match apub { + ReportableKinds::PageOrNote(p) => PostOrComment::verify(p, expected_domain, data).await, + ReportableKinds::Group(g) => ApubCommunity::verify(g, expected_domain, data).await, + } + } + + async fn from_json(apub: Self::Kind, data: &Data) -> LemmyResult { + Ok(match apub { + ReportableKinds::PageOrNote(p) => { + ReportableObjects::PostOrComment(PostOrComment::from_json(p, data).await?) + } + ReportableKinds::Group(g) => { + ReportableObjects::Community(ApubCommunity::from_json(*g, data).await?) + } + }) + } +} From 87de4a0656884d6c1872c8e9749d60dc8c65b2fa Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Tue, 25 Mar 2025 09:25:33 -0700 Subject: [PATCH 21/32] remove new trait impls on enums --- crates/apub/src/activities/block/mod.rs | 37 --------------- crates/apub/src/fetcher/report.rs | 60 ------------------------- 2 files changed, 97 deletions(-) diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 8baa82f6c8..9b4182fa2b 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -107,43 +107,6 @@ impl Object for SiteOrCommunity { } } -impl Actor for SiteOrCommunity { - fn id(&self) -> Url { - match self { - SiteOrCommunity::Site(u) => u.id(), - SiteOrCommunity::Community(c) => c.id(), - } - } - - fn public_key_pem(&self) -> &str { - match self { - SiteOrCommunity::Site(p) => p.public_key_pem(), - SiteOrCommunity::Community(p) => p.public_key_pem(), - } - } - - fn private_key_pem(&self) -> Option { - match self { - SiteOrCommunity::Site(p) => p.private_key_pem(), - SiteOrCommunity::Community(p) => p.private_key_pem(), - } - } - - fn inbox(&self) -> Url { - match self { - SiteOrCommunity::Site(u) => u.inbox(), - SiteOrCommunity::Community(c) => c.inbox(), - } - } - - fn shared_inbox(&self) -> Option { - match self { - SiteOrCommunity::Site(u) => u.shared_inbox(), - SiteOrCommunity::Community(c) => c.shared_inbox(), - } - } -} - impl SiteOrCommunity { fn id(&self) -> ObjectId { match self { diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs index 10deaf92d9..b9235320fd 100644 --- a/crates/apub/src/fetcher/report.rs +++ b/crates/apub/src/fetcher/report.rs @@ -23,63 +23,3 @@ pub(crate) enum ReportableKinds { PageOrNote(PageOrNote), Group(Box), } - -#[async_trait::async_trait] -impl Object for ReportableObjects { - type DataType = LemmyContext; - type Kind = ReportableKinds; - type Error = LemmyError; - - fn last_refreshed_at(&self) -> Option> { - match self { - ReportableObjects::PostOrComment(p) => p.last_refreshed_at(), - ReportableObjects::Community(c) => c.last_refreshed_at(), - } - } - - async fn read_from_id(object_id: Url, data: &Data) -> LemmyResult> { - let community = ApubCommunity::read_from_id(object_id.clone(), data).await?; - Ok(match community { - Some(o) => Some(ReportableObjects::Community(o)), - None => PostOrComment::read_from_id(object_id, data) - .await? - .map(ReportableObjects::PostOrComment), - }) - } - - async fn delete(self, data: &Data) -> LemmyResult<()> { - match self { - ReportableObjects::PostOrComment(p) => p.delete(data).await, - ReportableObjects::Community(c) => c.delete(data).await, - } - } - - async fn into_json(self, data: &Data) -> LemmyResult { - Ok(match self { - ReportableObjects::PostOrComment(p) => ReportableKinds::PageOrNote(p.into_json(data).await?), - ReportableObjects::Community(c) => ReportableKinds::Group(Box::new(c.into_json(data).await?)), - }) - } - - async fn verify( - apub: &Self::Kind, - expected_domain: &Url, - data: &Data, - ) -> LemmyResult<()> { - match apub { - ReportableKinds::PageOrNote(p) => PostOrComment::verify(p, expected_domain, data).await, - ReportableKinds::Group(g) => ApubCommunity::verify(g, expected_domain, data).await, - } - } - - async fn from_json(apub: Self::Kind, data: &Data) -> LemmyResult { - Ok(match apub { - ReportableKinds::PageOrNote(p) => { - ReportableObjects::PostOrComment(PostOrComment::from_json(p, data).await?) - } - ReportableKinds::Group(g) => { - ReportableObjects::Community(ApubCommunity::from_json(*g, data).await?) - } - }) - } -} From 7c5afda803f686704be07664af159b25120aa937 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 7 Apr 2025 13:56:33 -0700 Subject: [PATCH 22/32] change reportableobjects to type alias that uses either --- crates/apub/src/fetcher/report.rs | 7 ++----- crates/utils/translations | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) create mode 160000 crates/utils/translations diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs index b9235320fd..cf7dc9a42f 100644 --- a/crates/apub/src/fetcher/report.rs +++ b/crates/apub/src/fetcher/report.rs @@ -5,17 +5,14 @@ use crate::{ }; use activitypub_federation::{config::Data, traits::Object}; use chrono::{DateTime, Utc}; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::{LemmyError, LemmyResult}; use reqwest::Url; use serde::Deserialize; /// The types of ActivityPub objects that reports can be created for. -#[derive(Debug)] -pub(crate) enum ReportableObjects { - PostOrComment(PostOrComment), - Community(ApubCommunity), -} +pub(crate) type ReportableObjects = Either; #[derive(Deserialize)] #[serde(untagged)] diff --git a/crates/utils/translations b/crates/utils/translations new file mode 160000 index 0000000000..56581d6025 --- /dev/null +++ b/crates/utils/translations @@ -0,0 +1 @@ +Subproject commit 56581d60250680947e3e328bab21bc9e169df22c From 8dcdcd762a7cf840782adb6cb9d309f40992ffbc Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 7 Apr 2025 15:35:17 -0700 Subject: [PATCH 23/32] fix fetcher::report --- crates/apub/src/fetcher/report.rs | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs index cf7dc9a42f..fb6a21484b 100644 --- a/crates/apub/src/fetcher/report.rs +++ b/crates/apub/src/fetcher/report.rs @@ -1,22 +1,7 @@ -use crate::{ - fetcher::post_or_comment::{PageOrNote, PostOrComment}, - objects::community::ApubCommunity, - protocol::objects::group::Group, -}; -use activitypub_federation::{config::Data, traits::Object}; -use chrono::{DateTime, Utc}; +use crate::{fetcher::PostOrComment, objects::community::ApubCommunity}; use either::Either; -use lemmy_api_common::context::LemmyContext; -use lemmy_utils::error::{LemmyError, LemmyResult}; -use reqwest::Url; -use serde::Deserialize; + +// TODO don't use separate module for this /// The types of ActivityPub objects that reports can be created for. pub(crate) type ReportableObjects = Either; - -#[derive(Deserialize)] -#[serde(untagged)] -pub(crate) enum ReportableKinds { - PageOrNote(PageOrNote), - Group(Box), -} From b05924f5f72b95c1285c1e572f1612caf199a1be Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 7 Apr 2025 15:42:24 -0700 Subject: [PATCH 24/32] find and replace reportableobjects variant names --- crates/apub/src/activities/community/mod.rs | 4 ++-- crates/apub/src/activities/community/report.rs | 6 +++--- crates/apub/src/activities/community/resolve_report.rs | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index a7b78a9464..75512bd40c 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -96,8 +96,8 @@ async fn report_inboxes( // also send report to user's home instance if possible let object_creator_id = match object_id.dereference_local(context).await? { - ReportableObjects::PostOrComment(PostOrComment::Left(p)) => p.creator_id, - ReportableObjects::PostOrComment(PostOrComment::Right(c)) => c.creator_id, + ReportableObjects::Left(PostOrComment::Left(p)) => p.creator_id, + ReportableObjects::Left(PostOrComment::Right(c)) => c.creator_id, _ => return Ok(inboxes), }; let object_creator = Person::read(&mut context.pool(), object_creator_id).await?; diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 6f75ecaac9..4bc4b95a0c 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -103,7 +103,7 @@ impl ActivityHandler for Report { let actor = self.actor.dereference(context).await?; let reason = self.reason()?; match self.object.dereference(context).await? { - ReportableObjects::PostOrComment(PostOrComment::Left(post)) => { + ReportableObjects::Left(PostOrComment::Left(post)) => { check_post_deleted_or_removed(&post)?; let report_form = PostReportForm { @@ -117,7 +117,7 @@ impl ActivityHandler for Report { }; PostReport::report(&mut context.pool(), &report_form).await?; } - ReportableObjects::PostOrComment(PostOrComment::Right(comment)) => { + ReportableObjects::Left(PostOrComment::Right(comment)) => { check_comment_deleted_or_removed(&comment)?; let report_form = CommentReportForm { @@ -129,7 +129,7 @@ impl ActivityHandler for Report { }; CommentReport::report(&mut context.pool(), &report_form).await?; } - ReportableObjects::Community(community) => { + ReportableObjects::Right(community) => { check_community_deleted_removed(&community)?; let report_form = CommunityReportForm { creator_id: actor.id, diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index dbf5baa579..04a480c7c8 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -90,13 +90,13 @@ impl ActivityHandler for ResolveReport { let reporter = self.object.actor.dereference(context).await?; let actor = self.actor.dereference(context).await?; match self.object.object.dereference(context).await? { - ReportableObjects::PostOrComment(PostOrComment::Left(post)) => { + ReportableObjects::Left(PostOrComment::Left(post)) => { PostReport::resolve_apub(&mut context.pool(), post.id, reporter.id, actor.id).await?; } - ReportableObjects::PostOrComment(PostOrComment::Right(comment)) => { + ReportableObjects::Left(PostOrComment::Right(comment)) => { CommentReport::resolve_apub(&mut context.pool(), comment.id, reporter.id, actor.id).await?; } - ReportableObjects::Community(community) => { + ReportableObjects::Right(community) => { CommunityReport::resolve_apub(&mut context.pool(), community.id, reporter.id, actor.id) .await?; } From fae2a11c7b553742079c80b96e55f32c6be6a43e Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 7 Apr 2025 16:46:43 -0700 Subject: [PATCH 25/32] delete crates/utils/translations --- crates/utils/translations | 1 - 1 file changed, 1 deletion(-) delete mode 160000 crates/utils/translations diff --git a/crates/utils/translations b/crates/utils/translations deleted file mode 160000 index 56581d6025..0000000000 --- a/crates/utils/translations +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 56581d60250680947e3e328bab21bc9e169df22c From 9506e6741a4413a4c7c350bc7548c4ea1d3cf026 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 7 Apr 2025 17:20:46 -0700 Subject: [PATCH 26/32] remove uses of custom siteorcommunity enum --- crates/apub/src/activities/block/mod.rs | 7 --- crates/apub/src/activities/community/mod.rs | 12 ++++- .../apub/src/activities/community/report.rs | 11 ++--- .../activities/community/resolve_report.rs | 9 ++-- crates/apub/src/activities/mod.rs | 45 +++++-------------- crates/apub/src/activity_lists.rs | 9 ++-- .../protocol/activities/community/report.rs | 7 +-- .../activities/community/resolve_report.rs | 7 +-- 8 files changed, 46 insertions(+), 61 deletions(-) diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index 1d911d3dc9..d9d57f2e12 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -114,13 +114,6 @@ impl SiteOrCommunity { SiteOrCommunity::Community(c) => ObjectId::from(c.ap_id.clone()), } } - - pub(crate) fn local_community(&self) -> Option<&ApubCommunity> { - match self { - SiteOrCommunity::Community(c) if c.local => Some(c), - _ => None, - } - } } async fn generate_cc(target: &SiteOrCommunity, pool: &mut DbPool<'_>) -> LemmyResult> { diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 75512bd40c..16206cdbbd 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -6,6 +6,7 @@ use crate::{ protocol::activities::community::announce::AnnounceActivity, }; use activitypub_federation::{config::Data, fetch::object_id::ObjectId, traits::Actor}; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ @@ -80,13 +81,13 @@ pub(crate) async fn send_activity_in_community( async fn report_inboxes( object_id: ObjectId, - receiver: &SiteOrCommunity, + receiver: &Either, context: &Data, ) -> LemmyResult { // send report to the community where object was posted let mut inboxes = ActivitySendTargets::to_inbox(receiver.shared_inbox_or_inbox()); - if let Some(community) = receiver.local_community() { + if let Some(community) = local_community(receiver) { // send to all moderators let moderators = CommunityModeratorView::for_community(&mut context.pool(), community.id).await?; @@ -112,3 +113,10 @@ async fn report_inboxes( } Ok(inboxes) } + +fn local_community(site_or_community: &Either) -> Option<&ApubCommunity> { + match site_or_community { + Either::Right(c) if c.local => Some(c), + _ => None, + } +} diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 4bc4b95a0c..c962e53d70 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -1,4 +1,4 @@ -use super::report_inboxes; +use super::{local_community, report_inboxes}; use crate::{ activities::{ block::SiteOrCommunity, @@ -9,7 +9,7 @@ use crate::{ activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, insert_received_activity, - objects::person::ApubPerson, + objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::community::{ announce::AnnounceActivity, report::{Report, ReportObject}, @@ -22,6 +22,7 @@ use activitypub_federation::{ kinds::activity::FlagType, traits::{ActivityHandler, Actor}, }; +use either::Either; use lemmy_api_common::{ context::LemmyContext, utils::{ @@ -45,7 +46,7 @@ impl Report { pub(crate) fn new( object_id: &ObjectId, actor: &ApubPerson, - receiver: &SiteOrCommunity, + receiver: &Either, reason: Option, context: &Data, ) -> LemmyResult { @@ -68,7 +69,7 @@ impl Report { pub(crate) async fn send( object_id: ObjectId, actor: &ApubPerson, - receiver: &SiteOrCommunity, + receiver: &Either, reason: String, context: Data, ) -> LemmyResult<()> { @@ -147,7 +148,7 @@ impl ActivityHandler for Report { }; let receiver = self.receiver(context).await?; - if let Some(community) = receiver.local_community() { + if let Some(community) = local_community(&receiver) { // forward to remote mods let object_id = self.object.object_id(context).await?; let announce = AnnouncableActivities::Report(self); diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index 04a480c7c8..f967aa5986 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -1,4 +1,4 @@ -use super::report_inboxes; +use super::{local_community, report_inboxes}; use crate::{ activities::{ block::SiteOrCommunity, @@ -10,7 +10,7 @@ use crate::{ activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, insert_received_activity, - objects::person::ApubPerson, + objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::community::{ announce::AnnounceActivity, report::Report, @@ -24,6 +24,7 @@ use activitypub_federation::{ protocol::verification::verify_urls_match, traits::{ActivityHandler, Actor}, }; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ source::{ @@ -41,7 +42,7 @@ impl ResolveReport { object_id: ObjectId, actor: &ApubPerson, report_creator: &ApubPerson, - receiver: &SiteOrCommunity, + receiver: &Either, context: Data, ) -> LemmyResult<()> { let kind = ResolveType::Resolve; @@ -103,7 +104,7 @@ impl ActivityHandler for ResolveReport { }; let receiver = self.receiver(context).await?; - if let Some(community) = receiver.local_community() { + if let Some(community) = local_community(&receiver) { // forward to remote mods let object_id = self.object.object.object_id(context).await?; let announce = AnnouncableActivities::ResolveReport(self); diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index b68c474781..1bc31e113d 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -16,7 +16,7 @@ use crate::{ }, voting::send_like_activity, }, - objects::{community::ApubCommunity, person::ApubPerson}, + objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::{ community::{report::Report, resolve_report::ResolveReport}, create_or_update::{note::CreateOrUpdateNote, page::CreateOrUpdatePage}, @@ -30,6 +30,7 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use block::SiteOrCommunity; +use either::Either; use following::send_accept_or_reject_follow; use lemmy_api_common::{ context::LemmyContext, @@ -89,34 +90,12 @@ pub(crate) async fn verify_person_in_community( /// from local site or community. pub(crate) async fn verify_person_in_site_or_community( person_id: &ObjectId, - site_or_community: &SiteOrCommunity, + site_or_community: &Either, context: &Data, ) -> LemmyResult<()> { let person = person_id.dereference(context).await?; - if person.banned { - Err(FederationError::PersonIsBannedFromSite( - person.ap_id.to_string(), - ))? - } - let person_id = person.id; - let community_id = community.id; - CommunityPersonBanView::check(&mut context.pool(), person_id, community_id).await -} - -/// Fetches the person and community or site to verify their type, then checks if person is banned -/// from local site or community. -pub(crate) async fn verify_person_in_site_or_community( - person_id: &ObjectId, - site_or_community: &SiteOrCommunity, - context: &Data, -) -> LemmyResult<()> { - let person = person_id.dereference(context).await?; - if person.banned { - Err(FederationError::PersonIsBannedFromSite( - person.ap_id.to_string(), - ))? - } - if let SiteOrCommunity::Community(community) = site_or_community { + InstanceActions::check_ban(&mut context.pool(), person.id, person.instance_id).await?; + if let Either::Right(community) = site_or_community { let person_id = person.id; let community_id = community.id; CommunityPersonBanView::check(&mut context.pool(), person_id, community_id).await?; @@ -177,12 +156,12 @@ pub(crate) async fn verify_admin_action( pub(crate) async fn verify_mod_or_admin_action( person_id: &ObjectId, - site_or_community: &SiteOrCommunity, + site_or_community: &Either, context: &Data, ) -> LemmyResult<()> { match site_or_community { - SiteOrCommunity::Site(site) => verify_admin_action(person_id, site, context).await, - SiteOrCommunity::Community(community) => verify_mod_action(person_id, community, context).await, + Either::Left(site) => verify_admin_action(person_id, site, context).await, + Either::Right(community) => verify_mod_action(person_id, community, context).await, } } @@ -459,7 +438,7 @@ pub async fn match_outgoing_activities( Report::send( ObjectId::from(object_id), &actor.into(), - &SiteOrCommunity::Community(community.into()), + &Either::Right(community.into()), reason, context, ) @@ -475,7 +454,7 @@ pub async fn match_outgoing_activities( ObjectId::from(object_id), &actor.into(), &report_creator.into(), - &SiteOrCommunity::Community(community.into()), + &Either::Right(community.into()), context, ) .await @@ -489,7 +468,7 @@ pub async fn match_outgoing_activities( Report::send( ObjectId::from(object_id), &actor.into(), - &SiteOrCommunity::Site(site.into()), + &Either::Left(site.into()), reason, context, ) @@ -505,7 +484,7 @@ pub async fn match_outgoing_activities( ObjectId::from(object_id), &actor.into(), &report_creator.into(), - &SiteOrCommunity::Site(site.into()), + &Either::Left(site.into()), context, ) .await diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index c38c17f221..923d8e6d93 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -28,6 +28,7 @@ use crate::{ }, }; use activitypub_federation::{config::Data, traits::ActivityHandler}; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::{LemmyErrorType, LemmyResult}; use serde::{Deserialize, Serialize}; @@ -94,12 +95,12 @@ impl InCommunity for AnnouncableActivities { LockPost(a) => a.community(context).await, UndoLockPost(a) => a.community(context).await, Report(a) => match a.receiver(context).await? { - SiteOrCommunity::Site(_) => Err(LemmyErrorType::NotFound.into()), - SiteOrCommunity::Community(c) => Ok(c), + Either::Left(_) => Err(LemmyErrorType::NotFound.into()), + Either::Right(c) => Ok(c), }, ResolveReport(a) => match a.receiver(context).await? { - SiteOrCommunity::Site(_) => Err(LemmyErrorType::NotFound.into()), - SiteOrCommunity::Community(c) => Ok(c), + Either::Left(_) => Err(LemmyErrorType::NotFound.into()), + Either::Right(c) => Ok(c), }, Page(_) => Err(LemmyErrorType::NotFound.into()), } diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 81a083a93a..92c7c27076 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -1,7 +1,7 @@ use crate::{ activities::block::SiteOrCommunity, fetcher::report::ReportableObjects, - objects::person::ApubPerson, + objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, }; use activitypub_federation::{ config::Data, @@ -9,6 +9,7 @@ use activitypub_federation::{ kinds::activity::FlagType, protocol::helpers::deserialize_one, }; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::{LemmyErrorType, LemmyResult}; use serde::{Deserialize, Serialize}; @@ -19,7 +20,7 @@ use url::Url; pub struct Report { pub(crate) actor: ObjectId, #[serde(deserialize_with = "deserialize_one")] - pub(crate) to: [ObjectId; 1], + pub(crate) to: [ObjectId>; 1], pub(crate) object: ReportObject, /// Report reason as sent by Lemmy pub(crate) summary: Option, @@ -42,7 +43,7 @@ impl Report { pub(crate) async fn receiver( &self, context: &Data, - ) -> LemmyResult { + ) -> LemmyResult> { let receiver = self.to[0].dereference(context).await?; Ok(receiver) } diff --git a/crates/apub/src/protocol/activities/community/resolve_report.rs b/crates/apub/src/protocol/activities/community/resolve_report.rs index 11b9b9ee3a..36ed5de1fb 100644 --- a/crates/apub/src/protocol/activities/community/resolve_report.rs +++ b/crates/apub/src/protocol/activities/community/resolve_report.rs @@ -1,13 +1,14 @@ use super::report::Report; use crate::{ activities::block::SiteOrCommunity, - objects::{community::ApubCommunity, person::ApubPerson}, + objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, }; use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, protocol::helpers::deserialize_one, }; +use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::LemmyResult; use serde::{Deserialize, Serialize}; @@ -24,7 +25,7 @@ pub enum ResolveType { pub struct ResolveReport { pub(crate) actor: ObjectId, #[serde(deserialize_with = "deserialize_one")] - pub(crate) to: [ObjectId; 1], + pub(crate) to: [ObjectId>; 1], pub(crate) object: Report, #[serde(rename = "type")] pub(crate) kind: ResolveType, @@ -35,7 +36,7 @@ impl ResolveReport { pub(crate) async fn receiver( &self, context: &Data, - ) -> LemmyResult { + ) -> LemmyResult> { self.object.receiver(context).await } } From dfad1a03640c20a81bed05877dce01e5e07510e3 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 7 Apr 2025 17:45:57 -0700 Subject: [PATCH 27/32] clippy --- crates/apub/src/activities/community/mod.rs | 2 +- crates/apub/src/activities/community/report.rs | 7 +------ crates/apub/src/activities/community/resolve_report.rs | 1 - crates/apub/src/activities/mod.rs | 1 - crates/apub/src/activity_lists.rs | 1 - crates/apub/src/protocol/activities/community/report.rs | 1 - .../src/protocol/activities/community/resolve_report.rs | 5 +---- 7 files changed, 3 insertions(+), 15 deletions(-) diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 16206cdbbd..8b371192a9 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -1,5 +1,5 @@ use crate::{ - activities::{block::SiteOrCommunity, send_lemmy_activity}, + activities::send_lemmy_activity, activity_lists::AnnouncableActivities, fetcher::{report::ReportableObjects, PostOrComment}, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index c962e53d70..38c74685ad 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -1,11 +1,6 @@ use super::{local_community, report_inboxes}; use crate::{ - activities::{ - block::SiteOrCommunity, - generate_activity_id, - send_lemmy_activity, - verify_person_in_site_or_community, - }, + activities::{generate_activity_id, send_lemmy_activity, verify_person_in_site_or_community}, activity_lists::AnnouncableActivities, fetcher::report::ReportableObjects, insert_received_activity, diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index f967aa5986..01fe1ca620 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -1,7 +1,6 @@ use super::{local_community, report_inboxes}; use crate::{ activities::{ - block::SiteOrCommunity, generate_activity_id, send_lemmy_activity, verify_mod_or_admin_action, diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 1bc31e113d..461af73474 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -29,7 +29,6 @@ use activitypub_federation::{ kinds::{activity::AnnounceType, public}, traits::{ActivityHandler, Actor}, }; -use block::SiteOrCommunity; use either::Either; use following::send_accept_or_reject_follow; use lemmy_api_common::{ diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index 923d8e6d93..ddec9963ef 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -1,5 +1,4 @@ use crate::{ - activities::block::SiteOrCommunity, objects::community::ApubCommunity, protocol::{ activities::{ diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 92c7c27076..6bbe601ec3 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -1,5 +1,4 @@ use crate::{ - activities::block::SiteOrCommunity, fetcher::report::ReportableObjects, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, }; diff --git a/crates/apub/src/protocol/activities/community/resolve_report.rs b/crates/apub/src/protocol/activities/community/resolve_report.rs index 36ed5de1fb..fb801d7856 100644 --- a/crates/apub/src/protocol/activities/community/resolve_report.rs +++ b/crates/apub/src/protocol/activities/community/resolve_report.rs @@ -1,8 +1,5 @@ use super::report::Report; -use crate::{ - activities::block::SiteOrCommunity, - objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, -}; +use crate::objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}; use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, From 67d8a33d6c92b4c6ebd370d3e7256c83fef2f693 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 7 Apr 2025 17:59:29 -0700 Subject: [PATCH 28/32] dont use separate module for reportableobjects --- crates/apub/src/activities/community/mod.rs | 2 +- crates/apub/src/activities/community/report.rs | 2 +- crates/apub/src/activities/community/resolve_report.rs | 2 +- crates/apub/src/fetcher/mod.rs | 3 ++- crates/apub/src/fetcher/report.rs | 7 ------- crates/apub/src/protocol/activities/community/report.rs | 2 +- 6 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 crates/apub/src/fetcher/report.rs diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index 8b371192a9..17989d8f85 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -1,7 +1,7 @@ use crate::{ activities::send_lemmy_activity, activity_lists::AnnouncableActivities, - fetcher::{report::ReportableObjects, PostOrComment}, + fetcher::{PostOrComment, ReportableObjects}, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::community::announce::AnnounceActivity, }; diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 38c74685ad..0930677587 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -2,7 +2,7 @@ use super::{local_community, report_inboxes}; use crate::{ activities::{generate_activity_id, send_lemmy_activity, verify_person_in_site_or_community}, activity_lists::AnnouncableActivities, - fetcher::report::ReportableObjects, + fetcher::ReportableObjects, insert_received_activity, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::community::{ diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index 01fe1ca620..223f775029 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -7,7 +7,7 @@ use crate::{ verify_person_in_site_or_community, }, activity_lists::AnnouncableActivities, - fetcher::report::ReportableObjects, + fetcher::ReportableObjects, insert_received_activity, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, protocol::activities::community::{ diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index e0b615bcb9..91d984ad81 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -19,11 +19,12 @@ use lemmy_db_views::structs::LocalUserView; use lemmy_utils::error::{LemmyError, LemmyResult}; pub(crate) mod markdown_links; -pub(crate) mod report; pub mod search; pub(crate) type PostOrComment = Either; +pub(crate) type ReportableObjects = Either; + pub type SiteOrCommunityOrUser = Either; pub type UserOrCommunity = Either; diff --git a/crates/apub/src/fetcher/report.rs b/crates/apub/src/fetcher/report.rs deleted file mode 100644 index fb6a21484b..0000000000 --- a/crates/apub/src/fetcher/report.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::{fetcher::PostOrComment, objects::community::ApubCommunity}; -use either::Either; - -// TODO don't use separate module for this - -/// The types of ActivityPub objects that reports can be created for. -pub(crate) type ReportableObjects = Either; diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 6bbe601ec3..9c2e2d8070 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -1,5 +1,5 @@ use crate::{ - fetcher::report::ReportableObjects, + fetcher::ReportableObjects, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, }; use activitypub_federation::{ From 013663157cf5cfc7aa970924a96624ff4ead2ae9 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Sun, 20 Apr 2025 21:51:50 -0700 Subject: [PATCH 29/32] remove ResolveReport::reciever --- .../src/activities/community/resolve_report.rs | 4 ++-- crates/apub/src/activity_lists.rs | 2 +- .../activities/community/resolve_report.rs | 17 +---------------- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/crates/apub/src/activities/community/resolve_report.rs b/crates/apub/src/activities/community/resolve_report.rs index 223f775029..d70cc523f4 100644 --- a/crates/apub/src/activities/community/resolve_report.rs +++ b/crates/apub/src/activities/community/resolve_report.rs @@ -78,7 +78,7 @@ impl ActivityHandler for ResolveReport { async fn verify(&self, context: &Data) -> LemmyResult<()> { self.object.verify(context).await?; - let receiver = self.receiver(context).await?; + let receiver = self.object.receiver(context).await?; verify_person_in_site_or_community(&self.actor, &receiver, context).await?; verify_urls_match(self.to[0].inner(), self.object.to[0].inner())?; verify_mod_or_admin_action(&self.actor, &receiver, context).await?; @@ -102,7 +102,7 @@ impl ActivityHandler for ResolveReport { } }; - let receiver = self.receiver(context).await?; + let receiver = self.object.receiver(context).await?; if let Some(community) = local_community(&receiver) { // forward to remote mods let object_id = self.object.object.object_id(context).await?; diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index ddec9963ef..22e18b581a 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -97,7 +97,7 @@ impl InCommunity for AnnouncableActivities { Either::Left(_) => Err(LemmyErrorType::NotFound.into()), Either::Right(c) => Ok(c), }, - ResolveReport(a) => match a.receiver(context).await? { + ResolveReport(a) => match a.object.receiver(context).await? { Either::Left(_) => Err(LemmyErrorType::NotFound.into()), Either::Right(c) => Ok(c), }, diff --git a/crates/apub/src/protocol/activities/community/resolve_report.rs b/crates/apub/src/protocol/activities/community/resolve_report.rs index fb801d7856..3a756b7884 100644 --- a/crates/apub/src/protocol/activities/community/resolve_report.rs +++ b/crates/apub/src/protocol/activities/community/resolve_report.rs @@ -1,13 +1,7 @@ use super::report::Report; use crate::objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}; -use activitypub_federation::{ - config::Data, - fetch::object_id::ObjectId, - protocol::helpers::deserialize_one, -}; +use activitypub_federation::{fetch::object_id::ObjectId, protocol::helpers::deserialize_one}; use either::Either; -use lemmy_api_common::context::LemmyContext; -use lemmy_utils::error::LemmyResult; use serde::{Deserialize, Serialize}; use strum::Display; use url::Url; @@ -28,12 +22,3 @@ pub struct ResolveReport { pub(crate) kind: ResolveType, pub(crate) id: Url, } - -impl ResolveReport { - pub(crate) async fn receiver( - &self, - context: &Data, - ) -> LemmyResult> { - self.object.receiver(context).await - } -} From ad6d294946bfa0b69b6588015930aaf094ed4758 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 21 Apr 2025 17:22:15 -0700 Subject: [PATCH 30/32] replace match in activity_lists with Report::community --- crates/apub/src/activity_lists.rs | 11 ++--------- .../apub/src/protocol/activities/community/report.rs | 12 +++++++++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index 22e18b581a..9e4f58a5f5 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -27,7 +27,6 @@ use crate::{ }, }; use activitypub_federation::{config::Data, traits::ActivityHandler}; -use either::Either; use lemmy_api_common::context::LemmyContext; use lemmy_utils::error::{LemmyErrorType, LemmyResult}; use serde::{Deserialize, Serialize}; @@ -93,14 +92,8 @@ impl InCommunity for AnnouncableActivities { CollectionRemove(a) => a.community(context).await, LockPost(a) => a.community(context).await, UndoLockPost(a) => a.community(context).await, - Report(a) => match a.receiver(context).await? { - Either::Left(_) => Err(LemmyErrorType::NotFound.into()), - Either::Right(c) => Ok(c), - }, - ResolveReport(a) => match a.object.receiver(context).await? { - Either::Left(_) => Err(LemmyErrorType::NotFound.into()), - Either::Right(c) => Ok(c), - }, + Report(a) => a.community(context).await, + ResolveReport(a) => a.object.community(context).await, Page(_) => Err(LemmyErrorType::NotFound.into()), } } diff --git a/crates/apub/src/protocol/activities/community/report.rs b/crates/apub/src/protocol/activities/community/report.rs index 9c2e2d8070..637e089384 100644 --- a/crates/apub/src/protocol/activities/community/report.rs +++ b/crates/apub/src/protocol/activities/community/report.rs @@ -1,6 +1,7 @@ use crate::{ fetcher::ReportableObjects, objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson}, + protocol::InCommunity, }; use activitypub_federation::{ config::Data, @@ -21,7 +22,7 @@ pub struct Report { #[serde(deserialize_with = "deserialize_one")] pub(crate) to: [ObjectId>; 1], pub(crate) object: ReportObject, - /// Report reason as sent by Lemmy + /// Report reason as sent by Lemmy{ pub(crate) summary: Option, /// Report reason as sent by Mastodon pub(crate) content: Option, @@ -98,3 +99,12 @@ impl ReportObject { } } } + +impl InCommunity for Report { + async fn community(&self, context: &Data) -> LemmyResult { + match self.receiver(context).await? { + Either::Left(_) => Err(LemmyErrorType::NotFound.into()), + Either::Right(c) => Ok(c), + } + } +} From f31524087bc140fa3758ac23d10e3daee5728816 Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 21 Apr 2025 18:25:41 -0700 Subject: [PATCH 31/32] combine variants for community and site in SendActivityData enum --- Cargo.lock | 2 + crates/api/Cargo.toml | 1 + .../api/src/reports/comment_report/create.rs | 3 +- .../api/src/reports/comment_report/resolve.rs | 3 +- .../src/reports/community_report/create.rs | 5 ++- .../src/reports/community_report/resolve.rs | 5 ++- crates/api/src/reports/post_report/create.rs | 3 +- crates/api/src/reports/post_report/resolve.rs | 3 +- crates/api_common/Cargo.toml | 1 + crates/api_common/src/send_activity.rs | 17 ++------- crates/apub/src/activities/mod.rs | 38 ++----------------- 11 files changed, 25 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d3bcf04360..eef05660cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3114,6 +3114,7 @@ dependencies = [ "captcha", "chrono", "diesel-async", + "either", "elementtree", "hound", "lemmy_api_common", @@ -3142,6 +3143,7 @@ dependencies = [ "actix-web-httpauth", "anyhow", "chrono", + "either", "encoding_rs", "enum-map", "extism", diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 252a7e7cc8..c10b65c5a2 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -38,6 +38,7 @@ hound = "3.5.1" sitemap-rs = "0.2.2" totp-rs = { version = "5.6.0", features = ["gen_secret", "otpauth"] } diesel-async = { workspace = true, features = ["deadpool", "postgres"] } +either = { workspace = true } [dev-dependencies] serial_test = { workspace = true } diff --git a/crates/api/src/reports/comment_report/create.rs b/crates/api/src/reports/comment_report/create.rs index 49af35c4f0..0dc0fcffaf 100644 --- a/crates/api/src/reports/comment_report/create.rs +++ b/crates/api/src/reports/comment_report/create.rs @@ -1,6 +1,7 @@ use crate::check_report_reason; use activitypub_federation::config::Data; use actix_web::web::Json; +use either::Either; use lemmy_api_common::{ context::LemmyContext, reports::comment::{CommentReportResponse, CreateCommentReport}, @@ -75,7 +76,7 @@ pub async fn create_comment_report( SendActivityData::CreateReport { object_id: comment_view.comment.ap_id.inner().clone(), actor: local_user_view.person, - community: comment_view.community, + receiver: Either::Right(comment_view.community), reason: data.reason.clone(), }, &context, diff --git a/crates/api/src/reports/comment_report/resolve.rs b/crates/api/src/reports/comment_report/resolve.rs index 64965e83d0..218c5e9b9e 100644 --- a/crates/api/src/reports/comment_report/resolve.rs +++ b/crates/api/src/reports/comment_report/resolve.rs @@ -1,5 +1,6 @@ use activitypub_federation::config::Data; use actix_web::web::Json; +use either::Either; use lemmy_api_common::{ context::LemmyContext, reports::comment::{CommentReportResponse, ResolveCommentReport}, @@ -44,7 +45,7 @@ pub async fn resolve_comment_report( object_id: comment_report_view.comment.ap_id.inner().clone(), actor: local_user_view.person, report_creator: report.creator, - community: comment_report_view.community.clone(), + receiver: Either::Right(comment_report_view.community.clone()), }, &context, )?; diff --git a/crates/api/src/reports/community_report/create.rs b/crates/api/src/reports/community_report/create.rs index 0df088b4a2..c1fcefdf10 100644 --- a/crates/api/src/reports/community_report/create.rs +++ b/crates/api/src/reports/community_report/create.rs @@ -1,6 +1,7 @@ use crate::check_report_reason; use activitypub_federation::config::Data; use actix_web::web::Json; +use either::Either; use lemmy_api_common::{ context::LemmyContext, reports::community::{CommunityReportResponse, CreateCommunityReport}, @@ -66,10 +67,10 @@ pub async fn create_community_report( } ActivityChannel::submit_activity( - SendActivityData::CreateReportToSite { + SendActivityData::CreateReport { object_id: community.ap_id.inner().clone(), actor: local_user_view.person, - site, + receiver: Either::Left(site), reason: data.reason.clone(), }, &context, diff --git a/crates/api/src/reports/community_report/resolve.rs b/crates/api/src/reports/community_report/resolve.rs index 97b1c32b10..1f7f8a1851 100644 --- a/crates/api/src/reports/community_report/resolve.rs +++ b/crates/api/src/reports/community_report/resolve.rs @@ -1,5 +1,6 @@ use activitypub_federation::config::Data; use actix_web::web::Json; +use either::Either; use lemmy_api_common::{ context::LemmyContext, reports::community::{CommunityReportResponse, ResolveCommunityReport}, @@ -37,11 +38,11 @@ pub async fn resolve_community_report( .await?; ActivityChannel::submit_activity( - SendActivityData::SendResolveReportToSite { + SendActivityData::SendResolveReport { object_id: community_report_view.community.ap_id.inner().clone(), actor: local_user_view.person, report_creator: community_report_view.creator.clone(), - site, + receiver: Either::Left(site), }, &context, )?; diff --git a/crates/api/src/reports/post_report/create.rs b/crates/api/src/reports/post_report/create.rs index 992e6ea520..d8989e429c 100644 --- a/crates/api/src/reports/post_report/create.rs +++ b/crates/api/src/reports/post_report/create.rs @@ -1,6 +1,7 @@ use crate::check_report_reason; use activitypub_federation::config::Data; use actix_web::web::Json; +use either::Either; use lemmy_api_common::{ context::LemmyContext, reports::post::{CreatePostReport, PostReportResponse}, @@ -65,7 +66,7 @@ pub async fn create_post_report( SendActivityData::CreateReport { object_id: post_view.post.ap_id.inner().clone(), actor: local_user_view.person, - community: post_view.community, + receiver: Either::Right(post_view.community), reason: data.reason.clone(), }, &context, diff --git a/crates/api/src/reports/post_report/resolve.rs b/crates/api/src/reports/post_report/resolve.rs index 24dfdf7179..3e81d9a5a1 100644 --- a/crates/api/src/reports/post_report/resolve.rs +++ b/crates/api/src/reports/post_report/resolve.rs @@ -1,5 +1,6 @@ use activitypub_federation::config::Data; use actix_web::web::Json; +use either::Either; use lemmy_api_common::{ context::LemmyContext, reports::post::{PostReportResponse, ResolvePostReport}, @@ -42,7 +43,7 @@ pub async fn resolve_post_report( object_id: post_report_view.post.ap_id.inner().clone(), actor: local_user_view.person, report_creator: report.creator, - community: post_report_view.community.clone(), + receiver: Either::Right(post_report_view.community.clone()), }, &context, )?; diff --git a/crates/api_common/Cargo.toml b/crates/api_common/Cargo.toml index 98ef7b503d..34cdda6213 100644 --- a/crates/api_common/Cargo.toml +++ b/crates/api_common/Cargo.toml @@ -80,6 +80,7 @@ webmention = { version = "0.6.0", optional = true } extism = { git = "https://github.com/extism/extism.git", branch = "pool", optional = true } extism-convert = { git = "https://github.com/extism/extism.git", branch = "pool", optional = true } once_cell = { version = "1.21.0", optional = true } +either = { workspace = true } [dev-dependencies] serial_test = { workspace = true } diff --git a/crates/api_common/src/send_activity.rs b/crates/api_common/src/send_activity.rs index 28d3f5c9d7..abfe63f107 100644 --- a/crates/api_common/src/send_activity.rs +++ b/crates/api_common/src/send_activity.rs @@ -1,5 +1,6 @@ use crate::{community::BanFromCommunity, context::LemmyContext, post::DeletePost}; use activitypub_federation::config::Data; +use either::Either; use futures::future::BoxFuture; use lemmy_db_schema::{ newtypes::{CommunityId, DbUrl, PersonId}, @@ -97,26 +98,14 @@ pub enum SendActivityData { CreateReport { object_id: Url, actor: Person, - community: Community, + receiver: Either, reason: String, }, SendResolveReport { object_id: Url, actor: Person, report_creator: Person, - community: Community, - }, - CreateReportToSite { - object_id: Url, - actor: Person, - site: Site, - reason: String, - }, - SendResolveReportToSite { - object_id: Url, - actor: Person, - report_creator: Person, - site: Site, + receiver: Either, }, } diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 461af73474..8482766558 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -431,13 +431,13 @@ pub async fn match_outgoing_activities( CreateReport { object_id, actor, - community, + receiver, reason, } => { Report::send( ObjectId::from(object_id), &actor.into(), - &Either::Right(community.into()), + &receiver.map_either(Into::into, Into::into), reason, context, ) @@ -447,43 +447,13 @@ pub async fn match_outgoing_activities( object_id, actor, report_creator, - community, - } => { - ResolveReport::send( - ObjectId::from(object_id), - &actor.into(), - &report_creator.into(), - &Either::Right(community.into()), - context, - ) - .await - } - CreateReportToSite { - object_id, - actor, - site, - reason, - } => { - Report::send( - ObjectId::from(object_id), - &actor.into(), - &Either::Left(site.into()), - reason, - context, - ) - .await - } - SendResolveReportToSite { - object_id, - actor, - report_creator, - site, + receiver, } => { ResolveReport::send( ObjectId::from(object_id), &actor.into(), &report_creator.into(), - &Either::Left(site.into()), + &receiver.map_either(Into::into, Into::into), context, ) .await From 63253cbfd5654c72178e404bb3aace773ab5ec0c Mon Sep 17 00:00:00 2001 From: Dull Bananas Date: Mon, 21 Apr 2025 18:56:06 -0700 Subject: [PATCH 32/32] add reportCommunity function to shared.ts --- api_tests/src/shared.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts index 0998e47c15..b7be9a59e3 100644 --- a/api_tests/src/shared.ts +++ b/api_tests/src/shared.ts @@ -80,6 +80,8 @@ import { PostReportResponse } from "lemmy-js-client/dist/types/PostReportRespons import { CreatePostReport } from "lemmy-js-client/dist/types/CreatePostReport"; import { CommentReportResponse } from "lemmy-js-client/dist/types/CommentReportResponse"; import { CreateCommentReport } from "lemmy-js-client/dist/types/CreateCommentReport"; +import { CommunityReportResponse } from "lemmy-js-client/dist/types/CommunityReportResponse"; +import { CreateCommunityReport } from "lemmy-js-client/dist/types/CreateCommunityReport"; import { GetPostsResponse } from "lemmy-js-client/dist/types/GetPostsResponse"; import { GetPosts } from "lemmy-js-client/dist/types/GetPosts"; import { GetPersonDetailsResponse } from "lemmy-js-client/dist/types/GetPersonDetailsResponse"; @@ -797,6 +799,18 @@ export async function reportPost( return api.createPostReport(form); } +export async function reportCommunity( + api: LemmyHttp, + community_id: number, + reason: string, +): Promise { + let form: CreateCommunityReport = { + community_id, + reason, + }; + return api.createCommunityReport(form); +} + export async function listReports( api: LemmyHttp, show_community_rule_violations: boolean = false,