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