]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/report.rs
Merge pull request #1874 from LemmyNet/protocol-testing
[lemmy.git] / crates / apub / src / activities / community / report.rs
1 use activitystreams::activity::kind::FlagType;
2
3 use lemmy_api_common::{blocking, comment::CommentReportResponse, post::PostReportResponse};
4 use lemmy_apub_lib::{
5   data::Data,
6   traits::{ActivityHandler, ActorType},
7 };
8 use lemmy_db_schema::{
9   source::{
10     comment_report::{CommentReport, CommentReportForm},
11     post_report::{PostReport, PostReportForm},
12   },
13   traits::Reportable,
14 };
15 use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::PostReportView};
16 use lemmy_utils::LemmyError;
17 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
18
19 use crate::{
20   activities::{
21     generate_activity_id,
22     send_lemmy_activity,
23     verify_activity,
24     verify_person_in_community,
25   },
26   fetcher::object_id::ObjectId,
27   objects::{community::ApubCommunity, person::ApubPerson},
28   protocol::activities::community::report::Report,
29   PostOrComment,
30 };
31
32 impl Report {
33   pub async fn send(
34     object_id: ObjectId<PostOrComment>,
35     actor: &ApubPerson,
36     community_id: ObjectId<ApubCommunity>,
37     reason: String,
38     context: &LemmyContext,
39   ) -> Result<(), LemmyError> {
40     let community = community_id.dereference_local(context).await?;
41     let kind = FlagType::Flag;
42     let id = generate_activity_id(
43       kind.clone(),
44       &context.settings().get_protocol_and_hostname(),
45     )?;
46     let report = Report {
47       actor: ObjectId::new(actor.actor_id()),
48       to: [ObjectId::new(community.actor_id())],
49       object: object_id,
50       summary: reason,
51       kind,
52       id: id.clone(),
53       unparsed: Default::default(),
54     };
55     send_lemmy_activity(
56       context,
57       &report,
58       &id,
59       actor,
60       vec![community.shared_inbox_or_inbox_url()],
61       false,
62     )
63     .await
64   }
65 }
66
67 #[async_trait::async_trait(?Send)]
68 impl ActivityHandler for Report {
69   type DataType = LemmyContext;
70   async fn verify(
71     &self,
72     context: &Data<LemmyContext>,
73     request_counter: &mut i32,
74   ) -> Result<(), LemmyError> {
75     verify_activity(self, &context.settings())?;
76     let community = self.to[0].dereference(context, request_counter).await?;
77     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
78     Ok(())
79   }
80
81   async fn receive(
82     self,
83     context: &Data<LemmyContext>,
84     request_counter: &mut i32,
85   ) -> Result<(), LemmyError> {
86     let actor = self.actor.dereference(context, request_counter).await?;
87     match self.object.dereference(context, request_counter).await? {
88       PostOrComment::Post(post) => {
89         let report_form = PostReportForm {
90           creator_id: actor.id,
91           post_id: post.id,
92           original_post_name: post.name.clone(),
93           original_post_url: post.url.clone(),
94           reason: self.summary,
95           original_post_body: post.body.clone(),
96         };
97
98         let report = blocking(context.pool(), move |conn| {
99           PostReport::report(conn, &report_form)
100         })
101         .await??;
102
103         let post_report_view = blocking(context.pool(), move |conn| {
104           PostReportView::read(conn, report.id, actor.id)
105         })
106         .await??;
107
108         context.chat_server().do_send(SendModRoomMessage {
109           op: UserOperation::CreateCommentReport,
110           response: PostReportResponse { post_report_view },
111           community_id: post.community_id,
112           websocket_id: None,
113         });
114       }
115       PostOrComment::Comment(comment) => {
116         let report_form = CommentReportForm {
117           creator_id: actor.id,
118           comment_id: comment.id,
119           original_comment_text: comment.content.clone(),
120           reason: self.summary,
121         };
122
123         let report = blocking(context.pool(), move |conn| {
124           CommentReport::report(conn, &report_form)
125         })
126         .await??;
127
128         let comment_report_view = blocking(context.pool(), move |conn| {
129           CommentReportView::read(conn, report.id, actor.id)
130         })
131         .await??;
132         let community_id = comment_report_view.community.id;
133
134         context.chat_server().do_send(SendModRoomMessage {
135           op: UserOperation::CreateCommentReport,
136           response: CommentReportResponse {
137             comment_report_view,
138           },
139           community_id,
140           websocket_id: None,
141         });
142       }
143     };
144     Ok(())
145   }
146 }