From: Felix Ableitner <me@nutomic.com>
Date: Thu, 28 Oct 2021 11:46:48 +0000 (+0200)
Subject: When receiving activity, dont read community from cc (for pleroma compat and better... 
X-Git-Url: http://these/git/readmes/%7B%60%24%7BwebArchiveUrl%7D/save/static/README.es.md?a=commitdiff_plain;h=271785b7fbe824628d79187f33be3c2e75f42d1b;p=lemmy.git

When receiving activity, dont read community from cc (for pleroma compat and better verification)
---

diff --git a/crates/apub/src/activities/comment/create_or_update.rs b/crates/apub/src/activities/comment/create_or_update.rs
index 537563e9..f8469be9 100644
--- a/crates/apub/src/activities/comment/create_or_update.rs
+++ b/crates/apub/src/activities/comment/create_or_update.rs
@@ -2,8 +2,10 @@ use crate::{
   activities::{
     check_community_deleted_or_removed,
     comment::{collect_non_local_mentions, get_notif_recipients},
-    community::{announce::AnnouncableActivities, send_to_community},
-    extract_community,
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -108,12 +110,11 @@ impl ActivityHandler for CreateOrUpdateComment {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
-    let community = extract_community(&self.cc, context, request_counter).await?;
-    let community_id = ObjectId::new(community.actor_id());
     let post = self.object.get_parents(context, request_counter).await?.0;
+    let community = self.get_community(context, request_counter).await?;
 
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &community_id, context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_domains_match(self.actor.inner(), self.object.id_unchecked())?;
     check_community_deleted_or_removed(&community)?;
     check_post_deleted_or_removed(&post)?;
@@ -144,6 +145,22 @@ impl ActivityHandler for CreateOrUpdateComment {
   }
 }
 
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for CreateOrUpdateComment {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let post = self.object.get_parents(context, request_counter).await?.0;
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, post.community_id)
+    })
+    .await??;
+    Ok(community.into())
+  }
+}
+
 #[cfg(test)]
 mod tests {
   use super::*;
diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs
index 6df6f812..876fcc94 100644
--- a/crates/apub/src/activities/community/add_mod.rs
+++ b/crates/apub/src/activities/community/add_mod.rs
@@ -1,6 +1,10 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      get_community_from_moderators_url,
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_add_remove_moderator_target,
@@ -91,7 +95,8 @@ impl ActivityHandler for AddMod {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_add_remove_moderator_target(&self.target, &self.cc[0])?;
     Ok(())
@@ -102,7 +107,7 @@ impl ActivityHandler for AddMod {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.cc[0].dereference(context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
     let new_mod = self.object.dereference(context, request_counter).await?;
 
     // If we had to refetch the community while parsing the activity, then the new mod has already
@@ -126,3 +131,14 @@ impl ActivityHandler for AddMod {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for AddMod {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    get_community_from_moderators_url(&self.target, context, request_counter).await
+  }
+}
diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs
index deca2b73..6165eb2f 100644
--- a/crates/apub/src/activities/community/announce.rs
+++ b/crates/apub/src/activities/community/announce.rs
@@ -13,7 +13,6 @@ use crate::{
     generate_activity_id,
     post::create_or_update::CreateOrUpdatePost,
     verify_activity,
-    verify_community,
     verify_is_public,
     voting::{undo_vote::UndoVote, vote::Vote},
   },
@@ -23,7 +22,6 @@ use crate::{
   insert_activity,
   objects::community::ApubCommunity,
   send_lemmy_activity,
-  CommunityType,
 };
 use activitystreams::{
   activity::kind::AnnounceType,
@@ -35,6 +33,7 @@ use activitystreams::{
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
+  verify::verify_urls_match,
 };
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
@@ -58,6 +57,41 @@ pub enum AnnouncableActivities {
   RemoveMod(RemoveMod),
 }
 
+#[async_trait::async_trait(?Send)]
+pub(crate) trait GetCommunity {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError>;
+}
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for AnnouncableActivities {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    use AnnouncableActivities::*;
+    let community = match self {
+      CreateOrUpdateComment(a) => a.get_community(context, request_counter).await?,
+      CreateOrUpdatePost(a) => a.get_community(context, request_counter).await?,
+      Vote(a) => a.get_community(context, request_counter).await?,
+      UndoVote(a) => a.get_community(context, request_counter).await?,
+      Delete(a) => a.get_community(context, request_counter).await?,
+      UndoDelete(a) => a.get_community(context, request_counter).await?,
+      UpdateCommunity(a) => a.get_community(context, request_counter).await?,
+      BlockUserFromCommunity(a) => a.get_community(context, request_counter).await?,
+      UndoBlockUserFromCommunity(a) => a.get_community(context, request_counter).await?,
+      AddMod(a) => a.get_community(context, request_counter).await?,
+      RemoveMod(a) => a.get_community(context, request_counter).await?,
+    };
+    verify_urls_match(self.actor(), &community.actor_id())?;
+    Ok(community)
+  }
+}
+
 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
 #[serde(rename_all = "camelCase")]
 pub struct AnnounceActivity {
@@ -85,7 +119,7 @@ impl AnnounceActivity {
       actor: ObjectId::new(community.actor_id()),
       to: vec![public()],
       object,
-      cc: vec![community.followers_url()],
+      cc: vec![community.followers_url.clone().into_inner()],
       kind: AnnounceType::Announce,
       id: generate_activity_id(
         &AnnounceType::Announce,
@@ -109,7 +143,6 @@ impl ActivityHandler for AnnounceActivity {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_community(&self.actor, context, request_counter).await?;
     self.object.verify(context, request_counter).await?;
     Ok(())
   }
diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs
index 64a030c8..35cde2e6 100644
--- a/crates/apub/src/activities/community/block_user.rs
+++ b/crates/apub/src/activities/community/block_user.rs
@@ -1,6 +1,9 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -44,6 +47,7 @@ pub struct BlockUserFromCommunity {
   to: Vec<Url>,
   pub(in crate::activities::community) object: ObjectId<ApubPerson>,
   cc: [ObjectId<ApubCommunity>; 1],
+  target: ObjectId<ApubCommunity>,
   #[serde(rename = "type")]
   kind: BlockType,
   id: Url,
@@ -65,6 +69,7 @@ impl BlockUserFromCommunity {
       to: vec![public()],
       object: ObjectId::new(target.actor_id()),
       cc: [ObjectId::new(community.actor_id())],
+      target: ObjectId::new(community.actor_id()),
       kind: BlockType::Block,
       id: generate_activity_id(
         BlockType::Block,
@@ -100,7 +105,8 @@ impl ActivityHandler for BlockUserFromCommunity {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
     Ok(())
   }
@@ -110,7 +116,7 @@ impl ActivityHandler for BlockUserFromCommunity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.cc[0].dereference(context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
     let blocked_user = self.object.dereference(context, request_counter).await?;
 
     let community_user_ban_form = CommunityPersonBanForm {
@@ -138,3 +144,14 @@ impl ActivityHandler for BlockUserFromCommunity {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for BlockUserFromCommunity {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    self.target.dereference(context, request_counter).await
+  }
+}
diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs
index f69ee026..9db9d814 100644
--- a/crates/apub/src/activities/community/mod.rs
+++ b/crates/apub/src/activities/community/mod.rs
@@ -1,10 +1,10 @@
 use crate::{
   activities::community::announce::{AnnouncableActivities, AnnounceActivity},
   check_is_apub_id_valid,
+  fetcher::object_id::ObjectId,
   insert_activity,
   objects::community::ApubCommunity,
   send_lemmy_activity,
-  CommunityType,
 };
 use itertools::Itertools;
 use lemmy_apub_lib::traits::ActorType;
@@ -61,3 +61,14 @@ pub(crate) async fn send_to_community<T: ActorType>(
 
   Ok(())
 }
+
+async fn get_community_from_moderators_url(
+  moderators: &Url,
+  context: &LemmyContext,
+  request_counter: &mut i32,
+) -> Result<ApubCommunity, LemmyError> {
+  let community_id = Url::parse(&moderators.to_string().replace("/moderators", ""))?;
+  ObjectId::new(community_id)
+    .dereference(context, request_counter)
+    .await
+}
diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs
index d1a5675a..f08ae964 100644
--- a/crates/apub/src/activities/community/remove_mod.rs
+++ b/crates/apub/src/activities/community/remove_mod.rs
@@ -1,6 +1,10 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      get_community_from_moderators_url,
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_add_remove_moderator_target,
@@ -43,7 +47,6 @@ pub struct RemoveMod {
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
   kind: RemoveType,
-  // if target is set, this is means remove mod from community
   pub(in crate::activities) target: Url,
   id: Url,
   #[serde(rename = "@context")]
@@ -91,7 +94,8 @@ impl ActivityHandler for RemoveMod {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_add_remove_moderator_target(&self.target, &self.cc[0])?;
     Ok(())
@@ -102,7 +106,7 @@ impl ActivityHandler for RemoveMod {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.cc[0].dereference(context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
     let remove_mod = self.object.dereference(context, request_counter).await?;
 
     let form = CommunityModeratorForm {
@@ -117,3 +121,14 @@ impl ActivityHandler for RemoveMod {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for RemoveMod {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    get_community_from_moderators_url(&self.target, context, request_counter).await
+  }
+}
diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs
index ee36d1ae..c33c81e6 100644
--- a/crates/apub/src/activities/community/undo_block_user.rs
+++ b/crates/apub/src/activities/community/undo_block_user.rs
@@ -1,7 +1,7 @@
 use crate::{
   activities::{
     community::{
-      announce::AnnouncableActivities,
+      announce::{AnnouncableActivities, GetCommunity},
       block_user::BlockUserFromCommunity,
       send_to_community,
     },
@@ -92,7 +92,8 @@ impl ActivityHandler for UndoBlockUserFromCommunity {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
     self.object.verify(context, request_counter).await?;
     Ok(())
@@ -103,7 +104,7 @@ impl ActivityHandler for UndoBlockUserFromCommunity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.cc[0].dereference(context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
     let blocked_user = self
       .object
       .object
@@ -123,3 +124,14 @@ impl ActivityHandler for UndoBlockUserFromCommunity {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for UndoBlockUserFromCommunity {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    self.object.get_community(context, request_counter).await
+  }
+}
diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs
index 6c78dbfb..13837433 100644
--- a/crates/apub/src/activities/community/update.rs
+++ b/crates/apub/src/activities/community/update.rs
@@ -1,6 +1,9 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -90,7 +93,8 @@ impl ActivityHandler for UpdateCommunity {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
     Ok(())
   }
@@ -100,8 +104,7 @@ impl ActivityHandler for UpdateCommunity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let cc = self.cc[0].clone();
-    let community = cc.dereference(context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
 
     let updated_community = Group::from_apub_to_form(
       &self.object,
@@ -135,3 +138,15 @@ impl ActivityHandler for UpdateCommunity {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for UpdateCommunity {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let cid = ObjectId::new(self.object.id.clone());
+    cid.dereference(context, request_counter).await
+  }
+}
diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs
index 7593c5bf..8797ed6b 100644
--- a/crates/apub/src/activities/deletion/delete.rs
+++ b/crates/apub/src/activities/deletion/delete.rs
@@ -1,6 +1,9 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     deletion::{
       receive_delete_action,
       verify_delete_activity,
@@ -245,3 +248,26 @@ pub(in crate::activities) async fn receive_remove_action(
   }
   Ok(())
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for Delete {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    _request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let community_id = match DeletableObjects::read_from_db(&self.object, context).await? {
+      DeletableObjects::Community(c) => c.id,
+      DeletableObjects::Comment(c) => {
+        let post = blocking(context.pool(), move |conn| Post::read(conn, c.post_id)).await??;
+        post.community_id
+      }
+      DeletableObjects::Post(p) => p.community_id,
+    };
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, community_id)
+    })
+    .await??;
+    Ok(community.into())
+  }
+}
diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs
index 4352afe8..f523ca71 100644
--- a/crates/apub/src/activities/deletion/mod.rs
+++ b/crates/apub/src/activities/deletion/mod.rs
@@ -94,7 +94,7 @@ pub(in crate::activities) async fn verify_delete_activity(
       if c.local {
         // can only do this check for local community, in remote case it would try to fetch the
         // deleted community (which fails)
-        verify_person_in_community(&actor, community_id, context, request_counter).await?;
+        verify_person_in_community(&actor, &c, context, request_counter).await?;
       }
       // community deletion is always a mod (or admin) action
       verify_mod_action(
@@ -140,7 +140,8 @@ async fn verify_delete_activity_post_or_comment(
   request_counter: &mut i32,
 ) -> Result<(), LemmyError> {
   let actor = ObjectId::new(activity.actor().clone());
-  verify_person_in_community(&actor, community_id, context, request_counter).await?;
+  let community = community_id.dereference(context, request_counter).await?;
+  verify_person_in_community(&actor, &community, context, request_counter).await?;
   if is_mod_action {
     verify_mod_action(&actor, community_id, context, request_counter).await?;
   } else {
diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs
index 87c8eae7..d2816b11 100644
--- a/crates/apub/src/activities/deletion/undo_delete.rs
+++ b/crates/apub/src/activities/deletion/undo_delete.rs
@@ -1,6 +1,9 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     deletion::{
       delete::Delete,
       receive_delete_action,
@@ -166,3 +169,14 @@ impl UndoDelete {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for UndoDelete {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    self.object.get_community(context, request_counter).await
+  }
+}
diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs
index 78d12b52..92f53184 100644
--- a/crates/apub/src/activities/following/accept.rs
+++ b/crates/apub/src/activities/following/accept.rs
@@ -1,10 +1,5 @@
 use crate::{
-  activities::{
-    following::follow::FollowCommunity,
-    generate_activity_id,
-    verify_activity,
-    verify_community,
-  },
+  activities::{following::follow::FollowCommunity, generate_activity_id, verify_activity},
   context::lemmy_context,
   fetcher::object_id::ObjectId,
   objects::{community::ApubCommunity, person::ApubPerson},
@@ -84,7 +79,6 @@ impl ActivityHandler for AcceptFollowCommunity {
     verify_activity(self, &context.settings())?;
     verify_urls_match(self.to[0].inner(), self.object.actor())?;
     verify_urls_match(self.actor(), self.object.to[0].inner())?;
-    verify_community(&self.actor, context, request_counter).await?;
     self.object.verify(context, request_counter).await?;
     Ok(())
   }
diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs
index 82d2d540..4710f70f 100644
--- a/crates/apub/src/activities/following/follow.rs
+++ b/crates/apub/src/activities/following/follow.rs
@@ -4,6 +4,7 @@ use crate::{
     generate_activity_id,
     verify_activity,
     verify_person,
+    verify_person_in_community,
   },
   context::lemmy_context,
   fetcher::object_id::ObjectId,
@@ -97,6 +98,8 @@ impl ActivityHandler for FollowCommunity {
     verify_activity(self, &context.settings())?;
     verify_urls_match(self.to[0].inner(), self.object.inner())?;
     verify_person(&self.actor, context, request_counter).await?;
+    let community = self.to[0].dereference(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     Ok(())
   }
 
diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs
index 14a67394..b180b6f3 100644
--- a/crates/apub/src/activities/mod.rs
+++ b/crates/apub/src/activities/mod.rs
@@ -1,5 +1,4 @@
 use crate::{
-  check_community_or_site_ban,
   check_is_apub_id_valid,
   fetcher::object_id::ObjectId,
   generate_moderators_url,
@@ -10,11 +9,13 @@ use anyhow::anyhow;
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{traits::ActivityFields, verify::verify_domains_match};
 use lemmy_db_schema::source::community::Community;
-use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_db_views_actor::{
+  community_person_ban_view::CommunityPersonBanView,
+  community_view::CommunityView,
+};
 use lemmy_utils::{settings::structs::Settings, LemmyError};
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
-use std::ops::Deref;
 use strum_macros::ToString;
 use url::{ParseError, Url};
 use uuid::Uuid;
@@ -48,44 +49,26 @@ async fn verify_person(
   Ok(())
 }
 
-pub(crate) async fn extract_community(
-  cc: &[Url],
-  context: &LemmyContext,
-  request_counter: &mut i32,
-) -> Result<ApubCommunity, LemmyError> {
-  let mut cc_iter = cc.iter();
-  loop {
-    if let Some(cid) = cc_iter.next() {
-      let cid = ObjectId::new(cid.clone());
-      if let Ok(c) = cid.dereference(context, request_counter).await {
-        break Ok(c);
-      }
-    } else {
-      return Err(anyhow!("No community found in cc").into());
-    }
-  }
-}
-
 /// Fetches the person and community to verify their type, then checks if person is banned from site
 /// or community.
 pub(crate) async fn verify_person_in_community(
   person_id: &ObjectId<ApubPerson>,
-  community_id: &ObjectId<ApubCommunity>,
+  community: &ApubCommunity,
   context: &LemmyContext,
   request_counter: &mut i32,
 ) -> Result<(), LemmyError> {
-  let community = community_id.dereference(context, request_counter).await?;
   let person = person_id.dereference(context, request_counter).await?;
-  check_community_or_site_ban(person.deref(), community.id, context.pool()).await
-}
+  if person.banned {
+    return Err(anyhow!("Person is banned from site").into());
+  }
+  let person_id = person.id;
+  let community_id = community.id;
+  let is_banned =
+    move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
+  if blocking(context.pool(), is_banned).await? {
+    return Err(anyhow!("Person is banned from community").into());
+  }
 
-/// Simply check that the url actually refers to a valid group.
-async fn verify_community(
-  community_id: &ObjectId<ApubCommunity>,
-  context: &LemmyContext,
-  request_counter: &mut i32,
-) -> Result<(), LemmyError> {
-  community_id.dereference(context, request_counter).await?;
   Ok(())
 }
 
diff --git a/crates/apub/src/activities/post/create_or_update.rs b/crates/apub/src/activities/post/create_or_update.rs
index b3c0b694..b18d100e 100644
--- a/crates/apub/src/activities/post/create_or_update.rs
+++ b/crates/apub/src/activities/post/create_or_update.rs
@@ -1,7 +1,10 @@
 use crate::{
   activities::{
     check_community_deleted_or_removed,
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -99,8 +102,8 @@ impl ActivityHandler for CreateOrUpdatePost {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    let community = self.cc[0].dereference(context, request_counter).await?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     check_community_deleted_or_removed(&community)?;
 
     match self.kind {
@@ -148,3 +151,17 @@ impl ActivityHandler for CreateOrUpdatePost {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for CreateOrUpdatePost {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    self
+      .object
+      .extract_community(context, request_counter)
+      .await
+  }
+}
diff --git a/crates/apub/src/activities/private_message/create_or_update.rs b/crates/apub/src/activities/private_message/create_or_update.rs
index d6552b37..22f8edb8 100644
--- a/crates/apub/src/activities/private_message/create_or_update.rs
+++ b/crates/apub/src/activities/private_message/create_or_update.rs
@@ -4,7 +4,7 @@ use crate::{
   fetcher::object_id::ObjectId,
   objects::{
     person::ApubPerson,
-    private_message::{ApubPrivateMessage, Note},
+    private_message::{ApubPrivateMessage, ChatMessage},
   },
   send_lemmy_activity,
 };
@@ -29,7 +29,7 @@ pub struct CreateOrUpdatePrivateMessage {
   id: Url,
   actor: ObjectId<ApubPerson>,
   to: [ObjectId<ApubPerson>; 1],
-  object: Note,
+  object: ChatMessage,
   #[serde(rename = "type")]
   kind: CreateOrUpdateType,
   #[serde(flatten)]
diff --git a/crates/apub/src/activities/report.rs b/crates/apub/src/activities/report.rs
index d0b1f971..24041b0f 100644
--- a/crates/apub/src/activities/report.rs
+++ b/crates/apub/src/activities/report.rs
@@ -91,7 +91,8 @@ impl ActivityHandler for Report {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.to[0], context, request_counter).await?;
+    let community = self.to[0].dereference(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     Ok(())
   }
 
diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs
index 1ac1d4d8..6d63e905 100644
--- a/crates/apub/src/activities/voting/undo_vote.rs
+++ b/crates/apub/src/activities/voting/undo_vote.rs
@@ -1,6 +1,9 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -96,7 +99,8 @@ impl ActivityHandler for UndoVote {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_urls_match(self.actor(), self.object.actor())?;
     self.object.verify(context, request_counter).await?;
     Ok(())
@@ -119,3 +123,14 @@ impl ActivityHandler for UndoVote {
     }
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for UndoVote {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    self.object.get_community(context, request_counter).await
+  }
+}
diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs
index 166ce733..4d669728 100644
--- a/crates/apub/src/activities/voting/vote.rs
+++ b/crates/apub/src/activities/voting/vote.rs
@@ -1,6 +1,9 @@
 use crate::{
   activities::{
-    community::{announce::AnnouncableActivities, send_to_community},
+    community::{
+      announce::{AnnouncableActivities, GetCommunity},
+      send_to_community,
+    },
     generate_activity_id,
     verify_activity,
     verify_is_public,
@@ -19,7 +22,11 @@ use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
 };
-use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud};
+use lemmy_db_schema::{
+  newtypes::CommunityId,
+  source::{community::Community, post::Post},
+  traits::Crud,
+};
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
@@ -120,7 +127,8 @@ impl ActivityHandler for Vote {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
-    verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    let community = self.get_community(context, request_counter).await?;
+    verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     Ok(())
   }
 
@@ -137,3 +145,24 @@ impl ActivityHandler for Vote {
     }
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl GetCommunity for Vote {
+  async fn get_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let object = self.object.dereference(context, request_counter).await?;
+    let cid = match object {
+      PostOrComment::Post(p) => p.community_id,
+      PostOrComment::Comment(c) => {
+        blocking(context.pool(), move |conn| Post::read(conn, c.post_id))
+          .await??
+          .community_id
+      }
+    };
+    let community = blocking(context.pool(), move |conn| Community::read(conn, cid)).await??;
+    Ok(community.into())
+  }
+}
diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs
index faf33849..24465c95 100644
--- a/crates/apub/src/collections/community_outbox.rs
+++ b/crates/apub/src/collections/community_outbox.rs
@@ -6,8 +6,11 @@ use crate::{
   objects::{person::ApubPerson, post::ApubPost},
 };
 use activitystreams::{
-  base::AnyBase, chrono::NaiveDateTime, collection::kind::OrderedCollectionType,
-  primitives::OneOrMany, url::Url,
+  base::AnyBase,
+  chrono::NaiveDateTime,
+  collection::kind::OrderedCollectionType,
+  primitives::OneOrMany,
+  url::Url,
 };
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs
index a7e66d8a..f39f7b6f 100644
--- a/crates/apub/src/http/community.rs
+++ b/crates/apub/src/http/community.rs
@@ -1,9 +1,9 @@
 use crate::{
   activities::{
-    community::announce::{AnnouncableActivities, AnnounceActivity},
-    extract_community,
+    community::announce::{AnnouncableActivities, AnnounceActivity, GetCommunity},
     following::{follow::FollowCommunity, undo::UndoFollowCommunity},
     report::Report,
+    verify_person_in_community,
   },
   collections::{
     community_moderators::ApubCommunityModerators,
@@ -27,7 +27,10 @@ use activitystreams::{
 };
 use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
 use lemmy_api_common::blocking;
-use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ApubObject};
+use lemmy_apub_lib::{
+  traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
+  verify::verify_domains_match,
+};
 use lemmy_db_schema::source::community::Community;
 use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
 use lemmy_utils::LemmyError;
@@ -92,12 +95,17 @@ pub(in crate::http) async fn receive_group_inbox(
   context: &LemmyContext,
 ) -> Result<HttpResponse, LemmyError> {
   let res = receive_activity(request, activity.clone(), context).await;
-  if let GroupInboxActivities::AnnouncableActivities(announcable) = activity.clone() {
-    let community = extract_community(&announcable.cc(), context, &mut 0).await?;
+
+  if let GroupInboxActivities::AnnouncableActivities(announcable) = activity {
+    let community = announcable.get_community(context, &mut 0).await?;
+    let actor_id = ObjectId::new(announcable.actor().clone());
+    verify_domains_match(&community.actor_id(), announcable.id_unchecked())?;
+    verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
     if community.local {
       AnnounceActivity::send(announcable, &community, vec![], context).await?;
     }
   }
+
   res
 }
 
diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs
index a900ad3d..3bf3ff25 100644
--- a/crates/apub/src/lib.rs
+++ b/crates/apub/src/lib.rs
@@ -17,12 +17,7 @@ use lemmy_apub_lib::{
   traits::ActorType,
   webfinger::{webfinger_resolve_actor, WebfingerType},
 };
-use lemmy_db_schema::{
-  newtypes::{CommunityId, DbUrl},
-  source::{activity::Activity, person::Person},
-  DbPool,
-};
-use lemmy_db_views_actor::community_person_ban_view::CommunityPersonBanView;
+use lemmy_db_schema::{newtypes::DbUrl, source::activity::Activity, DbPool};
 use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
 use lemmy_websocket::LemmyContext;
 use log::info;
@@ -96,16 +91,6 @@ pub(crate) fn check_is_apub_id_valid(
   Ok(())
 }
 
-#[async_trait::async_trait(?Send)]
-pub trait CommunityType {
-  fn followers_url(&self) -> Url;
-  async fn get_follower_inboxes(
-    &self,
-    pool: &DbPool,
-    settings: &Settings,
-  ) -> Result<Vec<Url>, LemmyError>;
-}
-
 pub enum EndpointType {
   Community,
   Person,
@@ -211,24 +196,6 @@ where
   Ok(())
 }
 
-async fn check_community_or_site_ban(
-  person: &Person,
-  community_id: CommunityId,
-  pool: &DbPool,
-) -> Result<(), LemmyError> {
-  if person.banned {
-    return Err(anyhow!("Person is banned from site").into());
-  }
-  let person_id = person.id;
-  let is_banned =
-    move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
-  if blocking(pool, is_banned).await? {
-    return Err(anyhow!("Person is banned from community").into());
-  }
-
-  Ok(())
-}
-
 pub(crate) async fn send_lemmy_activity<T: Serialize>(
   context: &LemmyContext,
   activity: &T,
diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs
index 927127d8..335605a6 100644
--- a/crates/apub/src/objects/comment.rs
+++ b/crates/apub/src/objects/comment.rs
@@ -2,7 +2,13 @@ use crate::{
   activities::{verify_is_public, verify_person_in_community},
   context::lemmy_context,
   fetcher::object_id::ObjectId,
-  objects::{person::ApubPerson, post::ApubPost, tombstone::Tombstone, Source},
+  objects::{
+    community::ApubCommunity,
+    person::ApubPerson,
+    post::ApubPost,
+    tombstone::Tombstone,
+    Source,
+  },
   PostOrComment,
 };
 use activitystreams::{
@@ -121,22 +127,17 @@ impl Note {
   ) -> Result<(), LemmyError> {
     let (post, _parent_comment_id) = self.get_parents(context, request_counter).await?;
     let community_id = post.community_id;
-    let community = blocking(context.pool(), move |conn| {
+    let community: ApubCommunity = blocking(context.pool(), move |conn| {
       Community::read(conn, community_id)
     })
-    .await??;
+    .await??
+    .into();
 
     if post.locked {
       return Err(anyhow!("Post is locked").into());
     }
     verify_domains_match(self.attributed_to.inner(), &self.id)?;
-    verify_person_in_community(
-      &self.attributed_to,
-      &ObjectId::new(community.actor_id),
-      context,
-      request_counter,
-    )
-    .await?;
+    verify_person_in_community(&self.attributed_to, &community, context, request_counter).await?;
     verify_is_public(&self.to)?;
     Ok(())
   }
@@ -247,6 +248,18 @@ impl ApubObject for ApubComment {
       .dereference(context, request_counter)
       .await?;
     let (post, parent_comment_id) = note.get_parents(context, request_counter).await?;
+    let community_id = post.community_id;
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, community_id)
+    })
+    .await??;
+    verify_person_in_community(
+      &note.attributed_to,
+      &community.into(),
+      context,
+      request_counter,
+    )
+    .await?;
     if post.locked {
       return Err(anyhow!("Post is locked").into());
     }
diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs
index e71addba..a38e759f 100644
--- a/crates/apub/src/objects/community.rs
+++ b/crates/apub/src/objects/community.rs
@@ -10,7 +10,6 @@ use crate::{
   generate_moderators_url,
   generate_outbox_url,
   objects::{get_summary_from_string_or_source, tombstone::Tombstone, ImageObject, Source},
-  CommunityType,
 };
 use activitystreams::{
   actor::{kind::GroupType, Endpoints},
@@ -55,7 +54,7 @@ pub struct Group {
   context: OneOrMany<AnyBase>,
   #[serde(rename = "type")]
   kind: GroupType,
-  id: Url,
+  pub(crate) id: Url,
   /// username, set at account creation and can never be changed
   preferred_username: String,
   /// title (can be changed at any time)
@@ -81,16 +80,12 @@ pub struct Group {
 }
 
 impl Group {
-  pub(crate) fn id(&self, expected_domain: &Url) -> Result<&Url, LemmyError> {
-    verify_domains_match(&self.id, expected_domain)?;
-    Ok(&self.id)
-  }
   pub(crate) async fn from_apub_to_form(
     group: &Group,
     expected_domain: &Url,
     settings: &Settings,
   ) -> Result<CommunityForm, LemmyError> {
-    let actor_id = Some(group.id(expected_domain)?.clone().into());
+    verify_domains_match(expected_domain, &group.id)?;
     let name = group.preferred_username.clone();
     let title = group.name.clone();
     let description = get_summary_from_string_or_source(&group.summary, &group.source);
@@ -110,7 +105,7 @@ impl Group {
       updated: group.updated.map(|u| u.naive_local()),
       deleted: None,
       nsfw: Some(group.sensitive.unwrap_or(false)),
-      actor_id,
+      actor_id: Some(group.id.clone().into()),
       local: Some(false),
       private_key: None,
       public_key: Some(group.public_key.public_key_pem.clone()),
@@ -283,14 +278,9 @@ impl ActorType for ApubCommunity {
   }
 }
 
-#[async_trait::async_trait(?Send)]
-impl CommunityType for Community {
-  fn followers_url(&self) -> Url {
-    self.followers_url.clone().into()
-  }
-
+impl ApubCommunity {
   /// For a given community, returns the inboxes of all followers.
-  async fn get_follower_inboxes(
+  pub(crate) async fn get_follower_inboxes(
     &self,
     pool: &DbPool,
     settings: &Settings,
diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs
index 8b016188..f15bb5ba 100644
--- a/crates/apub/src/objects/post.rs
+++ b/crates/apub/src/objects/post.rs
@@ -1,8 +1,14 @@
 use crate::{
-  activities::{extract_community, verify_is_public, verify_person_in_community},
+  activities::{verify_is_public, verify_person_in_community},
   context::lemmy_context,
   fetcher::object_id::ObjectId,
-  objects::{person::ApubPerson, tombstone::Tombstone, ImageObject, Source},
+  objects::{
+    community::ApubCommunity,
+    person::ApubPerson,
+    tombstone::Tombstone,
+    ImageObject,
+    Source,
+  },
 };
 use activitystreams::{
   base::AnyBase,
@@ -11,10 +17,11 @@ use activitystreams::{
   public,
   unparsed::Unparsed,
 };
+use anyhow::anyhow;
 use chrono::{DateTime, FixedOffset, NaiveDateTime};
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
-  traits::{ActorType, ApubObject},
+  traits::ApubObject,
   values::{MediaTypeHtml, MediaTypeMarkdown},
   verify::verify_domains_match,
 };
@@ -94,20 +101,32 @@ impl Page {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = extract_community(&self.to, context, request_counter).await?;
+    let community = self.extract_community(context, request_counter).await?;
 
     check_slurs(&self.name, &context.settings().slur_regex())?;
     verify_domains_match(self.attributed_to.inner(), &self.id.clone())?;
-    verify_person_in_community(
-      &self.attributed_to,
-      &ObjectId::new(community.actor_id()),
-      context,
-      request_counter,
-    )
-    .await?;
+    verify_person_in_community(&self.attributed_to, &community, context, request_counter).await?;
     verify_is_public(&self.to.clone())?;
     Ok(())
   }
+
+  pub(crate) async fn extract_community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let mut to_iter = self.to.iter();
+    loop {
+      if let Some(cid) = to_iter.next() {
+        let cid = ObjectId::new(cid.clone());
+        if let Ok(c) = cid.dereference(context, request_counter).await {
+          break Ok(c);
+        }
+      } else {
+        return Err(anyhow!("No community found in cc").into());
+      }
+    }
+  }
 }
 
 #[derive(Clone, Debug)]
@@ -223,7 +242,8 @@ impl ApubObject for ApubPost {
       .attributed_to
       .dereference(context, request_counter)
       .await?;
-    let community = extract_community(&page.to, context, request_counter).await?;
+    let community = page.extract_community(context, request_counter).await?;
+    verify_person_in_community(&page.attributed_to, &community, context, request_counter).await?;
 
     let thumbnail_url: Option<Url> = page.image.clone().map(|i| i.url);
     let (metadata_res, pictrs_thumbnail) = if let Some(url) = &page.url {
diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs
index 407ae810..56200d1b 100644
--- a/crates/apub/src/objects/private_message.rs
+++ b/crates/apub/src/objects/private_message.rs
@@ -36,7 +36,7 @@ use url::Url;
 #[skip_serializing_none]
 #[derive(Clone, Debug, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
-pub struct Note {
+pub struct ChatMessage {
   #[serde(rename = "@context")]
   context: OneOrMany<AnyBase>,
   r#type: ChatMessageType,
@@ -58,7 +58,7 @@ pub enum ChatMessageType {
   ChatMessage,
 }
 
-impl Note {
+impl ChatMessage {
   pub(crate) fn id_unchecked(&self) -> &Url {
     &self.id
   }
@@ -103,7 +103,7 @@ impl From<PrivateMessage> for ApubPrivateMessage {
 #[async_trait::async_trait(?Send)]
 impl ApubObject for ApubPrivateMessage {
   type DataType = LemmyContext;
-  type ApubType = Note;
+  type ApubType = ChatMessage;
   type TombstoneType = Tombstone;
 
   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
@@ -128,7 +128,7 @@ impl ApubObject for ApubPrivateMessage {
     unimplemented!()
   }
 
-  async fn to_apub(&self, context: &LemmyContext) -> Result<Note, LemmyError> {
+  async fn to_apub(&self, context: &LemmyContext) -> Result<ChatMessage, LemmyError> {
     let creator_id = self.creator_id;
     let creator = blocking(context.pool(), move |conn| Person::read(conn, creator_id)).await??;
 
@@ -136,7 +136,7 @@ impl ApubObject for ApubPrivateMessage {
     let recipient =
       blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
 
-    let note = Note {
+    let note = ChatMessage {
       context: lemmy_context(),
       r#type: ChatMessageType::ChatMessage,
       id: self.ap_id.clone().into(),
@@ -160,7 +160,7 @@ impl ApubObject for ApubPrivateMessage {
   }
 
   async fn from_apub(
-    note: &Note,
+    note: &ChatMessage,
     context: &LemmyContext,
     expected_domain: &Url,
     request_counter: &mut i32,
diff --git a/crates/apub_lib/src/traits.rs b/crates/apub_lib/src/traits.rs
index 2240946d..8d819a27 100644
--- a/crates/apub_lib/src/traits.rs
+++ b/crates/apub_lib/src/traits.rs
@@ -8,7 +8,6 @@ use url::Url;
 pub trait ActivityFields {
   fn id_unchecked(&self) -> &Url;
   fn actor(&self) -> &Url;
-  fn cc(&self) -> Vec<Url>;
 }
 
 #[async_trait::async_trait(?Send)]
diff --git a/crates/apub_lib_derive/src/lib.rs b/crates/apub_lib_derive/src/lib.rs
index 44185d14..1f8d12a7 100644
--- a/crates/apub_lib_derive/src/lib.rs
+++ b/crates/apub_lib_derive/src/lib.rs
@@ -145,36 +145,18 @@ pub fn derive_activity_fields(input: proc_macro::TokenStream) -> proc_macro::Tok
       let impl_actor = variants
         .iter()
         .map(|v| generate_match_arm(&name, v, &quote! {a.actor()}));
-      let impl_cc = variants
-        .iter()
-        .map(|v| generate_match_arm(&name, v, &quote! {a.cc()}));
       quote! {
           impl #impl_generics lemmy_apub_lib::traits::ActivityFields for #name #ty_generics #where_clause {
               fn id_unchecked(&self) -> &url::Url { match self { #(#impl_id)* } }
               fn actor(&self) -> &url::Url { match self { #(#impl_actor)* } }
-              fn cc(&self) -> Vec<url::Url> { match self { #(#impl_cc)* } }
           }
       }
     }
-    Data::Struct(s) => {
-      // check if the struct has a field "cc", and generate impl for cc() function depending on that
-      let has_cc = if let syn::Fields::Named(n) = s.fields {
-        n.named
-          .iter()
-          .any(|i| format!("{}", i.ident.as_ref().unwrap()) == "cc")
-      } else {
-        unimplemented!()
-      };
-      let cc_impl = if has_cc {
-        quote! {self.cc.iter().map(|i| i.clone().into()).collect()}
-      } else {
-        quote! {vec![]}
-      };
+    Data::Struct(_) => {
       quote! {
           impl #impl_generics lemmy_apub_lib::traits::ActivityFields for #name #ty_generics #where_clause {
               fn id_unchecked(&self) -> &url::Url { &self.id }
               fn actor(&self) -> &url::Url { &self.actor.inner() }
-              fn cc(&self) -> Vec<url::Url> { #cc_impl }
           }
       }
     }