From 5a0621b37d9594a452be76b06c7cb2dfdb0edbd1 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Sun, 23 Apr 2023 23:27:43 +0200 Subject: [PATCH 1/2] Add `to` field in follow activities for better compatibility (fixes #2744) --- crates/apub/assets/lemmy/activities/following/accept.json | 2 ++ crates/apub/assets/lemmy/activities/following/follow.json | 1 + .../assets/lemmy/activities/following/undo_follow.json | 2 ++ crates/apub/src/activities/following/accept.rs | 4 ++++ crates/apub/src/activities/following/follow.rs | 5 +++++ crates/apub/src/activities/following/undo_follow.rs | 4 ++++ crates/apub/src/protocol/activities/following/accept.rs | 7 ++++++- crates/apub/src/protocol/activities/following/follow.rs | 2 ++ .../apub/src/protocol/activities/following/undo_follow.rs | 2 ++ 9 files changed, 28 insertions(+), 1 deletion(-) diff --git a/crates/apub/assets/lemmy/activities/following/accept.json b/crates/apub/assets/lemmy/activities/following/accept.json index 4097b36754..fde48880bc 100644 --- a/crates/apub/assets/lemmy/activities/following/accept.json +++ b/crates/apub/assets/lemmy/activities/following/accept.json @@ -1,7 +1,9 @@ { "actor": "http://enterprise.lemmy.ml/c/main", + "to": "http://ds9.lemmy.ml/u/lemmy_alpha", "object": { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": "http://enterprise.lemmy.ml/c/main", "object": "http://enterprise.lemmy.ml/c/main", "type": "Follow", "id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866" diff --git a/crates/apub/assets/lemmy/activities/following/follow.json b/crates/apub/assets/lemmy/activities/following/follow.json index 48f3fef8b7..5d1def0f8f 100644 --- a/crates/apub/assets/lemmy/activities/following/follow.json +++ b/crates/apub/assets/lemmy/activities/following/follow.json @@ -1,5 +1,6 @@ { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": "http://enterprise.lemmy.ml/c/main", "object": "http://enterprise.lemmy.ml/c/main", "type": "Follow", "id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866" diff --git a/crates/apub/assets/lemmy/activities/following/undo_follow.json b/crates/apub/assets/lemmy/activities/following/undo_follow.json index 5311bd990b..763c67d9d9 100644 --- a/crates/apub/assets/lemmy/activities/following/undo_follow.json +++ b/crates/apub/assets/lemmy/activities/following/undo_follow.json @@ -1,7 +1,9 @@ { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": "http://enterprise.lemmy.ml/c/main", "object": { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": "http://enterprise.lemmy.ml/c/main", "object": "http://enterprise.lemmy.ml/c/main", "type": "Follow", "id": "http://ds9.lemmy.ml/activities/follow/dc2f1bc5-f3a0-4daa-a46b-428cbfbd023c" diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index c57ec0b530..034013eae9 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -34,6 +34,7 @@ impl AcceptFollow { let person = follow.actor.clone().dereference(context).await?; let accept = AcceptFollow { actor: user_or_community.id().into(), + to: Some(person.id().into()), object: follow, kind: AcceptType::Accept, id: generate_activity_id( @@ -64,6 +65,9 @@ impl ActivityHandler for AcceptFollow { async fn verify(&self, context: &Data) -> Result<(), LemmyError> { verify_urls_match(self.actor.inner(), self.object.object.inner())?; self.object.verify(context).await?; + if let Some(to) = &self.to { + verify_urls_match(to.inner(), self.object.actor.inner())?; + } Ok(()) } diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 41d2e71ed7..893eea2e1e 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -18,6 +18,7 @@ use crate::{ use activitypub_federation::{ config::Data, kinds::activity::FollowType, + protocol::verification::verify_urls_match, traits::{ActivityHandler, Actor}, }; use lemmy_api_common::{ @@ -44,6 +45,7 @@ impl Follow { Ok(Follow { actor: actor.id().into(), object: community.id().into(), + to: Some(community.id().into()), kind: FollowType::Follow, id: generate_activity_id( FollowType::Follow, @@ -93,6 +95,9 @@ impl ActivityHandler for Follow { if let UserOrCommunity::Community(c) = object { verify_person_in_community(&self.actor, &c, context).await?; } + if let Some(to) = &self.to { + verify_urls_match(to.inner(), self.object.inner())?; + } Ok(()) } diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index 9f1b89dc1a..0233dcf778 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -32,6 +32,7 @@ impl UndoFollow { let object = Follow::new(actor, community, context)?; let undo = UndoFollow { actor: actor.id().into(), + to: Some(community.id().into()), object, kind: UndoType::Undo, id: generate_activity_id( @@ -62,6 +63,9 @@ impl ActivityHandler for UndoFollow { verify_urls_match(self.actor.inner(), self.object.actor.inner())?; verify_person(&self.actor, context).await?; self.object.verify(context).await?; + if let Some(to) = &self.to { + verify_urls_match(to.inner(), self.object.object.inner())?; + } Ok(()) } diff --git a/crates/apub/src/protocol/activities/following/accept.rs b/crates/apub/src/protocol/activities/following/accept.rs index 786827ed9b..a67fd92ed4 100644 --- a/crates/apub/src/protocol/activities/following/accept.rs +++ b/crates/apub/src/protocol/activities/following/accept.rs @@ -1,4 +1,7 @@ -use crate::{objects::community::ApubCommunity, protocol::activities::following::follow::Follow}; +use crate::{ + objects::{community::ApubCommunity, person::ApubPerson}, + protocol::activities::following::follow::Follow, +}; use activitypub_federation::{fetch::object_id::ObjectId, kinds::activity::AcceptType}; use serde::{Deserialize, Serialize}; use url::Url; @@ -7,6 +10,8 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct AcceptFollow { pub(crate) actor: ObjectId, + /// Optional, for compatibility with platforms that always expect recipient field + pub(crate) to: Option>, pub(crate) object: Follow, #[serde(rename = "type")] pub(crate) kind: AcceptType, diff --git a/crates/apub/src/protocol/activities/following/follow.rs b/crates/apub/src/protocol/activities/following/follow.rs index 27a3ba4be6..929224e73e 100644 --- a/crates/apub/src/protocol/activities/following/follow.rs +++ b/crates/apub/src/protocol/activities/following/follow.rs @@ -7,6 +7,8 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct Follow { pub(crate) actor: ObjectId, + /// Optional, for compatibility with platforms that always expect recipient field + pub(crate) to: Option>, pub(crate) object: ObjectId, #[serde(rename = "type")] pub(crate) kind: FollowType, diff --git a/crates/apub/src/protocol/activities/following/undo_follow.rs b/crates/apub/src/protocol/activities/following/undo_follow.rs index 4660db40a8..e813e9e1dd 100644 --- a/crates/apub/src/protocol/activities/following/undo_follow.rs +++ b/crates/apub/src/protocol/activities/following/undo_follow.rs @@ -7,6 +7,8 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoFollow { pub(crate) actor: ObjectId, + /// Optional, for compatibility with platforms that always expect recipient field + pub(crate) to: Option>, pub(crate) object: Follow, #[serde(rename = "type")] pub(crate) kind: UndoType, From 2b7491711f624cf13802203215fea7005af1e2d7 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 24 Apr 2023 21:38:31 +0200 Subject: [PATCH 2/2] fix tests --- crates/apub/assets/lemmy/activities/following/accept.json | 4 ++-- crates/apub/assets/lemmy/activities/following/follow.json | 2 +- .../apub/assets/lemmy/activities/following/undo_follow.json | 4 ++-- crates/apub/src/activities/following/accept.rs | 4 ++-- crates/apub/src/activities/following/follow.rs | 4 ++-- crates/apub/src/activities/following/undo_follow.rs | 4 ++-- crates/apub/src/protocol/activities/following/accept.rs | 2 +- crates/apub/src/protocol/activities/following/follow.rs | 2 +- crates/apub/src/protocol/activities/following/undo_follow.rs | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/apub/assets/lemmy/activities/following/accept.json b/crates/apub/assets/lemmy/activities/following/accept.json index fde48880bc..b524a56ec5 100644 --- a/crates/apub/assets/lemmy/activities/following/accept.json +++ b/crates/apub/assets/lemmy/activities/following/accept.json @@ -1,9 +1,9 @@ { "actor": "http://enterprise.lemmy.ml/c/main", - "to": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": ["http://ds9.lemmy.ml/u/lemmy_alpha"], "object": { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", - "to": "http://enterprise.lemmy.ml/c/main", + "to": ["http://enterprise.lemmy.ml/c/main"], "object": "http://enterprise.lemmy.ml/c/main", "type": "Follow", "id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866" diff --git a/crates/apub/assets/lemmy/activities/following/follow.json b/crates/apub/assets/lemmy/activities/following/follow.json index 5d1def0f8f..fe797233c1 100644 --- a/crates/apub/assets/lemmy/activities/following/follow.json +++ b/crates/apub/assets/lemmy/activities/following/follow.json @@ -1,6 +1,6 @@ { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", - "to": "http://enterprise.lemmy.ml/c/main", + "to": ["http://enterprise.lemmy.ml/c/main"], "object": "http://enterprise.lemmy.ml/c/main", "type": "Follow", "id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866" diff --git a/crates/apub/assets/lemmy/activities/following/undo_follow.json b/crates/apub/assets/lemmy/activities/following/undo_follow.json index 763c67d9d9..255823d8d6 100644 --- a/crates/apub/assets/lemmy/activities/following/undo_follow.json +++ b/crates/apub/assets/lemmy/activities/following/undo_follow.json @@ -1,9 +1,9 @@ { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", - "to": "http://enterprise.lemmy.ml/c/main", + "to": ["http://enterprise.lemmy.ml/c/main"], "object": { "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", - "to": "http://enterprise.lemmy.ml/c/main", + "to": ["http://enterprise.lemmy.ml/c/main"], "object": "http://enterprise.lemmy.ml/c/main", "type": "Follow", "id": "http://ds9.lemmy.ml/activities/follow/dc2f1bc5-f3a0-4daa-a46b-428cbfbd023c" diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index 034013eae9..34dc976ded 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -34,7 +34,7 @@ impl AcceptFollow { let person = follow.actor.clone().dereference(context).await?; let accept = AcceptFollow { actor: user_or_community.id().into(), - to: Some(person.id().into()), + to: Some([person.id().into()]), object: follow, kind: AcceptType::Accept, id: generate_activity_id( @@ -66,7 +66,7 @@ impl ActivityHandler for AcceptFollow { verify_urls_match(self.actor.inner(), self.object.object.inner())?; self.object.verify(context).await?; if let Some(to) = &self.to { - verify_urls_match(to.inner(), self.object.actor.inner())?; + verify_urls_match(to[0].inner(), self.object.actor.inner())?; } Ok(()) } diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 893eea2e1e..4e2acd518f 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -45,7 +45,7 @@ impl Follow { Ok(Follow { actor: actor.id().into(), object: community.id().into(), - to: Some(community.id().into()), + to: Some([community.id().into()]), kind: FollowType::Follow, id: generate_activity_id( FollowType::Follow, @@ -96,7 +96,7 @@ impl ActivityHandler for Follow { verify_person_in_community(&self.actor, &c, context).await?; } if let Some(to) = &self.to { - verify_urls_match(to.inner(), self.object.inner())?; + verify_urls_match(to[0].inner(), self.object.inner())?; } Ok(()) } diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index 0233dcf778..279054d53d 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -32,7 +32,7 @@ impl UndoFollow { let object = Follow::new(actor, community, context)?; let undo = UndoFollow { actor: actor.id().into(), - to: Some(community.id().into()), + to: Some([community.id().into()]), object, kind: UndoType::Undo, id: generate_activity_id( @@ -64,7 +64,7 @@ impl ActivityHandler for UndoFollow { verify_person(&self.actor, context).await?; self.object.verify(context).await?; if let Some(to) = &self.to { - verify_urls_match(to.inner(), self.object.object.inner())?; + verify_urls_match(to[0].inner(), self.object.object.inner())?; } Ok(()) } diff --git a/crates/apub/src/protocol/activities/following/accept.rs b/crates/apub/src/protocol/activities/following/accept.rs index a67fd92ed4..09e2cfda96 100644 --- a/crates/apub/src/protocol/activities/following/accept.rs +++ b/crates/apub/src/protocol/activities/following/accept.rs @@ -11,7 +11,7 @@ use url::Url; pub struct AcceptFollow { pub(crate) actor: ObjectId, /// Optional, for compatibility with platforms that always expect recipient field - pub(crate) to: Option>, + pub(crate) to: Option<[ObjectId; 1]>, pub(crate) object: Follow, #[serde(rename = "type")] pub(crate) kind: AcceptType, diff --git a/crates/apub/src/protocol/activities/following/follow.rs b/crates/apub/src/protocol/activities/following/follow.rs index 929224e73e..064a36055d 100644 --- a/crates/apub/src/protocol/activities/following/follow.rs +++ b/crates/apub/src/protocol/activities/following/follow.rs @@ -8,7 +8,7 @@ use url::Url; pub struct Follow { pub(crate) actor: ObjectId, /// Optional, for compatibility with platforms that always expect recipient field - pub(crate) to: Option>, + pub(crate) to: Option<[ObjectId; 1]>, pub(crate) object: ObjectId, #[serde(rename = "type")] pub(crate) kind: FollowType, diff --git a/crates/apub/src/protocol/activities/following/undo_follow.rs b/crates/apub/src/protocol/activities/following/undo_follow.rs index e813e9e1dd..f94a9b797c 100644 --- a/crates/apub/src/protocol/activities/following/undo_follow.rs +++ b/crates/apub/src/protocol/activities/following/undo_follow.rs @@ -8,7 +8,7 @@ use url::Url; pub struct UndoFollow { pub(crate) actor: ObjectId, /// Optional, for compatibility with platforms that always expect recipient field - pub(crate) to: Option>, + pub(crate) to: Option<[ObjectId; 1]>, pub(crate) object: Follow, #[serde(rename = "type")] pub(crate) kind: UndoType,