]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/deletion/delete_user.rs
Federate user account deletion (fixes #1284) (#2199)
[lemmy.git] / crates / apub / src / activities / deletion / delete_user.rs
1 use crate::{
2   activities::{generate_activity_id, send_lemmy_activity, verify_is_public, verify_person},
3   objects::person::ApubPerson,
4   protocol::activities::deletion::delete_user::DeleteUser,
5 };
6 use activitystreams_kinds::{activity::DeleteType, public};
7 use lemmy_api_common::{blocking, delete_user_account};
8 use lemmy_apub_lib::{
9   data::Data,
10   object_id::ObjectId,
11   traits::ActivityHandler,
12   verify::verify_urls_match,
13 };
14 use lemmy_db_schema::source::site::Site;
15 use lemmy_utils::LemmyError;
16 use lemmy_websocket::LemmyContext;
17
18 /// This can be separate from Delete activity because it doesn't need to be handled in shared inbox
19 /// (cause instance actor doesn't have shared inbox).
20 #[async_trait::async_trait(?Send)]
21 impl ActivityHandler for DeleteUser {
22   type DataType = LemmyContext;
23
24   async fn verify(
25     &self,
26     context: &Data<LemmyContext>,
27     request_counter: &mut i32,
28   ) -> Result<(), LemmyError> {
29     verify_is_public(&self.to, &[])?;
30     verify_person(&self.actor, context, request_counter).await?;
31     verify_urls_match(self.actor.inner(), self.object.inner())?;
32     Ok(())
33   }
34
35   async fn receive(
36     self,
37     context: &Data<LemmyContext>,
38     request_counter: &mut i32,
39   ) -> Result<(), LemmyError> {
40     let actor = self
41       .actor
42       .dereference(context, context.client(), request_counter)
43       .await?;
44     delete_user_account(actor.id, context.pool()).await?;
45     Ok(())
46   }
47 }
48
49 impl DeleteUser {
50   #[tracing::instrument(skip_all)]
51   pub async fn send(actor: &ApubPerson, context: &LemmyContext) -> Result<(), LemmyError> {
52     let actor_id = ObjectId::new(actor.actor_id.clone());
53     let id = generate_activity_id(
54       DeleteType::Delete,
55       &context.settings().get_protocol_and_hostname(),
56     )?;
57     let delete = DeleteUser {
58       actor: actor_id.clone(),
59       to: vec![public()],
60       object: actor_id,
61       kind: DeleteType::Delete,
62       id: id.clone(),
63       cc: vec![],
64     };
65
66     let remote_sites = blocking(context.pool(), Site::read_remote_sites).await??;
67     let inboxes = remote_sites
68       .into_iter()
69       .map(|s| s.inbox_url.into())
70       .collect();
71     send_lemmy_activity(context, &delete, &id, actor, inboxes, true).await?;
72     Ok(())
73   }
74 }