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