]> Untitled Git - lemmy.git/blob - crates/api/src/comment_report.rs
Moving settings and secrets to context.
[lemmy.git] / crates / api / src / comment_report.rs
1 use crate::Perform;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   blocking,
5   check_community_ban,
6   collect_moderated_communities,
7   comment::*,
8   get_local_user_view_from_jwt,
9   is_mod_or_admin,
10 };
11 use lemmy_db_queries::Reportable;
12 use lemmy_db_schema::source::comment_report::*;
13 use lemmy_db_views::{
14   comment_report_view::{CommentReportQueryBuilder, CommentReportView},
15   comment_view::CommentView,
16 };
17 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
18 use lemmy_websocket::{
19   messages::{SendModRoomMessage, SendUserRoomMessage},
20   LemmyContext,
21   UserOperation,
22 };
23
24 /// Creates a comment report and notifies the moderators of the community
25 #[async_trait::async_trait(?Send)]
26 impl Perform for CreateCommentReport {
27   type Response = CreateCommentReportResponse;
28
29   async fn perform(
30     &self,
31     context: &Data<LemmyContext>,
32     websocket_id: Option<ConnectionId>,
33   ) -> Result<CreateCommentReportResponse, LemmyError> {
34     let data: &CreateCommentReport = self;
35     let local_user_view =
36       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
37
38     // check size of report and check for whitespace
39     let reason = data.reason.trim();
40     if reason.is_empty() {
41       return Err(ApiError::err("report_reason_required").into());
42     }
43     if reason.chars().count() > 1000 {
44       return Err(ApiError::err("report_too_long").into());
45     }
46
47     let person_id = local_user_view.person.id;
48     let comment_id = data.comment_id;
49     let comment_view = blocking(context.pool(), move |conn| {
50       CommentView::read(conn, comment_id, None)
51     })
52     .await??;
53
54     check_community_ban(person_id, comment_view.community.id, context.pool()).await?;
55
56     let report_form = CommentReportForm {
57       creator_id: person_id,
58       comment_id,
59       original_comment_text: comment_view.comment.content,
60       reason: data.reason.to_owned(),
61     };
62
63     let report = blocking(context.pool(), move |conn| {
64       CommentReport::report(conn, &report_form)
65     })
66     .await?
67     .map_err(|_| ApiError::err("couldnt_create_report"))?;
68
69     let res = CreateCommentReportResponse { success: true };
70
71     context.chat_server().do_send(SendUserRoomMessage {
72       op: UserOperation::CreateCommentReport,
73       response: res.clone(),
74       local_recipient_id: local_user_view.local_user.id,
75       websocket_id,
76     });
77
78     context.chat_server().do_send(SendModRoomMessage {
79       op: UserOperation::CreateCommentReport,
80       response: report,
81       community_id: comment_view.community.id,
82       websocket_id,
83     });
84
85     Ok(res)
86   }
87 }
88
89 /// Resolves or unresolves a comment report and notifies the moderators of the community
90 #[async_trait::async_trait(?Send)]
91 impl Perform for ResolveCommentReport {
92   type Response = ResolveCommentReportResponse;
93
94   async fn perform(
95     &self,
96     context: &Data<LemmyContext>,
97     websocket_id: Option<ConnectionId>,
98   ) -> Result<ResolveCommentReportResponse, LemmyError> {
99     let data: &ResolveCommentReport = self;
100     let local_user_view =
101       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
102
103     let report_id = data.report_id;
104     let report = blocking(context.pool(), move |conn| {
105       CommentReportView::read(conn, report_id)
106     })
107     .await??;
108
109     let person_id = local_user_view.person.id;
110     is_mod_or_admin(context.pool(), person_id, report.community.id).await?;
111
112     let resolved = data.resolved;
113     let resolve_fun = move |conn: &'_ _| {
114       if resolved {
115         CommentReport::resolve(conn, report_id, person_id)
116       } else {
117         CommentReport::unresolve(conn, report_id, person_id)
118       }
119     };
120
121     if blocking(context.pool(), resolve_fun).await?.is_err() {
122       return Err(ApiError::err("couldnt_resolve_report").into());
123     };
124
125     let report_id = data.report_id;
126     let res = ResolveCommentReportResponse {
127       report_id,
128       resolved,
129     };
130
131     context.chat_server().do_send(SendModRoomMessage {
132       op: UserOperation::ResolveCommentReport,
133       response: res.clone(),
134       community_id: report.community.id,
135       websocket_id,
136     });
137
138     Ok(res)
139   }
140 }
141
142 /// Lists comment reports for a community if an id is supplied
143 /// or returns all comment reports for communities a user moderates
144 #[async_trait::async_trait(?Send)]
145 impl Perform for ListCommentReports {
146   type Response = ListCommentReportsResponse;
147
148   async fn perform(
149     &self,
150     context: &Data<LemmyContext>,
151     websocket_id: Option<ConnectionId>,
152   ) -> Result<ListCommentReportsResponse, LemmyError> {
153     let data: &ListCommentReports = self;
154     let local_user_view =
155       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
156
157     let person_id = local_user_view.person.id;
158     let community_id = data.community;
159     let community_ids =
160       collect_moderated_communities(person_id, community_id, context.pool()).await?;
161
162     let page = data.page;
163     let limit = data.limit;
164     let comments = blocking(context.pool(), move |conn| {
165       CommentReportQueryBuilder::create(conn)
166         .community_ids(community_ids)
167         .page(page)
168         .limit(limit)
169         .list()
170     })
171     .await??;
172
173     let res = ListCommentReportsResponse { comments };
174
175     context.chat_server().do_send(SendUserRoomMessage {
176       op: UserOperation::ListCommentReports,
177       response: res.clone(),
178       local_recipient_id: local_user_view.local_user.id,
179       websocket_id,
180     });
181
182     Ok(res)
183   }
184 }