Send Undo(Announce) activity when repost is deleted

This commit is contained in:
silverpill 2021-12-16 17:32:49 +00:00
parent cf69ac6eb2
commit 3989a40825
3 changed files with 66 additions and 9 deletions

View file

@ -285,19 +285,39 @@ pub fn create_activity_announce(
instance_url: &str, instance_url: &str,
actor_profile: &DbActorProfile, actor_profile: &DbActorProfile,
post: &Post, post: &Post,
repost_id: &Uuid,
) -> Activity { ) -> Activity {
let object_id = post.get_object_id(instance_url); let object_id = post.get_object_id(instance_url);
let activity = create_activity( let activity = create_activity(
instance_url, instance_url,
&actor_profile.username, &actor_profile.username,
ANNOUNCE, ANNOUNCE,
None, Some(repost_id),
object_id, object_id,
vec![AP_PUBLIC.to_string()], vec![AP_PUBLIC.to_string()],
); );
activity 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( pub fn create_activity_delete_note(
instance_url: &str, instance_url: &str,
actor_profile: &DbActorProfile, actor_profile: &DbActorProfile,

View file

@ -438,15 +438,27 @@ pub async fn receive_activity(
unfollow(db_client, &source_profile.id, &target_profile.id).await?; unfollow(db_client, &source_profile.id, &target_profile.id).await?;
}, },
(UNDO, _) => { (UNDO, _) => {
// Undo(Like)
let object_id = get_object_id(activity.object)?; let object_id = get_object_id(activity.object)?;
let reaction = get_reaction_by_activity_id(db_client, &object_id).await?; match get_reaction_by_activity_id(db_client, &object_id).await {
Ok(reaction) => {
// Undo(Like)
delete_reaction( delete_reaction(
db_client, db_client,
&reaction.author_id, &reaction.author_id,
&reaction.post_id, &reaction.post_id,
).await?; ).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) => { (UPDATE, PERSON) => {
let actor: Actor = serde_json::from_value(activity.object) let actor: Actor = serde_json::from_value(activity.object)
.map_err(|_| ValidationError("invalid actor data"))?; .map_err(|_| ValidationError("invalid actor data"))?;

View file

@ -9,6 +9,7 @@ use crate::activitypub::activity::{
create_activity_like, create_activity_like,
create_activity_undo_like, create_activity_undo_like,
create_activity_announce, create_activity_announce,
create_activity_undo_announce,
create_activity_delete_note, create_activity_delete_note,
}; };
use crate::activitypub::actor::Actor; use crate::activitypub::actor::Actor;
@ -323,7 +324,7 @@ async fn reblog(
repost_of_id: Some(status_id), repost_of_id: Some(status_id),
..Default::default() ..Default::default()
}; };
create_post(db_client, &current_user.id, repost_data).await?; let repost = create_post(db_client, &current_user.id, repost_data).await?;
let mut post = get_post_by_id(db_client, &status_id).await?; let mut post = get_post_by_id(db_client, &status_id).await?;
get_reposted_posts(db_client, vec![&mut post]).await?; get_reposted_posts(db_client, vec![&mut post]).await?;
get_actions_for_posts(db_client, &current_user.id, vec![&mut post]).await?; get_actions_for_posts(db_client, &current_user.id, vec![&mut post]).await?;
@ -333,6 +334,7 @@ async fn reblog(
&config.instance_url(), &config.instance_url(),
&current_user.profile, &current_user.profile,
&post, &post,
&repost.id,
); );
let mut recipients: Vec<Actor> = Vec::new(); let mut recipients: Vec<Actor> = Vec::new();
let followers = get_followers(db_client, &current_user.id).await?; let followers = get_followers(db_client, &current_user.id).await?;
@ -370,6 +372,29 @@ async fn unreblog(
let mut post = get_post_by_id(db_client, &status_id).await?; let mut post = get_post_by_id(db_client, &status_id).await?;
get_reposted_posts(db_client, vec![&mut post]).await?; get_reposted_posts(db_client, vec![&mut post]).await?;
get_actions_for_posts(db_client, &current_user.id, vec![&mut post]).await?; get_actions_for_posts(db_client, &current_user.id, vec![&mut post]).await?;
// Federate
let activity = create_activity_undo_announce(
&config.instance_url(),
&current_user.profile,
&repost_id,
);
let mut recipients: Vec<Actor> = Vec::new();
let followers = get_followers(db_client, &current_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, &current_user, activity, recipients);
let status = Status::from_post(post, &config.instance_url()); let status = Status::from_post(post, &config.instance_url());
Ok(HttpResponse::Ok().json(status)) Ok(HttpResponse::Ok().json(status))
} }