From e65c45f15272b5f43053a214600ee3b8cebffc0d Mon Sep 17 00:00:00 2001 From: Dessalines Date: Sat, 8 Jan 2022 07:37:07 -0500 Subject: [PATCH] Adding temporary bans. Fixes #1423 (#1999) * Adding temporary bans. Fixes #1423 * Adding ban_expires to person * Fix clippy * Removing ban_expires from federated fields. * Trying to add expires to blockcommunity apub. --- crates/api/src/community.rs | 6 ++-- crates/api/src/local_user.rs | 7 ++-- crates/api_common/src/lib.rs | 4 +-- .../activities/community/block_user.json | 3 +- .../src/activities/community/block_user.rs | 9 +++-- .../activities/community/undo_block_user.rs | 3 +- crates/apub/src/objects/person.rs | 1 + .../activities/community/block_user.rs | 2 ++ crates/db_schema/src/impls/community.rs | 5 +++ crates/db_schema/src/impls/person.rs | 36 +++++++++++++++++-- crates/db_schema/src/schema.rs | 4 +++ crates/db_schema/src/source/community.rs | 2 ++ crates/db_schema/src/source/person.rs | 7 ++++ crates/db_views/src/comment_report_view.rs | 20 +++++++++-- crates/db_views/src/comment_view.rs | 17 +++++++-- crates/db_views/src/post_report_view.rs | 20 +++++++++-- crates/db_views/src/post_view.rs | 17 +++++++-- .../src/registration_application_view.rs | 2 ++ .../src/community_person_ban_view.rs | 7 +++- .../db_views_actor/src/person_mention_view.rs | 16 +++++++-- crates/db_views_actor/src/person_view.rs | 8 ++++- .../down.sql | 7 ++++ .../up.sql | 8 +++++ 23 files changed, 179 insertions(+), 32 deletions(-) create mode 100644 migrations/2021-12-14-181537_add_temporary_bans/down.sql create mode 100644 migrations/2021-12-14-181537_add_temporary_bans/up.sql diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index c0aea6022..c8b44aceb 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -214,6 +214,7 @@ impl Perform for BanFromCommunity { let community_id = data.community_id; let banned_person_id = data.person_id; + let expires = data.expires.map(naive_from_unix); // Verify that only mods or admins can ban is_mod_or_admin(context.pool(), local_user_view.person.id, community_id).await?; @@ -221,6 +222,7 @@ impl Perform for BanFromCommunity { let community_user_ban_form = CommunityPersonBanForm { community_id: data.community_id, person_id: data.person_id, + expires: Some(expires), }; let community: ApubCommunity = blocking(context.pool(), move |conn: &'_ _| { @@ -257,6 +259,7 @@ impl Perform for BanFromCommunity { &community, &banned_person, &local_user_view.person.clone().into(), + expires, context, ) .await?; @@ -304,9 +307,6 @@ impl Perform for BanFromCommunity { } // Mod tables - // TODO eventually do correct expires - let expires = data.expires.map(naive_from_unix); - let form = ModBanFromCommunityForm { mod_person_id: local_user_view.person.id, other_person_id: data.person_id, diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index 8a2d2a922..9452e7540 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -256,6 +256,7 @@ impl Perform for SaveUserSettings { shared_inbox_url: None, matrix_user_id, bot_account, + ban_expires: None, }; blocking(context.pool(), move |conn| { @@ -452,7 +453,9 @@ impl Perform for BanPerson { let ban = data.ban; let banned_person_id = data.person_id; - let ban_person = move |conn: &'_ _| Person::ban_person(conn, banned_person_id, ban); + let expires = data.expires.map(naive_from_unix); + + let ban_person = move |conn: &'_ _| Person::ban_person(conn, banned_person_id, ban, expires); blocking(context.pool(), ban_person) .await? .map_err(LemmyError::from) @@ -495,8 +498,6 @@ impl Perform for BanPerson { } // Mod tables - let expires = data.expires.map(naive_from_unix); - let form = ModBanForm { mod_person_id: local_user_view.person.id, other_person_id: data.person_id, diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index 7ac95450f..6dcdb58bd 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -132,7 +132,7 @@ pub async fn get_local_user_view_from_jwt( let local_user_view = blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??; // Check for a site ban - if local_user_view.person.banned { + if local_user_view.person.is_banned() { return Err(LemmyError::from_message("site_ban")); } @@ -187,7 +187,7 @@ pub async fn get_local_user_settings_view_from_jwt( }) .await??; // Check for a site ban - if local_user_view.person.banned { + if local_user_view.person.is_banned() { return Err(LemmyError::from_message("site_ban")); } diff --git a/crates/apub/assets/lemmy/activities/community/block_user.json b/crates/apub/assets/lemmy/activities/community/block_user.json index 9ca00816d..4d43e086e 100644 --- a/crates/apub/assets/lemmy/activities/community/block_user.json +++ b/crates/apub/assets/lemmy/activities/community/block_user.json @@ -9,5 +9,6 @@ ], "target": "http://enterprise.lemmy.ml/c/main", "type": "Block", + "expires": "2021-11-01T12:23:50.151874+00:00", "id": "http://enterprise.lemmy.ml/activities/block/5d42fffb-0903-4625-86d4-0b39bb344fc2" -} \ No newline at end of file +} diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs index cff72c5c8..f5a6f02ce 100644 --- a/crates/apub/src/activities/community/block_user.rs +++ b/crates/apub/src/activities/community/block_user.rs @@ -12,6 +12,7 @@ use crate::{ protocol::activities::community::block_user::BlockUserFromCommunity, }; use activitystreams_kinds::{activity::BlockType, public}; +use chrono::NaiveDateTime; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, @@ -27,7 +28,7 @@ use lemmy_db_schema::{ }, traits::{Bannable, Followable}, }; -use lemmy_utils::LemmyError; +use lemmy_utils::{utils::convert_datetime, LemmyError}; use lemmy_websocket::LemmyContext; impl BlockUserFromCommunity { @@ -35,6 +36,7 @@ impl BlockUserFromCommunity { community: &ApubCommunity, target: &ApubPerson, actor: &ApubPerson, + expires: Option, context: &LemmyContext, ) -> Result { Ok(BlockUserFromCommunity { @@ -48,6 +50,7 @@ impl BlockUserFromCommunity { BlockType::Block, &context.settings().get_protocol_and_hostname(), )?, + expires: expires.map(convert_datetime), unparsed: Default::default(), }) } @@ -57,9 +60,10 @@ impl BlockUserFromCommunity { community: &ApubCommunity, target: &ApubPerson, actor: &ApubPerson, + expires: Option, context: &LemmyContext, ) -> Result<(), LemmyError> { - let block = BlockUserFromCommunity::new(community, target, actor, context)?; + let block = BlockUserFromCommunity::new(community, target, actor, expires, context)?; let block_id = block.id.clone(); let activity = AnnouncableActivities::BlockUserFromCommunity(block); @@ -101,6 +105,7 @@ impl ActivityHandler for BlockUserFromCommunity { let community_user_ban_form = CommunityPersonBanForm { community_id: community.id, person_id: blocked_user.id, + expires: Some(self.expires.map(|u| u.naive_local())), }; blocking(context.pool(), move |conn: &'_ _| { diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs index 8add53b6a..a62315ddd 100644 --- a/crates/apub/src/activities/community/undo_block_user.rs +++ b/crates/apub/src/activities/community/undo_block_user.rs @@ -36,7 +36,7 @@ impl UndoBlockUserFromCommunity { actor: &ApubPerson, context: &LemmyContext, ) -> Result<(), LemmyError> { - let block = BlockUserFromCommunity::new(community, target, actor, context)?; + let block = BlockUserFromCommunity::new(community, target, actor, None, context)?; let id = generate_activity_id( UndoType::Undo, @@ -93,6 +93,7 @@ impl ActivityHandler for UndoBlockUserFromCommunity { let community_user_ban_form = CommunityPersonBanForm { community_id: community.id, person_id: blocked_user.id, + expires: None, }; blocking(context.pool(), move |conn: &'_ _| { diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index aa658eb41..ff8f0a583 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -149,6 +149,7 @@ impl ApubObject for ApubPerson { name: person.preferred_username, display_name: Some(person.name), banned: None, + ban_expires: None, deleted: None, avatar: Some(person.icon.map(|i| i.url.into())), banner: Some(person.image.map(|i| i.url.into())), diff --git a/crates/apub/src/protocol/activities/community/block_user.rs b/crates/apub/src/protocol/activities/community/block_user.rs index ecde0ce3a..891fe1f55 100644 --- a/crates/apub/src/protocol/activities/community/block_user.rs +++ b/crates/apub/src/protocol/activities/community/block_user.rs @@ -3,6 +3,7 @@ use crate::{ protocol::Unparsed, }; use activitystreams_kinds::activity::BlockType; +use chrono::{DateTime, FixedOffset}; use lemmy_apub_lib::object_id::ObjectId; use serde::{Deserialize, Serialize}; use url::Url; @@ -22,4 +23,5 @@ pub struct BlockUserFromCommunity { pub(crate) id: Url, #[serde(flatten)] pub(crate) unparsed: Unparsed, + pub(crate) expires: Option>, } diff --git a/crates/db_schema/src/impls/community.rs b/crates/db_schema/src/impls/community.rs index 19a3a9548..228cf23ff 100644 --- a/crates/db_schema/src/impls/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -225,6 +225,9 @@ impl Bannable for CommunityPersonBan { use crate::schema::community_person_ban::dsl::*; insert_into(community_person_ban) .values(community_person_ban_form) + .on_conflict((community_id, person_id)) + .do_update() + .set(community_person_ban_form) .get_result::(conn) } @@ -383,6 +386,7 @@ mod tests { let community_person_ban_form = CommunityPersonBanForm { community_id: inserted_community.id, person_id: inserted_person.id, + expires: None, }; let inserted_community_person_ban = @@ -393,6 +397,7 @@ mod tests { community_id: inserted_community.id, person_id: inserted_person.id, published: inserted_community_person_ban.published, + expires: None, }; let read_community = Community::read(&conn, inserted_community.id).unwrap(); diff --git a/crates/db_schema/src/impls/person.rs b/crates/db_schema/src/impls/person.rs index f09cdfa0e..7e756543b 100644 --- a/crates/db_schema/src/impls/person.rs +++ b/crates/db_schema/src/impls/person.rs @@ -3,7 +3,7 @@ use crate::{ naive_now, newtypes::{DbUrl, PersonId}, schema::person::dsl::*, - source::person::{Person, PersonForm}, + source::person::{Person, PersonForm, PersonSafe}, traits::Crud, }; use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; @@ -30,6 +30,7 @@ mod safe_type { matrix_user_id, admin, bot_account, + ban_expires, ); impl ToSafe for Person { @@ -53,6 +54,7 @@ mod safe_type { matrix_user_id, admin, bot_account, + ban_expires, ) } } @@ -79,6 +81,7 @@ mod safe_type_alias_1 { matrix_user_id, admin, bot_account, + ban_expires, ); impl ToSafe for PersonAlias1 { @@ -102,6 +105,7 @@ mod safe_type_alias_1 { matrix_user_id, admin, bot_account, + ban_expires, ) } } @@ -128,6 +132,7 @@ mod safe_type_alias_2 { matrix_user_id, admin, bot_account, + ban_expires, ); impl ToSafe for PersonAlias2 { @@ -151,6 +156,7 @@ mod safe_type_alias_2 { matrix_user_id, admin, bot_account, + ban_expires, ) } } @@ -179,9 +185,14 @@ impl Crud for Person { } impl Person { - pub fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result { + pub fn ban_person( + conn: &PgConnection, + person_id: PersonId, + ban: bool, + expires: Option, + ) -> Result { diesel::update(person.find(person_id)) - .set(banned.eq(ban)) + .set((banned.eq(ban), ban_expires.eq(expires))) .get_result::(conn) } @@ -259,6 +270,24 @@ impl Person { .set(deleted.eq(new_deleted)) .get_result::(conn) } + + pub fn is_banned(&self) -> bool { + is_banned(self.banned, self.ban_expires) + } +} + +impl PersonSafe { + pub fn is_banned(&self) -> bool { + is_banned(self.banned, self.ban_expires) + } +} + +fn is_banned(banned_: bool, expires: Option) -> bool { + if let Some(expires) = expires { + banned_ && expires.gt(&naive_now()) + } else { + banned_ + } } #[cfg(test)] @@ -298,6 +327,7 @@ mod tests { inbox_url: inserted_person.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }; let read_person = Person::read(&conn, inserted_person.id).unwrap(); diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index 89ba5a113..c01114d9e 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -136,6 +136,7 @@ table! { community_id -> Int4, person_id -> Int4, published -> Timestamp, + expires -> Nullable, } } @@ -304,6 +305,7 @@ table! { matrix_user_id -> Nullable, admin -> Bool, bot_account -> Bool, + ban_expires -> Nullable, } } @@ -529,6 +531,7 @@ table! { matrix_user_id -> Nullable, admin -> Bool, bot_account -> Bool, + ban_expires -> Nullable, } } @@ -554,6 +557,7 @@ table! { matrix_user_id -> Nullable, admin -> Bool, bot_account -> Bool, + ban_expires -> Nullable, } } diff --git a/crates/db_schema/src/source/community.rs b/crates/db_schema/src/source/community.rs index 269e7dbf9..986015e7d 100644 --- a/crates/db_schema/src/source/community.rs +++ b/crates/db_schema/src/source/community.rs @@ -95,6 +95,7 @@ pub struct CommunityPersonBan { pub community_id: CommunityId, pub person_id: PersonId, pub published: chrono::NaiveDateTime, + pub expires: Option, } #[derive(Insertable, AsChangeset, Clone)] @@ -102,6 +103,7 @@ pub struct CommunityPersonBan { pub struct CommunityPersonBanForm { pub community_id: CommunityId, pub person_id: PersonId, + pub expires: Option>, } #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)] diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs index 8ff56eba4..978298307 100644 --- a/crates/db_schema/src/source/person.rs +++ b/crates/db_schema/src/source/person.rs @@ -27,6 +27,7 @@ pub struct Person { pub matrix_user_id: Option, pub admin: bool, pub bot_account: bool, + pub ban_expires: Option, } /// A safe representation of person, without the sensitive info @@ -50,6 +51,7 @@ pub struct PersonSafe { pub matrix_user_id: Option, pub admin: bool, pub bot_account: bool, + pub ban_expires: Option, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] @@ -75,6 +77,7 @@ pub struct PersonAlias1 { pub matrix_user_id: Option, pub admin: bool, pub bot_account: bool, + pub ban_expires: Option, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] @@ -97,6 +100,7 @@ pub struct PersonSafeAlias1 { pub matrix_user_id: Option, pub admin: bool, pub bot_account: bool, + pub ban_expires: Option, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] @@ -122,6 +126,7 @@ pub struct PersonAlias2 { pub matrix_user_id: Option, pub admin: bool, pub bot_account: bool, + pub ban_expires: Option, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] @@ -144,6 +149,7 @@ pub struct PersonSafeAlias2 { pub matrix_user_id: Option, pub admin: bool, pub bot_account: bool, + pub ban_expires: Option, } #[derive(Insertable, AsChangeset, Clone, Default)] @@ -168,4 +174,5 @@ pub struct PersonForm { pub matrix_user_id: Option>, pub admin: Option, pub bot_account: Option, + pub ban_expires: Option>, } diff --git a/crates/db_views/src/comment_report_view.rs b/crates/db_views/src/comment_report_view.rs index 343851751..52089ec57 100644 --- a/crates/db_views/src/comment_report_view.rs +++ b/crates/db_views/src/comment_report_view.rs @@ -1,4 +1,4 @@ -use diesel::{result::Error, *}; +use diesel::{dsl::*, result::Error, *}; use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, limit_and_offset, @@ -88,7 +88,12 @@ impl CommentReportView { community_person_ban::table.on( community::id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(comment::creator_id)), + .and(community_person_ban::person_id.eq(comment::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( @@ -229,7 +234,12 @@ impl<'a> CommentReportQueryBuilder<'a> { community_person_ban::table.on( community::id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(comment::creator_id)), + .and(community_person_ban::person_id.eq(comment::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( @@ -444,6 +454,7 @@ mod tests { inbox_url: inserted_jessica.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }, comment_creator: PersonSafeAlias1 { id: inserted_timmy.id, @@ -463,6 +474,7 @@ mod tests { inbox_url: inserted_timmy.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }, creator_banned_from_community: false, counts: CommentAggregates { @@ -499,6 +511,7 @@ mod tests { inbox_url: inserted_sara.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }; // Do a batch read of timmys reports @@ -554,6 +567,7 @@ mod tests { inbox_url: inserted_timmy.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }); assert_eq!( diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index 4fdd40970..6dcda899b 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -1,4 +1,4 @@ -use diesel::{result::Error, *}; +use diesel::{dsl::*, result::Error, *}; use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, functions::hot_rank, @@ -98,7 +98,12 @@ impl CommentView { community_person_ban::table.on( community::id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(comment::creator_id)), + .and(community_person_ban::person_id.eq(comment::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( @@ -345,7 +350,12 @@ impl<'a> CommentQueryBuilder<'a> { community_person_ban::table.on( community::id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(comment::creator_id)), + .and(community_person_ban::person_id.eq(comment::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( @@ -646,6 +656,7 @@ mod tests { inbox_url: inserted_person.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }, recipient: None, post: Post { diff --git a/crates/db_views/src/post_report_view.rs b/crates/db_views/src/post_report_view.rs index e5594487c..e7ba0308a 100644 --- a/crates/db_views/src/post_report_view.rs +++ b/crates/db_views/src/post_report_view.rs @@ -1,4 +1,4 @@ -use diesel::{result::Error, *}; +use diesel::{dsl::*, result::Error, *}; use lemmy_db_schema::{ aggregates::post_aggregates::PostAggregates, limit_and_offset, @@ -79,7 +79,12 @@ impl PostReportView { community_person_ban::table.on( post::community_id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(post::creator_id)), + .and(community_person_ban::person_id.eq(post::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( @@ -209,7 +214,12 @@ impl<'a> PostReportQueryBuilder<'a> { community_person_ban::table.on( post::community_id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(post::creator_id)), + .and(community_person_ban::person_id.eq(post::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( @@ -422,6 +432,7 @@ mod tests { inbox_url: inserted_jessica.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }, post_creator: PersonSafeAlias1 { id: inserted_timmy.id, @@ -441,6 +452,7 @@ mod tests { inbox_url: inserted_timmy.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }, creator_banned_from_community: false, my_vote: None, @@ -482,6 +494,7 @@ mod tests { inbox_url: inserted_sara.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }; // Do a batch read of timmys reports @@ -535,6 +548,7 @@ mod tests { inbox_url: inserted_timmy.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }); assert_eq!( diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index db7c76cda..14138374a 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -1,4 +1,4 @@ -use diesel::{pg::Pg, result::Error, *}; +use diesel::{dsl::*, pg::Pg, result::Error, *}; use lemmy_db_schema::{ aggregates::post_aggregates::PostAggregates, functions::hot_rank, @@ -86,7 +86,12 @@ impl PostView { community_person_ban::table.on( post::community_id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(post::creator_id)), + .and(community_person_ban::person_id.eq(post::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .inner_join(post_aggregates::table) @@ -284,7 +289,12 @@ impl<'a> PostQueryBuilder<'a> { community_person_ban::table.on( post::community_id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(post::creator_id)), + .and(community_person_ban::person_id.eq(post::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .inner_join(post_aggregates::table) @@ -653,6 +663,7 @@ mod tests { inbox_url: inserted_person.inbox_url.to_owned(), shared_inbox_url: None, matrix_user_id: None, + ban_expires: None, }, creator_banned_from_community: false, community: CommunitySafe { diff --git a/crates/db_views/src/registration_application_view.rs b/crates/db_views/src/registration_application_view.rs index 1a5fc9bbb..2eab15357 100644 --- a/crates/db_views/src/registration_application_view.rs +++ b/crates/db_views/src/registration_application_view.rs @@ -290,6 +290,7 @@ mod tests { actor_id: inserted_sara_person.actor_id.to_owned(), local: true, banned: false, + ban_expires: None, deleted: false, admin: false, bot_account: false, @@ -358,6 +359,7 @@ mod tests { actor_id: inserted_timmy_person.actor_id.to_owned(), local: true, banned: false, + ban_expires: None, deleted: false, admin: true, bot_account: false, diff --git a/crates/db_views_actor/src/community_person_ban_view.rs b/crates/db_views_actor/src/community_person_ban_view.rs index bffbacb12..6c67bd82a 100644 --- a/crates/db_views_actor/src/community_person_ban_view.rs +++ b/crates/db_views_actor/src/community_person_ban_view.rs @@ -1,4 +1,4 @@ -use diesel::{result::Error, *}; +use diesel::{dsl::*, result::Error, *}; use lemmy_db_schema::{ newtypes::{CommunityId, PersonId}, schema::{community, community_person_ban, person}, @@ -31,6 +31,11 @@ impl CommunityPersonBanView { )) .filter(community_person_ban::community_id.eq(from_community_id)) .filter(community_person_ban::person_id.eq(from_person_id)) + .filter( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ) .order_by(community_person_ban::published) .first::<(CommunitySafe, PersonSafe)>(conn)?; diff --git a/crates/db_views_actor/src/person_mention_view.rs b/crates/db_views_actor/src/person_mention_view.rs index 5e6e3df3f..0be446a91 100644 --- a/crates/db_views_actor/src/person_mention_view.rs +++ b/crates/db_views_actor/src/person_mention_view.rs @@ -1,4 +1,4 @@ -use diesel::{result::Error, *}; +use diesel::{dsl::*, result::Error, *}; use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, functions::hot_rank, @@ -96,7 +96,12 @@ impl PersonMentionView { community_person_ban::table.on( community::id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(comment::creator_id)), + .and(community_person_ban::person_id.eq(comment::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( @@ -241,7 +246,12 @@ impl<'a> PersonMentionQueryBuilder<'a> { community_person_ban::table.on( community::id .eq(community_person_ban::community_id) - .and(community_person_ban::person_id.eq(comment::creator_id)), + .and(community_person_ban::person_id.eq(comment::creator_id)) + .and( + community_person_ban::expires + .is_null() + .or(community_person_ban::expires.gt(now)), + ), ), ) .left_join( diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs index b6585196b..d4be05854 100644 --- a/crates/db_views_actor/src/person_view.rs +++ b/crates/db_views_actor/src/person_view.rs @@ -44,7 +44,13 @@ impl PersonViewSafe { let banned = person::table .inner_join(person_aggregates::table) .select((Person::safe_columns_tuple(), person_aggregates::all_columns)) - .filter(person::banned.eq(true)) + .filter( + person::banned.eq(true).and( + person::ban_expires + .is_null() + .or(person::ban_expires.gt(now)), + ), + ) .load::(conn)?; Ok(Self::from_tuple_to_vec(banned)) diff --git a/migrations/2021-12-14-181537_add_temporary_bans/down.sql b/migrations/2021-12-14-181537_add_temporary_bans/down.sql new file mode 100644 index 000000000..83a3715ec --- /dev/null +++ b/migrations/2021-12-14-181537_add_temporary_bans/down.sql @@ -0,0 +1,7 @@ +drop view person_alias_1, person_alias_2; + +alter table person drop column ban_expires; +alter table community_person_ban drop column expires; + +create view person_alias_1 as select * from person; +create view person_alias_2 as select * from person; diff --git a/migrations/2021-12-14-181537_add_temporary_bans/up.sql b/migrations/2021-12-14-181537_add_temporary_bans/up.sql new file mode 100644 index 000000000..7e6338361 --- /dev/null +++ b/migrations/2021-12-14-181537_add_temporary_bans/up.sql @@ -0,0 +1,8 @@ +-- Add ban_expires to person, community_person_ban +alter table person add column ban_expires timestamp; +alter table community_person_ban add column expires timestamp; + +drop view person_alias_1, person_alias_2; +create view person_alias_1 as select * from person; +create view person_alias_2 as select * from person; +