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