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(LemmyError::from)
76 .map_err(|e| e.with_message("couldnt_create_report"))?;
78 let post_report_view = blocking(context.pool(), move |conn| {
79 PostReportView::read(conn, report.id, person_id)
83 let res = PostReportResponse { post_report_view };
85 context.chat_server().do_send(SendModRoomMessage {
86 op: UserOperation::CreatePostReport,
87 response: res.clone(),
88 community_id: post_view.community.id,
93 ObjectId::new(post_view.post.ap_id),
94 &local_user_view.person.into(),
95 ObjectId::new(post_view.community.actor_id),
105 /// Resolves or unresolves a post report and notifies the moderators of the community
106 #[async_trait::async_trait(?Send)]
107 impl Perform for ResolvePostReport {
108 type Response = PostReportResponse;
110 #[tracing::instrument(skip(context, websocket_id))]
113 context: &Data<LemmyContext>,
114 websocket_id: Option<ConnectionId>,
115 ) -> Result<PostReportResponse, LemmyError> {
116 let data: &ResolvePostReport = self;
117 let local_user_view =
118 get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
120 let report_id = data.report_id;
121 let person_id = local_user_view.person.id;
122 let report = blocking(context.pool(), move |conn| {
123 PostReportView::read(conn, report_id, person_id)
127 let person_id = local_user_view.person.id;
128 is_mod_or_admin(context.pool(), person_id, report.community.id).await?;
130 let resolved = data.resolved;
131 let resolve_fun = move |conn: &'_ _| {
133 PostReport::resolve(conn, report_id, person_id)
135 PostReport::unresolve(conn, report_id, person_id)
139 blocking(context.pool(), resolve_fun)
141 .map_err(LemmyError::from)
142 .map_err(|e| e.with_message("couldnt_resolve_report"))?;
144 let post_report_view = blocking(context.pool(), move |conn| {
145 PostReportView::read(conn, report_id, person_id)
149 let res = PostReportResponse { post_report_view };
151 context.chat_server().do_send(SendModRoomMessage {
152 op: UserOperation::ResolvePostReport,
153 response: res.clone(),
154 community_id: report.community.id,
162 /// Lists post reports for a community if an id is supplied
163 /// or returns all post reports for communities a user moderates
164 #[async_trait::async_trait(?Send)]
165 impl Perform for ListPostReports {
166 type Response = ListPostReportsResponse;
168 #[tracing::instrument(skip(context, _websocket_id))]
171 context: &Data<LemmyContext>,
172 _websocket_id: Option<ConnectionId>,
173 ) -> Result<ListPostReportsResponse, LemmyError> {
174 let data: &ListPostReports = self;
175 let local_user_view =
176 get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
178 let person_id = local_user_view.person.id;
179 let admin = local_user_view.person.admin;
180 let community_id = data.community_id;
181 let unresolved_only = data.unresolved_only;
183 let page = data.page;
184 let limit = data.limit;
185 let post_reports = blocking(context.pool(), move |conn| {
186 PostReportQueryBuilder::create(conn, person_id, admin)
187 .community_id(community_id)
188 .unresolved_only(unresolved_only)
195 let res = ListPostReportsResponse { post_reports };