From 28d779a960884af445125a3682956203cd52a4a8 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 21 Nov 2023 10:33:49 -0500 Subject: [PATCH] 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. --- crates/api/src/comment_report/list.rs | 4 +-- crates/api/src/local_user/report_count.rs | 4 +-- crates/api/src/post_report/list.rs | 4 +-- crates/api/src/site/mod_log.rs | 10 +++--- crates/api_common/src/utils.rs | 33 +++++++++++-------- .../src/community_moderator_view.rs | 14 ++++++++ crates/db_views_actor/src/community_view.rs | 14 ++++++++ 7 files changed, 58 insertions(+), 25 deletions(-) diff --git a/crates/api/src/comment_report/list.rs b/crates/api/src/comment_report/list.rs index 3d434deba..e30a7ba84 100644 --- a/crates/api/src/comment_report/list.rs +++ b/crates/api/src/comment_report/list.rs @@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query}; use lemmy_api_common::{ comment::{ListCommentReports, ListCommentReportsResponse}, 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_utils::error::LemmyError; @@ -18,7 +18,7 @@ pub async fn list_comment_reports( let community_id = data.community_id; 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 limit = data.limit; diff --git a/crates/api/src/local_user/report_count.rs b/crates/api/src/local_user/report_count.rs index 6f219297a..3352f64eb 100644 --- a/crates/api/src/local_user/report_count.rs +++ b/crates/api/src/local_user/report_count.rs @@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query}; use lemmy_api_common::{ context::LemmyContext, person::{GetReportCount, GetReportCountResponse}, - utils::check_community_mod_action_opt, + utils::check_community_mod_of_any_or_admin_action, }; use lemmy_db_views::structs::{ CommentReportView, @@ -22,7 +22,7 @@ pub async fn report_count( let admin = local_user_view.local_user.admin; 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 = CommentReportView::get_report_count(&mut context.pool(), person_id, admin, community_id) diff --git a/crates/api/src/post_report/list.rs b/crates/api/src/post_report/list.rs index 420052e35..cce88a2e3 100644 --- a/crates/api/src/post_report/list.rs +++ b/crates/api/src/post_report/list.rs @@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query}; use lemmy_api_common::{ context::LemmyContext, 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_utils::error::LemmyError; @@ -18,7 +18,7 @@ pub async fn list_post_reports( let community_id = data.community_id; 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 limit = data.limit; diff --git a/crates/api/src/site/mod_log.rs b/crates/api/src/site/mod_log.rs index 133cce8d8..e54d13731 100644 --- a/crates/api/src/site/mod_log.rs +++ b/crates/api/src/site/mod_log.rs @@ -2,7 +2,7 @@ use actix_web::web::{Data, Json, Query}; use lemmy_api_common::{ context::LemmyContext, 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_views::structs::LocalUserView; @@ -41,11 +41,9 @@ pub async fn get_mod_log( let community_id = data.community_id; let is_mod_or_admin = if let Some(local_user_view) = local_user_view { - let is_mod = community_id.is_some() - && check_community_mod_action_opt(&local_user_view, community_id, &mut context.pool()) - .await - .is_ok(); - is_mod || is_admin(&local_user_view).is_ok() + check_community_mod_of_any_or_admin_action(&local_user_view, &mut context.pool()) + .await + .is_ok() } else { false }; diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index 84f3f148c..3c57a36cd 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -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> { check_user_valid(&local_user_view.person)?; if !local_user_view.local_user.admin { @@ -199,19 +219,6 @@ pub async fn check_community_mod_action( Ok(()) } -pub async fn check_community_mod_action_opt( - local_user_view: &LocalUserView, - community_id: Option, - 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> { if post.deleted || post.removed { Err(LemmyErrorType::Deleted)? diff --git a/crates/db_views_actor/src/community_moderator_view.rs b/crates/db_views_actor/src/community_moderator_view.rs index 63e711225..cab4e2a09 100644 --- a/crates/db_views_actor/src/community_moderator_view.rs +++ b/crates/db_views_actor/src/community_moderator_view.rs @@ -27,6 +27,20 @@ impl CommunityModeratorView { .get_result::(conn) .await } + + pub(crate) async fn is_community_moderator_of_any( + pool: &mut DbPool<'_>, + find_person_id: PersonId, + ) -> Result { + 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::(conn) + .await + } + pub async fn for_community( pool: &mut DbPool<'_>, community_id: CommunityId, diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index 7db6cfcf8..5e5f81073 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -194,6 +194,20 @@ impl CommunityView { 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 { + 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)]