]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/report.rs
Add cargo feature for building lemmy_api_common with mininum deps (#2243)
[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::{comment::CommentReportResponse, post::PostReportResponse, utils::blocking};
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::structs::{CommentReportView, 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]
78       .dereference(context, context.client(), 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, context.client(), request_counter)
93       .await?;
94     match self
95       .object
96       .dereference(context, context.client(), 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 }