From a85334c675e4f68b3ff01808d0cf96339cea5fa0 Mon Sep 17 00:00:00 2001 From: Nutomic Date: Fri, 29 Jul 2022 15:32:12 +0200 Subject: [PATCH] Handle Like, Undo/Like activities from Mastodon, add tests (fixes #2378) (#2380) --- .../assets/mastodon/activities/like_page.json | 7 ++++ .../mastodon/activities/undo_like_page.json | 12 ++++++ .../apub/src/activities/voting/undo_vote.rs | 3 +- crates/apub/src/activities/voting/vote.rs | 4 +- crates/apub/src/activity_lists.rs | 40 +++++++++++++++++++ crates/apub/src/http/mod.rs | 1 + crates/apub/src/protocol/activities/mod.rs | 2 + .../protocol/activities/voting/undo_vote.rs | 4 +- .../src/protocol/activities/voting/vote.rs | 4 +- 9 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 crates/apub/assets/mastodon/activities/like_page.json create mode 100644 crates/apub/assets/mastodon/activities/undo_like_page.json diff --git a/crates/apub/assets/mastodon/activities/like_page.json b/crates/apub/assets/mastodon/activities/like_page.json new file mode 100644 index 000000000..d8468f73e --- /dev/null +++ b/crates/apub/assets/mastodon/activities/like_page.json @@ -0,0 +1,7 @@ +{ + "@context":"https://www.w3.org/ns/activitystreams", + "id":"https://mastodon.madrid/users/felix#likes/212340", + "type":"Like", + "actor":"https://mastodon.madrid/users/felix", + "object":"https://ds9.lemmy.ml/post/147" +} diff --git a/crates/apub/assets/mastodon/activities/undo_like_page.json b/crates/apub/assets/mastodon/activities/undo_like_page.json new file mode 100644 index 000000000..83afb210b --- /dev/null +++ b/crates/apub/assets/mastodon/activities/undo_like_page.json @@ -0,0 +1,12 @@ +{ + "@context":"https://www.w3.org/ns/activitystreams", + "id":"https://mastodon.madrid/users/felix#likes/212341/undo", + "type":"Undo", + "actor":"https://mastodon.madrid/users/felix", + "object": { + "id":"https://mastodon.madrid/users/felix#likes/212341", + "type":"Like", + "actor":"https://mastodon.madrid/users/felix", + "object":"https://ds9.lemmy.ml/post/147" + } +} \ No newline at end of file diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index 35b642519..69abdac51 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -46,14 +46,13 @@ impl UndoVote { .await?? .into(); - let object = Vote::new(object, actor, &community, kind.clone(), context)?; + let object = Vote::new(object, actor, kind.clone(), context)?; let id = generate_activity_id( UndoType::Undo, &context.settings().get_protocol_and_hostname(), )?; let undo_vote = UndoVote { actor: ObjectId::new(actor.actor_id()), - to: vec![community.actor_id()], object, cc: vec![public()], kind: UndoType::Undo, diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index b4f442388..d83ce3643 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -31,13 +31,11 @@ impl Vote { pub(in crate::activities::voting) fn new( object: &PostOrComment, actor: &ApubPerson, - community: &ApubCommunity, kind: VoteType, context: &LemmyContext, ) -> Result { Ok(Vote { actor: ObjectId::new(actor.actor_id()), - to: vec![community.actor_id()], object: ObjectId::new(object.ap_id()), cc: vec![public()], kind: kind.clone(), @@ -59,7 +57,7 @@ impl Vote { }) .await?? .into(); - let vote = Vote::new(object, actor, &community, kind, context)?; + let vote = Vote::new(object, actor, kind, context)?; let activity = AnnouncableActivities::Vote(vote); send_activity_in_community(activity, actor, &community, vec![], context).await diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index 656c80206..dbd185bdd 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -197,3 +197,43 @@ impl ActivityHandler for GroupInboxActivities { } } } + +#[cfg(test)] +mod tests { + use crate::{ + activity_lists::{GroupInboxActivities, PersonInboxActivities, SiteInboxActivities}, + protocol::tests::test_parse_lemmy_item, + }; + + #[test] + fn test_group_inbox() { + test_parse_lemmy_item::("assets/lemmy/activities/following/follow.json") + .unwrap(); + test_parse_lemmy_item::( + "assets/lemmy/activities/create_or_update/create_note.json", + ) + .unwrap(); + } + + #[test] + fn test_person_inbox() { + test_parse_lemmy_item::("assets/lemmy/activities/following/accept.json") + .unwrap(); + test_parse_lemmy_item::( + "assets/lemmy/activities/create_or_update/create_note.json", + ) + .unwrap(); + test_parse_lemmy_item::( + "assets/lemmy/activities/create_or_update/create_private_message.json", + ) + .unwrap(); + } + + #[test] + fn test_site_inbox() { + test_parse_lemmy_item::( + "assets/lemmy/activities/deletion/delete_user.json", + ) + .unwrap(); + } +} diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index 87a8a4127..e2fb0b429 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -56,6 +56,7 @@ where for<'de2> ::ApubType: serde::Deserialize<'de2>, { let activity_value: Value = serde_json::from_str(&payload)?; + debug!("Received activity {:#}", payload.as_str()); let activity: Activity = serde_json::from_value(activity_value.clone())?; // Log the activity, so we avoid receiving and parsing it twice. let insert = insert_activity(activity.id(), activity_value, false, true, context.pool()).await?; diff --git a/crates/apub/src/protocol/activities/mod.rs b/crates/apub/src/protocol/activities/mod.rs index 35d14f8f2..82c5215b4 100644 --- a/crates/apub/src/protocol/activities/mod.rs +++ b/crates/apub/src/protocol/activities/mod.rs @@ -45,6 +45,8 @@ mod tests { test_json::("assets/mastodon/activities/delete.json").unwrap(); test_json::("assets/mastodon/activities/follow.json").unwrap(); test_json::("assets/mastodon/activities/undo_follow.json").unwrap(); + test_json::("assets/mastodon/activities/like_page.json").unwrap(); + test_json::("assets/mastodon/activities/undo_like_page.json").unwrap(); } #[test] diff --git a/crates/apub/src/protocol/activities/voting/undo_vote.rs b/crates/apub/src/protocol/activities/voting/undo_vote.rs index 77e526884..6c43f4892 100644 --- a/crates/apub/src/protocol/activities/voting/undo_vote.rs +++ b/crates/apub/src/protocol/activities/voting/undo_vote.rs @@ -11,10 +11,8 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct UndoVote { pub(crate) actor: ObjectId, - #[serde(deserialize_with = "deserialize_one_or_many")] - pub(crate) to: Vec, pub(crate) object: Vote, - #[serde(deserialize_with = "deserialize_one_or_many")] + #[serde(deserialize_with = "deserialize_one_or_many", default)] pub(crate) cc: Vec, #[serde(rename = "type")] pub(crate) kind: UndoType, diff --git a/crates/apub/src/protocol/activities/voting/vote.rs b/crates/apub/src/protocol/activities/voting/vote.rs index 80ea2ed56..2bc674f1d 100644 --- a/crates/apub/src/protocol/activities/voting/vote.rs +++ b/crates/apub/src/protocol/activities/voting/vote.rs @@ -14,10 +14,8 @@ use url::Url; #[serde(rename_all = "camelCase")] pub struct Vote { pub(crate) actor: ObjectId, - #[serde(deserialize_with = "deserialize_one_or_many")] - pub(crate) to: Vec, pub(crate) object: ObjectId, - #[serde(deserialize_with = "deserialize_one_or_many")] + #[serde(deserialize_with = "deserialize_one_or_many", default)] pub(crate) cc: Vec, #[serde(rename = "type")] pub(crate) kind: VoteType,