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