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