]> Untitled Git - lemmy.git/blobdiff - crates/apub/src/activities/deletion/mod.rs
Fixing broken SQL migration formatting. (#3800)
[lemmy.git] / crates / apub / src / activities / deletion / mod.rs
index 1ff8429aa9a74a7ef7ad16b711a3f7466afe8172..e03074f19d96531c32065b76dc8a641796eea375 100644 (file)
@@ -1,6 +1,6 @@
 use crate::{
   activities::{
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     send_lemmy_activity,
     verify_is_public,
     verify_mod_action,
@@ -15,36 +15,31 @@ use crate::{
     post::ApubPost,
     private_message::ApubPrivateMessage,
   },
-  protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
+  protocol::{
+    activities::deletion::{delete::Delete, undo_delete::UndoDelete},
+    InCommunity,
+  },
 };
-use activitystreams_kinds::public;
-use lemmy_api_common::blocking;
-use lemmy_apub_lib::{
-  object_id::ObjectId,
-  traits::{ActorType, ApubObject},
-  verify::verify_domains_match,
+use activitypub_federation::{
+  config::Data,
+  fetch::object_id::ObjectId,
+  kinds::public,
+  protocol::verification::verify_domains_match,
+  traits::{Actor, Object},
 };
+use lemmy_api_common::context::LemmyContext;
 use lemmy_db_schema::{
+  newtypes::CommunityId,
   source::{
-    comment::Comment,
-    community::Community,
+    comment::{Comment, CommentUpdateForm},
+    community::{Community, CommunityUpdateForm},
     person::Person,
-    post::Post,
-    private_message::PrivateMessage,
+    post::{Post, PostUpdateForm},
+    private_message::{PrivateMessage, PrivateMessageUpdateForm},
   },
   traits::Crud,
 };
-use lemmy_utils::LemmyError;
-use lemmy_websocket::{
-  send::{
-    send_comment_ws_message_simple,
-    send_community_ws_message,
-    send_pm_ws_message,
-    send_post_ws_message,
-  },
-  LemmyContext,
-  UserOperationCrud,
-};
+use lemmy_utils::error::LemmyError;
 use std::ops::Deref;
 use url::Url;
 
@@ -55,90 +50,121 @@ pub mod undo_delete;
 /// Parameter `reason` being set indicates that this is a removal by a mod. If its unset, this
 /// action was done by a normal user.
 #[tracing::instrument(skip_all)]
-pub async fn send_apub_delete_in_community(
+pub(crate) async fn send_apub_delete_in_community(
   actor: Person,
   community: Community,
   object: DeletableObjects,
   reason: Option<String>,
   deleted: bool,
-  context: &LemmyContext,
+  context: &Data<LemmyContext>,
 ) -> Result<(), LemmyError> {
-  let (id, activity) = if deleted {
+  let actor = ApubPerson::from(actor);
+  let is_mod_action = reason.is_some();
+  let activity = if deleted {
     let delete = Delete::new(&actor, object, public(), Some(&community), reason, context)?;
-    (delete.id.clone(), AnnouncableActivities::Delete(delete))
+    AnnouncableActivities::Delete(delete)
   } else {
     let undo = UndoDelete::new(&actor, object, public(), Some(&community), reason, context)?;
-    (undo.id.clone(), AnnouncableActivities::UndoDelete(undo))
+    AnnouncableActivities::UndoDelete(undo)
   };
   send_activity_in_community(
     activity,
-    &id,
-    &ApubPerson::from(actor),
+    &actor,
     &community.into(),
     vec![],
+    is_mod_action,
     context,
   )
   .await
 }
 
+/// Parameter `reason` being set indicates that this is a removal by a mod. If its unset, this
+/// action was done by a normal user.
+#[tracing::instrument(skip_all)]
+pub(crate) async fn send_apub_delete_in_community_new(
+  actor: Person,
+  community_id: CommunityId,
+  object: DeletableObjects,
+  reason: Option<String>,
+  deleted: bool,
+  context: Data<LemmyContext>,
+) -> Result<(), LemmyError> {
+  let community = Community::read(&mut context.pool(), community_id).await?;
+  let actor = ApubPerson::from(actor);
+  let is_mod_action = reason.is_some();
+  let activity = if deleted {
+    let delete = Delete::new(&actor, object, public(), Some(&community), reason, &context)?;
+    AnnouncableActivities::Delete(delete)
+  } else {
+    let undo = UndoDelete::new(&actor, object, public(), Some(&community), reason, &context)?;
+    AnnouncableActivities::UndoDelete(undo)
+  };
+  send_activity_in_community(
+    activity,
+    &actor,
+    &community.into(),
+    vec![],
+    is_mod_action,
+    &context,
+  )
+  .await
+}
+
 #[tracing::instrument(skip_all)]
-pub async fn send_apub_delete_private_message(
+pub(crate) async fn send_apub_delete_private_message(
   actor: &ApubPerson,
   pm: PrivateMessage,
   deleted: bool,
-  context: &LemmyContext,
+  context: Data<LemmyContext>,
 ) -> Result<(), LemmyError> {
   let recipient_id = pm.recipient_id;
-  let recipient: ApubPerson =
-    blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
-      .await??
-      .into();
+  let recipient: ApubPerson = Person::read(&mut context.pool(), recipient_id)
+    .await?
+    .into();
 
-  let deletable = DeletableObjects::PrivateMessage(Box::new(pm.into()));
-  let inbox = vec![recipient.shared_inbox_or_inbox_url()];
+  let deletable = DeletableObjects::PrivateMessage(pm.into());
+  let inbox = vec![recipient.shared_inbox_or_inbox()];
   if deleted {
-    let delete = Delete::new(actor, deletable, recipient.actor_id(), None, None, context)?;
-    let id = delete.id.clone();
-    send_lemmy_activity(context, &delete, &id, actor, inbox, true).await?;
+    let delete = Delete::new(actor, deletable, recipient.id(), None, None, &context)?;
+    send_lemmy_activity(&context, delete, actor, inbox, true).await?;
   } else {
-    let undo = UndoDelete::new(actor, deletable, recipient.actor_id(), None, None, context)?;
-    let id = undo.id.clone();
-    send_lemmy_activity(context, &undo, &id, actor, inbox, true).await?;
+    let undo = UndoDelete::new(actor, deletable, recipient.id(), None, None, &context)?;
+    send_lemmy_activity(&context, undo, actor, inbox, true).await?;
   };
   Ok(())
 }
 
 pub enum DeletableObjects {
-  Community(Box<ApubCommunity>),
-  Comment(Box<ApubComment>),
-  Post(Box<ApubPost>),
-  PrivateMessage(Box<ApubPrivateMessage>),
+  Community(ApubCommunity),
+  Comment(ApubComment),
+  Post(ApubPost),
+  PrivateMessage(ApubPrivateMessage),
 }
 
 impl DeletableObjects {
   #[tracing::instrument(skip_all)]
   pub(crate) async fn read_from_db(
     ap_id: &Url,
-    context: &LemmyContext,
+    context: &Data<LemmyContext>,
   ) -> Result<DeletableObjects, LemmyError> {
-    if let Some(c) = ApubCommunity::read_from_apub_id(ap_id.clone(), context).await? {
-      return Ok(DeletableObjects::Community(Box::new(c)));
+    if let Some(c) = ApubCommunity::read_from_id(ap_id.clone(), context).await? {
+      return Ok(DeletableObjects::Community(c));
     }
-    if let Some(p) = ApubPost::read_from_apub_id(ap_id.clone(), context).await? {
-      return Ok(DeletableObjects::Post(Box::new(p)));
+    if let Some(p) = ApubPost::read_from_id(ap_id.clone(), context).await? {
+      return Ok(DeletableObjects::Post(p));
     }
-    if let Some(c) = ApubComment::read_from_apub_id(ap_id.clone(), context).await? {
-      return Ok(DeletableObjects::Comment(Box::new(c)));
+    if let Some(c) = ApubComment::read_from_id(ap_id.clone(), context).await? {
+      return Ok(DeletableObjects::Comment(c));
     }
-    if let Some(p) = ApubPrivateMessage::read_from_apub_id(ap_id.clone(), context).await? {
-      return Ok(DeletableObjects::PrivateMessage(Box::new(p)));
+    if let Some(p) = ApubPrivateMessage::read_from_id(ap_id.clone(), context).await? {
+      return Ok(DeletableObjects::PrivateMessage(p));
     }
     Err(diesel::NotFound.into())
   }
 
   pub(crate) fn id(&self) -> Url {
     match self {
-      DeletableObjects::Community(c) => c.actor_id(),
+      DeletableObjects::Community(c) => c.id(),
       DeletableObjects::Comment(c) => c.ap_id.clone().into(),
       DeletableObjects::Post(p) => p.ap_id.clone().into(),
       DeletableObjects::PrivateMessage(p) => p.ap_id.clone().into(),
@@ -150,8 +176,7 @@ impl DeletableObjects {
 pub(in crate::activities) async fn verify_delete_activity(
   activity: &Delete,
   is_mod_action: bool,
-  context: &LemmyContext,
-  request_counter: &mut i32,
+  context: &Data<LemmyContext>,
 ) -> Result<(), LemmyError> {
   let object = DeletableObjects::read_from_db(activity.object.id(), context).await?;
   match object {
@@ -160,27 +185,19 @@ pub(in crate::activities) async fn verify_delete_activity(
       if community.local {
         // can only do this check for local community, in remote case it would try to fetch the
         // deleted community (which fails)
-        verify_person_in_community(&activity.actor, &community, context, request_counter).await?;
+        verify_person_in_community(&activity.actor, &community, context).await?;
       }
       // community deletion is always a mod (or admin) action
-      verify_mod_action(
-        &activity.actor,
-        activity.object.id(),
-        &community,
-        context,
-        request_counter,
-      )
-      .await?;
+      verify_mod_action(&activity.actor, activity.object.id(), community.id, context).await?;
     }
     DeletableObjects::Post(p) => {
       verify_is_public(&activity.to, &[])?;
       verify_delete_post_or_comment(
         &activity.actor,
         &p.ap_id.clone().into(),
-        &activity.get_community(context, request_counter).await?,
+        &activity.community(context).await?,
         is_mod_action,
         context,
-        request_counter,
       )
       .await?;
     }
@@ -189,15 +206,14 @@ pub(in crate::activities) async fn verify_delete_activity(
       verify_delete_post_or_comment(
         &activity.actor,
         &c.ap_id.clone().into(),
-        &activity.get_community(context, request_counter).await?,
+        &activity.community(context).await?,
         is_mod_action,
         context,
-        request_counter,
       )
       .await?;
     }
     DeletableObjects::PrivateMessage(_) => {
-      verify_person(&activity.actor, context, request_counter).await?;
+      verify_person(&activity.actor, context).await?;
       verify_domains_match(activity.actor.inner(), activity.object.id())?;
     }
   }
@@ -210,12 +226,11 @@ async fn verify_delete_post_or_comment(
   object_id: &Url,
   community: &ApubCommunity,
   is_mod_action: bool,
-  context: &LemmyContext,
-  request_counter: &mut i32,
+  context: &Data<LemmyContext>,
 ) -> Result<(), LemmyError> {
-  verify_person_in_community(actor, community, context, request_counter).await?;
+  verify_person_in_community(actor, community, context).await?;
   if is_mod_action {
-    verify_mod_action(actor, object_id, community, context, request_counter).await?;
+    verify_mod_action(actor, object_id, community.id, context).await?;
   } else {
     // domain of post ap_id and post.creator ap_id are identical, so we just check the former
     verify_domains_match(actor.inner(), object_id)?;
@@ -229,76 +244,53 @@ async fn receive_delete_action(
   object: &Url,
   actor: &ObjectId<ApubPerson>,
   deleted: bool,
-  context: &LemmyContext,
-  request_counter: &mut i32,
+  context: &Data<LemmyContext>,
 ) -> Result<(), LemmyError> {
   match DeletableObjects::read_from_db(object, context).await? {
     DeletableObjects::Community(community) => {
       if community.local {
-        let mod_: Person = actor
-          .dereference(context, context.client(), request_counter)
-          .await?
-          .deref()
-          .clone();
+        let mod_: Person = actor.dereference(context).await?.deref().clone();
         let object = DeletableObjects::Community(community.clone());
-        let c: Community = community.deref().deref().clone();
+        let c: Community = community.deref().clone();
         send_apub_delete_in_community(mod_, c, object, None, true, context).await?;
       }
 
-      let community = blocking(context.pool(), move |conn| {
-        Community::update_deleted(conn, community.id, deleted)
-      })
-      .await??;
-      send_community_ws_message(
+      Community::update(
+        &mut context.pool(),
         community.id,
-        UserOperationCrud::DeleteCommunity,
-        None,
-        None,
-        context,
+        &CommunityUpdateForm::builder()
+          .deleted(Some(deleted))
+          .build(),
       )
       .await?;
     }
     DeletableObjects::Post(post) => {
       if deleted != post.deleted {
-        let deleted_post = blocking(context.pool(), move |conn| {
-          Post::update_deleted(conn, post.id, deleted)
-        })
-        .await??;
-        send_post_ws_message(
-          deleted_post.id,
-          UserOperationCrud::DeletePost,
-          None,
-          None,
-          context,
+        Post::update(
+          &mut context.pool(),
+          post.id,
+          &PostUpdateForm::builder().deleted(Some(deleted)).build(),
         )
         .await?;
       }
     }
     DeletableObjects::Comment(comment) => {
       if deleted != comment.deleted {
-        let deleted_comment = blocking(context.pool(), move |conn| {
-          Comment::update_deleted(conn, comment.id, deleted)
-        })
-        .await??;
-        send_comment_ws_message_simple(
-          deleted_comment.id,
-          UserOperationCrud::DeleteComment,
-          context,
+        Comment::update(
+          &mut context.pool(),
+          comment.id,
+          &CommentUpdateForm::builder().deleted(Some(deleted)).build(),
         )
         .await?;
       }
     }
     DeletableObjects::PrivateMessage(pm) => {
-      let deleted_private_message = blocking(context.pool(), move |conn| {
-        PrivateMessage::update_deleted(conn, pm.id, deleted)
-      })
-      .await??;
-
-      send_pm_ws_message(
-        deleted_private_message.id,
-        UserOperationCrud::DeletePrivateMessage,
-        None,
-        context,
+      PrivateMessage::update(
+        &mut context.pool(),
+        pm.id,
+        &PrivateMessageUpdateForm::builder()
+          .deleted(Some(deleted))
+          .build(),
       )
       .await?;
     }