]> Untitled Git - lemmy.git/commitdiff
Dont include full objects with remove/delete activities
authorFelix Ableitner <me@nutomic.com>
Tue, 13 Oct 2020 12:09:49 +0000 (14:09 +0200)
committerFelix Ableitner <me@nutomic.com>
Tue, 13 Oct 2020 15:47:05 +0000 (17:47 +0200)
lemmy_apub/src/activities/receive/delete.rs
lemmy_apub/src/activities/receive/mod.rs
lemmy_apub/src/activities/receive/remove.rs
lemmy_apub/src/activities/receive/undo.rs
lemmy_apub/src/activities/receive/undo_comment.rs
lemmy_apub/src/activities/receive/undo_post.rs
lemmy_apub/src/activities/send/comment.rs
lemmy_apub/src/activities/send/community.rs
lemmy_apub/src/activities/send/post.rs
lemmy_apub/src/activities/send/private_message.rs
lemmy_apub/src/inbox/user_inbox.rs

index a1985881e9f79645f089b3630b6107bd6d64a146..579c6e7eaf473b80d9ada36570b4c3f3453f7792 100644 (file)
@@ -1,27 +1,19 @@
-use crate::{
-  activities::receive::{
-    announce_if_community_is_local,
-    get_actor_as_user,
-    receive_unhandled_activity,
-  },
-  fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
-  ActorType,
-  FromApub,
-  GroupExt,
-  PageExt,
+use crate::activities::receive::{
+  announce_if_community_is_local,
+  find_by_id,
+  get_actor_as_user,
+  FindResults,
 };
-use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*};
+use activitystreams::{activity::Delete, base::AnyBase, prelude::*};
 use actix_web::HttpResponse;
 use anyhow::Context;
 use lemmy_db::{
-  comment::{Comment, CommentForm},
+  comment::Comment,
   comment_view::CommentView,
-  community::{Community, CommunityForm},
+  community::Community,
   community_view::CommunityView,
-  naive_now,
-  post::{Post, PostForm},
+  post::Post,
   post_view::PostView,
-  Crud,
 };
 use lemmy_structs::{
   blocking,
@@ -41,108 +33,66 @@ pub async fn receive_delete(
   context: &LemmyContext,
 ) -> Result<HttpResponse, LemmyError> {
   let delete = Delete::from_any_base(activity)?.context(location_info!())?;
-  match delete.object().as_single_kind_str() {
-    Some("Page") => receive_delete_post(delete, context).await,
-    Some("Note") => receive_delete_comment(delete, context).await,
-    Some("Group") => receive_delete_community(delete, context).await,
-    _ => receive_unhandled_activity(delete),
+
+  let object = delete
+    .object()
+    .to_owned()
+    .single_xsd_any_uri()
+    .context(location_info!())?;
+
+  // Ensure that delete activity comes from the same domain as the object
+  delete.id(object.domain().context(location_info!())?)?;
+
+  match find_by_id(context, object).await {
+    Ok(FindResults::Post(p)) => receive_delete_post(context, delete, p).await,
+    Ok(FindResults::Comment(c)) => receive_delete_comment(context, delete, c).await,
+    Ok(FindResults::Community(c)) => receive_delete_community(context, delete, c).await,
+    // if we dont have the object, no need to do anything
+    Err(_) => Ok(HttpResponse::Ok().finish()),
   }
 }
 
 async fn receive_delete_post(
-  delete: Delete,
   context: &LemmyContext,
+  delete: Delete,
+  post: Post,
 ) -> Result<HttpResponse, LemmyError> {
-  let user = get_actor_as_user(&delete, context).await?;
-  let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let post_ap_id = PostForm::from_apub(&page, context, Some(user.actor_id()?))
-    .await?
-    .get_ap_id()?;
-
-  let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
-
-  let post_form = PostForm {
-    name: post.name.to_owned(),
-    url: post.url.to_owned(),
-    body: post.body.to_owned(),
-    creator_id: post.creator_id.to_owned(),
-    community_id: post.community_id,
-    removed: None,
-    deleted: Some(true),
-    nsfw: post.nsfw,
-    locked: None,
-    stickied: None,
-    updated: Some(naive_now()),
-    embed_title: post.embed_title,
-    embed_description: post.embed_description,
-    embed_html: post.embed_html,
-    thumbnail_url: post.thumbnail_url,
-    ap_id: Some(post.ap_id),
-    local: post.local,
-    published: None,
-  };
-  let post_id = post.id;
-  blocking(context.pool(), move |conn| {
-    Post::update(conn, post_id, &post_form)
+  let deleted_post = blocking(context.pool(), move |conn| {
+    Post::update_deleted(conn, post.id, true)
   })
   .await??;
 
   // Refetch the view
-  let post_id = post.id;
+  let post_id = deleted_post.id;
   let post_view = blocking(context.pool(), move |conn| {
     PostView::read(conn, post_id, None)
   })
   .await??;
 
   let res = PostResponse { post: post_view };
-
   context.chat_server().do_send(SendPost {
     op: UserOperation::EditPost,
     post: res,
     websocket_id: None,
   });
 
+  let user = get_actor_as_user(&delete, context).await?;
   announce_if_community_is_local(delete, &user, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
 
 async fn receive_delete_comment(
-  delete: Delete,
   context: &LemmyContext,
+  delete: Delete,
+  comment: Comment,
 ) -> Result<HttpResponse, LemmyError> {
-  let user = get_actor_as_user(&delete, context).await?;
-  let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let comment_ap_id = CommentForm::from_apub(&note, context, Some(user.actor_id()?))
-    .await?
-    .get_ap_id()?;
-
-  let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
-
-  let comment_form = CommentForm {
-    content: comment.content.to_owned(),
-    parent_id: comment.parent_id,
-    post_id: comment.post_id,
-    creator_id: comment.creator_id,
-    removed: None,
-    deleted: Some(true),
-    read: None,
-    published: None,
-    updated: Some(naive_now()),
-    ap_id: Some(comment.ap_id),
-    local: comment.local,
-  };
-  let comment_id = comment.id;
-  blocking(context.pool(), move |conn| {
-    Comment::update(conn, comment_id, &comment_form)
+  let deleted_comment = blocking(context.pool(), move |conn| {
+    Comment::update_deleted(conn, comment.id, true)
   })
   .await??;
 
   // Refetch the view
-  let comment_id = comment.id;
+  let comment_id = deleted_comment.id;
   let comment_view = blocking(context.pool(), move |conn| {
     CommentView::read(conn, comment_id, None)
   })
@@ -155,62 +105,28 @@ async fn receive_delete_comment(
     recipient_ids,
     form_id: None,
   };
-
   context.chat_server().do_send(SendComment {
     op: UserOperation::EditComment,
     comment: res,
     websocket_id: None,
   });
 
+  let user = get_actor_as_user(&delete, context).await?;
   announce_if_community_is_local(delete, &user, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
 
 async fn receive_delete_community(
-  delete: Delete,
   context: &LemmyContext,
+  delete: Delete,
+  community: Community,
 ) -> Result<HttpResponse, LemmyError> {
-  let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-  let user = get_actor_as_user(&delete, context).await?;
-
-  let community_actor_id = CommunityForm::from_apub(&group, context, Some(user.actor_id()?))
-    .await?
-    .actor_id
-    .context(location_info!())?;
-
-  let community = blocking(context.pool(), move |conn| {
-    Community::read_from_actor_id(conn, &community_actor_id)
-  })
-  .await??;
-
-  let community_form = CommunityForm {
-    name: community.name.to_owned(),
-    title: community.title.to_owned(),
-    description: community.description.to_owned(),
-    category_id: community.category_id, // Note: need to keep this due to foreign key constraint
-    creator_id: community.creator_id,   // Note: need to keep this due to foreign key constraint
-    removed: None,
-    published: None,
-    updated: Some(naive_now()),
-    deleted: Some(true),
-    nsfw: community.nsfw,
-    actor_id: Some(community.actor_id),
-    local: community.local,
-    private_key: community.private_key,
-    public_key: community.public_key,
-    last_refreshed_at: None,
-    icon: Some(community.icon.to_owned()),
-    banner: Some(community.banner.to_owned()),
-  };
-
-  let community_id = community.id;
-  blocking(context.pool(), move |conn| {
-    Community::update(conn, community_id, &community_form)
+  let deleted_community = blocking(context.pool(), move |conn| {
+    Community::update_deleted(conn, community.id, true)
   })
   .await??;
 
-  let community_id = community.id;
+  let community_id = deleted_community.id;
   let res = CommunityResponse {
     community: blocking(context.pool(), move |conn| {
       CommunityView::read(conn, community_id, None)
@@ -219,7 +135,6 @@ async fn receive_delete_community(
   };
 
   let community_id = res.community.id;
-
   context.chat_server().do_send(SendCommunityRoomMessage {
     op: UserOperation::EditCommunity,
     response: res,
@@ -227,6 +142,7 @@ async fn receive_delete_community(
     websocket_id: None,
   });
 
+  let user = get_actor_as_user(&delete, context).await?;
   announce_if_community_is_local(delete, &user, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
index 06c5f291abc4d3e977229539d8794939bac80c1a..730454b4eed9ef76b0201f07ffc2dd235afe5790 100644 (file)
@@ -9,7 +9,9 @@ use activitystreams::{
 };
 use actix_web::HttpResponse;
 use anyhow::Context;
-use lemmy_db::user::User_;
+use diesel::result::Error::NotFound;
+use lemmy_db::{comment::Comment, community::Community, post::Post, user::User_};
+use lemmy_structs::blocking;
 use lemmy_utils::{location_info, LemmyError};
 use lemmy_websocket::LemmyContext;
 use log::debug;
@@ -68,7 +70,7 @@ where
   Ok(())
 }
 
-pub(in crate) async fn get_actor_as_user<T, A>(
+pub(crate) async fn get_actor_as_user<T, A>(
   activity: &T,
   context: &LemmyContext,
 ) -> Result<User_, LemmyError>
@@ -79,3 +81,43 @@ where
   let user_uri = actor.as_single_xsd_any_uri().context(location_info!())?;
   get_or_fetch_and_upsert_user(&user_uri, context).await
 }
+
+pub(crate) enum FindResults {
+  Comment(Comment),
+  Community(Community),
+  Post(Post),
+}
+
+pub(crate) async fn find_by_id(
+  context: &LemmyContext,
+  apub_id: Url,
+) -> Result<FindResults, LemmyError> {
+  let ap_id = apub_id.to_string();
+  let community = blocking(context.pool(), move |conn| {
+    Community::read_from_actor_id(conn, &ap_id)
+  })
+  .await?;
+  if let Ok(c) = community {
+    return Ok(FindResults::Community(c));
+  }
+
+  let ap_id = apub_id.to_string();
+  let post = blocking(context.pool(), move |conn| {
+    Post::read_from_apub_id(conn, &ap_id)
+  })
+  .await?;
+  if let Ok(p) = post {
+    return Ok(FindResults::Post(p));
+  }
+
+  let ap_id = apub_id.to_string();
+  let comment = blocking(context.pool(), move |conn| {
+    Comment::read_from_apub_id(conn, &ap_id)
+  })
+  .await?;
+  if let Ok(c) = comment {
+    return Ok(FindResults::Comment(c));
+  }
+
+  return Err(NotFound.into());
+}
index dfd166e6cdc9110446a0ef1f9371d8addbe1ce4f..c9f248d6423e37e8cc389cbac457b03d408c7c8c 100644 (file)
@@ -1,27 +1,17 @@
 use crate::{
-  activities::receive::{
-    announce_if_community_is_local,
-    get_actor_as_user,
-    receive_unhandled_activity,
-  },
-  fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
+  activities::receive::{find_by_id, get_actor_as_user, FindResults},
   ActorType,
-  FromApub,
-  GroupExt,
-  PageExt,
 };
-use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*};
+use activitystreams::{activity::Remove, base::AnyBase, error::DomainError, prelude::*};
 use actix_web::HttpResponse;
-use anyhow::{anyhow, Context};
+use anyhow::Context;
 use lemmy_db::{
-  comment::{Comment, CommentForm},
+  comment::Comment,
   comment_view::CommentView,
-  community::{Community, CommunityForm},
+  community::Community,
   community_view::CommunityView,
-  naive_now,
-  post::{Post, PostForm},
+  post::Post,
   post_view::PostView,
-  Crud,
 };
 use lemmy_structs::{
   blocking,
@@ -52,112 +42,69 @@ pub async fn receive_remove(
     .map(|c| c.as_xsd_any_uri())
     .flatten()
     .context(location_info!())?;
+
+  let object = remove
+    .object()
+    .to_owned()
+    .single_xsd_any_uri()
+    .context(location_info!())?;
+
+  // Ensure that remove comes from the same domain as the community
   if actor.actor_id()?.domain() != community_id.domain() {
-    return Err(anyhow!("Remove receive are only allowed on local objects").into());
+    return Err(DomainError.into());
   }
 
-  match remove.object().as_single_kind_str() {
-    Some("Page") => receive_remove_post(remove, context).await,
-    Some("Note") => receive_remove_comment(remove, context).await,
-    Some("Group") => receive_remove_community(remove, context).await,
-    _ => receive_unhandled_activity(remove),
+  // Ensure that remove activity comes from the same domain as the community
+  remove.id(community_id.domain().context(location_info!())?)?;
+
+  match find_by_id(context, object).await {
+    Ok(FindResults::Post(p)) => receive_remove_post(context, remove, p).await,
+    Ok(FindResults::Comment(c)) => receive_remove_comment(context, remove, c).await,
+    Ok(FindResults::Community(c)) => receive_remove_community(context, remove, c).await,
+    // if we dont have the object, no need to do anything
+    Err(_) => Ok(HttpResponse::Ok().finish()),
   }
 }
 
 async fn receive_remove_post(
-  remove: Remove,
   context: &LemmyContext,
+  _remove: Remove,
+  post: Post,
 ) -> Result<HttpResponse, LemmyError> {
-  let mod_ = get_actor_as_user(&remove, context).await?;
-  let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let post_ap_id = PostForm::from_apub(&page, context, None)
-    .await?
-    .get_ap_id()?;
-
-  let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
-
-  let post_form = PostForm {
-    name: post.name.to_owned(),
-    url: post.url.to_owned(),
-    body: post.body.to_owned(),
-    creator_id: post.creator_id.to_owned(),
-    community_id: post.community_id,
-    removed: Some(true),
-    deleted: None,
-    nsfw: post.nsfw,
-    locked: None,
-    stickied: None,
-    updated: Some(naive_now()),
-    embed_title: post.embed_title,
-    embed_description: post.embed_description,
-    embed_html: post.embed_html,
-    thumbnail_url: post.thumbnail_url,
-    ap_id: Some(post.ap_id),
-    local: post.local,
-    published: None,
-  };
-  let post_id = post.id;
-  blocking(context.pool(), move |conn| {
-    Post::update(conn, post_id, &post_form)
+  let removed_post = blocking(context.pool(), move |conn| {
+    Post::update_removed(conn, post.id, true)
   })
   .await??;
 
   // Refetch the view
-  let post_id = post.id;
+  let post_id = removed_post.id;
   let post_view = blocking(context.pool(), move |conn| {
     PostView::read(conn, post_id, None)
   })
   .await??;
 
   let res = PostResponse { post: post_view };
-
   context.chat_server().do_send(SendPost {
     op: UserOperation::EditPost,
     post: res,
     websocket_id: None,
   });
 
-  announce_if_community_is_local(remove, &mod_, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
 
 async fn receive_remove_comment(
-  remove: Remove,
   context: &LemmyContext,
+  _remove: Remove,
+  comment: Comment,
 ) -> Result<HttpResponse, LemmyError> {
-  let mod_ = get_actor_as_user(&remove, context).await?;
-  let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let comment_ap_id = CommentForm::from_apub(&note, context, None)
-    .await?
-    .get_ap_id()?;
-
-  let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
-
-  let comment_form = CommentForm {
-    content: comment.content.to_owned(),
-    parent_id: comment.parent_id,
-    post_id: comment.post_id,
-    creator_id: comment.creator_id,
-    removed: Some(true),
-    deleted: None,
-    read: None,
-    published: None,
-    updated: Some(naive_now()),
-    ap_id: Some(comment.ap_id),
-    local: comment.local,
-  };
-  let comment_id = comment.id;
-  blocking(context.pool(), move |conn| {
-    Comment::update(conn, comment_id, &comment_form)
+  let removed_comment = blocking(context.pool(), move |conn| {
+    Comment::update_removed(conn, comment.id, true)
   })
   .await??;
 
   // Refetch the view
-  let comment_id = comment.id;
+  let comment_id = removed_comment.id;
   let comment_view = blocking(context.pool(), move |conn| {
     CommentView::read(conn, comment_id, None)
   })
@@ -170,62 +117,26 @@ async fn receive_remove_comment(
     recipient_ids,
     form_id: None,
   };
-
   context.chat_server().do_send(SendComment {
     op: UserOperation::EditComment,
     comment: res,
     websocket_id: None,
   });
 
-  announce_if_community_is_local(remove, &mod_, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
 
 async fn receive_remove_community(
-  remove: Remove,
   context: &LemmyContext,
+  _remove: Remove,
+  community: Community,
 ) -> Result<HttpResponse, LemmyError> {
-  let mod_ = get_actor_as_user(&remove, context).await?;
-  let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
-    .await?
-    .actor_id
-    .context(location_info!())?;
-
-  let community = blocking(context.pool(), move |conn| {
-    Community::read_from_actor_id(conn, &community_actor_id)
+  let removed_community = blocking(context.pool(), move |conn| {
+    Community::update_removed(conn, community.id, true)
   })
   .await??;
 
-  let community_form = CommunityForm {
-    name: community.name.to_owned(),
-    title: community.title.to_owned(),
-    description: community.description.to_owned(),
-    category_id: community.category_id, // Note: need to keep this due to foreign key constraint
-    creator_id: community.creator_id,   // Note: need to keep this due to foreign key constraint
-    removed: Some(true),
-    published: None,
-    updated: Some(naive_now()),
-    deleted: None,
-    nsfw: community.nsfw,
-    actor_id: Some(community.actor_id),
-    local: community.local,
-    private_key: community.private_key,
-    public_key: community.public_key,
-    last_refreshed_at: None,
-    icon: Some(community.icon.to_owned()),
-    banner: Some(community.banner.to_owned()),
-  };
-
-  let community_id = community.id;
-  blocking(context.pool(), move |conn| {
-    Community::update(conn, community_id, &community_form)
-  })
-  .await??;
-
-  let community_id = community.id;
+  let community_id = removed_community.id;
   let res = CommunityResponse {
     community: blocking(context.pool(), move |conn| {
       CommunityView::read(conn, community_id, None)
@@ -234,7 +145,6 @@ async fn receive_remove_community(
   };
 
   let community_id = res.community.id;
-
   context.chat_server().do_send(SendCommunityRoomMessage {
     op: UserOperation::EditCommunity,
     response: res,
@@ -242,6 +152,5 @@ async fn receive_remove_community(
     websocket_id: None,
   });
 
-  announce_if_community_is_local(remove, &mod_, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
index 95a73950512148e405488f33194f4aff36dd9a84..9c5dc01a9ab27fd181268a1db694478b858a9953 100644 (file)
@@ -1,14 +1,11 @@
-use crate::{
-  activities::receive::{
-    announce_if_community_is_local,
-    get_actor_as_user,
-    receive_unhandled_activity,
-    undo_comment::*,
-    undo_post::*,
-  },
-  ActorType,
-  FromApub,
-  GroupExt,
+use crate::activities::receive::{
+  announce_if_community_is_local,
+  find_by_id,
+  get_actor_as_user,
+  receive_unhandled_activity,
+  undo_comment::*,
+  undo_post::*,
+  FindResults,
 };
 use activitystreams::{
   activity::*,
@@ -17,12 +14,7 @@ use activitystreams::{
 };
 use actix_web::HttpResponse;
 use anyhow::{anyhow, Context};
-use lemmy_db::{
-  community::{Community, CommunityForm},
-  community_view::CommunityView,
-  naive_now,
-  Crud,
-};
+use lemmy_db::{community::Community, community_view::CommunityView};
 use lemmy_structs::{blocking, community::CommunityResponse};
 use lemmy_utils::{location_info, LemmyError};
 use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
@@ -69,15 +61,18 @@ async fn receive_undo_delete(
   let delete = Delete::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
     .context(location_info!())?;
   check_is_undo_valid(&undo, &delete)?;
-  let type_ = delete
+
+  let object = delete
     .object()
-    .as_single_kind_str()
+    .to_owned()
+    .single_xsd_any_uri()
     .context(location_info!())?;
-  match type_ {
-    "Note" => receive_undo_delete_comment(undo, &delete, context).await,
-    "Page" => receive_undo_delete_post(undo, &delete, context).await,
-    "Group" => receive_undo_delete_community(undo, &delete, context).await,
-    d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
+  match find_by_id(context, object).await {
+    Ok(FindResults::Post(p)) => receive_undo_delete_post(context, undo, p).await,
+    Ok(FindResults::Comment(c)) => receive_undo_delete_comment(context, undo, c).await,
+    Ok(FindResults::Community(c)) => receive_undo_delete_community(context, undo, c).await,
+    // if we dont have the object, no need to do anything
+    Err(_) => Ok(HttpResponse::Ok().finish()),
   }
 }
 
@@ -89,15 +84,17 @@ async fn receive_undo_remove(
     .context(location_info!())?;
   check_is_undo_valid(&undo, &remove)?;
 
-  let type_ = remove
+  let object = remove
     .object()
-    .as_single_kind_str()
+    .to_owned()
+    .single_xsd_any_uri()
     .context(location_info!())?;
-  match type_ {
-    "Note" => receive_undo_remove_comment(undo, &remove, context).await,
-    "Page" => receive_undo_remove_post(undo, &remove, context).await,
-    "Group" => receive_undo_remove_community(undo, &remove, context).await,
-    d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
+  match find_by_id(context, object).await {
+    Ok(FindResults::Post(p)) => receive_undo_remove_post(context, undo, p).await,
+    Ok(FindResults::Comment(c)) => receive_undo_remove_comment(context, undo, c).await,
+    Ok(FindResults::Community(c)) => receive_undo_remove_community(context, undo, c).await,
+    // if we dont have the object, no need to do anything
+    Err(_) => Ok(HttpResponse::Ok().finish()),
   }
 }
 
@@ -137,51 +134,16 @@ async fn receive_undo_dislike(
 }
 
 async fn receive_undo_delete_community(
-  undo: Undo,
-  delete: &Delete,
   context: &LemmyContext,
+  undo: Undo,
+  community: Community,
 ) -> Result<HttpResponse, LemmyError> {
-  let user = get_actor_as_user(delete, context).await?;
-  let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let community_actor_id = CommunityForm::from_apub(&group, context, Some(user.actor_id()?))
-    .await?
-    .actor_id
-    .context(location_info!())?;
-
-  let community = blocking(context.pool(), move |conn| {
-    Community::read_from_actor_id(conn, &community_actor_id)
+  let deleted_community = blocking(context.pool(), move |conn| {
+    Community::update_deleted(conn, community.id, false)
   })
   .await??;
 
-  let community_form = CommunityForm {
-    name: community.name.to_owned(),
-    title: community.title.to_owned(),
-    description: community.description.to_owned(),
-    category_id: community.category_id, // Note: need to keep this due to foreign key constraint
-    creator_id: community.creator_id,   // Note: need to keep this due to foreign key constraint
-    removed: None,
-    published: None,
-    updated: Some(naive_now()),
-    deleted: Some(false),
-    nsfw: community.nsfw,
-    actor_id: Some(community.actor_id),
-    local: community.local,
-    private_key: community.private_key,
-    public_key: community.public_key,
-    last_refreshed_at: None,
-    icon: Some(community.icon.to_owned()),
-    banner: Some(community.banner.to_owned()),
-  };
-
-  let community_id = community.id;
-  blocking(context.pool(), move |conn| {
-    Community::update(conn, community_id, &community_form)
-  })
-  .await??;
-
-  let community_id = community.id;
+  let community_id = deleted_community.id;
   let res = CommunityResponse {
     community: blocking(context.pool(), move |conn| {
       CommunityView::read(conn, community_id, None)
@@ -190,7 +152,6 @@ async fn receive_undo_delete_community(
   };
 
   let community_id = res.community.id;
-
   context.chat_server().do_send(SendCommunityRoomMessage {
     op: UserOperation::EditCommunity,
     response: res,
@@ -198,56 +159,22 @@ async fn receive_undo_delete_community(
     websocket_id: None,
   });
 
+  let user = get_actor_as_user(&undo, context).await?;
   announce_if_community_is_local(undo, &user, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
 
 async fn receive_undo_remove_community(
-  undo: Undo,
-  remove: &Remove,
   context: &LemmyContext,
+  undo: Undo,
+  community: Community,
 ) -> Result<HttpResponse, LemmyError> {
-  let mod_ = get_actor_as_user(remove, context).await?;
-  let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
-    .await?
-    .actor_id
-    .context(location_info!())?;
-
-  let community = blocking(context.pool(), move |conn| {
-    Community::read_from_actor_id(conn, &community_actor_id)
-  })
-  .await??;
-
-  let community_form = CommunityForm {
-    name: community.name.to_owned(),
-    title: community.title.to_owned(),
-    description: community.description.to_owned(),
-    category_id: community.category_id, // Note: need to keep this due to foreign key constraint
-    creator_id: community.creator_id,   // Note: need to keep this due to foreign key constraint
-    removed: Some(false),
-    published: None,
-    updated: Some(naive_now()),
-    deleted: None,
-    nsfw: community.nsfw,
-    actor_id: Some(community.actor_id),
-    local: community.local,
-    private_key: community.private_key,
-    public_key: community.public_key,
-    last_refreshed_at: None,
-    icon: Some(community.icon.to_owned()),
-    banner: Some(community.banner.to_owned()),
-  };
-
-  let community_id = community.id;
-  blocking(context.pool(), move |conn| {
-    Community::update(conn, community_id, &community_form)
+  let removed_community = blocking(context.pool(), move |conn| {
+    Community::update_removed(conn, community.id, false)
   })
   .await??;
 
-  let community_id = community.id;
+  let community_id = removed_community.id;
   let res = CommunityResponse {
     community: blocking(context.pool(), move |conn| {
       CommunityView::read(conn, community_id, None)
@@ -264,6 +191,7 @@ async fn receive_undo_remove_community(
     websocket_id: None,
   });
 
+  let mod_ = get_actor_as_user(&undo, context).await?;
   announce_if_community_is_local(undo, &mod_, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
index d7566827d9b2869fdc670051465190c0afd45b1f..4c046b6fe5172ddaf6f624f182324e3a33395aa7 100644 (file)
@@ -1,7 +1,6 @@
 use crate::{
   activities::receive::{announce_if_community_is_local, get_actor_as_user},
   fetcher::get_or_fetch_and_insert_comment,
-  ActorType,
   FromApub,
 };
 use activitystreams::{activity::*, object::Note, prelude::*};
@@ -10,8 +9,6 @@ use anyhow::Context;
 use lemmy_db::{
   comment::{Comment, CommentForm, CommentLike},
   comment_view::CommentView,
-  naive_now,
-  Crud,
   Likeable,
 };
 use lemmy_structs::{blocking, comment::CommentResponse};
@@ -115,41 +112,17 @@ pub(crate) async fn receive_undo_dislike_comment(
 }
 
 pub(crate) async fn receive_undo_delete_comment(
-  undo: Undo,
-  delete: &Delete,
   context: &LemmyContext,
+  undo: Undo,
+  comment: Comment,
 ) -> Result<HttpResponse, LemmyError> {
-  let user = get_actor_as_user(delete, context).await?;
-  let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let comment_ap_id = CommentForm::from_apub(&note, context, Some(user.actor_id()?))
-    .await?
-    .get_ap_id()?;
-
-  let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
-
-  let comment_form = CommentForm {
-    content: comment.content.to_owned(),
-    parent_id: comment.parent_id,
-    post_id: comment.post_id,
-    creator_id: comment.creator_id,
-    removed: None,
-    deleted: Some(false),
-    read: None,
-    published: None,
-    updated: Some(naive_now()),
-    ap_id: Some(comment.ap_id),
-    local: comment.local,
-  };
-  let comment_id = comment.id;
-  blocking(context.pool(), move |conn| {
-    Comment::update(conn, comment_id, &comment_form)
+  let deleted_comment = blocking(context.pool(), move |conn| {
+    Comment::update_deleted(conn, comment.id, false)
   })
   .await??;
 
   // Refetch the view
-  let comment_id = comment.id;
+  let comment_id = deleted_comment.id;
   let comment_view = blocking(context.pool(), move |conn| {
     CommentView::read(conn, comment_id, None)
   })
@@ -169,46 +142,23 @@ pub(crate) async fn receive_undo_delete_comment(
     websocket_id: None,
   });
 
+  let user = get_actor_as_user(&undo, context).await?;
   announce_if_community_is_local(undo, &user, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
 
 pub(crate) async fn receive_undo_remove_comment(
-  undo: Undo,
-  remove: &Remove,
   context: &LemmyContext,
+  undo: Undo,
+  comment: Comment,
 ) -> Result<HttpResponse, LemmyError> {
-  let mod_ = get_actor_as_user(remove, context).await?;
-  let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let comment_ap_id = CommentForm::from_apub(&note, context, None)
-    .await?
-    .get_ap_id()?;
-
-  let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
-
-  let comment_form = CommentForm {
-    content: comment.content.to_owned(),
-    parent_id: comment.parent_id,
-    post_id: comment.post_id,
-    creator_id: comment.creator_id,
-    removed: Some(false),
-    deleted: None,
-    read: None,
-    published: None,
-    updated: Some(naive_now()),
-    ap_id: Some(comment.ap_id),
-    local: comment.local,
-  };
-  let comment_id = comment.id;
-  blocking(context.pool(), move |conn| {
-    Comment::update(conn, comment_id, &comment_form)
+  let removed_comment = blocking(context.pool(), move |conn| {
+    Comment::update_removed(conn, comment.id, false)
   })
   .await??;
 
   // Refetch the view
-  let comment_id = comment.id;
+  let comment_id = removed_comment.id;
   let comment_view = blocking(context.pool(), move |conn| {
     CommentView::read(conn, comment_id, None)
   })
@@ -228,6 +178,7 @@ pub(crate) async fn receive_undo_remove_comment(
     websocket_id: None,
   });
 
+  let mod_ = get_actor_as_user(&undo, context).await?;
   announce_if_community_is_local(undo, &mod_, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
index 3eebb08ec9391c01ade5c78debd0fb2db111e49c..e1638bc4cbb3059696775d24b9031073dc684eec 100644 (file)
@@ -1,7 +1,6 @@
 use crate::{
   activities::receive::{announce_if_community_is_local, get_actor_as_user},
   fetcher::get_or_fetch_and_insert_post,
-  ActorType,
   FromApub,
   PageExt,
 };
@@ -9,10 +8,8 @@ use activitystreams::{activity::*, prelude::*};
 use actix_web::HttpResponse;
 use anyhow::Context;
 use lemmy_db::{
-  naive_now,
   post::{Post, PostForm, PostLike},
   post_view::PostView,
-  Crud,
   Likeable,
 };
 use lemmy_structs::{blocking, post::PostResponse};
@@ -104,108 +101,46 @@ pub(crate) async fn receive_undo_dislike_post(
 }
 
 pub(crate) async fn receive_undo_delete_post(
-  undo: Undo,
-  delete: &Delete,
   context: &LemmyContext,
+  undo: Undo,
+  post: Post,
 ) -> Result<HttpResponse, LemmyError> {
-  let user = get_actor_as_user(delete, context).await?;
-  let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let post_ap_id = PostForm::from_apub(&page, context, Some(user.actor_id()?))
-    .await?
-    .get_ap_id()?;
-
-  let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
-
-  let post_form = PostForm {
-    name: post.name.to_owned(),
-    url: post.url.to_owned(),
-    body: post.body.to_owned(),
-    creator_id: post.creator_id.to_owned(),
-    community_id: post.community_id,
-    removed: None,
-    deleted: Some(false),
-    nsfw: post.nsfw,
-    locked: None,
-    stickied: None,
-    updated: Some(naive_now()),
-    embed_title: post.embed_title,
-    embed_description: post.embed_description,
-    embed_html: post.embed_html,
-    thumbnail_url: post.thumbnail_url,
-    ap_id: Some(post.ap_id),
-    local: post.local,
-    published: None,
-  };
-  let post_id = post.id;
-  blocking(context.pool(), move |conn| {
-    Post::update(conn, post_id, &post_form)
+  let deleted_post = blocking(context.pool(), move |conn| {
+    Post::update_deleted(conn, post.id, false)
   })
   .await??;
 
   // Refetch the view
-  let post_id = post.id;
+  let post_id = deleted_post.id;
   let post_view = blocking(context.pool(), move |conn| {
     PostView::read(conn, post_id, None)
   })
   .await??;
 
   let res = PostResponse { post: post_view };
-
   context.chat_server().do_send(SendPost {
     op: UserOperation::EditPost,
     post: res,
     websocket_id: None,
   });
 
+  let user = get_actor_as_user(&undo, context).await?;
   announce_if_community_is_local(undo, &user, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
 
 pub(crate) async fn receive_undo_remove_post(
-  undo: Undo,
-  remove: &Remove,
   context: &LemmyContext,
+  undo: Undo,
+  post: Post,
 ) -> Result<HttpResponse, LemmyError> {
-  let mod_ = get_actor_as_user(remove, context).await?;
-  let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
-    .context(location_info!())?;
-
-  let post_ap_id = PostForm::from_apub(&page, context, None)
-    .await?
-    .get_ap_id()?;
-
-  let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
-
-  let post_form = PostForm {
-    name: post.name.to_owned(),
-    url: post.url.to_owned(),
-    body: post.body.to_owned(),
-    creator_id: post.creator_id.to_owned(),
-    community_id: post.community_id,
-    removed: Some(false),
-    deleted: None,
-    nsfw: post.nsfw,
-    locked: None,
-    stickied: None,
-    updated: Some(naive_now()),
-    embed_title: post.embed_title,
-    embed_description: post.embed_description,
-    embed_html: post.embed_html,
-    thumbnail_url: post.thumbnail_url,
-    ap_id: Some(post.ap_id),
-    local: post.local,
-    published: None,
-  };
-  let post_id = post.id;
-  blocking(context.pool(), move |conn| {
-    Post::update(conn, post_id, &post_form)
+  let removed_post = blocking(context.pool(), move |conn| {
+    Post::update_removed(conn, post.id, false)
   })
   .await??;
 
   // Refetch the view
-  let post_id = post.id;
+  let post_id = removed_post.id;
   let post_view = blocking(context.pool(), move |conn| {
     PostView::read(conn, post_id, None)
   })
@@ -219,6 +154,7 @@ pub(crate) async fn receive_undo_remove_post(
     websocket_id: None,
   });
 
+  let mod_ = get_actor_as_user(&undo, context).await?;
   announce_if_community_is_local(undo, &mod_, context).await?;
   Ok(HttpResponse::Ok().finish())
 }
index 092d7ef3d9c35fb668ba2b8a2520c01e56009de7..bbf3adb17f170b97a53d008c9ab941e6cc840111 100644 (file)
@@ -106,8 +106,6 @@ impl ApubObjectType for Comment {
   }
 
   async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let note = self.to_apub(context.pool()).await?;
-
     let post_id = self.post_id;
     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
 
@@ -117,7 +115,7 @@ impl ApubObjectType for Comment {
     })
     .await??;
 
-    let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
+    let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     delete
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(DeleteType::Delete)?)
@@ -133,8 +131,6 @@ impl ApubObjectType for Comment {
     creator: &User_,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let note = self.to_apub(context.pool()).await?;
-
     let post_id = self.post_id;
     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
 
@@ -145,7 +141,7 @@ impl ApubObjectType for Comment {
     .await??;
 
     // Generate a fake delete activity, with the correct object
-    let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
+    let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     delete
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(DeleteType::Delete)?)
@@ -165,8 +161,6 @@ impl ApubObjectType for Comment {
   }
 
   async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let note = self.to_apub(context.pool()).await?;
-
     let post_id = self.post_id;
     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
 
@@ -176,7 +170,7 @@ impl ApubObjectType for Comment {
     })
     .await??;
 
-    let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
+    let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     remove
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(RemoveType::Remove)?)
@@ -188,8 +182,6 @@ impl ApubObjectType for Comment {
   }
 
   async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let note = self.to_apub(context.pool()).await?;
-
     let post_id = self.post_id;
     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
 
@@ -200,7 +192,7 @@ impl ApubObjectType for Comment {
     .await??;
 
     // Generate a fake delete activity, with the correct object
-    let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
+    let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     remove
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(RemoveType::Remove)?)
index 0d16d6361e9beb6dafeffa7f1825fd03a3944f5b..3bed1a2ae9626e781db9a76e53270961f6fe496b 100644 (file)
@@ -124,9 +124,7 @@ impl ActorType for Community {
   }
 
   async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let group = self.to_apub(context.pool()).await?;
-
-    let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
+    let mut remove = Remove::new(mod_.actor_id.to_owned(), self.actor_id()?);
     remove
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(RemoveType::Remove)?)
@@ -138,9 +136,7 @@ impl ActorType for Community {
   }
 
   async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let group = self.to_apub(context.pool()).await?;
-
-    let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
+    let mut remove = Remove::new(mod_.actor_id.to_owned(), self.actor_id()?);
     remove
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(RemoveType::Remove)?)
index 81d1a954cac7f2411c569bc318bb16fa33e2e744..568a5f5716192fca023408d82e57d75dc18d6411 100644 (file)
@@ -24,6 +24,7 @@ use lemmy_db::{community::Community, post::Post, user::User_, Crud};
 use lemmy_structs::blocking;
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
+use url::Url;
 
 #[async_trait::async_trait(?Send)]
 impl ApubObjectType for Post {
@@ -70,15 +71,13 @@ impl ApubObjectType for Post {
   }
 
   async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let page = self.to_apub(context.pool()).await?;
-
     let community_id = self.community_id;
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, community_id)
     })
     .await??;
 
-    let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
+    let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     delete
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(DeleteType::Delete)?)
@@ -94,15 +93,13 @@ impl ApubObjectType for Post {
     creator: &User_,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let page = self.to_apub(context.pool()).await?;
-
     let community_id = self.community_id;
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, community_id)
     })
     .await??;
 
-    let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
+    let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     delete
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(DeleteType::Delete)?)
@@ -122,15 +119,13 @@ impl ApubObjectType for Post {
   }
 
   async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let page = self.to_apub(context.pool()).await?;
-
     let community_id = self.community_id;
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, community_id)
     })
     .await??;
 
-    let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
+    let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     remove
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(RemoveType::Remove)?)
@@ -142,15 +137,13 @@ impl ApubObjectType for Post {
   }
 
   async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let page = self.to_apub(context.pool()).await?;
-
     let community_id = self.community_id;
     let community = blocking(context.pool(), move |conn| {
       Community::read(conn, community_id)
     })
     .await??;
 
-    let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
+    let mut remove = Remove::new(mod_.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     remove
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(RemoveType::Remove)?)
index fc3e52252922c778610d57712ec5356060a43e1e..89b6540416d11cb1d1a504eef51c42bade5ad7c3 100644 (file)
@@ -19,6 +19,7 @@ use lemmy_db::{private_message::PrivateMessage, user::User_, Crud};
 use lemmy_structs::blocking;
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
+use url::Url;
 
 #[async_trait::async_trait(?Send)]
 impl ApubObjectType for PrivateMessage {
@@ -58,12 +59,10 @@ impl ApubObjectType for PrivateMessage {
   }
 
   async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
-    let note = self.to_apub(context.pool()).await?;
-
     let recipient_id = self.recipient_id;
     let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
 
-    let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
+    let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     delete
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(DeleteType::Delete)?)
@@ -78,12 +77,10 @@ impl ApubObjectType for PrivateMessage {
     creator: &User_,
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
-    let note = self.to_apub(context.pool()).await?;
-
     let recipient_id = self.recipient_id;
     let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
 
-    let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
+    let mut delete = Delete::new(creator.actor_id.to_owned(), Url::parse(&self.ap_id)?);
     delete
       .set_context(activitystreams::context())
       .set_id(generate_activity_id(DeleteType::Delete)?)
index db6a6cea9c9e4e50af46b50bc56081c4a6531085..7791785092d835766bbb767569cff9afc12dcf1a 100644 (file)
@@ -15,7 +15,6 @@ use actix_web::{web, HttpRequest, HttpResponse};
 use anyhow::Context;
 use lemmy_db::{
   community::{CommunityFollower, CommunityFollowerForm},
-  naive_now,
   private_message::{PrivateMessage, PrivateMessageForm},
   private_message_view::PrivateMessageView,
   user::User_,
@@ -216,52 +215,27 @@ async fn receive_delete_private_message(
   context: &LemmyContext,
 ) -> Result<HttpResponse, LemmyError> {
   let delete = Delete::from_any_base(activity)?.context(location_info!())?;
-  let note = Note::from_any_base(
-    delete
-      .object()
-      .as_one()
-      .context(location_info!())?
-      .to_owned(),
-  )?
-  .context(location_info!())?;
-
-  let domain = Some(delete.id_unchecked().context(location_info!())?.to_owned());
-  let private_message_form = PrivateMessageForm::from_apub(&note, context, domain).await?;
-
-  let private_message_ap_id = private_message_form.ap_id.context(location_info!())?;
-  let private_message = blocking(&context.pool(), move |conn| {
-    PrivateMessage::read_from_apub_id(conn, &private_message_ap_id)
+  let private_message_id = delete
+    .object()
+    .to_owned()
+    .single_xsd_any_uri()
+    .context(location_info!())?;
+  let private_message = blocking(context.pool(), move |conn| {
+    PrivateMessage::read_from_apub_id(conn, private_message_id.as_str())
   })
   .await??;
-
-  let private_message_form = PrivateMessageForm {
-    content: private_message_form.content,
-    recipient_id: private_message.recipient_id,
-    creator_id: private_message.creator_id,
-    deleted: Some(true),
-    read: None,
-    ap_id: Some(private_message.ap_id),
-    local: private_message.local,
-    published: None,
-    updated: Some(naive_now()),
-  };
-
-  let private_message_id = private_message.id;
-  blocking(&context.pool(), move |conn| {
-    PrivateMessage::update(conn, private_message_id, &private_message_form)
+  let deleted_private_message = blocking(context.pool(), move |conn| {
+    PrivateMessage::update_deleted(conn, private_message.id, true)
   })
   .await??;
 
-  let private_message_id = private_message.id;
   let message = blocking(&context.pool(), move |conn| {
-    PrivateMessageView::read(&conn, private_message_id)
+    PrivateMessageView::read(&conn, deleted_private_message.id)
   })
   .await??;
 
   let res = PrivateMessageResponse { message };
-
   let recipient_id = res.message.recipient_id;
-
   context.chat_server().do_send(SendUserRoomMessage {
     op: UserOperation::EditPrivateMessage,
     response: res,
@@ -279,47 +253,22 @@ async fn receive_undo_delete_private_message(
   let undo = Undo::from_any_base(activity)?.context(location_info!())?;
   let delete = Delete::from_any_base(undo.object().as_one().context(location_info!())?.to_owned())?
     .context(location_info!())?;
-  let note = Note::from_any_base(
-    delete
-      .object()
-      .as_one()
-      .context(location_info!())?
-      .to_owned(),
-  )?
-  .context(location_info!())?;
-
-  let domain = Some(undo.id_unchecked().context(location_info!())?.to_owned());
-  let private_message = PrivateMessageForm::from_apub(&note, context, domain).await?;
-
-  let private_message_ap_id = private_message
-    .ap_id
-    .as_ref()
-    .context(location_info!())?
-    .clone();
-  let private_message_id = blocking(&context.pool(), move |conn| {
-    PrivateMessage::read_from_apub_id(conn, &private_message_ap_id).map(|pm| pm.id)
+  let private_message_id = delete
+    .object()
+    .to_owned()
+    .single_xsd_any_uri()
+    .context(location_info!())?;
+  let private_message = blocking(context.pool(), move |conn| {
+    PrivateMessage::read_from_apub_id(conn, private_message_id.as_str())
   })
   .await??;
-
-  let private_message_form = PrivateMessageForm {
-    content: private_message.content,
-    recipient_id: private_message.recipient_id,
-    creator_id: private_message.creator_id,
-    deleted: Some(false),
-    read: None,
-    ap_id: private_message.ap_id,
-    local: private_message.local,
-    published: None,
-    updated: Some(naive_now()),
-  };
-
-  blocking(&context.pool(), move |conn| {
-    PrivateMessage::update(conn, private_message_id, &private_message_form)
+  let deleted_private_message = blocking(context.pool(), move |conn| {
+    PrivateMessage::update_deleted(conn, private_message.id, false)
   })
   .await??;
 
   let message = blocking(&context.pool(), move |conn| {
-    PrivateMessageView::read(&conn, private_message_id)
+    PrivateMessageView::read(&conn, deleted_private_message.id)
   })
   .await??;