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