From efee2062dde40e002f0d45d21dfe9ea0063f1c67 Mon Sep 17 00:00:00 2001 From: Nutomic Date: Wed, 21 Apr 2021 21:41:14 +0000 Subject: [PATCH] Mark accounts as bot nutomic (#1565) * Mark account as bot. Fixes #1357 * Fix clippy * Federate bot status using actor `type` field * fix clippy Co-authored-by: Dessalines --- crates/api/src/local_user.rs | 6 +++ crates/api/src/site.rs | 17 ++++++-- crates/api_common/src/lib.rs | 16 +++++++ crates/api_common/src/person.rs | 2 + crates/api_crud/src/comment/read.rs | 10 ++++- crates/api_crud/src/post/read.rs | 19 ++++++--- crates/api_crud/src/user/create.rs | 1 + crates/api_crud/src/user/read.rs | 16 ++++--- crates/apub/src/lib.rs | 9 +++- crates/apub/src/objects/person.rs | 19 +++++++-- crates/db_queries/src/source/local_user.rs | 2 + crates/db_queries/src/source/person.rs | 7 ++++ crates/db_schema/src/schema.rs | 4 ++ crates/db_schema/src/source/local_user.rs | 3 ++ crates/db_schema/src/source/person.rs | 7 ++++ crates/db_views/src/comment_view.rs | 12 ++++++ crates/db_views/src/post_view.rs | 42 +++++++++++++++++-- crates/routes/src/feeds.rs | 10 ++++- .../down.sql | 6 +++ .../2021-03-31-105915_add_bot_account/up.sql | 8 ++++ 20 files changed, 191 insertions(+), 25 deletions(-) create mode 100644 migrations/2021-03-31-105915_add_bot_account/down.sql create mode 100644 migrations/2021-03-31-105915_add_bot_account/up.sql diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index 241e3405f..b273b5820 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -169,6 +169,7 @@ impl Perform for SaveUserSettings { let bio = diesel_option_overwrite(&data.bio); let display_name = diesel_option_overwrite(&data.display_name); let matrix_user_id = diesel_option_overwrite(&data.matrix_user_id); + let bot_account = data.bot_account; if let Some(Some(bio)) = &bio { if bio.chars().count() > 300 { @@ -213,6 +214,7 @@ impl Perform for SaveUserSettings { last_refreshed_at: None, shared_inbox_url: None, matrix_user_id, + bot_account, }; let person_res = blocking(context.pool(), move |conn| { @@ -231,6 +233,7 @@ impl Perform for SaveUserSettings { email, password_encrypted, show_nsfw: data.show_nsfw, + show_bot_accounts: data.show_bot_accounts, show_scores: data.show_scores, theme: data.theme.to_owned(), default_sort_type, @@ -465,11 +468,14 @@ impl Perform for GetReplies { let limit = data.limit; let unread_only = data.unread_only; let person_id = local_user_view.person.id; + let show_bot_accounts = local_user_view.local_user.show_bot_accounts; + let replies = blocking(context.pool(), move |conn| { CommentQueryBuilder::create(conn) .sort(&sort) .unread_only(unread_only) .recipient_id(person_id) + .show_bot_accounts(show_bot_accounts) .my_person_id(person_id) .page(page) .limit(limit) diff --git a/crates/api/src/site.rs b/crates/api/src/site.rs index cc61b5206..aae400ca7 100644 --- a/crates/api/src/site.rs +++ b/crates/api/src/site.rs @@ -9,6 +9,8 @@ use lemmy_api_common::{ get_local_user_view_from_jwt_opt, is_admin, site::*, + user_show_bot_accounts, + user_show_nsfw, }; use lemmy_apub::fetcher::search::search_by_apub_id; use lemmy_db_queries::{source::site::Site_, Crud, SearchType, SortType}; @@ -136,6 +138,10 @@ impl Perform for Search { } let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; + + let show_nsfw = user_show_nsfw(&local_user_view); + let show_bot_accounts = user_show_bot_accounts(&local_user_view); + let person_id = local_user_view.map(|u| u.person.id); let type_ = SearchType::from_str(&data.type_)?; @@ -158,7 +164,8 @@ impl Perform for Search { posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) .sort(&sort) - .show_nsfw(true) + .show_nsfw(show_nsfw) + .show_bot_accounts(show_bot_accounts) .community_id(community_id) .community_name(community_name) .my_person_id(person_id) @@ -174,6 +181,7 @@ impl Perform for Search { CommentQueryBuilder::create(&conn) .sort(&sort) .search_term(q) + .show_bot_accounts(show_bot_accounts) .my_person_id(person_id) .page(page) .limit(limit) @@ -208,7 +216,8 @@ impl Perform for Search { posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) .sort(&sort) - .show_nsfw(true) + .show_nsfw(show_nsfw) + .show_bot_accounts(show_bot_accounts) .community_id(community_id) .community_name(community_name) .my_person_id(person_id) @@ -226,6 +235,7 @@ impl Perform for Search { CommentQueryBuilder::create(conn) .sort(&sort) .search_term(q) + .show_bot_accounts(show_bot_accounts) .my_person_id(person_id) .page(page) .limit(limit) @@ -264,7 +274,8 @@ impl Perform for Search { posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) .sort(&sort) - .show_nsfw(true) + .show_nsfw(show_nsfw) + .show_bot_accounts(show_bot_accounts) .my_person_id(person_id) .community_id(community_id) .community_name(community_name) diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index dca09b97e..1a644b7d4 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -236,6 +236,22 @@ pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> { Ok(()) } +/// A helper method for showing the bot account +pub fn user_show_bot_accounts(local_user_view: &Option) -> bool { + match local_user_view { + Some(uv) => uv.to_owned().local_user.show_bot_accounts, + None => true, + } +} + +/// A helper method for showing nsfw +pub fn user_show_nsfw(local_user_view: &Option) -> bool { + match &local_user_view { + Some(uv) => uv.local_user.show_nsfw, + None => false, + } +} + pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result { blocking(pool, move |conn| Post::read(conn, post_id)) .await? diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index fc061a35b..5473a4820 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -60,6 +60,8 @@ pub struct SaveUserSettings { pub matrix_user_id: Option, pub show_avatars: Option, pub send_notifications_to_email: Option, + pub bot_account: Option, + pub show_bot_accounts: Option, pub auth: String, } diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index 17f3a57d1..4d1443820 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -1,6 +1,11 @@ use crate::PerformCrud; use actix_web::web::Data; -use lemmy_api_common::{blocking, comment::*, get_local_user_view_from_jwt_opt}; +use lemmy_api_common::{ + blocking, + comment::*, + get_local_user_view_from_jwt_opt, + user_show_bot_accounts, +}; use lemmy_db_queries::{ListingType, SortType}; use lemmy_db_views::comment_view::CommentQueryBuilder; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; @@ -18,6 +23,8 @@ impl PerformCrud for GetComments { ) -> Result { let data: &GetComments = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; + + let show_bot_accounts = user_show_bot_accounts(&local_user_view); let person_id = local_user_view.map(|u| u.person.id); let type_ = ListingType::from_str(&data.type_)?; @@ -36,6 +43,7 @@ impl PerformCrud for GetComments { .community_id(community_id) .community_name(community_name) .my_person_id(person_id) + .show_bot_accounts(show_bot_accounts) .page(page) .limit(limit) .list() diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 323889101..d2231d24b 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -1,6 +1,12 @@ use crate::PerformCrud; use actix_web::web::Data; -use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, post::*}; +use lemmy_api_common::{ + blocking, + get_local_user_view_from_jwt_opt, + post::*, + user_show_bot_accounts, + user_show_nsfw, +}; use lemmy_db_queries::{ListingType, SortType}; use lemmy_db_views::{ comment_view::CommentQueryBuilder, @@ -25,6 +31,9 @@ impl PerformCrud for GetPost { ) -> Result { let data: &GetPost = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; + + let show_bot_accounts = user_show_bot_accounts(&local_user_view); + let person_id = local_user_view.map(|u| u.person.id); let id = data.id; @@ -38,6 +47,7 @@ impl PerformCrud for GetPost { let comments = blocking(context.pool(), move |conn| { CommentQueryBuilder::create(conn) .my_person_id(person_id) + .show_bot_accounts(show_bot_accounts) .post_id(id) .limit(9999) .list() @@ -88,10 +98,8 @@ impl PerformCrud for GetPosts { let person_id = local_user_view.to_owned().map(|l| l.person.id); - let show_nsfw = match &local_user_view { - Some(uv) => uv.local_user.show_nsfw, - None => false, - }; + let show_nsfw = user_show_nsfw(&local_user_view); + let show_bot_accounts = user_show_bot_accounts(&local_user_view); let type_ = ListingType::from_str(&data.type_)?; let sort = SortType::from_str(&data.sort)?; @@ -107,6 +115,7 @@ impl PerformCrud for GetPosts { .listing_type(&type_) .sort(&sort) .show_nsfw(show_nsfw) + .show_bot_accounts(show_bot_accounts) .community_id(community_id) .community_name(community_name) .saved_only(saved_only) diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index be9fdbed9..097555561 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -123,6 +123,7 @@ impl PerformCrud for Register { email: Some(data.email.to_owned()), password_encrypted: data.password.to_owned(), show_nsfw: Some(data.show_nsfw), + show_bot_accounts: Some(true), theme: Some("browser".into()), default_sort_type: Some(SortType::Active as i16), default_listing_type: Some(ListingType::Subscribed as i16), diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index 710bccb75..24ac2f61e 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -1,6 +1,12 @@ use crate::PerformCrud; use actix_web::web::Data; -use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*}; +use lemmy_api_common::{ + blocking, + get_local_user_view_from_jwt_opt, + person::*, + user_show_bot_accounts, + user_show_nsfw, +}; use lemmy_db_queries::{source::person::Person_, SortType}; use lemmy_db_schema::source::person::*; use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder}; @@ -25,10 +31,8 @@ impl PerformCrud for GetPersonDetails { let data: &GetPersonDetails = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; - let show_nsfw = match &local_user_view { - Some(uv) => uv.local_user.show_nsfw, - None => false, - }; + let show_nsfw = user_show_nsfw(&local_user_view); + let show_bot_accounts = user_show_bot_accounts(&local_user_view); let sort = SortType::from_str(&data.sort)?; @@ -67,6 +71,7 @@ impl PerformCrud for GetPersonDetails { let mut posts_query = PostQueryBuilder::create(conn) .sort(&sort) .show_nsfw(show_nsfw) + .show_bot_accounts(show_bot_accounts) .saved_only(saved_only) .community_id(community_id) .my_person_id(person_id) @@ -75,6 +80,7 @@ impl PerformCrud for GetPersonDetails { let mut comments_query = CommentQueryBuilder::create(conn) .my_person_id(person_id) + .show_bot_accounts(show_bot_accounts) .sort(&sort) .saved_only(saved_only) .community_id(community_id) diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 394de73bb..fe63d4d58 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -50,11 +50,18 @@ use url::{ParseError, Url}; pub type GroupExt = Ext2>, GroupExtension, PublicKeyExtension>; /// Activitystreams type for person -type PersonExt = Ext2>, PersonExtension, PublicKeyExtension>; +type PersonExt = + Ext2>>, PersonExtension, PublicKeyExtension>; /// Activitystreams type for post pub type PageExt = Ext1, PageExtension>; pub type NoteExt = ApObject; +#[derive(Clone, Copy, Debug, serde::Deserialize, serde::Serialize, PartialEq)] +pub enum UserTypes { + Person, + Service, +} + pub static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json"; /// Checks if the ID is allowed for sending or receiving. diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 34146dc25..a508f4e08 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -10,11 +10,12 @@ use crate::{ }, ActorType, PersonExt, + UserTypes, }; use activitystreams::{ - actor::{ApActor, Endpoints, Person}, - object::{ApObject, Image, Tombstone}, - prelude::*, + actor::{Actor, ApActor, ApActorExt, Endpoints}, + base::{BaseExt, ExtendsExt}, + object::{ApObject, Image, Object, ObjectExt, Tombstone}, }; use activitystreams_ext::Ext2; use anyhow::Context; @@ -38,7 +39,16 @@ impl ToApub for DbPerson { type ApubType = PersonExt; async fn to_apub(&self, _pool: &DbPool) -> Result { - let mut person = ApObject::new(Person::new()); + let object = Object::::new_none_type(); + let mut actor = Actor(object); + let kind = if self.bot_account { + UserTypes::Service + } else { + UserTypes::Person + }; + actor.set_kind(kind); + let mut person = ApObject::new(actor); + person .set_many_contexts(lemmy_context()?) .set_id(self.actor_id.to_owned().into_inner()) @@ -193,6 +203,7 @@ impl FromApubToForm for PersonForm { bio: Some(bio), local: Some(false), admin: Some(false), + bot_account: Some(person.inner.is_kind(&UserTypes::Service)), private_key: None, public_key: Some(Some(person.ext_two.public_key.to_owned().public_key_pem)), last_refreshed_at: Some(naive_now()), diff --git a/crates/db_queries/src/source/local_user.rs b/crates/db_queries/src/source/local_user.rs index d1fad2e85..43a5c7727 100644 --- a/crates/db_queries/src/source/local_user.rs +++ b/crates/db_queries/src/source/local_user.rs @@ -24,6 +24,7 @@ mod safe_settings_type { show_avatars, send_notifications_to_email, validator_time, + show_bot_accounts, show_scores, ); @@ -44,6 +45,7 @@ mod safe_settings_type { show_avatars, send_notifications_to_email, validator_time, + show_bot_accounts, show_scores, ) } diff --git a/crates/db_queries/src/source/person.rs b/crates/db_queries/src/source/person.rs index 2d332bd01..4624ae191 100644 --- a/crates/db_queries/src/source/person.rs +++ b/crates/db_queries/src/source/person.rs @@ -29,6 +29,7 @@ mod safe_type { shared_inbox_url, matrix_user_id, admin, + bot_account, ); impl ToSafe for Person { @@ -51,6 +52,7 @@ mod safe_type { shared_inbox_url, matrix_user_id, admin, + bot_account, ) } } @@ -77,6 +79,7 @@ mod safe_type_alias_1 { shared_inbox_url, matrix_user_id, admin, + bot_account, ); impl ToSafe for PersonAlias1 { @@ -99,6 +102,7 @@ mod safe_type_alias_1 { shared_inbox_url, matrix_user_id, admin, + bot_account, ) } } @@ -125,6 +129,7 @@ mod safe_type_alias_2 { shared_inbox_url, matrix_user_id, admin, + bot_account, ); impl ToSafe for PersonAlias2 { @@ -147,6 +152,7 @@ mod safe_type_alias_2 { shared_inbox_url, matrix_user_id, admin, + bot_account, ) } } @@ -274,6 +280,7 @@ mod tests { actor_id: inserted_person.actor_id.to_owned(), bio: None, local: true, + bot_account: false, admin: false, private_key: None, public_key: None, diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index 9b05d29ab..f92e43f72 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -153,6 +153,7 @@ table! { show_avatars -> Bool, send_notifications_to_email -> Bool, validator_time -> Timestamp, + show_bot_accounts -> Bool, show_scores -> Bool, } } @@ -287,6 +288,7 @@ table! { shared_inbox_url -> Nullable, matrix_user_id -> Nullable, admin -> Bool, + bot_account -> Bool, } } @@ -488,6 +490,7 @@ table! { shared_inbox_url -> Nullable, matrix_user_id -> Nullable, admin -> Bool, + bot_account -> Bool, } } @@ -512,6 +515,7 @@ table! { shared_inbox_url -> Nullable, matrix_user_id -> Nullable, admin -> Bool, + bot_account -> Bool, } } diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs index 0a7181fdb..64afb49a4 100644 --- a/crates/db_schema/src/source/local_user.rs +++ b/crates/db_schema/src/source/local_user.rs @@ -16,6 +16,7 @@ pub struct LocalUser { pub show_avatars: bool, pub send_notifications_to_email: bool, pub validator_time: chrono::NaiveDateTime, + pub show_bot_accounts: bool, pub show_scores: bool, } @@ -33,6 +34,7 @@ pub struct LocalUserForm { pub lang: Option, pub show_avatars: Option, pub send_notifications_to_email: Option, + pub show_bot_accounts: Option, pub show_scores: Option, } @@ -51,5 +53,6 @@ pub struct LocalUserSettings { pub show_avatars: bool, pub send_notifications_to_email: bool, pub validator_time: chrono::NaiveDateTime, + pub show_bot_accounts: bool, pub show_scores: bool, } diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs index be1ce268f..965378616 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 shared_inbox_url: Option, pub matrix_user_id: Option, pub admin: bool, + pub bot_account: bool, } /// A safe representation of person, without the sensitive info @@ -49,6 +50,7 @@ pub struct PersonSafe { pub shared_inbox_url: Option, pub matrix_user_id: Option, pub admin: bool, + pub bot_account: bool, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)] @@ -73,6 +75,7 @@ pub struct PersonAlias1 { pub shared_inbox_url: Option, pub matrix_user_id: Option, pub admin: bool, + pub bot_account: bool, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)] @@ -94,6 +97,7 @@ pub struct PersonSafeAlias1 { pub shared_inbox_url: Option, pub matrix_user_id: Option, pub admin: bool, + pub bot_account: bool, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)] @@ -118,6 +122,7 @@ pub struct PersonAlias2 { pub shared_inbox_url: Option, pub matrix_user_id: Option, pub admin: bool, + pub bot_account: bool, } #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)] @@ -139,6 +144,7 @@ pub struct PersonSafeAlias2 { pub shared_inbox_url: Option, pub matrix_user_id: Option, pub admin: bool, + pub bot_account: bool, } #[derive(Insertable, AsChangeset, Clone, Default)] @@ -162,4 +168,5 @@ pub struct PersonForm { pub shared_inbox_url: Option>, pub matrix_user_id: Option>, pub admin: Option, + pub bot_account: Option, } diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index fd2debf2c..b85b1c77a 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -183,6 +183,7 @@ pub struct CommentQueryBuilder<'a> { search_term: Option, saved_only: bool, unread_only: bool, + show_bot_accounts: bool, page: Option, limit: Option, } @@ -202,6 +203,7 @@ impl<'a> CommentQueryBuilder<'a> { search_term: None, saved_only: false, unread_only: false, + show_bot_accounts: true, page: None, limit: None, } @@ -262,6 +264,11 @@ impl<'a> CommentQueryBuilder<'a> { self } + pub fn show_bot_accounts(mut self, show_bot_accounts: bool) -> Self { + self.show_bot_accounts = show_bot_accounts; + self + } + pub fn page>(mut self, page: T) -> Self { self.page = page.get_optional(); self @@ -380,6 +387,10 @@ impl<'a> CommentQueryBuilder<'a> { query = query.filter(comment_saved::id.is_not_null()); } + if !self.show_bot_accounts { + query = query.filter(person::bot_account.eq(false)); + }; + query = match self.sort { SortType::Hot | SortType::Active => query .order_by(hot_rank(comment_aggregates::score, comment_aggregates::published).desc()) @@ -526,6 +537,7 @@ mod tests { banned: false, deleted: false, admin: false, + bot_account: false, bio: None, banner: None, updated: None, diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index a6843416e..8248bfd29 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -164,6 +164,7 @@ pub struct PostQueryBuilder<'a> { search_term: Option, url_search: Option, show_nsfw: bool, + show_bot_accounts: bool, saved_only: bool, unread_only: bool, page: Option, @@ -183,6 +184,7 @@ impl<'a> PostQueryBuilder<'a> { search_term: None, url_search: None, show_nsfw: true, + show_bot_accounts: true, saved_only: false, unread_only: false, page: None, @@ -235,6 +237,11 @@ impl<'a> PostQueryBuilder<'a> { self } + pub fn show_bot_accounts(mut self, show_bot_accounts: bool) -> Self { + self.show_bot_accounts = show_bot_accounts; + self + } + pub fn saved_only(mut self, saved_only: bool) -> Self { self.saved_only = saved_only; self @@ -351,6 +358,10 @@ impl<'a> PostQueryBuilder<'a> { .filter(community::nsfw.eq(false)); }; + if !self.show_bot_accounts { + query = query.filter(person::bot_account.eq(false)); + }; + // TODO These two might be wrong if self.saved_only { query = query.filter(post_saved::id.is_not_null()); @@ -451,6 +462,7 @@ mod tests { let person_name = "tegan".to_string(); let community_name = "test_community_3".to_string(); let post_name = "test post 3".to_string(); + let bot_post_name = "test bot post".to_string(); let new_person = PersonForm { name: person_name.to_owned(), @@ -459,6 +471,14 @@ mod tests { let inserted_person = Person::create(&conn, &new_person).unwrap(); + let new_bot = PersonForm { + name: person_name.to_owned(), + bot_account: Some(true), + ..PersonForm::default() + }; + + let inserted_bot = Person::create(&conn, &new_bot).unwrap(); + let new_community = CommunityForm { name: community_name.to_owned(), title: "nada".to_owned(), @@ -476,6 +496,15 @@ mod tests { let inserted_post = Post::create(&conn, &new_post).unwrap(); + let new_bot_post = PostForm { + name: bot_post_name, + creator_id: inserted_bot.id, + community_id: inserted_community.id, + ..PostForm::default() + }; + + let _inserted_bot_post = Post::create(&conn, &new_bot_post).unwrap(); + let post_like_form = PostLikeForm { post_id: inserted_post.id, person_id: inserted_person.id, @@ -495,6 +524,7 @@ mod tests { let read_post_listings_with_person = PostQueryBuilder::create(&conn) .listing_type(&ListingType::Community) .sort(&SortType::New) + .show_bot_accounts(false) .community_id(inserted_community.id) .my_person_id(inserted_person.id) .list() @@ -546,6 +576,7 @@ mod tests { actor_id: inserted_person.actor_id.to_owned(), local: true, admin: false, + bot_account: false, banned: false, deleted: false, bio: None, @@ -596,6 +627,7 @@ mod tests { let num_deleted = Post::delete(&conn, inserted_post.id).unwrap(); Community::delete(&conn, inserted_community.id).unwrap(); Person::delete(&conn, inserted_person.id).unwrap(); + Person::delete(&conn, inserted_bot.id).unwrap(); // The with user assert_eq!( @@ -606,18 +638,20 @@ mod tests { expected_post_listing_with_user, read_post_listing_with_person ); + + // Should be only one person, IE the bot post should be missing assert_eq!(1, read_post_listings_with_person.len()); // Without the user assert_eq!( expected_post_listing_no_person, - read_post_listings_no_person[0] + read_post_listings_no_person[1] ); assert_eq!(expected_post_listing_no_person, read_post_listing_no_person); - assert_eq!(1, read_post_listings_no_person.len()); - // assert_eq!(expected_post, inserted_post); - // assert_eq!(expected_post, updated_post); + // Should be 2 posts, with the bot post + assert_eq!(2, read_post_listings_no_person.len()); + assert_eq!(expected_post_like, inserted_post_like); assert_eq!(1, like_removed); assert_eq!(1, num_deleted); diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 9181a129b..21263fd61 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -228,11 +228,14 @@ fn get_feed_front( ) -> Result { let site_view = SiteView::read(&conn)?; let local_user_id = LocalUserId(Claims::decode(&jwt)?.claims.sub); - let person_id = LocalUser::read(&conn, local_user_id)?.person_id; + let local_user = LocalUser::read(&conn, local_user_id)?; + let person_id = local_user.person_id; + let show_bot_accounts = local_user.show_bot_accounts; let posts = PostQueryBuilder::create(&conn) .listing_type(&ListingType::Subscribed) .my_person_id(person_id) + .show_bot_accounts(show_bot_accounts) .sort(sort_type) .list()?; @@ -255,13 +258,16 @@ fn get_feed_front( fn get_feed_inbox(conn: &PgConnection, jwt: String) -> Result { let site_view = SiteView::read(&conn)?; let local_user_id = LocalUserId(Claims::decode(&jwt)?.claims.sub); - let person_id = LocalUser::read(&conn, local_user_id)?.person_id; + let local_user = LocalUser::read(&conn, local_user_id)?; + let person_id = local_user.person_id; + let show_bot_accounts = local_user.show_bot_accounts; let sort = SortType::New; let replies = CommentQueryBuilder::create(&conn) .recipient_id(person_id) .my_person_id(person_id) + .show_bot_accounts(show_bot_accounts) .sort(&sort) .list()?; diff --git a/migrations/2021-03-31-105915_add_bot_account/down.sql b/migrations/2021-03-31-105915_add_bot_account/down.sql new file mode 100644 index 000000000..4f407ce86 --- /dev/null +++ b/migrations/2021-03-31-105915_add_bot_account/down.sql @@ -0,0 +1,6 @@ +drop view person_alias_1, person_alias_2; +alter table person drop column bot_account; +create view person_alias_1 as select * from person; +create view person_alias_2 as select * from person; + +alter table local_user drop column show_bot_accounts; diff --git a/migrations/2021-03-31-105915_add_bot_account/up.sql b/migrations/2021-03-31-105915_add_bot_account/up.sql new file mode 100644 index 000000000..a1e207a1d --- /dev/null +++ b/migrations/2021-03-31-105915_add_bot_account/up.sql @@ -0,0 +1,8 @@ +-- Add the bot_account column to the person table +drop view person_alias_1, person_alias_2; +alter table person add column bot_account boolean not null default false; +create view person_alias_1 as select * from person; +create view person_alias_2 as select * from person; + +-- Add the show_bot_accounts to the local user table as a setting +alter table local_user add column show_bot_accounts boolean not null default true;