]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/private_message/undo_delete.rs
Don't drop error context when adding a message to errors (#1958)
[lemmy.git] / crates / apub / src / activities / private_message / undo_delete.rs
1 use crate::{
2   activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_person},
3   objects::{person::ApubPerson, private_message::ApubPrivateMessage},
4   protocol::activities::private_message::{
5     delete::DeletePrivateMessage,
6     undo_delete::UndoDeletePrivateMessage,
7   },
8 };
9 use activitystreams_kinds::activity::UndoType;
10 use lemmy_api_common::blocking;
11 use lemmy_apub_lib::{
12   data::Data,
13   object_id::ObjectId,
14   traits::{ActivityHandler, ActorType},
15   verify::{verify_domains_match, verify_urls_match},
16 };
17 use lemmy_db_schema::{
18   source::{person::Person, private_message::PrivateMessage},
19   traits::Crud,
20 };
21 use lemmy_utils::LemmyError;
22 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
23
24 impl UndoDeletePrivateMessage {
25   #[tracing::instrument(skip_all)]
26   pub async fn send(
27     actor: &ApubPerson,
28     pm: &ApubPrivateMessage,
29     context: &LemmyContext,
30   ) -> Result<(), LemmyError> {
31     let recipient_id = pm.recipient_id;
32     let recipient: ApubPerson =
33       blocking(context.pool(), move |conn| Person::read(conn, recipient_id))
34         .await??
35         .into();
36
37     let object = DeletePrivateMessage::new(actor, pm, context)?;
38     let id = generate_activity_id(
39       UndoType::Undo,
40       &context.settings().get_protocol_and_hostname(),
41     )?;
42     let undo = UndoDeletePrivateMessage {
43       actor: ObjectId::new(actor.actor_id()),
44       to: [ObjectId::new(recipient.actor_id())],
45       object,
46       kind: UndoType::Undo,
47       id: id.clone(),
48       unparsed: Default::default(),
49     };
50     let inbox = vec![recipient.shared_inbox_or_inbox_url()];
51     send_lemmy_activity(context, &undo, &id, actor, inbox, true).await
52   }
53 }
54
55 #[async_trait::async_trait(?Send)]
56 impl ActivityHandler for UndoDeletePrivateMessage {
57   type DataType = LemmyContext;
58
59   #[tracing::instrument(skip_all)]
60   async fn verify(
61     &self,
62     context: &Data<LemmyContext>,
63     request_counter: &mut i32,
64   ) -> Result<(), LemmyError> {
65     verify_activity(&self.id, self.actor.inner(), &context.settings())?;
66     verify_person(&self.actor, context, request_counter).await?;
67     verify_urls_match(self.actor.inner(), self.object.actor.inner())?;
68     verify_domains_match(self.actor.inner(), self.object.object.inner())?;
69     self.object.verify(context, request_counter).await?;
70     Ok(())
71   }
72
73   #[tracing::instrument(skip_all)]
74   async fn receive(
75     self,
76     context: &Data<LemmyContext>,
77     _request_counter: &mut i32,
78   ) -> Result<(), LemmyError> {
79     let ap_id = self.object.object.clone();
80     let private_message = ap_id.dereference_local(context).await?;
81
82     let deleted_private_message = blocking(context.pool(), move |conn| {
83       PrivateMessage::update_deleted(conn, private_message.id, false)
84     })
85     .await??;
86
87     send_pm_ws_message(
88       deleted_private_message.id,
89       UserOperationCrud::EditPrivateMessage,
90       None,
91       context,
92     )
93     .await?;
94
95     Ok(())
96   }
97 }