From 492d8f1b01cd87b7f19616cb75bc50ef82fd60c9 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Mon, 29 Apr 2024 06:22:00 -0400 Subject: [PATCH] Fix communities with broken outboxes, and use PostView. Fixes #4658 (#4668) * Fix communities with broken outboxes, and use PostView. Fixes #4658 * Fixing tests. * Dont pass ref and clone. --- .../src/activities/create_or_update/post.rs | 3 +- .../apub/src/collections/community_outbox.rs | 42 +++++++++++-------- crates/apub/src/http/community.rs | 36 ++++++++++++++-- crates/db_schema/src/impls/post.rs | 16 ------- 4 files changed, 59 insertions(+), 38 deletions(-) diff --git a/crates/apub/src/activities/create_or_update/post.rs b/crates/apub/src/activities/create_or_update/post.rs index 2ca7e52cc..53900c799 100644 --- a/crates/apub/src/activities/create_or_update/post.rs +++ b/crates/apub/src/activities/create_or_update/post.rs @@ -66,7 +66,6 @@ impl CreateOrUpdatePage { kind: CreateOrUpdateType, context: Data, ) -> LemmyResult<()> { - let post = ApubPost(post); let community_id = post.community_id; let person: ApubPerson = Person::read(&mut context.pool(), person_id) .await? @@ -78,7 +77,7 @@ impl CreateOrUpdatePage { .into(); let create_or_update = - CreateOrUpdatePage::new(post, &person, &community, kind, &context).await?; + CreateOrUpdatePage::new(post.into(), &person, &community, kind, &context).await?; let is_mod_action = create_or_update.object.is_mod_action(&context).await?; let activity = AnnouncableActivities::CreateOrUpdatePost(create_or_update); send_activity_in_community( diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index 71985f946..6b66c0859 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -1,6 +1,6 @@ use crate::{ activity_lists::AnnouncableActivities, - objects::{community::ApubCommunity, post::ApubPost}, + objects::community::ApubCommunity, protocol::{ activities::{ community::announce::AnnounceActivity, @@ -18,11 +18,8 @@ use activitypub_federation::{ }; use futures::future::join_all; use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url}; -use lemmy_db_schema::{ - source::{person::Person, post::Post}, - traits::Crud, - utils::FETCH_LIMIT_MAX, -}; +use lemmy_db_schema::{utils::FETCH_LIMIT_MAX, SortType}; +use lemmy_db_views::{post_view::PostQuery, structs::SiteView}; use lemmy_utils::{ error::{LemmyError, LemmyResult}, LemmyErrorType, @@ -41,19 +38,30 @@ impl Collection for ApubCommunityOutbox { #[tracing::instrument(skip_all)] async fn read_local(owner: &Self::Owner, data: &Data) -> LemmyResult { - let post_list: Vec = Post::list_for_community(&mut data.pool(), owner.id) + let site = SiteView::read_local(&mut data.pool()) .await? - .into_iter() - .map(Into::into) - .collect(); + .ok_or(LemmyErrorType::LocalSiteNotSetup)? + .site; + + let post_views = PostQuery { + community_id: Some(owner.id), + sort: Some(SortType::New), + limit: Some(FETCH_LIMIT_MAX), + ..Default::default() + } + .list(&site, &mut data.pool()) + .await?; + let mut ordered_items = vec![]; - for post in post_list { - let person = Person::read(&mut data.pool(), post.creator_id) - .await? - .ok_or(LemmyErrorType::CouldntFindPerson)? - .into(); - let create = - CreateOrUpdatePage::new(post, &person, owner, CreateOrUpdateType::Create, data).await?; + for post_view in post_views { + let create = CreateOrUpdatePage::new( + post_view.post.into(), + &post_view.creator.into(), + owner, + CreateOrUpdateType::Create, + data, + ) + .await?; let announcable = AnnouncableActivities::CreateOrUpdatePost(create); let announce = AnnounceActivity::new(announcable.try_into()?, owner, data)?; ordered_items.push(announce); diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index c7a1f9eda..0f6ee57cb 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -128,7 +128,14 @@ pub(crate) mod tests { use crate::protocol::objects::{group::Group, tombstone::Tombstone}; use actix_web::body::to_bytes; use lemmy_db_schema::{ - source::{community::CommunityInsertForm, instance::Instance}, + newtypes::InstanceId, + source::{ + community::CommunityInsertForm, + instance::Instance, + local_site::{LocalSite, LocalSiteInsertForm}, + local_site_rate_limit::{LocalSiteRateLimit, LocalSiteRateLimitInsertForm}, + site::{Site, SiteInsertForm}, + }, traits::Crud, CommunityVisibility, }; @@ -142,6 +149,8 @@ pub(crate) mod tests { ) -> LemmyResult<(Instance, Community)> { let instance = Instance::read_or_create(&mut context.pool(), "my_domain.tld".to_string()).await?; + create_local_site(context, instance.id).await?; + let community_form = CommunityInsertForm::builder() .name("testcom6".to_string()) .title("nada".to_owned()) @@ -154,6 +163,28 @@ pub(crate) mod tests { Ok((instance, community)) } + /// Necessary for the community outbox fetching + async fn create_local_site( + context: &Data, + instance_id: InstanceId, + ) -> LemmyResult<()> { + // Create a local site, since this is necessary for community fetching. + let site_form = SiteInsertForm::builder() + .name("test site".to_string()) + .instance_id(instance_id) + .build(); + let site = Site::create(&mut context.pool(), &site_form).await?; + + let local_site_form = LocalSiteInsertForm::builder().site_id(site.id).build(); + let local_site = LocalSite::create(&mut context.pool(), &local_site_form).await?; + let local_site_rate_limit_form = LocalSiteRateLimitInsertForm::builder() + .local_site_id(local_site.id) + .build(); + + LocalSiteRateLimit::create(&mut context.pool(), &local_site_rate_limit_form).await?; + Ok(()) + } + async fn decode_response(res: HttpResponse) -> LemmyResult { let body = to_bytes(res.into_body()).await.unwrap(); let body = std::str::from_utf8(&body)?; @@ -164,6 +195,7 @@ pub(crate) mod tests { #[serial] async fn test_get_community() -> LemmyResult<()> { let context = LemmyContext::init_test_context().await; + let (instance, community) = init(false, CommunityVisibility::Public, &context).await?; // fetch invalid community let query = CommunityQuery { @@ -172,8 +204,6 @@ pub(crate) mod tests { let res = get_apub_community_http(query.into(), context.reset_request_count()).await; assert!(res.is_err()); - let (instance, community) = init(false, CommunityVisibility::Public, &context).await?; - // fetch valid community let query = CommunityQuery { community_name: community.name.clone(), diff --git a/crates/db_schema/src/impls/post.rs b/crates/db_schema/src/impls/post.rs index 2d055b1a8..d5f1cba98 100644 --- a/crates/db_schema/src/impls/post.rs +++ b/crates/db_schema/src/impls/post.rs @@ -84,22 +84,6 @@ impl Post { .await } - pub async fn list_for_community( - pool: &mut DbPool<'_>, - the_community_id: CommunityId, - ) -> Result, Error> { - let conn = &mut get_conn(pool).await?; - post::table - .filter(post::community_id.eq(the_community_id)) - .filter(post::deleted.eq(false)) - .filter(post::removed.eq(false)) - .then_order_by(post::featured_community.desc()) - .then_order_by(post::published.desc()) - .limit(FETCH_LIMIT_MAX) - .load::(conn) - .await - } - pub async fn list_featured_for_community( pool: &mut DbPool<'_>, the_community_id: CommunityId,