From a25faf3e9743ccf8c24357ec28539230f692b10c Mon Sep 17 00:00:00 2001 From: Nutomic Date: Mon, 24 Apr 2023 23:19:08 +0200 Subject: [PATCH] Add `to` field in follow activities for better compatibility (#2829) * Add `to` field in follow activities for better compatibility (fixes #2744) * fix tests --- 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 4097b3675..b524a56ec 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 48f3fef8b..fe797233c 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 5311bd990..255823d8d 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 c57ec0b53..34dc976de 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[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 41d2e71ed..4e2acd518 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[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 9f1b89dc1..279054d53 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[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 786827ed9..09e2cfda9 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<[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 27a3ba4be..064a36055 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<[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 4660db40a..f94a9b797 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<[ObjectId; 1]>, pub(crate) object: Follow, #[serde(rename = "type")] pub(crate) kind: UndoType,