Fixing issue with mods not being able to view reports. Fixes #4172 (#4174)

* Fixing issue with mods not being able to view reports. Fixes #4172

* Addressing PR comments.
This commit is contained in:
Dessalines 2023-11-21 10:33:49 -05:00 committed by GitHub
parent 7ba1d98915
commit 28d779a960
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 25 deletions

View file

@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query};
use lemmy_api_common::{ use lemmy_api_common::{
comment::{ListCommentReports, ListCommentReportsResponse}, comment::{ListCommentReports, ListCommentReportsResponse},
context::LemmyContext, context::LemmyContext,
utils::check_community_mod_action_opt, utils::check_community_mod_of_any_or_admin_action,
}; };
use lemmy_db_views::{comment_report_view::CommentReportQuery, structs::LocalUserView}; use lemmy_db_views::{comment_report_view::CommentReportQuery, structs::LocalUserView};
use lemmy_utils::error::LemmyError; use lemmy_utils::error::LemmyError;
@ -18,7 +18,7 @@ pub async fn list_comment_reports(
let community_id = data.community_id; let community_id = data.community_id;
let unresolved_only = data.unresolved_only.unwrap_or_default(); let unresolved_only = data.unresolved_only.unwrap_or_default();
check_community_mod_action_opt(&local_user_view, community_id, &mut context.pool()).await?; check_community_mod_of_any_or_admin_action(&local_user_view, &mut context.pool()).await?;
let page = data.page; let page = data.page;
let limit = data.limit; let limit = data.limit;

View file

@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query};
use lemmy_api_common::{ use lemmy_api_common::{
context::LemmyContext, context::LemmyContext,
person::{GetReportCount, GetReportCountResponse}, person::{GetReportCount, GetReportCountResponse},
utils::check_community_mod_action_opt, utils::check_community_mod_of_any_or_admin_action,
}; };
use lemmy_db_views::structs::{ use lemmy_db_views::structs::{
CommentReportView, CommentReportView,
@ -22,7 +22,7 @@ pub async fn report_count(
let admin = local_user_view.local_user.admin; let admin = local_user_view.local_user.admin;
let community_id = data.community_id; let community_id = data.community_id;
check_community_mod_action_opt(&local_user_view, community_id, &mut context.pool()).await?; check_community_mod_of_any_or_admin_action(&local_user_view, &mut context.pool()).await?;
let comment_reports = let comment_reports =
CommentReportView::get_report_count(&mut context.pool(), person_id, admin, community_id) CommentReportView::get_report_count(&mut context.pool(), person_id, admin, community_id)

View file

@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query};
use lemmy_api_common::{ use lemmy_api_common::{
context::LemmyContext, context::LemmyContext,
post::{ListPostReports, ListPostReportsResponse}, post::{ListPostReports, ListPostReportsResponse},
utils::check_community_mod_action_opt, utils::check_community_mod_of_any_or_admin_action,
}; };
use lemmy_db_views::{post_report_view::PostReportQuery, structs::LocalUserView}; use lemmy_db_views::{post_report_view::PostReportQuery, structs::LocalUserView};
use lemmy_utils::error::LemmyError; use lemmy_utils::error::LemmyError;
@ -18,7 +18,7 @@ pub async fn list_post_reports(
let community_id = data.community_id; let community_id = data.community_id;
let unresolved_only = data.unresolved_only.unwrap_or_default(); let unresolved_only = data.unresolved_only.unwrap_or_default();
check_community_mod_action_opt(&local_user_view, community_id, &mut context.pool()).await?; check_community_mod_of_any_or_admin_action(&local_user_view, &mut context.pool()).await?;
let page = data.page; let page = data.page;
let limit = data.limit; let limit = data.limit;

View file

@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query};
use lemmy_api_common::{ use lemmy_api_common::{
context::LemmyContext, context::LemmyContext,
site::{GetModlog, GetModlogResponse}, site::{GetModlog, GetModlogResponse},
utils::{check_community_mod_action_opt, check_private_instance, is_admin}, utils::{check_community_mod_of_any_or_admin_action, check_private_instance},
}; };
use lemmy_db_schema::{source::local_site::LocalSite, ModlogActionType}; use lemmy_db_schema::{source::local_site::LocalSite, ModlogActionType};
use lemmy_db_views::structs::LocalUserView; use lemmy_db_views::structs::LocalUserView;
@ -41,11 +41,9 @@ pub async fn get_mod_log(
let community_id = data.community_id; let community_id = data.community_id;
let is_mod_or_admin = if let Some(local_user_view) = local_user_view { let is_mod_or_admin = if let Some(local_user_view) = local_user_view {
let is_mod = community_id.is_some() check_community_mod_of_any_or_admin_action(&local_user_view, &mut context.pool())
&& check_community_mod_action_opt(&local_user_view, community_id, &mut context.pool())
.await .await
.is_ok(); .is_ok()
is_mod || is_admin(&local_user_view).is_ok()
} else { } else {
false false
}; };

View file

@ -78,6 +78,26 @@ pub async fn is_mod_or_admin_opt(
} }
} }
/// Check that a person is either a mod of any community, or an admin
///
/// Should only be used for read operations
#[tracing::instrument(skip_all)]
pub async fn check_community_mod_of_any_or_admin_action(
local_user_view: &LocalUserView,
pool: &mut DbPool<'_>,
) -> LemmyResult<()> {
let person = &local_user_view.person;
check_user_valid(person)?;
let is_mod_of_any_or_admin = CommunityView::is_mod_of_any_or_admin(pool, person.id).await?;
if !is_mod_of_any_or_admin {
Err(LemmyErrorType::NotAModOrAdmin)?
} else {
Ok(())
}
}
pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> { pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
check_user_valid(&local_user_view.person)?; check_user_valid(&local_user_view.person)?;
if !local_user_view.local_user.admin { if !local_user_view.local_user.admin {
@ -199,19 +219,6 @@ pub async fn check_community_mod_action(
Ok(()) Ok(())
} }
pub async fn check_community_mod_action_opt(
local_user_view: &LocalUserView,
community_id: Option<CommunityId>,
pool: &mut DbPool<'_>,
) -> LemmyResult<()> {
if let Some(community_id) = community_id {
check_community_mod_action(&local_user_view.person, community_id, false, pool).await?;
} else {
is_admin(local_user_view)?;
}
Ok(())
}
pub fn check_post_deleted_or_removed(post: &Post) -> Result<(), LemmyError> { pub fn check_post_deleted_or_removed(post: &Post) -> Result<(), LemmyError> {
if post.deleted || post.removed { if post.deleted || post.removed {
Err(LemmyErrorType::Deleted)? Err(LemmyErrorType::Deleted)?

View file

@ -27,6 +27,20 @@ impl CommunityModeratorView {
.get_result::<bool>(conn) .get_result::<bool>(conn)
.await .await
} }
pub(crate) async fn is_community_moderator_of_any(
pool: &mut DbPool<'_>,
find_person_id: PersonId,
) -> Result<bool, Error> {
use lemmy_db_schema::schema::community_moderator::dsl::{community_moderator, person_id};
let conn = &mut get_conn(pool).await?;
select(exists(
community_moderator.filter(person_id.eq(find_person_id)),
))
.get_result::<bool>(conn)
.await
}
pub async fn for_community( pub async fn for_community(
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
community_id: CommunityId, community_id: CommunityId,

View file

@ -194,6 +194,20 @@ impl CommunityView {
PersonView::is_admin(pool, person_id).await PersonView::is_admin(pool, person_id).await
} }
/// Checks if a person is an admin, or moderator of any community.
pub async fn is_mod_of_any_or_admin(
pool: &mut DbPool<'_>,
person_id: PersonId,
) -> Result<bool, Error> {
let is_mod_of_any =
CommunityModeratorView::is_community_moderator_of_any(pool, person_id).await?;
if is_mod_of_any {
return Ok(true);
}
PersonView::is_admin(pool, person_id).await
}
} }
#[derive(Default)] #[derive(Default)]