]> Untitled Git - lemmy.git/blobdiff - crates/apub/src/activities/create_or_update/private_message.rs
Split activity table into sent and received parts (fixes #3103) (#3583)
[lemmy.git] / crates / apub / src / activities / create_or_update / private_message.rs
index 523135db770b95887e5885e32496caaf3850cca1..3eaad2f713ad5e1eedcc5295f9a8b8685b58db6c 100644 (file)
 use crate::{
   activities::{generate_activity_id, send_lemmy_activity, verify_person},
+  insert_received_activity,
   objects::{person::ApubPerson, private_message::ApubPrivateMessage},
   protocol::activities::{
-    create_or_update::private_message::CreateOrUpdatePrivateMessage,
+    create_or_update::chat_message::CreateOrUpdateChatMessage,
     CreateOrUpdateType,
   },
-  ActorType,
+  SendActivity,
 };
 use activitypub_federation::{
-  core::object_id::ObjectId,
-  data::Data,
-  traits::{ActivityHandler, Actor, ApubObject},
-  utils::verify_domains_match,
+  config::Data,
+  protocol::verification::verify_domains_match,
+  traits::{ActivityHandler, Actor, Object},
+};
+use lemmy_api_common::{
+  context::LemmyContext,
+  private_message::{CreatePrivateMessage, EditPrivateMessage, PrivateMessageResponse},
+};
+use lemmy_db_schema::{
+  newtypes::PersonId,
+  source::{person::Person, private_message::PrivateMessage},
+  traits::Crud,
 };
-use lemmy_db_schema::{source::person::Person, traits::Crud};
 use lemmy_utils::error::LemmyError;
-use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
-impl CreateOrUpdatePrivateMessage {
+#[async_trait::async_trait]
+impl SendActivity for CreatePrivateMessage {
+  type Response = PrivateMessageResponse;
+
+  async fn send_activity(
+    _request: &Self,
+    response: &Self::Response,
+    context: &Data<LemmyContext>,
+  ) -> Result<(), LemmyError> {
+    CreateOrUpdateChatMessage::send(
+      &response.private_message_view.private_message,
+      response.private_message_view.creator.id,
+      CreateOrUpdateType::Create,
+      context,
+    )
+    .await
+  }
+}
+#[async_trait::async_trait]
+impl SendActivity for EditPrivateMessage {
+  type Response = PrivateMessageResponse;
+
+  async fn send_activity(
+    _request: &Self,
+    response: &Self::Response,
+    context: &Data<LemmyContext>,
+  ) -> Result<(), LemmyError> {
+    CreateOrUpdateChatMessage::send(
+      &response.private_message_view.private_message,
+      response.private_message_view.creator.id,
+      CreateOrUpdateType::Update,
+      context,
+    )
+    .await
+  }
+}
+
+impl CreateOrUpdateChatMessage {
   #[tracing::instrument(skip_all)]
-  pub async fn send(
-    private_message: ApubPrivateMessage,
-    actor: &ApubPerson,
+  async fn send(
+    private_message: &PrivateMessage,
+    sender_id: PersonId,
     kind: CreateOrUpdateType,
-    context: &LemmyContext,
+    context: &Data<LemmyContext>,
   ) -> Result<(), LemmyError> {
     let recipient_id = private_message.recipient_id;
-    let recipient: ApubPerson = Person::read(context.pool(), recipient_id).await?.into();
+    let sender: ApubPerson = Person::read(&mut context.pool(), sender_id).await?.into();
+    let recipient: ApubPerson = Person::read(&mut context.pool(), recipient_id)
+      .await?
+      .into();
 
     let id = generate_activity_id(
       kind.clone(),
       &context.settings().get_protocol_and_hostname(),
     )?;
-    let create_or_update = CreateOrUpdatePrivateMessage {
+    let create_or_update = CreateOrUpdateChatMessage {
       id: id.clone(),
-      actor: ObjectId::new(actor.actor_id()),
-      to: [ObjectId::new(recipient.actor_id())],
-      object: private_message.into_apub(context).await?,
+      actor: sender.id().into(),
+      to: [recipient.id().into()],
+      object: ApubPrivateMessage(private_message.clone())
+        .into_json(context)
+        .await?,
       kind,
-      unparsed: Default::default(),
     };
     let inbox = vec![recipient.shared_inbox_or_inbox()];
-    send_lemmy_activity(context, create_or_update, actor, inbox, true).await
+    send_lemmy_activity(context, create_or_update, &sender, inbox, true).await
   }
 }
 
-#[async_trait::async_trait(?Send)]
-impl ActivityHandler for CreateOrUpdatePrivateMessage {
+#[async_trait::async_trait]
+impl ActivityHandler for CreateOrUpdateChatMessage {
   type DataType = LemmyContext;
   type Error = LemmyError;
 
@@ -60,33 +108,18 @@ impl ActivityHandler for CreateOrUpdatePrivateMessage {
   }
 
   #[tracing::instrument(skip_all)]
-  async fn verify(
-    &self,
-    context: &Data<LemmyContext>,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    verify_person(&self.actor, context, request_counter).await?;
+  async fn verify(&self, context: &Data<Self::DataType>) -> Result<(), LemmyError> {
+    insert_received_activity(&self.id, context).await?;
+    verify_person(&self.actor, context).await?;
     verify_domains_match(self.actor.inner(), self.object.id.inner())?;
     verify_domains_match(self.to[0].inner(), self.object.to[0].inner())?;
-    ApubPrivateMessage::verify(&self.object, self.actor.inner(), context, request_counter).await?;
+    ApubPrivateMessage::verify(&self.object, self.actor.inner(), context).await?;
     Ok(())
   }
 
   #[tracing::instrument(skip_all)]
-  async fn receive(
-    self,
-    context: &Data<LemmyContext>,
-    request_counter: &mut i32,
-  ) -> Result<(), LemmyError> {
-    let private_message =
-      ApubPrivateMessage::from_apub(self.object, context, request_counter).await?;
-
-    let notif_type = match self.kind {
-      CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage,
-      CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage,
-    };
-    send_pm_ws_message(private_message.id, notif_type, None, context).await?;
-
+  async fn receive(self, context: &Data<Self::DataType>) -> Result<(), LemmyError> {
+    ApubPrivateMessage::from_json(self.object, context).await?;
     Ok(())
   }
 }