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