mirror of https://github.com/LemmyNet/lemmy
reports: split post/comment out again, add some other fixes
parent
e8e0890341
commit
2cd2a4df45
@ -1,300 +0,0 @@
|
||||
use actix_web::web::Data;
|
||||
use std::str::FromStr;
|
||||
|
||||
use lemmy_db::{comment_report::*, comment_view::*, post_report::*, post_view::*, Reportable, ReportType,};
|
||||
use lemmy_structs::{blocking, report::*};
|
||||
use lemmy_utils::{APIError, ConnectionId, LemmyError};
|
||||
use lemmy_websocket::{LemmyContext, UserOperation, messages::SendUserRoomMessage};
|
||||
|
||||
use crate::{check_community_ban, get_user_from_jwt, is_mod_or_admin, Perform};
|
||||
|
||||
const MAX_REPORT_LEN: usize = 1000;
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for CreateReport {
|
||||
type Response = CreateReportResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<CreateReportResponse, LemmyError> {
|
||||
let data: &CreateReport = &self;
|
||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
// check size of report and check for whitespace
|
||||
let reason = data.reason.clone();
|
||||
if reason.trim().is_empty() {
|
||||
return Err(APIError::err("report_reason_required").into());
|
||||
}
|
||||
if reason.len() > MAX_REPORT_LEN {
|
||||
return Err(APIError::err("report_too_long").into());
|
||||
}
|
||||
|
||||
let report_type = ReportType::from_str(&data.report_type)?;
|
||||
let user_id = user.id;
|
||||
match report_type {
|
||||
ReportType::Comment => { create_comment_report(context, data, user_id).await?; }
|
||||
ReportType::Post => { create_post_report(context, data, user_id).await?; }
|
||||
}
|
||||
|
||||
// to build on this, the user should get a success response, however
|
||||
// mods should get a different response with more details
|
||||
let res = CreateReportResponse { success: true };
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
op: UserOperation::CreateReport,
|
||||
response: res.clone(),
|
||||
recipient_id: user.id,
|
||||
websocket_id,
|
||||
});
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for GetReportCount {
|
||||
type Response = GetReportCountResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<GetReportCountResponse, LemmyError> {
|
||||
let data: &GetReportCount = &self;
|
||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||
let community_id = data.community;
|
||||
|
||||
// Check for mod/admin privileges
|
||||
is_mod_or_admin(context.pool(), user.id, community_id).await?;
|
||||
|
||||
let comment_reports = blocking(context.pool(), move |conn| {
|
||||
CommentReportQueryBuilder::create(conn)
|
||||
.community_id(community_id)
|
||||
.resolved(false)
|
||||
.count()
|
||||
})
|
||||
.await??;
|
||||
let post_reports = blocking(context.pool(), move |conn| {
|
||||
PostReportQueryBuilder::create(conn)
|
||||
.community_id(community_id)
|
||||
.resolved(false)
|
||||
.count()
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = GetReportCountResponse {
|
||||
community: community_id,
|
||||
comment_reports,
|
||||
post_reports,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
op: UserOperation::ListReports,
|
||||
response: res.clone(),
|
||||
recipient_id: user.id,
|
||||
websocket_id,
|
||||
});
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for ListReports {
|
||||
type Response = ListReportsResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<ListReportsResponse, LemmyError> {
|
||||
let data: &ListReports = &self;
|
||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||
let community_id = data.community;
|
||||
|
||||
// Check for mod/admin privileges
|
||||
is_mod_or_admin(context.pool(), user.id, community_id).await?;
|
||||
|
||||
let page = data.page;
|
||||
let limit = data.limit;
|
||||
let comments = blocking(context.pool(), move |conn| {
|
||||
CommentReportQueryBuilder::create(conn)
|
||||
.community_id(community_id)
|
||||
.page(page)
|
||||
.limit(limit)
|
||||
.list()
|
||||
})
|
||||
.await??;
|
||||
|
||||
let posts = blocking(context.pool(), move |conn| {
|
||||
PostReportQueryBuilder::create(conn)
|
||||
.community_id(community_id)
|
||||
.page(page)
|
||||
.limit(limit)
|
||||
.list()
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = ListReportsResponse { comments, posts };
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
op: UserOperation::ListReports,
|
||||
response: res.clone(),
|
||||
recipient_id: user.id,
|
||||
websocket_id,
|
||||
});
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Perform for ResolveReport {
|
||||
type Response = ResolveReportResponse;
|
||||
|
||||
async fn perform(
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
websocket_id: Option<ConnectionId>,
|
||||
) -> Result<ResolveReportResponse, LemmyError> {
|
||||
let data: &ResolveReport = &self;
|
||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||
|
||||
let report_type = ReportType::from_str(&data.report_type)?;
|
||||
let user_id = user.id;
|
||||
match report_type {
|
||||
ReportType::Comment => { resolve_comment_report(context, data, user_id).await?; }
|
||||
ReportType::Post => { resolve_post_report(context, data, user_id).await?; }
|
||||
}
|
||||
|
||||
let report_id = data.report_id;
|
||||
let res = ResolveReportResponse {
|
||||
report_type: data.report_type.to_owned(),
|
||||
report_id,
|
||||
resolved: true,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
op: UserOperation::ResolveReport,
|
||||
response: res.clone(),
|
||||
recipient_id: user.id,
|
||||
websocket_id,
|
||||
});
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_comment_report(
|
||||
context: &Data<LemmyContext>,
|
||||
data: &CreateReport,
|
||||
user_id: i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let comment_id = data.entity_id;
|
||||
let comment = blocking(context.pool(), move |conn| {
|
||||
CommentView::read(&conn, comment_id, None)
|
||||
}).await??;
|
||||
|
||||
check_community_ban(user_id, comment.community_id, context.pool()).await?;
|
||||
|
||||
let report_form = CommentReportForm {
|
||||
creator_id: user_id,
|
||||
comment_id,
|
||||
comment_text: comment.content,
|
||||
reason: data.reason.to_owned(),
|
||||
};
|
||||
|
||||
return match blocking(context.pool(), move |conn| {
|
||||
CommentReport::report(conn, &report_form)
|
||||
}).await? {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_e) => Err(APIError::err("couldnt_create_report").into())
|
||||
};
|
||||
}
|
||||
|
||||
async fn create_post_report(
|
||||
context: &Data<LemmyContext>,
|
||||
data: &CreateReport,
|
||||
user_id: i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let post_id = data.entity_id;
|
||||
let post = blocking(context.pool(), move |conn| {
|
||||
PostView::read(&conn, post_id, None)
|
||||
}).await??;
|
||||
|
||||
check_community_ban(user_id, post.community_id, context.pool()).await?;
|
||||
|
||||
let report_form = PostReportForm {
|
||||
creator_id: user_id,
|
||||
post_id,
|
||||
post_name: post.name,
|
||||
post_url: post.url,
|
||||
post_body: post.body,
|
||||
reason: data.reason.to_owned(),
|
||||
};
|
||||
|
||||
return match blocking(context.pool(), move |conn| {
|
||||
PostReport::report(conn, &report_form)
|
||||
}).await? {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_e) => Err(APIError::err("couldnt_create_report").into())
|
||||
};
|
||||
}
|
||||
|
||||
async fn resolve_comment_report(
|
||||
context: &Data<LemmyContext>,
|
||||
data: &ResolveReport,
|
||||
user_id: i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let report_id = data.report_id;
|
||||
let report = blocking(context.pool(), move |conn| {
|
||||
CommentReportView::read(&conn, report_id)
|
||||
}).await??;
|
||||
|
||||
is_mod_or_admin(context.pool(), user_id, report.community_id).await?;
|
||||
|
||||
let resolved = data.resolved;
|
||||
let resolve_fun = move |conn: &'_ _| {
|
||||
if resolved {
|
||||
CommentReport::resolve(conn, report_id.clone(), user_id)
|
||||
} else {
|
||||
CommentReport::unresolve(conn, report_id.clone())
|
||||
}
|
||||
};
|
||||
|
||||
if blocking(context.pool(),resolve_fun).await?.is_err() {
|
||||
return Err(APIError::err("couldnt_resolve_report").into())
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn resolve_post_report(
|
||||
context: &Data<LemmyContext>,
|
||||
data: &ResolveReport,
|
||||
user_id: i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let report_id = data.report_id;
|
||||
let report = blocking(context.pool(), move |conn| {
|
||||
PostReportView::read(&conn, report_id)
|
||||
}).await??;
|
||||
|
||||
is_mod_or_admin(context.pool(), user_id, report.community_id).await?;
|
||||
|
||||
let resolved = data.resolved;
|
||||
let resolve_fun = move |conn: &'_ _| {
|
||||
if resolved {
|
||||
PostReport::resolve(conn, report_id.clone(), user_id)
|
||||
} else {
|
||||
PostReport::unresolve(conn, report_id.clone())
|
||||
}
|
||||
};
|
||||
|
||||
if blocking(context.pool(),resolve_fun).await?.is_err() {
|
||||
return Err(APIError::err("couldnt_resolve_report").into())
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
use lemmy_db::{comment_report::CommentReportView, post_report::PostReportView};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CreateReport {
|
||||
pub report_type: String,
|
||||
pub entity_id: i32,
|
||||
pub reason: String,
|
||||
pub auth: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct CreateReportResponse {
|
||||
pub success: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ListReports {
|
||||
pub page: Option<i64>,
|
||||
pub limit: Option<i64>,
|
||||
pub community: i32,
|
||||
pub auth: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ListReportsResponse {
|
||||
pub posts: Vec<PostReportView>,
|
||||
pub comments: Vec<CommentReportView>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GetReportCount {
|
||||
pub community: i32,
|
||||
pub auth: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct GetReportCountResponse {
|
||||
pub community: i32,
|
||||
pub comment_reports: usize,
|
||||
pub post_reports: usize,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ResolveReport {
|
||||
pub report_type: String,
|
||||
pub report_id: i32,
|
||||
pub resolved: bool,
|
||||
pub auth: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ResolveReportResponse {
|
||||
pub report_type: String,
|
||||
pub report_id: i32,
|
||||
pub resolved: bool,
|
||||
}
|
Loading…
Reference in New Issue