]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/private_message/create_or_update.rs
Moving settings and secrets to context.
[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   fetcher::object_id::ObjectId,
6   objects::{private_message::Note, FromApub, ToApub},
7   ActorType,
8 };
9 use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed};
10 use lemmy_api_common::blocking;
11 use lemmy_apub_lib::{verify_domains_match, ActivityFields, ActivityHandler};
12 use lemmy_db_queries::Crud;
13 use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
14 use lemmy_utils::LemmyError;
15 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
16 use serde::{Deserialize, Serialize};
17 use url::Url;
18
19 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
20 #[serde(rename_all = "camelCase")]
21 pub struct CreateOrUpdatePrivateMessage {
22   #[serde(rename = "@context")]
23   pub context: OneOrMany<AnyBase>,
24   id: Url,
25   actor: ObjectId<Person>,
26   to: ObjectId<Person>,
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(
46       kind.clone(),
47       &context.settings().get_protocol_and_hostname(),
48     )?;
49     let create_or_update = CreateOrUpdatePrivateMessage {
50       context: lemmy_context(),
51       id: id.clone(),
52       actor: ObjectId::new(actor.actor_id()),
53       to: ObjectId::new(recipient.actor_id()),
54       object: private_message.to_apub(context.pool()).await?,
55       kind,
56       unparsed: Default::default(),
57     };
58     let inbox = vec![recipient.get_shared_inbox_or_inbox_url()];
59     send_activity_new(context, &create_or_update, &id, actor, inbox, true).await
60   }
61 }
62 #[async_trait::async_trait(?Send)]
63 impl ActivityHandler for CreateOrUpdatePrivateMessage {
64   async fn verify(
65     &self,
66     context: &LemmyContext,
67     request_counter: &mut i32,
68   ) -> Result<(), LemmyError> {
69     verify_activity(self, &context.settings())?;
70     verify_person(&self.actor, context, request_counter).await?;
71     verify_domains_match(self.actor.inner(), self.object.id_unchecked())?;
72     self.object.verify(context, request_counter).await?;
73     Ok(())
74   }
75
76   async fn receive(
77     self,
78     context: &LemmyContext,
79     request_counter: &mut i32,
80   ) -> Result<(), LemmyError> {
81     let private_message =
82       PrivateMessage::from_apub(&self.object, context, self.actor.inner(), request_counter).await?;
83
84     let notif_type = match self.kind {
85       CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage,
86       CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage,
87     };
88     send_pm_ws_message(private_message.id, notif_type, None, context).await?;
89
90     Ok(())
91   }
92 }