]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/report.rs
Rework websocket (#2598)
[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, InCommunity},
6   ActorType,
7   PostOrComment,
8   SendActivity,
9 };
10 use activitypub_federation::{
11   core::object_id::ObjectId,
12   data::Data,
13   traits::{ActivityHandler, Actor},
14 };
15 use activitystreams_kinds::activity::FlagType;
16 use lemmy_api_common::{
17   comment::{CommentReportResponse, CreateCommentReport},
18   context::LemmyContext,
19   post::{CreatePostReport, PostReportResponse},
20   utils::get_local_user_view_from_jwt,
21   websocket::UserOperation,
22 };
23 use lemmy_db_schema::{
24   source::{
25     comment_report::{CommentReport, CommentReportForm},
26     post_report::{PostReport, PostReportForm},
27   },
28   traits::Reportable,
29 };
30 use lemmy_db_views::structs::{CommentReportView, PostReportView};
31 use lemmy_utils::error::LemmyError;
32 use url::Url;
33
34 #[async_trait::async_trait(?Send)]
35 impl SendActivity for CreatePostReport {
36   type Response = PostReportResponse;
37
38   async fn send_activity(
39     request: &Self,
40     response: &Self::Response,
41     context: &LemmyContext,
42   ) -> Result<(), LemmyError> {
43     let local_user_view =
44       get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?;
45     Report::send(
46       ObjectId::new(response.post_report_view.post.ap_id.clone()),
47       &local_user_view.person.into(),
48       ObjectId::new(response.post_report_view.community.actor_id.clone()),
49       request.reason.to_string(),
50       context,
51     )
52     .await
53   }
54 }
55
56 #[async_trait::async_trait(?Send)]
57 impl SendActivity for CreateCommentReport {
58   type Response = CommentReportResponse;
59
60   async fn send_activity(
61     request: &Self,
62     response: &Self::Response,
63     context: &LemmyContext,
64   ) -> Result<(), LemmyError> {
65     let local_user_view =
66       get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?;
67     Report::send(
68       ObjectId::new(response.comment_report_view.comment.ap_id.clone()),
69       &local_user_view.person.into(),
70       ObjectId::new(response.comment_report_view.community.actor_id.clone()),
71       request.reason.to_string(),
72       context,
73     )
74     .await
75   }
76 }
77
78 impl Report {
79   #[tracing::instrument(skip_all)]
80   async fn send(
81     object_id: ObjectId<PostOrComment>,
82     actor: &ApubPerson,
83     community_id: ObjectId<ApubCommunity>,
84     reason: String,
85     context: &LemmyContext,
86   ) -> Result<(), LemmyError> {
87     let community = community_id.dereference_local(context).await?;
88     let kind = FlagType::Flag;
89     let id = generate_activity_id(
90       kind.clone(),
91       &context.settings().get_protocol_and_hostname(),
92     )?;
93     let report = Report {
94       actor: ObjectId::new(actor.actor_id()),
95       to: [ObjectId::new(community.actor_id())],
96       object: object_id,
97       summary: reason,
98       kind,
99       id: id.clone(),
100       audience: Some(ObjectId::new(community.actor_id())),
101     };
102
103     let inbox = vec![community.shared_inbox_or_inbox()];
104     send_lemmy_activity(context, report, actor, inbox, false).await
105   }
106 }
107
108 #[async_trait::async_trait(?Send)]
109 impl ActivityHandler for Report {
110   type DataType = LemmyContext;
111   type Error = LemmyError;
112
113   fn id(&self) -> &Url {
114     &self.id
115   }
116
117   fn actor(&self) -> &Url {
118     self.actor.inner()
119   }
120
121   #[tracing::instrument(skip_all)]
122   async fn verify(
123     &self,
124     context: &Data<LemmyContext>,
125     request_counter: &mut i32,
126   ) -> Result<(), LemmyError> {
127     let community = self.community(context, request_counter).await?;
128     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
129     Ok(())
130   }
131
132   #[tracing::instrument(skip_all)]
133   async fn receive(
134     self,
135     context: &Data<LemmyContext>,
136     request_counter: &mut i32,
137   ) -> Result<(), LemmyError> {
138     let actor = self
139       .actor
140       .dereference(context, local_instance(context).await, request_counter)
141       .await?;
142     match self
143       .object
144       .dereference(context, local_instance(context).await, request_counter)
145       .await?
146     {
147       PostOrComment::Post(post) => {
148         let report_form = PostReportForm {
149           creator_id: actor.id,
150           post_id: post.id,
151           original_post_name: post.name.clone(),
152           original_post_url: post.url.clone(),
153           reason: self.summary,
154           original_post_body: post.body.clone(),
155         };
156
157         let report = PostReport::report(context.pool(), &report_form).await?;
158
159         let post_report_view = PostReportView::read(context.pool(), report.id, actor.id).await?;
160
161         context
162           .chat_server()
163           .send_mod_room_message(
164             UserOperation::CreateCommentReport,
165             &PostReportResponse { post_report_view },
166             post.community_id,
167             None,
168           )
169           .await?;
170       }
171       PostOrComment::Comment(comment) => {
172         let report_form = CommentReportForm {
173           creator_id: actor.id,
174           comment_id: comment.id,
175           original_comment_text: comment.content.clone(),
176           reason: self.summary,
177         };
178
179         let report = CommentReport::report(context.pool(), &report_form).await?;
180
181         let comment_report_view =
182           CommentReportView::read(context.pool(), report.id, actor.id).await?;
183         let community_id = comment_report_view.community.id;
184
185         context
186           .chat_server()
187           .send_mod_room_message(
188             UserOperation::CreateCommentReport,
189             &CommentReportResponse {
190               comment_report_view,
191             },
192             community_id,
193             None,
194           )
195           .await?;
196       }
197     };
198     Ok(())
199   }
200 }