]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/report.rs
When announcing incoming activities, keep extra fields (#2550)
[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};
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     };
51
52     let inbox = vec![community.shared_inbox_or_inbox()];
53     send_lemmy_activity(context, report, actor, inbox, false).await
54   }
55 }
56
57 #[async_trait::async_trait(?Send)]
58 impl ActivityHandler for Report {
59   type DataType = LemmyContext;
60   type Error = LemmyError;
61
62   fn id(&self) -> &Url {
63     &self.id
64   }
65
66   fn actor(&self) -> &Url {
67     self.actor.inner()
68   }
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     let community = self.to[0]
77       .dereference(context, local_instance(context).await, request_counter)
78       .await?;
79     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
80     Ok(())
81   }
82
83   #[tracing::instrument(skip_all)]
84   async fn receive(
85     self,
86     context: &Data<LemmyContext>,
87     request_counter: &mut i32,
88   ) -> Result<(), LemmyError> {
89     let actor = self
90       .actor
91       .dereference(context, local_instance(context).await, request_counter)
92       .await?;
93     match self
94       .object
95       .dereference(context, local_instance(context).await, request_counter)
96       .await?
97     {
98       PostOrComment::Post(post) => {
99         let report_form = PostReportForm {
100           creator_id: actor.id,
101           post_id: post.id,
102           original_post_name: post.name.clone(),
103           original_post_url: post.url.clone(),
104           reason: self.summary,
105           original_post_body: post.body.clone(),
106         };
107
108         let report = PostReport::report(context.pool(), &report_form).await?;
109
110         let post_report_view = PostReportView::read(context.pool(), report.id, actor.id).await?;
111
112         context.chat_server().do_send(SendModRoomMessage {
113           op: UserOperation::CreateCommentReport,
114           response: PostReportResponse { post_report_view },
115           community_id: post.community_id,
116           websocket_id: None,
117         });
118       }
119       PostOrComment::Comment(comment) => {
120         let report_form = CommentReportForm {
121           creator_id: actor.id,
122           comment_id: comment.id,
123           original_comment_text: comment.content.clone(),
124           reason: self.summary,
125         };
126
127         let report = CommentReport::report(context.pool(), &report_form).await?;
128
129         let comment_report_view =
130           CommentReportView::read(context.pool(), report.id, actor.id).await?;
131         let community_id = comment_report_view.community.id;
132
133         context.chat_server().do_send(SendModRoomMessage {
134           op: UserOperation::CreateCommentReport,
135           response: CommentReportResponse {
136             comment_report_view,
137           },
138           community_id,
139           websocket_id: None,
140         });
141       }
142     };
143     Ok(())
144   }
145 }