use crate::{ activities::{generate_activity_id, send_lemmy_activity, verify_person_in_community}, insert_activity, objects::{community::ApubCommunity, person::ApubPerson}, protocol::{activities::community::report::Report, InCommunity}, PostOrComment, SendActivity, }; use activitypub_federation::{ config::Data, fetch::object_id::ObjectId, kinds::activity::FlagType, traits::{ActivityHandler, Actor}, }; use lemmy_api_common::{ comment::{CommentReportResponse, CreateCommentReport}, context::LemmyContext, post::{CreatePostReport, PostReportResponse}, utils::get_local_user_view_from_jwt, websocket::UserOperation, }; use lemmy_db_schema::{ source::{ comment_report::{CommentReport, CommentReportForm}, post_report::{PostReport, PostReportForm}, }, traits::Reportable, }; use lemmy_db_views::structs::{CommentReportView, PostReportView}; use lemmy_utils::error::LemmyError; use url::Url; #[async_trait::async_trait] impl SendActivity for CreatePostReport { type Response = PostReportResponse; async fn send_activity( request: &Self, response: &Self::Response, context: &Data, ) -> Result<(), LemmyError> { let local_user_view = get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; Report::send( ObjectId::from(response.post_report_view.post.ap_id.clone()), &local_user_view.person.into(), ObjectId::from(response.post_report_view.community.actor_id.clone()), request.reason.to_string(), context, ) .await } } #[async_trait::async_trait] impl SendActivity for CreateCommentReport { type Response = CommentReportResponse; async fn send_activity( request: &Self, response: &Self::Response, context: &Data, ) -> Result<(), LemmyError> { let local_user_view = get_local_user_view_from_jwt(&request.auth, context.pool(), context.secret()).await?; Report::send( ObjectId::from(response.comment_report_view.comment.ap_id.clone()), &local_user_view.person.into(), ObjectId::from(response.comment_report_view.community.actor_id.clone()), request.reason.to_string(), context, ) .await } } impl Report { #[tracing::instrument(skip_all)] async fn send( object_id: ObjectId, actor: &ApubPerson, community_id: ObjectId, reason: String, context: &Data, ) -> Result<(), LemmyError> { let community = community_id.dereference_local(context).await?; let kind = FlagType::Flag; let id = generate_activity_id( kind.clone(), &context.settings().get_protocol_and_hostname(), )?; let report = Report { actor: actor.id().into(), to: [community.id().into()], object: object_id, summary: reason, kind, id: id.clone(), audience: Some(community.id().into()), }; let inbox = vec![community.shared_inbox_or_inbox()]; send_lemmy_activity(context, report, actor, inbox, false).await } } #[async_trait::async_trait] impl ActivityHandler for Report { type DataType = LemmyContext; type Error = LemmyError; fn id(&self) -> &Url { &self.id } fn actor(&self) -> &Url { self.actor.inner() } #[tracing::instrument(skip_all)] async fn verify(&self, context: &Data) -> Result<(), LemmyError> { let community = self.community(context).await?; verify_person_in_community(&self.actor, &community, context).await?; Ok(()) } #[tracing::instrument(skip_all)] async fn receive(self, context: &Data) -> Result<(), LemmyError> { insert_activity(&self.id, &self, false, true, context).await?; let actor = self.actor.dereference(context).await?; match self.object.dereference(context).await? { PostOrComment::Post(post) => { let report_form = PostReportForm { creator_id: actor.id, post_id: post.id, original_post_name: post.name.clone(), original_post_url: post.url.clone(), reason: self.summary, original_post_body: post.body.clone(), }; let report = PostReport::report(context.pool(), &report_form).await?; let post_report_view = PostReportView::read(context.pool(), report.id, actor.id).await?; context.send_mod_ws_message( &UserOperation::CreateCommentReport, &PostReportResponse { post_report_view }, post.community_id, None, )?; } PostOrComment::Comment(comment) => { let report_form = CommentReportForm { creator_id: actor.id, comment_id: comment.id, original_comment_text: comment.content.clone(), reason: self.summary, }; let report = CommentReport::report(context.pool(), &report_form).await?; let comment_report_view = CommentReportView::read(context.pool(), report.id, actor.id).await?; let community_id = comment_report_view.community.id; context.send_mod_ws_message( &UserOperation::CreateCommentReport, &CommentReportResponse { comment_report_view, }, community_id, None, )?; } }; Ok(()) } }