3 comment::send_websocket_message as send_comment_message,
4 community::send_websocket_message as send_community_message,
5 post::send_websocket_message as send_post_message,
8 verify_person_in_community,
11 community::get_or_fetch_and_upsert_community,
12 objects::get_or_fetch_and_insert_post_or_comment,
13 person::get_or_fetch_and_upsert_person,
19 use activitystreams::activity::kind::DeleteType;
20 use lemmy_api_common::blocking;
21 use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandler, PublicUrl};
22 use lemmy_db_queries::{
23 source::{comment::Comment_, community::Community_, post::Post_},
26 use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
27 use lemmy_utils::LemmyError;
28 use lemmy_websocket::{LemmyContext, UserOperationCrud};
31 /// This is very confusing, because there are four distinct cases to handle:
32 /// - user deletes their post
33 /// - user deletes their comment
34 /// - remote community mod deletes local community
35 /// - remote community deletes itself (triggered by a mod)
37 /// TODO: we should probably change how community deletions work to simplify this. Probably by
38 /// wrapping it in an announce just like other activities, instead of having the community send it.
39 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
40 #[serde(rename_all = "camelCase")]
41 pub struct DeletePostCommentOrCommunity {
43 pub(in crate::activities::deletion) object: Url,
45 #[serde(rename = "type")]
48 common: ActivityCommonFields,
51 #[async_trait::async_trait(?Send)]
52 impl ActivityHandler for DeletePostCommentOrCommunity {
55 context: &LemmyContext,
56 request_counter: &mut i32,
57 ) -> Result<(), LemmyError> {
58 verify_activity(self.common())?;
59 let object_community =
60 get_or_fetch_and_upsert_community(&self.object, context, request_counter).await;
61 // deleting a community (set counter 0 to only fetch from local db)
62 if object_community.is_ok() {
63 verify_mod_action(&self.common.actor, self.object.clone(), context).await?;
65 // deleting a post or comment
67 verify_person_in_community(&self.common().actor, &self.cc, context, request_counter).await?;
69 get_post_or_comment_actor_id(&self.object, context, request_counter).await?;
70 verify_urls_match(&self.common.actor, &object_creator)?;
77 context: &LemmyContext,
78 request_counter: &mut i32,
79 ) -> Result<(), LemmyError> {
80 let object_community =
81 get_or_fetch_and_upsert_community(&self.object, context, request_counter).await;
82 // deleting a community
83 if let Ok(community) = object_community {
85 // repeat these checks just to be sure
86 verify_person_in_community(&self.common().actor, &self.cc, context, request_counter)
88 verify_mod_action(&self.common.actor, self.object.clone(), context).await?;
90 get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
91 community.send_delete(mod_, context).await?;
93 let deleted_community = blocking(context.pool(), move |conn| {
94 Community::update_deleted(conn, community.id, true)
98 send_community_message(
100 UserOperationCrud::DeleteCommunity,
105 // deleting a post or comment
107 match get_or_fetch_and_insert_post_or_comment(&self.object, context, request_counter).await? {
108 PostOrComment::Post(post) => {
109 let deleted_post = blocking(context.pool(), move |conn| {
110 Post::update_deleted(conn, post.id, true)
113 send_post_message(deleted_post.id, UserOperationCrud::EditPost, context).await
115 PostOrComment::Comment(comment) => {
116 let deleted_comment = blocking(context.pool(), move |conn| {
117 Comment::update_deleted(conn, comment.id, true)
120 send_comment_message(
123 UserOperationCrud::EditComment,
132 fn common(&self) -> &ActivityCommonFields {
137 async fn get_post_or_comment_actor_id(
139 context: &LemmyContext,
140 request_counter: &mut i32,
141 ) -> Result<Url, LemmyError> {
143 match get_or_fetch_and_insert_post_or_comment(object, context, request_counter).await? {
144 PostOrComment::Post(post) => {
145 let creator_id = post.creator_id;
146 blocking(context.pool(), move |conn| Person::read(conn, creator_id))
150 PostOrComment::Comment(comment) => {
151 let creator_id = comment.creator_id;
152 blocking(context.pool(), move |conn| Person::read(conn, creator_id))