]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/report.rs
Don't drop error context when adding a message to errors (#1958)
[lemmy.git] / crates / apub / src / activities / community / report.rs
1 use crate::{
2   activities::{
3     generate_activity_id,
4     send_lemmy_activity,
5     verify_activity,
6     verify_person_in_community,
7   },
8   objects::{community::ApubCommunity, person::ApubPerson},
9   protocol::activities::community::report::Report,
10   PostOrComment,
11 };
12 use activitystreams_kinds::activity::FlagType;
13 use lemmy_api_common::{blocking, comment::CommentReportResponse, post::PostReportResponse};
14 use lemmy_apub_lib::{
15   data::Data,
16   object_id::ObjectId,
17   traits::{ActivityHandler, ActorType},
18 };
19 use lemmy_db_schema::{
20   source::{
21     comment_report::{CommentReport, CommentReportForm},
22     post_report::{PostReport, PostReportForm},
23   },
24   traits::Reportable,
25 };
26 use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::PostReportView};
27 use lemmy_utils::LemmyError;
28 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
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     send_lemmy_activity(
55       context,
56       &report,
57       &id,
58       actor,
59       vec![community.shared_inbox_or_inbox_url()],
60       false,
61     )
62     .await
63   }
64 }
65
66 #[async_trait::async_trait(?Send)]
67 impl ActivityHandler for Report {
68   type DataType = LemmyContext;
69
70   #[tracing::instrument(skip_all)]
71   async fn verify(
72     &self,
73     context: &Data<LemmyContext>,
74     request_counter: &mut i32,
75   ) -> Result<(), LemmyError> {
76     verify_activity(&self.id, self.actor.inner(), &context.settings())?;
77     let community = self.to[0].dereference(context, request_counter).await?;
78     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
79     Ok(())
80   }
81
82   #[tracing::instrument(skip_all)]
83   async fn receive(
84     self,
85     context: &Data<LemmyContext>,
86     request_counter: &mut i32,
87   ) -> Result<(), LemmyError> {
88     let actor = self.actor.dereference(context, request_counter).await?;
89     match self.object.dereference(context, request_counter).await? {
90       PostOrComment::Post(post) => {
91         let report_form = PostReportForm {
92           creator_id: actor.id,
93           post_id: post.id,
94           original_post_name: post.name.clone(),
95           original_post_url: post.url.clone(),
96           reason: self.summary,
97           original_post_body: post.body.clone(),
98         };
99
100         let report = blocking(context.pool(), move |conn| {
101           PostReport::report(conn, &report_form)
102         })
103         .await??;
104
105         let post_report_view = blocking(context.pool(), move |conn| {
106           PostReportView::read(conn, report.id, actor.id)
107         })
108         .await??;
109
110         context.chat_server().do_send(SendModRoomMessage {
111           op: UserOperation::CreateCommentReport,
112           response: PostReportResponse { post_report_view },
113           community_id: post.community_id,
114           websocket_id: None,
115         });
116       }
117       PostOrComment::Comment(comment) => {
118         let report_form = CommentReportForm {
119           creator_id: actor.id,
120           comment_id: comment.id,
121           original_comment_text: comment.content.clone(),
122           reason: self.summary,
123         };
124
125         let report = blocking(context.pool(), move |conn| {
126           CommentReport::report(conn, &report_form)
127         })
128         .await??;
129
130         let comment_report_view = blocking(context.pool(), move |conn| {
131           CommentReportView::read(conn, report.id, actor.id)
132         })
133         .await??;
134         let community_id = comment_report_view.community.id;
135
136         context.chat_server().do_send(SendModRoomMessage {
137           op: UserOperation::CreateCommentReport,
138           response: CommentReportResponse {
139             comment_report_view,
140           },
141           community_id,
142           websocket_id: None,
143         });
144       }
145     };
146     Ok(())
147   }
148 }