2 use actix_web::web::Data;
3 use lemmy_api_common::{
6 get_local_user_view_from_jwt,
11 ListPostReportsResponse,
16 use lemmy_apub::protocol::activities::community::report::Report;
17 use lemmy_apub_lib::object_id::ObjectId;
18 use lemmy_db_schema::{
19 source::post_report::{PostReport, PostReportForm},
23 post_report_view::{PostReportQueryBuilder, PostReportView},
26 use lemmy_utils::{ConnectionId, LemmyError};
27 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
29 /// Creates a post report and notifies the moderators of the community
30 #[async_trait::async_trait(?Send)]
31 impl Perform for CreatePostReport {
32 type Response = PostReportResponse;
34 #[tracing::instrument(skip(context, websocket_id))]
37 context: &Data<LemmyContext>,
38 websocket_id: Option<ConnectionId>,
39 ) -> Result<PostReportResponse, LemmyError> {
40 let data: &CreatePostReport = self;
42 get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
44 // check size of report and check for whitespace
45 let reason = data.reason.trim();
46 if reason.is_empty() {
47 return Err(LemmyError::from_message("report_reason_required"));
49 if reason.chars().count() > 1000 {
50 return Err(LemmyError::from_message("report_too_long"));
53 let person_id = local_user_view.person.id;
54 let post_id = data.post_id;
55 let post_view = blocking(context.pool(), move |conn| {
56 PostView::read(conn, post_id, None)
60 check_community_ban(person_id, post_view.community.id, context.pool()).await?;
62 let report_form = PostReportForm {
63 creator_id: person_id,
65 original_post_name: post_view.post.name,
66 original_post_url: post_view.post.url,
67 original_post_body: post_view.post.body,
68 reason: data.reason.to_owned(),
71 let report = blocking(context.pool(), move |conn| {
72 PostReport::report(conn, &report_form)
75 .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_report"))?;
77 let post_report_view = blocking(context.pool(), move |conn| {
78 PostReportView::read(conn, report.id, person_id)
82 let res = PostReportResponse { post_report_view };
84 context.chat_server().do_send(SendModRoomMessage {
85 op: UserOperation::CreatePostReport,
86 response: res.clone(),
87 community_id: post_view.community.id,
92 ObjectId::new(post_view.post.ap_id),
93 &local_user_view.person.into(),
94 ObjectId::new(post_view.community.actor_id),
104 /// Resolves or unresolves a post report and notifies the moderators of the community
105 #[async_trait::async_trait(?Send)]
106 impl Perform for ResolvePostReport {
107 type Response = PostReportResponse;
109 #[tracing::instrument(skip(context, websocket_id))]
112 context: &Data<LemmyContext>,
113 websocket_id: Option<ConnectionId>,
114 ) -> Result<PostReportResponse, LemmyError> {
115 let data: &ResolvePostReport = self;
116 let local_user_view =
117 get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
119 let report_id = data.report_id;
120 let person_id = local_user_view.person.id;
121 let report = blocking(context.pool(), move |conn| {
122 PostReportView::read(conn, report_id, person_id)
126 let person_id = local_user_view.person.id;
127 is_mod_or_admin(context.pool(), person_id, report.community.id).await?;
129 let resolved = data.resolved;
130 let resolve_fun = move |conn: &'_ _| {
132 PostReport::resolve(conn, report_id, person_id)
134 PostReport::unresolve(conn, report_id, person_id)
138 blocking(context.pool(), resolve_fun)
140 .map_err(|e| LemmyError::from_error_message(e, "couldnt_resolve_report"))?;
142 let post_report_view = blocking(context.pool(), move |conn| {
143 PostReportView::read(conn, report_id, person_id)
147 let res = PostReportResponse { post_report_view };
149 context.chat_server().do_send(SendModRoomMessage {
150 op: UserOperation::ResolvePostReport,
151 response: res.clone(),
152 community_id: report.community.id,
160 /// Lists post reports for a community if an id is supplied
161 /// or returns all post reports for communities a user moderates
162 #[async_trait::async_trait(?Send)]
163 impl Perform for ListPostReports {
164 type Response = ListPostReportsResponse;
166 #[tracing::instrument(skip(context, _websocket_id))]
169 context: &Data<LemmyContext>,
170 _websocket_id: Option<ConnectionId>,
171 ) -> Result<ListPostReportsResponse, LemmyError> {
172 let data: &ListPostReports = self;
173 let local_user_view =
174 get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
176 let person_id = local_user_view.person.id;
177 let admin = local_user_view.person.admin;
178 let community_id = data.community_id;
179 let unresolved_only = data.unresolved_only;
181 let page = data.page;
182 let limit = data.limit;
183 let post_reports = blocking(context.pool(), move |conn| {
184 PostReportQueryBuilder::create(conn, person_id, admin)
185 .community_id(community_id)
186 .unresolved_only(unresolved_only)
193 let res = ListPostReportsResponse { post_reports };