]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/private_message/undo_delete.rs
5bbca90e6e28a28b873adf98b2693e10b03a35cb
[lemmy.git] / crates / apub / src / activities / private_message / undo_delete.rs
1 use crate::{
2   activities::{
3     generate_activity_id,
4     private_message::{delete::DeletePrivateMessage, send_websocket_message},
5     verify_activity,
6     verify_person,
7   },
8   activity_queue::send_activity_new,
9   extensions::context::lemmy_context,
10   ActorType,
11 };
12 use activitystreams::activity::kind::{DeleteType, UndoType};
13 use lemmy_api_common::blocking;
14 use lemmy_apub_lib::{
15   verify_domains_match,
16   verify_urls_match,
17   ActivityCommonFields,
18   ActivityHandler,
19 };
20 use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject, Crud};
21 use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
22 use lemmy_utils::LemmyError;
23 use lemmy_websocket::{LemmyContext, UserOperationCrud};
24 use url::Url;
25
26 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
27 #[serde(rename_all = "camelCase")]
28 pub struct UndoDeletePrivateMessage {
29   to: Url,
30   object: DeletePrivateMessage,
31   #[serde(rename = "type")]
32   kind: UndoType,
33   #[serde(flatten)]
34   common: ActivityCommonFields,
35 }
36
37 impl UndoDeletePrivateMessage {
38   pub async fn send(
39     actor: &Person,
40     pm: &PrivateMessage,
41     context: &LemmyContext,
42   ) -> Result<(), LemmyError> {
43     let recipient_id = pm.recipient_id;
44     let recipient =
45       blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
46
47     let object = DeletePrivateMessage {
48       to: recipient.actor_id(),
49       object: pm.ap_id.clone().into(),
50       kind: DeleteType::Delete,
51       common: ActivityCommonFields {
52         context: lemmy_context(),
53         id: generate_activity_id(DeleteType::Delete)?,
54         actor: actor.actor_id(),
55         unparsed: Default::default(),
56       },
57     };
58
59     let id = generate_activity_id(UndoType::Undo)?;
60     let undo = UndoDeletePrivateMessage {
61       to: recipient.actor_id(),
62       object,
63       kind: UndoType::Undo,
64       common: ActivityCommonFields {
65         context: lemmy_context(),
66         id: id.clone(),
67         actor: actor.actor_id(),
68         unparsed: Default::default(),
69       },
70     };
71     let inbox = vec![recipient.get_shared_inbox_or_inbox_url()];
72     send_activity_new(context, &undo, &id, actor, inbox, true).await
73   }
74 }
75
76 #[async_trait::async_trait(?Send)]
77 impl ActivityHandler for UndoDeletePrivateMessage {
78   async fn verify(
79     &self,
80     context: &LemmyContext,
81     request_counter: &mut i32,
82   ) -> Result<(), LemmyError> {
83     verify_activity(self.common())?;
84     verify_person(&self.common.actor, context, request_counter).await?;
85     verify_urls_match(&self.common.actor, &self.object.common.actor)?;
86     verify_domains_match(&self.common.actor, &self.object.object)?;
87     self.object.verify(context, request_counter).await?;
88     Ok(())
89   }
90
91   async fn receive(
92     self,
93     context: &LemmyContext,
94     _request_counter: &mut i32,
95   ) -> Result<(), LemmyError> {
96     let ap_id = self.object.object.clone();
97     let private_message = blocking(context.pool(), move |conn| {
98       PrivateMessage::read_from_apub_id(conn, &ap_id.into())
99     })
100     .await??;
101
102     let deleted_private_message = blocking(context.pool(), move |conn| {
103       PrivateMessage::update_deleted(conn, private_message.id, false)
104     })
105     .await??;
106
107     send_websocket_message(
108       deleted_private_message.id,
109       UserOperationCrud::EditPrivateMessage,
110       context,
111     )
112     .await?;
113
114     Ok(())
115   }
116
117   fn common(&self) -> &ActivityCommonFields {
118     &self.common
119   }
120 }