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[0], context, request_counter)
70 get_post_or_comment_actor_id(&self.object, context, request_counter).await?;
71 verify_urls_match(&self.common.actor, &object_creator)?;
78 context: &LemmyContext,
79 request_counter: &mut i32,
80 ) -> Result<(), LemmyError> {
81 let object_community =
82 get_or_fetch_and_upsert_community(&self.object, context, request_counter).await;
83 // deleting a community
84 if let Ok(community) = object_community {
86 // repeat these checks just to be sure
87 verify_person_in_community(&self.common().actor, &self.cc[0], context, request_counter)
89 verify_mod_action(&self.common.actor, self.object.clone(), context).await?;
91 get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
92 community.send_delete(mod_, context).await?;
94 let deleted_community = blocking(context.pool(), move |conn| {
95 Community::update_deleted(conn, community.id, true)
99 send_community_message(
100 deleted_community.id,
101 UserOperationCrud::DeleteCommunity,
106 // deleting a post or comment
108 match get_or_fetch_and_insert_post_or_comment(&self.object, context, request_counter).await? {
109 PostOrComment::Post(post) => {
110 let deleted_post = blocking(context.pool(), move |conn| {
111 Post::update_deleted(conn, post.id, true)
114 send_post_message(deleted_post.id, UserOperationCrud::EditPost, context).await
116 PostOrComment::Comment(comment) => {
117 let deleted_comment = blocking(context.pool(), move |conn| {
118 Comment::update_deleted(conn, comment.id, true)
121 send_comment_message(
124 UserOperationCrud::EditComment,
133 fn common(&self) -> &ActivityCommonFields {
138 async fn get_post_or_comment_actor_id(
140 context: &LemmyContext,
141 request_counter: &mut i32,
142 ) -> Result<Url, LemmyError> {
144 match get_or_fetch_and_insert_post_or_comment(object, context, request_counter).await? {
145 PostOrComment::Post(post) => {
146 let creator_id = post.creator_id;
147 blocking(context.pool(), move |conn| Person::read(conn, creator_id))
151 PostOrComment::Comment(comment) => {
152 let creator_id = comment.creator_id;
153 blocking(context.pool(), move |conn| Person::read(conn, creator_id))