From 63d9c0ee46ff0f457c367a84e612932c46695a46 Mon Sep 17 00:00:00 2001
From: Felix Ableitner <me@nutomic.com>
Date: Wed, 10 Feb 2021 14:01:02 +0100
Subject: [PATCH] Explicitly mark posts and comments as public (ref #1220)

---
 crates/apub/src/objects/comment.rs |  3 ++-
 crates/apub/src/objects/mod.rs     | 32 +++++++++++++++++++++++++-----
 crates/apub/src/objects/post.rs    | 17 +++++-----------
 3 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs
index f20da66f..beebe833 100644
--- a/crates/apub/src/objects/comment.rs
+++ b/crates/apub/src/objects/comment.rs
@@ -18,6 +18,7 @@ use crate::{
 use activitystreams::{
   object::{kind::NoteType, ApObject, Note, Tombstone},
   prelude::*,
+  public,
 };
 use anyhow::{anyhow, Context};
 use lemmy_db_queries::{Crud, DbPool};
@@ -67,7 +68,7 @@ impl ToApub for Comment {
       .set_many_contexts(lemmy_context()?)
       .set_id(self.ap_id.to_owned().into_inner())
       .set_published(convert_datetime(self.published))
-      .set_to(community.actor_id.into_inner())
+      .set_many_tos(vec![community.actor_id.into_inner(), public()])
       .set_many_in_reply_tos(in_reply_to_vec)
       .set_attributed_to(creator.actor_id.into_inner());
 
diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs
index e32bfe72..bf0ac24c 100644
--- a/crates/apub/src/objects/mod.rs
+++ b/crates/apub/src/objects/mod.rs
@@ -11,7 +11,9 @@ use activitystreams::{
 };
 use anyhow::{anyhow, Context};
 use chrono::NaiveDateTime;
+use diesel::result::Error::NotFound;
 use lemmy_db_queries::{ApubObject, Crud, DbPool};
+use lemmy_db_schema::source::community::Community;
 use lemmy_structs::blocking;
 use lemmy_utils::{location_info, settings::Settings, utils::convert_datetime, LemmyError};
 use lemmy_websocket::LemmyContext;
@@ -217,11 +219,31 @@ where
     .as_single_xsd_any_uri()
     .context(location_info!())?;
   let user = get_or_fetch_and_upsert_user(user_id, context, request_counter).await?;
-  let community_id = object
+  let community = get_to_community(object, context, request_counter).await?;
+  check_community_or_site_ban(&user, &community, context.pool()).await
+}
+
+pub(in crate::objects) async fn get_to_community<T, Kind>(
+  object: &T,
+  context: &LemmyContext,
+  request_counter: &mut i32,
+) -> Result<Community, LemmyError>
+where
+  T: ObjectExt<Kind>,
+{
+  let community_ids = object
     .to()
     .context(location_info!())?
-    .as_single_xsd_any_uri()
-    .context(location_info!())?;
-  let community = get_or_fetch_and_upsert_community(community_id, context, request_counter).await?;
-  check_community_or_site_ban(&user, &community, context.pool()).await
+    .as_many()
+    .context(location_info!())?
+    .iter()
+    .map(|a| a.as_xsd_any_uri().context(location_info!()))
+    .collect::<Result<Vec<&Url>, anyhow::Error>>()?;
+  for cid in community_ids {
+    let community = get_or_fetch_and_upsert_community(&cid, context, request_counter).await;
+    if community.is_ok() {
+      return community;
+    }
+  }
+  Err(NotFound.into())
 }
diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs
index 1420e145..097480cf 100644
--- a/crates/apub/src/objects/post.rs
+++ b/crates/apub/src/objects/post.rs
@@ -1,12 +1,13 @@
 use crate::{
   extensions::{context::lemmy_context, page_extension::PageExtension},
-  fetcher::{community::get_or_fetch_and_upsert_community, user::get_or_fetch_and_upsert_user},
+  fetcher::user::get_or_fetch_and_upsert_user,
   objects::{
     check_object_domain,
     check_object_for_community_or_site_ban,
     create_tombstone,
     get_object_from_apub,
     get_source_markdown_value,
+    get_to_community,
     set_content_and_source,
     FromApub,
     FromApubToForm,
@@ -17,6 +18,7 @@ use crate::{
 use activitystreams::{
   object::{kind::PageType, ApObject, Image, Page, Tombstone},
   prelude::*,
+  public,
 };
 use activitystreams_ext::Ext1;
 use anyhow::Context;
@@ -60,7 +62,7 @@ impl ToApub for Post {
       // https://mastodon.xyz/@Louisa/103987265222901387.json
       .set_summary(self.name.to_owned())
       .set_published(convert_datetime(self.published))
-      .set_to(community.actor_id.into_inner())
+      .set_many_tos(vec![community.actor_id.into_inner(), public()])
       .set_attributed_to(creator.actor_id.into_inner());
 
     if let Some(body) = &self.body {
@@ -139,16 +141,7 @@ impl FromApubToForm<PageExt> for PostForm {
 
     let creator = get_or_fetch_and_upsert_user(creator_actor_id, context, request_counter).await?;
 
-    let community_actor_id = page
-      .inner
-      .to()
-      .as_ref()
-      .context(location_info!())?
-      .as_single_xsd_any_uri()
-      .context(location_info!())?;
-
-    let community =
-      get_or_fetch_and_upsert_community(community_actor_id, context, request_counter).await?;
+    let community = get_to_community(page, context, request_counter).await?;
 
     let thumbnail_url = match &page.inner.image() {
       Some(any_image) => Image::from_any_base(
-- 
2.44.1