]> Untitled Git - lemmy.git/blob - server/src/apub/inbox/activities/delete.rs
Merge branch 'main' into federation-authorisation
[lemmy.git] / server / src / apub / inbox / activities / delete.rs
1 use crate::{
2   api::{comment::CommentResponse, community::CommunityResponse, post::PostResponse},
3   apub::{
4     fetcher::{get_or_fetch_and_insert_comment, get_or_fetch_and_insert_post},
5     inbox::shared_inbox::{
6       announce_if_community_is_local,
7       get_user_from_activity,
8       receive_unhandled_activity,
9     },
10     ActorType,
11     FromApub,
12     GroupExt,
13     PageExt,
14   },
15   blocking,
16   routes::ChatServerParam,
17   websocket::{
18     server::{SendComment, SendCommunityRoomMessage, SendPost},
19     UserOperation,
20   },
21   DbPool,
22   LemmyError,
23 };
24 use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*};
25 use actix_web::{client::Client, HttpResponse};
26 use lemmy_db::{
27   comment::{Comment, CommentForm},
28   comment_view::CommentView,
29   community::{Community, CommunityForm},
30   community_view::CommunityView,
31   naive_now,
32   post::{Post, PostForm},
33   post_view::PostView,
34   Crud,
35 };
36
37 pub async fn receive_delete(
38   activity: AnyBase,
39   client: &Client,
40   pool: &DbPool,
41   chat_server: ChatServerParam,
42 ) -> Result<HttpResponse, LemmyError> {
43   let delete = Delete::from_any_base(activity)?.unwrap();
44   match delete.object().as_single_kind_str() {
45     Some("Page") => receive_delete_post(delete, client, pool, chat_server).await,
46     Some("Note") => receive_delete_comment(delete, client, pool, chat_server).await,
47     Some("Group") => receive_delete_community(delete, client, pool, chat_server).await,
48     _ => receive_unhandled_activity(delete),
49   }
50 }
51
52 async fn receive_delete_post(
53   delete: Delete,
54   client: &Client,
55   pool: &DbPool,
56   chat_server: ChatServerParam,
57 ) -> Result<HttpResponse, LemmyError> {
58   let user = get_user_from_activity(&delete, client, pool).await?;
59   let page = PageExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap();
60
61   let post_ap_id = PostForm::from_apub(&page, client, pool, Some(user.actor_id()?))
62     .await?
63     .get_ap_id()?;
64
65   let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
66
67   let post_form = PostForm {
68     name: post.name.to_owned(),
69     url: post.url.to_owned(),
70     body: post.body.to_owned(),
71     creator_id: post.creator_id.to_owned(),
72     community_id: post.community_id,
73     removed: None,
74     deleted: Some(true),
75     nsfw: post.nsfw,
76     locked: None,
77     stickied: None,
78     updated: Some(naive_now()),
79     embed_title: post.embed_title,
80     embed_description: post.embed_description,
81     embed_html: post.embed_html,
82     thumbnail_url: post.thumbnail_url,
83     ap_id: post.ap_id,
84     local: post.local,
85     published: None,
86   };
87   let post_id = post.id;
88   blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??;
89
90   // Refetch the view
91   let post_id = post.id;
92   let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
93
94   let res = PostResponse { post: post_view };
95
96   chat_server.do_send(SendPost {
97     op: UserOperation::EditPost,
98     post: res,
99     my_id: None,
100   });
101
102   announce_if_community_is_local(delete, &user, client, pool).await?;
103   Ok(HttpResponse::Ok().finish())
104 }
105
106 async fn receive_delete_comment(
107   delete: Delete,
108   client: &Client,
109   pool: &DbPool,
110   chat_server: ChatServerParam,
111 ) -> Result<HttpResponse, LemmyError> {
112   let user = get_user_from_activity(&delete, client, pool).await?;
113   let note = Note::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap();
114
115   let comment_ap_id = CommentForm::from_apub(&note, client, pool, Some(user.actor_id()?))
116     .await?
117     .get_ap_id()?;
118
119   let comment = get_or_fetch_and_insert_comment(&comment_ap_id, client, pool).await?;
120
121   let comment_form = CommentForm {
122     content: comment.content.to_owned(),
123     parent_id: comment.parent_id,
124     post_id: comment.post_id,
125     creator_id: comment.creator_id,
126     removed: None,
127     deleted: Some(true),
128     read: None,
129     published: None,
130     updated: Some(naive_now()),
131     ap_id: comment.ap_id,
132     local: comment.local,
133   };
134   let comment_id = comment.id;
135   blocking(pool, move |conn| {
136     Comment::update(conn, comment_id, &comment_form)
137   })
138   .await??;
139
140   // Refetch the view
141   let comment_id = comment.id;
142   let comment_view =
143     blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
144
145   // TODO get those recipient actor ids from somewhere
146   let recipient_ids = vec![];
147   let res = CommentResponse {
148     comment: comment_view,
149     recipient_ids,
150     form_id: None,
151   };
152
153   chat_server.do_send(SendComment {
154     op: UserOperation::EditComment,
155     comment: res,
156     my_id: None,
157   });
158
159   announce_if_community_is_local(delete, &user, client, pool).await?;
160   Ok(HttpResponse::Ok().finish())
161 }
162
163 async fn receive_delete_community(
164   delete: Delete,
165   client: &Client,
166   pool: &DbPool,
167   chat_server: ChatServerParam,
168 ) -> Result<HttpResponse, LemmyError> {
169   let group = GroupExt::from_any_base(delete.object().to_owned().one().unwrap())?.unwrap();
170   let user = get_user_from_activity(&delete, client, pool).await?;
171
172   let community_actor_id = CommunityForm::from_apub(&group, client, pool, Some(user.actor_id()?))
173     .await?
174     .actor_id;
175
176   let community = blocking(pool, move |conn| {
177     Community::read_from_actor_id(conn, &community_actor_id)
178   })
179   .await??;
180
181   let community_form = CommunityForm {
182     name: community.name.to_owned(),
183     title: community.title.to_owned(),
184     description: community.description.to_owned(),
185     category_id: community.category_id, // Note: need to keep this due to foreign key constraint
186     creator_id: community.creator_id,   // Note: need to keep this due to foreign key constraint
187     removed: None,
188     published: None,
189     updated: Some(naive_now()),
190     deleted: Some(true),
191     nsfw: community.nsfw,
192     actor_id: community.actor_id,
193     local: community.local,
194     private_key: community.private_key,
195     public_key: community.public_key,
196     last_refreshed_at: None,
197     icon: Some(community.icon.to_owned()),
198     banner: Some(community.banner.to_owned()),
199   };
200
201   let community_id = community.id;
202   blocking(pool, move |conn| {
203     Community::update(conn, community_id, &community_form)
204   })
205   .await??;
206
207   let community_id = community.id;
208   let res = CommunityResponse {
209     community: blocking(pool, move |conn| {
210       CommunityView::read(conn, community_id, None)
211     })
212     .await??,
213   };
214
215   let community_id = res.community.id;
216
217   chat_server.do_send(SendCommunityRoomMessage {
218     op: UserOperation::EditCommunity,
219     response: res,
220     community_id,
221     my_id: None,
222   });
223
224   announce_if_community_is_local(delete, &user, client, pool).await?;
225   Ok(HttpResponse::Ok().finish())
226 }