From 8a1af056e2a833db88976ad7144deddca74758c0 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Fri, 13 Aug 2021 13:39:56 -0400 Subject: [PATCH] When banning a user, remove communities they've created (#1700) - Fixes #1659 --- crates/api/src/local_user.rs | 21 +++++++++++++++++- .../src/community_moderator_view.rs | 22 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index 54fe6d76b..8eee3c1c4 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -19,6 +19,7 @@ use lemmy_db_queries::{ from_opt_str_to_opt_enum, source::{ comment::Comment_, + community::Community_, local_user::LocalUser_, password_reset_request::PasswordResetRequest_, person::Person_, @@ -33,6 +34,7 @@ use lemmy_db_schema::{ naive_now, source::{ comment::Comment, + community::Community, local_user::{LocalUser, LocalUserForm}, moderator::*, password_reset_request::*, @@ -51,6 +53,7 @@ use lemmy_db_views::{ }; use lemmy_db_views_actor::{ community_follower_view::CommunityFollowerView, + community_moderator_view::CommunityModeratorView, person_mention_view::{PersonMentionQueryBuilder, PersonMentionView}, person_view::PersonViewSafe, }; @@ -408,8 +411,24 @@ impl Perform for BanPerson { // Communities // Remove all communities where they're the top mod - // TODO couldn't get group by's working in diesel, // for now, remove the communities manually + let first_mod_communities = blocking(context.pool(), move |conn: &'_ _| { + CommunityModeratorView::get_community_first_mods(conn) + }) + .await??; + + // Filter to only this banned users top communities + let banned_user_first_communities: Vec = first_mod_communities + .into_iter() + .filter(|fmc| fmc.moderator.id == banned_person_id) + .collect(); + + for first_mod_community in banned_user_first_communities { + blocking(context.pool(), move |conn: &'_ _| { + Community::update_removed(conn, first_mod_community.community.id, true) + }) + .await??; + } // Comments blocking(context.pool(), move |conn: &'_ _| { diff --git a/crates/db_views_actor/src/community_moderator_view.rs b/crates/db_views_actor/src/community_moderator_view.rs index 274f68243..9ea107935 100644 --- a/crates/db_views_actor/src/community_moderator_view.rs +++ b/crates/db_views_actor/src/community_moderator_view.rs @@ -49,6 +49,28 @@ impl CommunityModeratorView { Ok(Self::from_tuple_to_vec(res)) } + + /// Finds all communities first mods / creators + /// Ideally this should be a group by, but diesel doesn't support it yet + pub fn get_community_first_mods(conn: &PgConnection) -> Result, Error> { + let res = community_moderator::table + .inner_join(community::table) + .inner_join(person::table) + .select(( + Community::safe_columns_tuple(), + Person::safe_columns_tuple(), + )) + // A hacky workaround instead of group_bys + // https://stackoverflow.com/questions/24042359/how-to-join-only-one-row-in-joined-table-with-postgres + .distinct_on(community_moderator::community_id) + .order_by(( + community_moderator::community_id, + community_moderator::person_id, + )) + .load::(conn)?; + + Ok(Self::from_tuple_to_vec(res)) + } } impl ViewToVec for CommunityModeratorView {