From 3989a40825aeb12329f51781385b6a9e4aae06c2 Mon Sep 17 00:00:00 2001 From: silverpill Date: Thu, 16 Dec 2021 17:32:49 +0000 Subject: [PATCH] Send Undo(Announce) activity when repost is deleted --- src/activitypub/activity.rs | 22 +++++++++++++++++++++- src/activitypub/receiver.rs | 26 +++++++++++++++++++------- src/mastodon_api/statuses/views.rs | 27 ++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/activitypub/activity.rs b/src/activitypub/activity.rs index 8e6cd36..ecc7d78 100644 --- a/src/activitypub/activity.rs +++ b/src/activitypub/activity.rs @@ -285,19 +285,39 @@ pub fn create_activity_announce( instance_url: &str, actor_profile: &DbActorProfile, post: &Post, + repost_id: &Uuid, ) -> Activity { let object_id = post.get_object_id(instance_url); let activity = create_activity( instance_url, &actor_profile.username, ANNOUNCE, - None, + Some(repost_id), object_id, vec![AP_PUBLIC.to_string()], ); activity } +pub fn create_activity_undo_announce( + instance_url: &str, + actor_profile: &DbActorProfile, + repost_id: &Uuid, +) -> Activity { + let object_id = get_object_url( + instance_url, + repost_id, + ); + create_activity( + instance_url, + &actor_profile.username, + UNDO, + None, + object_id, + vec![AP_PUBLIC.to_string()], + ) +} + pub fn create_activity_delete_note( instance_url: &str, actor_profile: &DbActorProfile, diff --git a/src/activitypub/receiver.rs b/src/activitypub/receiver.rs index 6d182e2..68a744e 100644 --- a/src/activitypub/receiver.rs +++ b/src/activitypub/receiver.rs @@ -438,14 +438,26 @@ pub async fn receive_activity( unfollow(db_client, &source_profile.id, &target_profile.id).await?; }, (UNDO, _) => { - // Undo(Like) let object_id = get_object_id(activity.object)?; - let reaction = get_reaction_by_activity_id(db_client, &object_id).await?; - delete_reaction( - db_client, - &reaction.author_id, - &reaction.post_id, - ).await?; + match get_reaction_by_activity_id(db_client, &object_id).await { + Ok(reaction) => { + // Undo(Like) + delete_reaction( + db_client, + &reaction.author_id, + &reaction.post_id, + ).await?; + }, + Err(DatabaseError::NotFound(_)) => { + // Undo(Announce) + let post = get_post_by_object_id(db_client, &object_id).await?; + match post.repost_of_id { + Some(_) => delete_post(db_client, &post.id).await?, + None => return Err(HttpError::NotFoundError("object")), + }; + }, + Err(other_error) => return Err(other_error.into()), + }; }, (UPDATE, PERSON) => { let actor: Actor = serde_json::from_value(activity.object) diff --git a/src/mastodon_api/statuses/views.rs b/src/mastodon_api/statuses/views.rs index 37c9bd4..d8104bf 100644 --- a/src/mastodon_api/statuses/views.rs +++ b/src/mastodon_api/statuses/views.rs @@ -9,6 +9,7 @@ use crate::activitypub::activity::{ create_activity_like, create_activity_undo_like, create_activity_announce, + create_activity_undo_announce, create_activity_delete_note, }; use crate::activitypub::actor::Actor; @@ -323,7 +324,7 @@ async fn reblog( repost_of_id: Some(status_id), ..Default::default() }; - create_post(db_client, ¤t_user.id, repost_data).await?; + let repost = create_post(db_client, ¤t_user.id, repost_data).await?; let mut post = get_post_by_id(db_client, &status_id).await?; get_reposted_posts(db_client, vec![&mut post]).await?; get_actions_for_posts(db_client, ¤t_user.id, vec![&mut post]).await?; @@ -333,6 +334,7 @@ async fn reblog( &config.instance_url(), ¤t_user.profile, &post, + &repost.id, ); let mut recipients: Vec = Vec::new(); let followers = get_followers(db_client, ¤t_user.id).await?; @@ -370,6 +372,29 @@ async fn unreblog( let mut post = get_post_by_id(db_client, &status_id).await?; get_reposted_posts(db_client, vec![&mut post]).await?; get_actions_for_posts(db_client, ¤t_user.id, vec![&mut post]).await?; + + // Federate + let activity = create_activity_undo_announce( + &config.instance_url(), + ¤t_user.profile, + &repost_id, + ); + let mut recipients: Vec = Vec::new(); + let followers = get_followers(db_client, ¤t_user.id).await?; + for follower in followers { + let maybe_remote_follower = follower.remote_actor() + .map_err(|_| HttpError::InternalError)?; + if let Some(remote_actor) = maybe_remote_follower { + recipients.push(remote_actor); + }; + }; + let maybe_remote_author = post.author.remote_actor() + .map_err(|_| HttpError::InternalError)?; + if let Some(remote_actor) = maybe_remote_author { + recipients.push(remote_actor); + }; + deliver_activity(&config, ¤t_user, activity, recipients); + let status = Status::from_post(post, &config.instance_url()); Ok(HttpResponse::Ok().json(status)) }