]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/create_or_update/private_message.rs
9ad54769121d9cd6009254efb43abb6552746d77
[lemmy.git] / crates / apub / src / activities / create_or_update / private_message.rs
1 use crate::{
2   activities::{generate_activity_id, send_lemmy_activity, verify_person},
3   objects::{person::ApubPerson, private_message::ApubPrivateMessage},
4   protocol::activities::{
5     create_or_update::private_message::CreateOrUpdatePrivateMessage,
6     CreateOrUpdateType,
7   },
8   ActorType,
9 };
10 use activitypub_federation::{
11   core::object_id::ObjectId,
12   data::Data,
13   traits::{ActivityHandler, Actor, ApubObject},
14   utils::verify_domains_match,
15 };
16 use lemmy_api_common::utils::blocking;
17 use lemmy_db_schema::{source::person::Person, traits::Crud};
18 use lemmy_utils::error::LemmyError;
19 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
20 use url::Url;
21
22 impl CreateOrUpdatePrivateMessage {
23   #[tracing::instrument(skip_all)]
24   pub async fn send(
25     private_message: ApubPrivateMessage,
26     actor: &ApubPerson,
27     kind: CreateOrUpdateType,
28     context: &LemmyContext,
29   ) -> Result<(), LemmyError> {
30     let recipient_id = private_message.recipient_id;
31     let recipient: ApubPerson =
32       blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
33         .await??
34         .into();
35
36     let id = generate_activity_id(
37       kind.clone(),
38       &context.settings().get_protocol_and_hostname(),
39     )?;
40     let create_or_update = CreateOrUpdatePrivateMessage {
41       id: id.clone(),
42       actor: ObjectId::new(actor.actor_id()),
43       to: [ObjectId::new(recipient.actor_id())],
44       object: private_message.into_apub(context).await?,
45       kind,
46       unparsed: Default::default(),
47     };
48     let inbox = vec![recipient.shared_inbox_or_inbox()];
49     send_lemmy_activity(context, create_or_update, actor, inbox, true).await
50   }
51 }
52
53 #[async_trait::async_trait(?Send)]
54 impl ActivityHandler for CreateOrUpdatePrivateMessage {
55   type DataType = LemmyContext;
56   type Error = LemmyError;
57
58   fn id(&self) -> &Url {
59     &self.id
60   }
61
62   fn actor(&self) -> &Url {
63     self.actor.inner()
64   }
65
66   #[tracing::instrument(skip_all)]
67   async fn verify(
68     &self,
69     context: &Data<LemmyContext>,
70     request_counter: &mut i32,
71   ) -> Result<(), LemmyError> {
72     verify_person(&self.actor, context, request_counter).await?;
73     verify_domains_match(self.actor.inner(), self.object.id.inner())?;
74     verify_domains_match(self.to[0].inner(), self.object.to[0].inner())?;
75     ApubPrivateMessage::verify(&self.object, self.actor.inner(), context, request_counter).await?;
76     Ok(())
77   }
78
79   #[tracing::instrument(skip_all)]
80   async fn receive(
81     self,
82     context: &Data<LemmyContext>,
83     request_counter: &mut i32,
84   ) -> Result<(), LemmyError> {
85     let private_message =
86       ApubPrivateMessage::from_apub(self.object, context, request_counter).await?;
87
88     let notif_type = match self.kind {
89       CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage,
90       CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage,
91     };
92     send_pm_ws_message(private_message.id, notif_type, None, context).await?;
93
94     Ok(())
95   }
96 }