From 766ca99fd5de1b21e9e4c457f6c66a4982938fd5 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 25 Oct 2023 06:01:40 -0400 Subject: [PATCH] Hide private messages from blocked users. (#4102) - Also fixes the unread count calls for CommentReply and PrivateMessage. - Fixes #3629 --- crates/db_views/src/private_message_view.rs | 62 +++++++++++++++++-- .../db_views_actor/src/comment_reply_view.rs | 9 +++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/crates/db_views/src/private_message_view.rs b/crates/db_views/src/private_message_view.rs index b8628ecc5..de0ae2282 100644 --- a/crates/db_views/src/private_message_view.rs +++ b/crates/db_views/src/private_message_view.rs @@ -12,7 +12,7 @@ use diesel_async::RunQueryDsl; use lemmy_db_schema::{ aliases, newtypes::{PersonId, PrivateMessageId}, - schema::{person, private_message}, + schema::{person, person_block, private_message}, utils::{get_conn, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn}, }; use tracing::debug; @@ -27,6 +27,13 @@ fn queries<'a>() -> Queries< .inner_join( aliases::person1.on(private_message::recipient_id.eq(aliases::person1.field(person::id))), ) + .left_join( + person_block::table.on( + private_message::creator_id + .eq(person_block::target_id) + .and(person_block::person_id.eq(aliases::person1.field(person::id))), + ), + ) }; let selection = ( @@ -45,7 +52,10 @@ fn queries<'a>() -> Queries< let list = move |mut conn: DbConn<'a>, (options, recipient_id): (PrivateMessageQuery, PersonId)| async move { - let mut query = all_joins(private_message::table.into_boxed()).select(selection); + let mut query = all_joins(private_message::table.into_boxed()) + .select(selection) + // Dont show replies from blocked users + .filter(person_block::person_id.is_null()); // If its unread, I only want the ones to me if options.unread_only { @@ -106,6 +116,15 @@ impl PrivateMessageView { use diesel::dsl::count; let conn = &mut get_conn(pool).await?; private_message::table + .left_join( + person_block::table.on( + private_message::creator_id + .eq(person_block::target_id) + .and(person_block::person_id.eq(my_person_id)), + ), + ) + // Dont count replies from blocked users + .filter(person_block::person_id.is_null()) .filter(private_message::read.eq(false)) .filter(private_message::recipient_id.eq(my_person_id)) .filter(private_message::deleted.eq(false)) @@ -138,14 +157,15 @@ mod tests { #![allow(clippy::unwrap_used)] #![allow(clippy::indexing_slicing)] - use crate::private_message_view::PrivateMessageQuery; + use crate::{private_message_view::PrivateMessageQuery, structs::PrivateMessageView}; use lemmy_db_schema::{ source::{ instance::Instance, person::{Person, PersonInsertForm}, + person_block::{PersonBlock, PersonBlockForm}, private_message::{PrivateMessage, PrivateMessageInsertForm}, }, - traits::Crud, + traits::{Blockable, Crud}, utils::build_db_pool_for_tests, }; use serial_test::serial; @@ -280,5 +300,39 @@ mod tests { assert_eq!(timmy_sara_unread_messages.len(), 1); assert_eq!(timmy_sara_unread_messages[0].creator.id, sara.id); assert_eq!(timmy_sara_unread_messages[0].recipient.id, timmy.id); + + // Make sure blocks are working + let timmy_blocks_sara_form = PersonBlockForm { + person_id: timmy.id, + target_id: sara.id, + }; + + let inserted_block = PersonBlock::block(pool, &timmy_blocks_sara_form) + .await + .unwrap(); + + let expected_block = PersonBlock { + id: inserted_block.id, + person_id: timmy.id, + target_id: sara.id, + published: inserted_block.published, + }; + assert_eq!(expected_block, inserted_block); + + let timmy_messages = PrivateMessageQuery { + unread_only: true, + creator_id: Option::None, + ..Default::default() + } + .list(pool, timmy.id) + .await + .unwrap(); + + assert_eq!(timmy_messages.len(), 1); + + let timmy_unread_messages = PrivateMessageView::get_unread_messages(pool, timmy.id) + .await + .unwrap(); + assert_eq!(timmy_unread_messages, 1); } } diff --git a/crates/db_views_actor/src/comment_reply_view.rs b/crates/db_views_actor/src/comment_reply_view.rs index a97ad96fb..6ca4182e8 100644 --- a/crates/db_views_actor/src/comment_reply_view.rs +++ b/crates/db_views_actor/src/comment_reply_view.rs @@ -164,6 +164,15 @@ impl CommentReplyView { comment_reply::table .inner_join(comment::table) + .left_join( + person_block::table.on( + comment::creator_id + .eq(person_block::target_id) + .and(person_block::person_id.eq(my_person_id)), + ), + ) + // Dont count replies from blocked users + .filter(person_block::person_id.is_null()) .filter(comment_reply::recipient_id.eq(my_person_id)) .filter(comment_reply::read.eq(false)) .filter(comment::deleted.eq(false))