]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/report.rs
Make verify apub url function async (#2514)
[lemmy.git] / crates / apub / src / activities / community / report.rs
1 use crate::{
2   activities::{generate_activity_id, send_lemmy_activity, verify_person_in_community},
3   local_instance,
4   objects::{community::ApubCommunity, person::ApubPerson},
5   protocol::activities::community::report::Report,
6   ActorType,
7   PostOrComment,
8 };
9 use activitypub_federation::{
10   core::object_id::ObjectId,
11   data::Data,
12   traits::{ActivityHandler, Actor},
13 };
14 use activitystreams_kinds::activity::FlagType;
15 use lemmy_api_common::{comment::CommentReportResponse, post::PostReportResponse, utils::blocking};
16 use lemmy_db_schema::{
17   source::{
18     comment_report::{CommentReport, CommentReportForm},
19     post_report::{PostReport, PostReportForm},
20   },
21   traits::Reportable,
22 };
23 use lemmy_db_views::structs::{CommentReportView, PostReportView};
24 use lemmy_utils::error::LemmyError;
25 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
26 use url::Url;
27
28 impl Report {
29   #[tracing::instrument(skip_all)]
30   pub async fn send(
31     object_id: ObjectId<PostOrComment>,
32     actor: &ApubPerson,
33     community_id: ObjectId<ApubCommunity>,
34     reason: String,
35     context: &LemmyContext,
36   ) -> Result<(), LemmyError> {
37     let community = community_id.dereference_local(context).await?;
38     let kind = FlagType::Flag;
39     let id = generate_activity_id(
40       kind.clone(),
41       &context.settings().get_protocol_and_hostname(),
42     )?;
43     let report = Report {
44       actor: ObjectId::new(actor.actor_id()),
45       to: [ObjectId::new(community.actor_id())],
46       object: object_id,
47       summary: reason,
48       kind,
49       id: id.clone(),
50       unparsed: Default::default(),
51     };
52
53     let inbox = vec![community.shared_inbox_or_inbox()];
54     send_lemmy_activity(context, report, actor, inbox, false).await
55   }
56 }
57
58 #[async_trait::async_trait(?Send)]
59 impl ActivityHandler for Report {
60   type DataType = LemmyContext;
61   type Error = LemmyError;
62
63   fn id(&self) -> &Url {
64     &self.id
65   }
66
67   fn actor(&self) -> &Url {
68     self.actor.inner()
69   }
70
71   #[tracing::instrument(skip_all)]
72   async fn verify(
73     &self,
74     context: &Data<LemmyContext>,
75     request_counter: &mut i32,
76   ) -> Result<(), LemmyError> {
77     let community = self.to[0]
78       .dereference(context, local_instance(context), request_counter)
79       .await?;
80     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
81     Ok(())
82   }
83
84   #[tracing::instrument(skip_all)]
85   async fn receive(
86     self,
87     context: &Data<LemmyContext>,
88     request_counter: &mut i32,
89   ) -> Result<(), LemmyError> {
90     let actor = self
91       .actor
92       .dereference(context, local_instance(context), request_counter)
93       .await?;
94     match self
95       .object
96       .dereference(context, local_instance(context), request_counter)
97       .await?
98     {
99       PostOrComment::Post(post) => {
100         let report_form = PostReportForm {
101           creator_id: actor.id,
102           post_id: post.id,
103           original_post_name: post.name.clone(),
104           original_post_url: post.url.clone(),
105           reason: self.summary,
106           original_post_body: post.body.clone(),
107         };
108
109         let report = blocking(context.pool(), move |conn| {
110           PostReport::report(conn, &report_form)
111         })
112         .await??;
113
114         let post_report_view = blocking(context.pool(), move |conn| {
115           PostReportView::read(conn, report.id, actor.id)
116         })
117         .await??;
118
119         context.chat_server().do_send(SendModRoomMessage {
120           op: UserOperation::CreateCommentReport,
121           response: PostReportResponse { post_report_view },
122           community_id: post.community_id,
123           websocket_id: None,
124         });
125       }
126       PostOrComment::Comment(comment) => {
127         let report_form = CommentReportForm {
128           creator_id: actor.id,
129           comment_id: comment.id,
130           original_comment_text: comment.content.clone(),
131           reason: self.summary,
132         };
133
134         let report = blocking(context.pool(), move |conn| {
135           CommentReport::report(conn, &report_form)
136         })
137         .await??;
138
139         let comment_report_view = blocking(context.pool(), move |conn| {
140           CommentReportView::read(conn, report.id, actor.id)
141         })
142         .await??;
143         let community_id = comment_report_view.community.id;
144
145         context.chat_server().do_send(SendModRoomMessage {
146           op: UserOperation::CreateCommentReport,
147           response: CommentReportResponse {
148             comment_report_view,
149           },
150           community_id,
151           websocket_id: None,
152         });
153       }
154     };
155     Ok(())
156   }
157 }