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.
This commit is contained in:
Dessalines 2024-04-29 06:22:00 -04:00 committed by GitHub
parent d3737d4453
commit 492d8f1b01
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 38 deletions

View file

@ -66,7 +66,6 @@ impl CreateOrUpdatePage {
kind: CreateOrUpdateType, kind: CreateOrUpdateType,
context: Data<LemmyContext>, context: Data<LemmyContext>,
) -> LemmyResult<()> { ) -> LemmyResult<()> {
let post = ApubPost(post);
let community_id = post.community_id; let community_id = post.community_id;
let person: ApubPerson = Person::read(&mut context.pool(), person_id) let person: ApubPerson = Person::read(&mut context.pool(), person_id)
.await? .await?
@ -78,7 +77,7 @@ impl CreateOrUpdatePage {
.into(); .into();
let create_or_update = 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 is_mod_action = create_or_update.object.is_mod_action(&context).await?;
let activity = AnnouncableActivities::CreateOrUpdatePost(create_or_update); let activity = AnnouncableActivities::CreateOrUpdatePost(create_or_update);
send_activity_in_community( send_activity_in_community(

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
activity_lists::AnnouncableActivities, activity_lists::AnnouncableActivities,
objects::{community::ApubCommunity, post::ApubPost}, objects::community::ApubCommunity,
protocol::{ protocol::{
activities::{ activities::{
community::announce::AnnounceActivity, community::announce::AnnounceActivity,
@ -18,11 +18,8 @@ use activitypub_federation::{
}; };
use futures::future::join_all; use futures::future::join_all;
use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url}; use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url};
use lemmy_db_schema::{ use lemmy_db_schema::{utils::FETCH_LIMIT_MAX, SortType};
source::{person::Person, post::Post}, use lemmy_db_views::{post_view::PostQuery, structs::SiteView};
traits::Crud,
utils::FETCH_LIMIT_MAX,
};
use lemmy_utils::{ use lemmy_utils::{
error::{LemmyError, LemmyResult}, error::{LemmyError, LemmyResult},
LemmyErrorType, LemmyErrorType,
@ -41,19 +38,30 @@ impl Collection for ApubCommunityOutbox {
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn read_local(owner: &Self::Owner, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> { async fn read_local(owner: &Self::Owner, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> {
let post_list: Vec<ApubPost> = Post::list_for_community(&mut data.pool(), owner.id) let site = SiteView::read_local(&mut data.pool())
.await? .await?
.into_iter() .ok_or(LemmyErrorType::LocalSiteNotSetup)?
.map(Into::into) .site;
.collect();
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![]; let mut ordered_items = vec![];
for post in post_list { for post_view in post_views {
let person = Person::read(&mut data.pool(), post.creator_id) let create = CreateOrUpdatePage::new(
.await? post_view.post.into(),
.ok_or(LemmyErrorType::CouldntFindPerson)? &post_view.creator.into(),
.into(); owner,
let create = CreateOrUpdateType::Create,
CreateOrUpdatePage::new(post, &person, owner, CreateOrUpdateType::Create, data).await?; data,
)
.await?;
let announcable = AnnouncableActivities::CreateOrUpdatePost(create); let announcable = AnnouncableActivities::CreateOrUpdatePost(create);
let announce = AnnounceActivity::new(announcable.try_into()?, owner, data)?; let announce = AnnounceActivity::new(announcable.try_into()?, owner, data)?;
ordered_items.push(announce); ordered_items.push(announce);

View file

@ -128,7 +128,14 @@ pub(crate) mod tests {
use crate::protocol::objects::{group::Group, tombstone::Tombstone}; use crate::protocol::objects::{group::Group, tombstone::Tombstone};
use actix_web::body::to_bytes; use actix_web::body::to_bytes;
use lemmy_db_schema::{ 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, traits::Crud,
CommunityVisibility, CommunityVisibility,
}; };
@ -142,6 +149,8 @@ pub(crate) mod tests {
) -> LemmyResult<(Instance, Community)> { ) -> LemmyResult<(Instance, Community)> {
let instance = let instance =
Instance::read_or_create(&mut context.pool(), "my_domain.tld".to_string()).await?; 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() let community_form = CommunityInsertForm::builder()
.name("testcom6".to_string()) .name("testcom6".to_string())
.title("nada".to_owned()) .title("nada".to_owned())
@ -154,6 +163,28 @@ pub(crate) mod tests {
Ok((instance, community)) Ok((instance, community))
} }
/// Necessary for the community outbox fetching
async fn create_local_site(
context: &Data<LemmyContext>,
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<T: DeserializeOwned>(res: HttpResponse) -> LemmyResult<T> { async fn decode_response<T: DeserializeOwned>(res: HttpResponse) -> LemmyResult<T> {
let body = to_bytes(res.into_body()).await.unwrap(); let body = to_bytes(res.into_body()).await.unwrap();
let body = std::str::from_utf8(&body)?; let body = std::str::from_utf8(&body)?;
@ -164,6 +195,7 @@ pub(crate) mod tests {
#[serial] #[serial]
async fn test_get_community() -> LemmyResult<()> { async fn test_get_community() -> LemmyResult<()> {
let context = LemmyContext::init_test_context().await; let context = LemmyContext::init_test_context().await;
let (instance, community) = init(false, CommunityVisibility::Public, &context).await?;
// fetch invalid community // fetch invalid community
let query = CommunityQuery { let query = CommunityQuery {
@ -172,8 +204,6 @@ pub(crate) mod tests {
let res = get_apub_community_http(query.into(), context.reset_request_count()).await; let res = get_apub_community_http(query.into(), context.reset_request_count()).await;
assert!(res.is_err()); assert!(res.is_err());
let (instance, community) = init(false, CommunityVisibility::Public, &context).await?;
// fetch valid community // fetch valid community
let query = CommunityQuery { let query = CommunityQuery {
community_name: community.name.clone(), community_name: community.name.clone(),

View file

@ -84,22 +84,6 @@ impl Post {
.await .await
} }
pub async fn list_for_community(
pool: &mut DbPool<'_>,
the_community_id: CommunityId,
) -> Result<Vec<Self>, 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::<Self>(conn)
.await
}
pub async fn list_featured_for_community( pub async fn list_featured_for_community(
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
the_community_id: CommunityId, the_community_id: CommunityId,