]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/private_message/create_or_update.rs
Rewrite remaining activities (#1712)
[lemmy.git] / crates / apub / src / activities / private_message / create_or_update.rs
1 use crate::{
2   activities::{generate_activity_id, verify_activity, verify_person, CreateOrUpdateType},
3   activity_queue::send_activity_new,
4   extensions::context::lemmy_context,
5   objects::{private_message::Note, FromApub, ToApub},
6   ActorType,
7 };
8 use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed};
9 use lemmy_api_common::blocking;
10 use lemmy_apub_lib::{verify_domains_match, ActivityFields, ActivityHandler};
11 use lemmy_db_queries::Crud;
12 use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
13 use lemmy_utils::LemmyError;
14 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
15 use serde::{Deserialize, Serialize};
16 use url::Url;
17
18 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
19 #[serde(rename_all = "camelCase")]
20 pub struct CreateOrUpdatePrivateMessage {
21   #[serde(rename = "@context")]
22   pub context: OneOrMany<AnyBase>,
23   id: Url,
24   actor: Url,
25   to: Url,
26   cc: [Url; 0],
27   object: Note,
28   #[serde(rename = "type")]
29   kind: CreateOrUpdateType,
30   #[serde(flatten)]
31   pub unparsed: Unparsed,
32 }
33
34 impl CreateOrUpdatePrivateMessage {
35   pub async fn send(
36     private_message: &PrivateMessage,
37     actor: &Person,
38     kind: CreateOrUpdateType,
39     context: &LemmyContext,
40   ) -> Result<(), LemmyError> {
41     let recipient_id = private_message.recipient_id;
42     let recipient =
43       blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
44
45     let id = generate_activity_id(kind.clone())?;
46     let create_or_update = CreateOrUpdatePrivateMessage {
47       context: lemmy_context(),
48       id: id.clone(),
49       actor: actor.actor_id(),
50       to: recipient.actor_id(),
51       cc: [],
52       object: private_message.to_apub(context.pool()).await?,
53       kind,
54       unparsed: Default::default(),
55     };
56     let inbox = vec![recipient.get_shared_inbox_or_inbox_url()];
57     send_activity_new(context, &create_or_update, &id, actor, inbox, true).await
58   }
59 }
60 #[async_trait::async_trait(?Send)]
61 impl ActivityHandler for CreateOrUpdatePrivateMessage {
62   async fn verify(
63     &self,
64     context: &LemmyContext,
65     request_counter: &mut i32,
66   ) -> Result<(), LemmyError> {
67     verify_activity(self)?;
68     verify_person(&self.actor, context, request_counter).await?;
69     verify_domains_match(&self.actor, self.object.id_unchecked())?;
70     self.object.verify(context, request_counter).await?;
71     Ok(())
72   }
73
74   async fn receive(
75     self,
76     context: &LemmyContext,
77     request_counter: &mut i32,
78   ) -> Result<(), LemmyError> {
79     let private_message =
80       PrivateMessage::from_apub(&self.object, context, &self.actor, request_counter).await?;
81
82     let notif_type = match self.kind {
83       CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage,
84       CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage,
85     };
86     send_pm_ws_message(private_message.id, notif_type, None, context).await?;
87
88     Ok(())
89   }
90 }