]> Untitled Git - lemmy.git/commitdiff
Use audience field to federate items in groups (fixes #2464) (#2584)
authorNutomic <me@nutomic.com>
Thu, 1 Dec 2022 20:52:49 +0000 (20:52 +0000)
committerGitHub <noreply@github.com>
Thu, 1 Dec 2022 20:52:49 +0000 (15:52 -0500)
70 files changed:
crates/api/src/post/lock.rs
crates/api/src/post/sticky.rs
crates/api_crud/src/comment/create.rs
crates/api_crud/src/comment/update.rs
crates/api_crud/src/post/create.rs
crates/api_crud/src/post/update.rs
crates/api_crud/src/private_message/create.rs
crates/api_crud/src/private_message/update.rs
crates/apub/assets/lemmy/activities/block/block_user.json
crates/apub/assets/lemmy/activities/block/undo_block_user.json
crates/apub/assets/lemmy/activities/community/add_mod.json
crates/apub/assets/lemmy/activities/community/remove_mod.json
crates/apub/assets/lemmy/activities/community/report_page.json
crates/apub/assets/lemmy/activities/community/update_community.json
crates/apub/assets/lemmy/activities/create_or_update/create_note.json
crates/apub/assets/lemmy/activities/create_or_update/create_page.json
crates/apub/assets/lemmy/activities/create_or_update/update_page.json
crates/apub/assets/lemmy/activities/deletion/delete_page.json
crates/apub/assets/lemmy/activities/deletion/delete_user.json
crates/apub/assets/lemmy/activities/deletion/remove_note.json
crates/apub/assets/lemmy/activities/deletion/undo_delete_page.json
crates/apub/assets/lemmy/activities/deletion/undo_remove_note.json
crates/apub/assets/lemmy/activities/voting/dislike_page.json
crates/apub/assets/lemmy/activities/voting/like_note.json
crates/apub/assets/lemmy/activities/voting/undo_dislike_page.json
crates/apub/assets/lemmy/activities/voting/undo_like_note.json
crates/apub/assets/lemmy/objects/note.json
crates/apub/assets/lemmy/objects/page.json
crates/apub/src/activities/block/block_user.rs
crates/apub/src/activities/block/undo_block_user.rs
crates/apub/src/activities/community/add_mod.rs
crates/apub/src/activities/community/announce.rs
crates/apub/src/activities/community/mod.rs
crates/apub/src/activities/community/remove_mod.rs
crates/apub/src/activities/community/report.rs
crates/apub/src/activities/community/update.rs
crates/apub/src/activities/create_or_update/comment.rs
crates/apub/src/activities/create_or_update/post.rs
crates/apub/src/activities/create_or_update/private_message.rs
crates/apub/src/activities/deletion/delete.rs
crates/apub/src/activities/deletion/mod.rs
crates/apub/src/activities/deletion/undo_delete.rs
crates/apub/src/activities/mod.rs
crates/apub/src/activities/voting/undo_vote.rs
crates/apub/src/activities/voting/vote.rs
crates/apub/src/activity_lists.rs
crates/apub/src/collections/community_outbox.rs
crates/apub/src/fetcher/post_or_comment.rs
crates/apub/src/objects/comment.rs
crates/apub/src/objects/post.rs
crates/apub/src/protocol/activities/block/block_user.rs
crates/apub/src/protocol/activities/block/undo_block_user.rs
crates/apub/src/protocol/activities/community/add_mod.rs
crates/apub/src/protocol/activities/community/remove_mod.rs
crates/apub/src/protocol/activities/community/report.rs
crates/apub/src/protocol/activities/community/update.rs
crates/apub/src/protocol/activities/create_or_update/chat_message.rs [moved from crates/apub/src/protocol/activities/create_or_update/private_message.rs with 93% similarity]
crates/apub/src/protocol/activities/create_or_update/comment.rs [deleted file]
crates/apub/src/protocol/activities/create_or_update/mod.rs
crates/apub/src/protocol/activities/create_or_update/note.rs [new file with mode: 0644]
crates/apub/src/protocol/activities/create_or_update/page.rs [new file with mode: 0644]
crates/apub/src/protocol/activities/create_or_update/post.rs [deleted file]
crates/apub/src/protocol/activities/deletion/delete.rs
crates/apub/src/protocol/activities/deletion/undo_delete.rs
crates/apub/src/protocol/activities/mod.rs
crates/apub/src/protocol/activities/voting/undo_vote.rs
crates/apub/src/protocol/activities/voting/vote.rs
crates/apub/src/protocol/mod.rs
crates/apub/src/protocol/objects/note.rs
crates/apub/src/protocol/objects/page.rs

index d47088e865a4513e893d6179dd058ff18ac8fc97..ae726ee926968f0c59ee2dd8fad38918c6a7c72c 100644 (file)
@@ -11,7 +11,7 @@ use lemmy_api_common::{
 };
 use lemmy_apub::{
   objects::post::ApubPost,
-  protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
+  protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType},
 };
 use lemmy_db_schema::{
   source::{
@@ -76,7 +76,7 @@ impl Perform for LockPost {
     ModLockPost::create(context.pool(), &form).await?;
 
     // apub updates
-    CreateOrUpdatePost::send(
+    CreateOrUpdatePage::send(
       updated_post,
       &local_user_view.person.clone().into(),
       CreateOrUpdateType::Update,
index ec4c39a85a7b651abc1781461a4bd27935675da4..384ba52d6605b71de04f158843e2d279c6097c62 100644 (file)
@@ -11,7 +11,7 @@ use lemmy_api_common::{
 };
 use lemmy_apub::{
   objects::post::ApubPost,
-  protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
+  protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType},
 };
 use lemmy_db_schema::{
   source::{
@@ -78,7 +78,7 @@ impl Perform for StickyPost {
 
     // Apub updates
     // TODO stickied should pry work like locked for ease of use
-    CreateOrUpdatePost::send(
+    CreateOrUpdatePage::send(
       updated_post,
       &local_user_view.person.clone().into(),
       CreateOrUpdateType::Update,
index 5e067b183162cc6a00d9ba342d8362af25ac9543..f027b0fe2b6c12317581b77e612d1f6049b9c066 100644 (file)
@@ -14,7 +14,7 @@ use lemmy_api_common::{
 use lemmy_apub::{
   generate_local_apub_endpoint,
   objects::comment::ApubComment,
-  protocol::activities::{create_or_update::comment::CreateOrUpdateComment, CreateOrUpdateType},
+  protocol::activities::{create_or_update::note::CreateOrUpdateNote, CreateOrUpdateType},
   EndpointType,
 };
 use lemmy_db_schema::{
@@ -158,7 +158,7 @@ impl PerformCrud for CreateComment {
       .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_comment"))?;
 
     let apub_comment: ApubComment = updated_comment.into();
-    CreateOrUpdateComment::send(
+    CreateOrUpdateNote::send(
       apub_comment.clone(),
       &local_user_view.person.clone().into(),
       CreateOrUpdateType::Create,
index d941529537354c1ded10017a2d9f040cdcc09ff2..0d89acc2924c6657cf6b1fdb64ad5ab915e7d300 100644 (file)
@@ -12,7 +12,7 @@ use lemmy_api_common::{
   },
 };
 use lemmy_apub::protocol::activities::{
-  create_or_update::comment::CreateOrUpdateComment,
+  create_or_update::note::CreateOrUpdateNote,
   CreateOrUpdateType,
 };
 use lemmy_db_schema::{
@@ -115,7 +115,7 @@ impl PerformCrud for EditComment {
     .await?;
 
     // Send the apub update
-    CreateOrUpdateComment::send(
+    CreateOrUpdateNote::send(
       updated_comment.into(),
       &local_user_view.person.into(),
       CreateOrUpdateType::Update,
index 20d32b12c83867ce40ef0c2296c6c8dea3e7171f..cad8b28e227f7ad50bed13f2678c953f04e58c06 100644 (file)
@@ -15,7 +15,7 @@ use lemmy_api_common::{
 use lemmy_apub::{
   generate_local_apub_endpoint,
   objects::post::ApubPost,
-  protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
+  protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType},
   EndpointType,
 };
 use lemmy_db_schema::{
@@ -174,7 +174,7 @@ impl PerformCrud for CreatePost {
     }
 
     let apub_post: ApubPost = updated_post.into();
-    CreateOrUpdatePost::send(
+    CreateOrUpdatePage::send(
       apub_post.clone(),
       &local_user_view.person.clone().into(),
       CreateOrUpdateType::Create,
index f6a2e08416c23352b0a78b05693dcb877508030b..11b566bc92bcb1e9a4206ce7a0aff279e38f6bd8 100644 (file)
@@ -11,7 +11,7 @@ use lemmy_api_common::{
   },
 };
 use lemmy_apub::protocol::activities::{
-  create_or_update::post::CreateOrUpdatePost,
+  create_or_update::page::CreateOrUpdatePage,
   CreateOrUpdateType,
 };
 use lemmy_db_schema::{
@@ -122,7 +122,7 @@ impl PerformCrud for EditPost {
     };
 
     // Send apub update
-    CreateOrUpdatePost::send(
+    CreateOrUpdatePage::send(
       updated_post.into(),
       &local_user_view.person.clone().into(),
       CreateOrUpdateType::Update,
index 84e747ffc199fd400c02b0f4cde9f9d9a2b138d9..35bc09e2291245f7b4c65ffd42f5f369c164edd6 100644 (file)
@@ -13,7 +13,7 @@ use lemmy_api_common::{
 use lemmy_apub::{
   generate_local_apub_endpoint,
   protocol::activities::{
-    create_or_update::private_message::CreateOrUpdatePrivateMessage,
+    create_or_update::chat_message::CreateOrUpdateChatMessage,
     CreateOrUpdateType,
   },
   EndpointType,
@@ -85,7 +85,7 @@ impl PerformCrud for CreatePrivateMessage {
     .await
     .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_private_message"))?;
 
-    CreateOrUpdatePrivateMessage::send(
+    CreateOrUpdateChatMessage::send(
       updated_private_message.into(),
       &local_user_view.person.into(),
       CreateOrUpdateType::Create,
index dfe06e8e924c3d3ede163efe39a81548b3c5af4b..5f79735e99235d8a4652bde39c076bee83b3f3c1 100644 (file)
@@ -5,7 +5,7 @@ use lemmy_api_common::{
   utils::{get_local_user_view_from_jwt, local_site_to_slur_regex},
 };
 use lemmy_apub::protocol::activities::{
-  create_or_update::private_message::CreateOrUpdatePrivateMessage,
+  create_or_update::chat_message::CreateOrUpdateChatMessage,
   CreateOrUpdateType,
 };
 use lemmy_db_schema::{
@@ -56,7 +56,7 @@ impl PerformCrud for EditPrivateMessage {
     .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_private_message"))?;
 
     // Send the apub update
-    CreateOrUpdatePrivateMessage::send(
+    CreateOrUpdateChatMessage::send(
       updated_private_message.into(),
       &local_user_view.person.into(),
       CreateOrUpdateType::Update,
index f400fa504828306005833d855560e4a389582c26..ffe0504f17ab5a9cf2bbe4b54885a326673ddd68 100644 (file)
@@ -7,6 +7,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "target": "http://enterprise.lemmy.ml/c/main",
   "type": "Block",
   "removeData": true,
index 99f9077863303d8e4f1ae23bf7913ac4ed236a20..15ab22b2cabb256ba9959ec4dfad085d8eb85a0d 100644 (file)
@@ -12,6 +12,7 @@
     "cc": [
       "http://enterprise.lemmy.ml/c/main"
     ],
+    "audience": "http://enterprise.lemmy.ml/u/main",
     "target": "http://enterprise.lemmy.ml/c/main",
     "type": "Block",
     "removeData": true,
@@ -22,6 +23,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "type": "Undo",
   "id": "http://enterprise.lemmy.ml/activities/undo/06a20ffb-3e32-42fb-8f4c-674b36d7c557"
 }
\ No newline at end of file
index d0eedd8bfd18cce4a8c98778d923403835147bd7..69cfabc91f3e55b60eb07f2143b5889449733399 100644 (file)
@@ -8,6 +8,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "type": "Add",
   "id": "http://enterprise.lemmy.ml/activities/add/ec069147-77c3-447f-88c8-0ef1df10403f"
 }
\ No newline at end of file
index 2932fec37a29eb4955b47129f34d845af80806d3..0c6db15567f27902879128633206c40d54b463ef 100644 (file)
@@ -9,5 +9,6 @@
   ],
   "type": "Remove",
   "target": "http://enterprise.lemmy.ml/c/main/moderators",
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "id": "http://enterprise.lemmy.ml/activities/remove/aab114f8-cfbd-4935-a5b7-e1a64603650d"
 }
\ No newline at end of file
index bd1691b57b437eaad1cbf5f74dfda3b29a9bde67..e58f656c79cc22b578a21dbbf14d60a4c20ae2b5 100644 (file)
@@ -3,6 +3,7 @@
   "to": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "object": "http://enterprise.lemmy.ml/post/7",
   "summary": "report this post",
   "type": "Flag",
index 5ffe0fb9dad6e8c3548e6bda6bbac273fa3c2347..3da15a06fa6d7ddcf9eee0c8c9d70cfc06ba1da5 100644 (file)
@@ -43,6 +43,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "type": "Update",
   "id": "http://ds9.lemmy.ml/activities/update/d3717cf5-096d-473f-9530-5d52f9d51f5f"
 }
\ No newline at end of file
index 33ce1cfd9430238d33d955cb4fe1b9af7e9121a4..6eecfcfc928b86d2ea939972e8401e249a222d1b 100644 (file)
     "to": [
       "https://www.w3.org/ns/activitystreams#Public"
     ],
+    "cc": [
+      "http://enterprise.lemmy.ml/c/main",
+      "http://ds9.lemmy.ml/u/lemmy_alpha"
+    ],
+    "audience": "http://ds9.lemmy.ml/u/lemmy_alpha",
     "content": "hello",
     "mediaType": "text/html",
     "source": {
@@ -23,6 +28,7 @@
     "http://enterprise.lemmy.ml/c/main",
     "http://ds9.lemmy.ml/u/lemmy_alpha"
   ],
+  "audience": "http://ds9.lemmy.ml/u/lemmy_alpha",
   "tag": [
     {
       "href": "http://ds9.lemmy.ml/u/lemmy_alpha",
index 4fff07c8b751334627c406663967929ba15ad25e..907faa5ca72e04d055571ebf73ef3d413f8602a1 100644 (file)
@@ -11,6 +11,7 @@
       "http://enterprise.lemmy.ml/c/main",
       "https://www.w3.org/ns/activitystreams#Public"
     ],
+    "audience": "https://enterprise.lemmy.ml/c/main",
     "name": "test post",
     "content": "<p>test body</p>\n",
     "mediaType": "text/html",
@@ -37,6 +38,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "https://enterprise.lemmy.ml/c/main",
   "type": "Create",
   "id": "http://ds9.lemmy.ml/activities/create/eee6a57a-622f-464d-b560-73ae1fcd3ddf"
 }
\ No newline at end of file
index 7cde6cdd900d7c2a43a972390b3d4aa78d8667c9..46cb0e2ae531868ed2e4c7d4e850f3d8279e0825 100644 (file)
@@ -11,6 +11,7 @@
       "http://enterprise.lemmy.ml/c/main",
       "https://www.w3.org/ns/activitystreams#Public"
     ],
+    "audience": "https://enterprise.lemmy.ml/c/main",
     "name": "test post 1",
     "content": "<p>test body</p>\n",
     "mediaType": "text/html",
@@ -34,6 +35,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "https://enterprise.lemmy.ml/c/main",
   "type": "Update",
   "id": "http://ds9.lemmy.ml/activities/update/ab360117-e165-4de4-b7fc-906b62c98631"
 }
\ No newline at end of file
index 8dd26a109ebe48cf7d32b7119ae0bf70327beaf8..590db014d2a4268d4c5b846479bb84076b766562 100644 (file)
@@ -7,6 +7,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "type": "Delete",
   "id": "http://ds9.lemmy.ml/activities/delete/f2abee48-c7bb-41d5-9e27-8775ff32db12"
 }
\ No newline at end of file
index 1e000c12d54d231f4f1c2095facad7138916ce3b..da93cdbe6068d57496019a3590af3373c6e391be 100644 (file)
@@ -4,9 +4,6 @@
     "https://www.w3.org/ns/activitystreams#Public"
   ],
   "object": "http://ds9.lemmy.ml/u/lemmy_alpha",
-  "cc": [
-    "http://enterprise.lemmy.ml/c/main"
-  ],
   "type": "Delete",
   "id": "http://ds9.lemmy.ml/activities/delete/f2abee48-c7bb-41d5-9e27-8775ff32db12"
 }
\ No newline at end of file
index 8ea354044f84487143ea8859dc2df3399dc95779..29a299832f97cd43201cf45b374c06f6ebeb1402 100644 (file)
@@ -7,6 +7,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "type": "Delete",
   "summary": "bad comment",
   "id": "http://enterprise.lemmy.ml/activities/delete/42ca1a79-f99e-4518-a2ca-ba2df221eb5e"
index 9f824fa1f8f0fb60610ac85385fffcee4ee3197c..2e7fbce4cf256869262682d14175526d55535b8c 100644 (file)
     "cc": [
       "http://enterprise.lemmy.ml/c/main"
     ],
+    "audience": "http://enterprise.lemmy.ml/u/main",
     "type": "Delete",
     "id": "http://ds9.lemmy.ml/activities/delete/b13cca96-7737-41e1-9769-8fbf972b3509"
   },
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "type": "Undo",
   "id": "http://ds9.lemmy.ml/activities/undo/5e939cfb-b8a1-4de8-950f-9d684e9162b9"
 }
\ No newline at end of file
index 413cf16b4e4e605eb94aebaf0ffa8331489a8592..6cabdaf2aae659bd29ceceae0862b5b3b9c4128a 100644 (file)
@@ -12,6 +12,7 @@
     "cc": [
       "http://enterprise.lemmy.ml/c/main"
     ],
+    "audience": "http://enterprise.lemmy.ml/u/main",
     "type": "Delete",
     "summary": "bad comment",
     "id": "http://enterprise.lemmy.ml/activities/delete/2598435c-87a3-49cd-81f3-a44b03b7af9d"
@@ -19,6 +20,7 @@
   "cc": [
     "http://enterprise.lemmy.ml/c/main"
   ],
+  "audience": "http://enterprise.lemmy.ml/u/main",
   "type": "Undo",
   "id": "http://enterprise.lemmy.ml/activities/undo/a850cf21-3866-4b3a-b80b-56aa00997fee"
 }
\ No newline at end of file
index 0917329e75469c8d66a9f436efd563ef1902cc72..3d11a51c2904292e2d20aa59523896fddb4aeafe 100644 (file)
@@ -1,6 +1,7 @@
 {
   "actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
   "object": "http://ds9.lemmy.ml/post/1",
+  "audience": "https://enterprise.lemmy.ml/c/tenforward",
   "type": "Dislike",
   "id": "http://enterprise.lemmy.ml/activities/dislike/64d40d40-a829-43a5-8247-1fb595b3ca1c"
 }
\ No newline at end of file
index 78ee5b12bc9b596f0654b810ff979014fcc2c3e5..e72fb5d9d4b761695e26cd1f91cf686eabdfbbdb 100644 (file)
@@ -1,6 +1,7 @@
 {
   "actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
   "object": "http://ds9.lemmy.ml/comment/1",
+  "audience": "https://enterprise.lemmy.ml/c/tenforward",
   "type": "Like",
   "id": "http://ds9.lemmy.ml/activities/like/fd61d070-7382-46a9-b2b7-6bb253732877"
 }
\ No newline at end of file
index 54fc19039e56d76c8864e7180d8996a111324c72..098242dbec8d6eb2e060f086f96759268ae71c7a 100644 (file)
@@ -3,9 +3,11 @@
   "object": {
     "actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
     "object": "http://ds9.lemmy.ml/post/1",
+    "audience": "https://enterprise.lemmy.ml/c/tenforward",
     "type": "Like",
     "id": "http://enterprise.lemmy.ml/activities/like/2227ab2c-79e2-4fca-a1d2-1d67dacf2457"
   },
+  "audience": "https://enterprise.lemmy.ml/c/tenforward",
   "type": "Undo",
   "id": "http://enterprise.lemmy.ml/activities/undo/6cc6fb71-39fe-49ea-9506-f0423b101e98"
 }
\ No newline at end of file
index 65ed510eb064076bca5ec49415a05ca98f5463c8..b4d5d31a6640956b7b8f9ef3228663ff90603c8f 100644 (file)
@@ -3,9 +3,11 @@
   "object": {
     "actor": "http://ds9.lemmy.ml/u/lemmy_alpha",
     "object": "http://ds9.lemmy.ml/comment/1",
+    "audience": "https://enterprise.lemmy.ml/c/tenforward",
     "type": "Like",
     "id": "http://ds9.lemmy.ml/activities/like/efcf7ae2-dfcc-4ff4-9ce4-6adf251ff004"
   },
+  "audience": "https://enterprise.lemmy.ml/c/tenforward",
   "type": "Undo",
   "id": "http://ds9.lemmy.ml/activities/undo/3518565c-24a7-4d9e-8e0a-f7a2f45ac618"
 }
\ No newline at end of file
index 4fcb906a4895892454d3929cfc261c60581dcb9e..2e50abcdbaae90dec3e8250df29465a835a7fdc7 100644 (file)
@@ -7,6 +7,7 @@
     "https://enterprise.lemmy.ml/c/tenforward",
     "https://enterprise.lemmy.ml/u/picard"
   ],
+  "audience": "https://enterprise.lemmy.ml/c/tenforward",
   "inReplyTo": "https://enterprise.lemmy.ml/post/55143",
   "content": "<p>first comment!</p>\n",
   "mediaType": "text/html",
index 816c32495fd2a23feff79b504101cf110111a04f..0f514bc013a02ece2a132b1569df62600ef5bcf5 100644 (file)
@@ -6,6 +6,7 @@
     "https://enterprise.lemmy.ml/c/tenforward",
     "https://www.w3.org/ns/activitystreams#Public"
   ],
+  "audience": "https://enterprise.lemmy.ml/c/tenforward",
   "name": "Post title",
   "content": "<p>This is a post in the /c/tenforward community</p>\n",
   "mediaType": "text/html",
index a701f8d90e0c573c6a6d318f31d6e7d85efba032..1d726e7ce1e8feabf59684283a8acdb265f27c6d 100644 (file)
@@ -1,7 +1,7 @@
 use crate::{
   activities::{
     block::{generate_cc, SiteOrCommunity},
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     generate_activity_id,
     send_lemmy_activity,
     verify_is_public,
@@ -10,7 +10,7 @@ use crate::{
   },
   activity_lists::AnnouncableActivities,
   local_instance,
-  objects::{community::ApubCommunity, instance::remote_instance_inboxes, person::ApubPerson},
+  objects::{instance::remote_instance_inboxes, person::ApubPerson},
   protocol::activities::block::block_user::BlockUser,
   ActorType,
 };
@@ -51,6 +51,11 @@ impl BlockUser {
     expires: Option<NaiveDateTime>,
     context: &LemmyContext,
   ) -> Result<BlockUser, LemmyError> {
+    let audience = if let SiteOrCommunity::Community(c) = target {
+      Some(ObjectId::new(c.actor_id()))
+    } else {
+      None
+    };
     Ok(BlockUser {
       actor: ObjectId::new(mod_.actor_id()),
       to: vec![public()],
@@ -64,6 +69,7 @@ impl BlockUser {
         BlockType::Block,
         &context.settings().get_protocol_and_hostname(),
       )?,
+      audience,
       expires: expires.map(convert_datetime),
     })
   }
@@ -242,22 +248,3 @@ impl ActivityHandler for BlockUser {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for BlockUser {
-  #[tracing::instrument(skip_all)]
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    let target = self
-      .target
-      .dereference(context, local_instance(context).await, request_counter)
-      .await?;
-    match target {
-      SiteOrCommunity::Community(c) => Ok(c),
-      SiteOrCommunity::Site(_) => Err(anyhow!("Calling get_community() on site activity").into()),
-    }
-  }
-}
index ff76d9140b817d6ef023ac3a65404bc6f2c99583..eb54f5e48b445c9169d07294adb8936f7870bd8d 100644 (file)
@@ -1,14 +1,14 @@
 use crate::{
   activities::{
     block::{generate_cc, SiteOrCommunity},
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     generate_activity_id,
     send_lemmy_activity,
     verify_is_public,
   },
   activity_lists::AnnouncableActivities,
   local_instance,
-  objects::{community::ApubCommunity, instance::remote_instance_inboxes, person::ApubPerson},
+  objects::{instance::remote_instance_inboxes, person::ApubPerson},
   protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
   ActorType,
 };
@@ -41,6 +41,11 @@ impl UndoBlockUser {
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
     let block = BlockUser::new(target, user, mod_, None, reason, None, context).await?;
+    let audience = if let SiteOrCommunity::Community(c) = target {
+      Some(ObjectId::new(c.actor_id()))
+    } else {
+      None
+    };
 
     let id = generate_activity_id(
       UndoType::Undo,
@@ -53,6 +58,7 @@ impl UndoBlockUser {
       cc: generate_cc(target, context.pool()).await?,
       kind: UndoType::Undo,
       id: id.clone(),
+      audience,
     };
 
     let mut inboxes = vec![user.shared_inbox_or_inbox()];
@@ -162,15 +168,3 @@ impl ActivityHandler for UndoBlockUser {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for UndoBlockUser {
-  #[tracing::instrument(skip_all)]
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    self.object.get_community(context, request_counter).await
-  }
-}
index e863cf0dd5c73f87e7ca5ab9dac3ce822cf4ee6f..c212cfe148add1d4f7593f7dfa4d8b1f48a6f207 100644 (file)
@@ -1,10 +1,6 @@
 use crate::{
   activities::{
-    community::{
-      announce::GetCommunity,
-      get_community_from_moderators_url,
-      send_activity_in_community,
-    },
+    community::send_activity_in_community,
     generate_activity_id,
     verify_add_remove_moderator_target,
     verify_is_public,
@@ -15,7 +11,7 @@ use crate::{
   generate_moderators_url,
   local_instance,
   objects::{community::ApubCommunity, person::ApubPerson},
-  protocol::activities::community::add_mod::AddMod,
+  protocol::{activities::community::add_mod::AddMod, InCommunity},
   ActorType,
 };
 use activitypub_federation::{
@@ -55,6 +51,7 @@ impl AddMod {
       cc: vec![community.actor_id()],
       kind: AddType::Add,
       id: id.clone(),
+      audience: Some(ObjectId::new(community.actor_id())),
     };
 
     let activity = AnnouncableActivities::AddMod(add);
@@ -83,7 +80,7 @@ impl ActivityHandler for AddMod {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to, &self.cc)?;
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(
       &self.actor,
@@ -103,7 +100,7 @@ impl ActivityHandler for AddMod {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     let new_mod = self
       .object
       .dereference(context, local_instance(context).await, request_counter)
@@ -138,15 +135,3 @@ impl ActivityHandler for AddMod {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for AddMod {
-  #[tracing::instrument(skip_all)]
-  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
-  }
-}
index 9c1b752a6c8ba2820d1990e9910bba46c852ae87..b6c31af5d590467989845b6f436da5b7ab0853bf 100644 (file)
@@ -12,6 +12,7 @@ use crate::{
     activities::community::announce::{AnnounceActivity, RawAnnouncableActivities},
     Id,
     IdOrNestedObject,
+    InCommunity,
   },
   ActorType,
 };
@@ -56,7 +57,7 @@ impl ActivityHandler for RawAnnouncableActivities {
     if let AnnouncableActivities::Page(_) = activity {
       return Err(LemmyError::from_message("Cant receive page"));
     }
-    let community = activity.get_community(data, &mut 0).await?;
+    let community = activity.community(data, &mut 0).await?;
     let actor_id = ObjectId::new(activity.actor().clone());
 
     // verify and receive activity
@@ -72,15 +73,6 @@ impl ActivityHandler for RawAnnouncableActivities {
   }
 }
 
-#[async_trait::async_trait(?Send)]
-pub(crate) trait GetCommunity {
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError>;
-}
-
 impl AnnounceActivity {
   pub(crate) fn new(
     object: RawAnnouncableActivities,
index d05a3d66c5bd28e80a83053c56560a90354cb726..a7b35595e035d629182d212eff609ec259817d5a 100644 (file)
@@ -64,7 +64,7 @@ pub(crate) async fn send_activity_in_community(
 }
 
 #[tracing::instrument(skip_all)]
-async fn get_community_from_moderators_url(
+pub(crate) async fn get_community_from_moderators_url(
   moderators: &Url,
   context: &LemmyContext,
   request_counter: &mut i32,
index 6740d3f10afcdd166cd1a50ad68e1a7ca844b4dd..3934df3b1c4b20b8fe39220508cacfddfd36303d 100644 (file)
@@ -1,10 +1,6 @@
 use crate::{
   activities::{
-    community::{
-      announce::GetCommunity,
-      get_community_from_moderators_url,
-      send_activity_in_community,
-    },
+    community::send_activity_in_community,
     generate_activity_id,
     verify_add_remove_moderator_target,
     verify_is_public,
@@ -15,7 +11,7 @@ use crate::{
   generate_moderators_url,
   local_instance,
   objects::{community::ApubCommunity, person::ApubPerson},
-  protocol::activities::community::remove_mod::RemoveMod,
+  protocol::{activities::community::remove_mod::RemoveMod, InCommunity},
   ActorType,
 };
 use activitypub_federation::{
@@ -55,6 +51,7 @@ impl RemoveMod {
       id: id.clone(),
       cc: vec![community.actor_id()],
       kind: RemoveType::Remove,
+      audience: Some(ObjectId::new(community.actor_id())),
     };
 
     let activity = AnnouncableActivities::RemoveMod(remove);
@@ -83,7 +80,7 @@ impl ActivityHandler for RemoveMod {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to, &self.cc)?;
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(
       &self.actor,
@@ -103,7 +100,7 @@ impl ActivityHandler for RemoveMod {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     let remove_mod = self
       .object
       .dereference(context, local_instance(context).await, request_counter)
@@ -132,15 +129,3 @@ impl ActivityHandler for RemoveMod {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for RemoveMod {
-  #[tracing::instrument(skip_all)]
-  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
-  }
-}
index 867307f58d9871fbaa8dab98f0e7c31b78cc9352..440a8ebbba9f3e60dc004a91c342b419c07c5895 100644 (file)
@@ -2,7 +2,7 @@ use crate::{
   activities::{generate_activity_id, send_lemmy_activity, verify_person_in_community},
   local_instance,
   objects::{community::ApubCommunity, person::ApubPerson},
-  protocol::activities::community::report::Report,
+  protocol::{activities::community::report::Report, InCommunity},
   ActorType,
   PostOrComment,
 };
@@ -47,6 +47,7 @@ impl Report {
       summary: reason,
       kind,
       id: id.clone(),
+      audience: Some(ObjectId::new(community.actor_id())),
     };
 
     let inbox = vec![community.shared_inbox_or_inbox()];
@@ -73,9 +74,7 @@ impl ActivityHandler for Report {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.to[0]
-      .dereference(context, local_instance(context).await, request_counter)
-      .await?;
+    let community = self.community(context, request_counter).await?;
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     Ok(())
   }
index a4beccc01deb08aaab05f0bc59bca5142f121a06..f41f2d47c2bdc6d04ff6fb22d4e993c82ab27e6c 100644 (file)
@@ -1,15 +1,14 @@
 use crate::{
   activities::{
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     generate_activity_id,
     verify_is_public,
     verify_mod_action,
     verify_person_in_community,
   },
   activity_lists::AnnouncableActivities,
-  local_instance,
   objects::{community::ApubCommunity, person::ApubPerson},
-  protocol::activities::community::update::UpdateCommunity,
+  protocol::{activities::community::update::UpdateCommunity, InCommunity},
   ActorType,
 };
 use activitypub_federation::{
@@ -41,6 +40,7 @@ impl UpdateCommunity {
       cc: vec![community.actor_id()],
       kind: UpdateType::Update,
       id: id.clone(),
+      audience: Some(ObjectId::new(community.actor_id())),
     };
 
     let activity = AnnouncableActivities::UpdateCommunity(update);
@@ -68,7 +68,7 @@ impl ActivityHandler for UpdateCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to, &self.cc)?;
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_mod_action(
       &self.actor,
@@ -94,7 +94,7 @@ impl ActivityHandler for UpdateCommunity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
 
     let community_update_form = self.object.into_update_form();
 
@@ -112,18 +112,3 @@ impl ActivityHandler for UpdateCommunity {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for UpdateCommunity {
-  #[tracing::instrument(skip_all)]
-  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, local_instance(context).await, request_counter)
-      .await
-  }
-}
index 59e9d4b4e1ce14130530094d386378c948ff97cb..a4b60ad4d052a8b3163c8aa623826c6728906221 100644 (file)
@@ -1,7 +1,7 @@
 use crate::{
   activities::{
     check_community_deleted_or_removed,
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     create_or_update::get_comment_notif_recipients,
     generate_activity_id,
     verify_is_public,
@@ -11,7 +11,10 @@ use crate::{
   local_instance,
   mentions::MentionOrValue,
   objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson},
-  protocol::activities::{create_or_update::comment::CreateOrUpdateComment, CreateOrUpdateType},
+  protocol::{
+    activities::{create_or_update::note::CreateOrUpdateNote, CreateOrUpdateType},
+    InCommunity,
+  },
   ActorType,
 };
 use activitypub_federation::{
@@ -34,7 +37,7 @@ use lemmy_utils::error::LemmyError;
 use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
-impl CreateOrUpdateComment {
+impl CreateOrUpdateNote {
   #[tracing::instrument(skip(comment, actor, kind, context))]
   pub async fn send(
     comment: ApubComment,
@@ -55,7 +58,7 @@ impl CreateOrUpdateComment {
     )?;
     let note = comment.into_apub(context).await?;
 
-    let create_or_update = CreateOrUpdateComment {
+    let create_or_update = CreateOrUpdateNote {
       actor: ObjectId::new(actor.actor_id()),
       to: vec![public()],
       cc: note.cc.clone(),
@@ -63,6 +66,7 @@ impl CreateOrUpdateComment {
       object: note,
       kind,
       id: id.clone(),
+      audience: Some(ObjectId::new(community.actor_id())),
     };
 
     let tagged_users: Vec<ObjectId<ApubPerson>> = create_or_update
@@ -92,7 +96,7 @@ impl CreateOrUpdateComment {
 }
 
 #[async_trait::async_trait(?Send)]
-impl ActivityHandler for CreateOrUpdateComment {
+impl ActivityHandler for CreateOrUpdateNote {
   type DataType = LemmyContext;
   type Error = LemmyError;
 
@@ -112,7 +116,7 @@ impl ActivityHandler for CreateOrUpdateComment {
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to, &self.cc)?;
     let post = self.object.get_parents(context, request_counter).await?.0;
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
 
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_domains_match(self.actor.inner(), self.object.id.inner())?;
@@ -160,17 +164,3 @@ impl ActivityHandler for CreateOrUpdateComment {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for CreateOrUpdateComment {
-  #[tracing::instrument(skip_all)]
-  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 = Community::read(context.pool(), post.community_id).await?;
-    Ok(community.into())
-  }
-}
index bff289d99f033e540aeb901962fd46a12a18bae6..abe9be1a66a22593d3ee84827e8613034752a4a6 100644 (file)
@@ -1,7 +1,7 @@
 use crate::{
   activities::{
     check_community_deleted_or_removed,
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     generate_activity_id,
     verify_is_public,
     verify_mod_action,
@@ -9,7 +9,10 @@ use crate::{
   },
   activity_lists::AnnouncableActivities,
   objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
-  protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
+  protocol::{
+    activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType},
+    InCommunity,
+  },
   ActorType,
 };
 use activitypub_federation::{
@@ -30,25 +33,26 @@ use lemmy_utils::error::LemmyError;
 use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
-impl CreateOrUpdatePost {
+impl CreateOrUpdatePage {
   pub(crate) async fn new(
     post: ApubPost,
     actor: &ApubPerson,
     community: &ApubCommunity,
     kind: CreateOrUpdateType,
     context: &LemmyContext,
-  ) -> Result<CreateOrUpdatePost, LemmyError> {
+  ) -> Result<CreateOrUpdatePage, LemmyError> {
     let id = generate_activity_id(
       kind.clone(),
       &context.settings().get_protocol_and_hostname(),
     )?;
-    Ok(CreateOrUpdatePost {
+    Ok(CreateOrUpdatePage {
       actor: ObjectId::new(actor.actor_id()),
       to: vec![public()],
       object: post.into_apub(context).await?,
       cc: vec![community.actor_id()],
       kind,
       id: id.clone(),
+      audience: Some(ObjectId::new(community.actor_id())),
     })
   }
 
@@ -62,7 +66,7 @@ impl CreateOrUpdatePost {
     let community_id = post.community_id;
     let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into();
 
-    let create_or_update = CreateOrUpdatePost::new(post, actor, &community, kind, context).await?;
+    let create_or_update = CreateOrUpdatePage::new(post, actor, &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(activity, actor, &community, vec![], is_mod_action, context).await?;
@@ -71,7 +75,7 @@ impl CreateOrUpdatePost {
 }
 
 #[async_trait::async_trait(?Send)]
-impl ActivityHandler for CreateOrUpdatePost {
+impl ActivityHandler for CreateOrUpdatePage {
   type DataType = LemmyContext;
   type Error = LemmyError;
 
@@ -90,7 +94,7 @@ impl ActivityHandler for CreateOrUpdatePost {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_is_public(&self.to, &self.cc)?;
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     check_community_deleted_or_removed(&community)?;
 
@@ -155,18 +159,3 @@ impl ActivityHandler for CreateOrUpdatePost {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for CreateOrUpdatePost {
-  #[tracing::instrument(skip_all)]
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    self
-      .object
-      .extract_community(context, request_counter)
-      .await
-  }
-}
index e07661961805af4995884589919e953557dc9f9f..eb310ce9cf26feda214ff9a6bf466a39b7868a89 100644 (file)
@@ -2,7 +2,7 @@ use crate::{
   activities::{generate_activity_id, send_lemmy_activity, verify_person},
   objects::{person::ApubPerson, private_message::ApubPrivateMessage},
   protocol::activities::{
-    create_or_update::private_message::CreateOrUpdatePrivateMessage,
+    create_or_update::chat_message::CreateOrUpdateChatMessage,
     CreateOrUpdateType,
   },
   ActorType,
@@ -18,7 +18,7 @@ use lemmy_utils::error::LemmyError;
 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
-impl CreateOrUpdatePrivateMessage {
+impl CreateOrUpdateChatMessage {
   #[tracing::instrument(skip_all)]
   pub async fn send(
     private_message: ApubPrivateMessage,
@@ -33,7 +33,7 @@ impl CreateOrUpdatePrivateMessage {
       kind.clone(),
       &context.settings().get_protocol_and_hostname(),
     )?;
-    let create_or_update = CreateOrUpdatePrivateMessage {
+    let create_or_update = CreateOrUpdateChatMessage {
       id: id.clone(),
       actor: ObjectId::new(actor.actor_id()),
       to: [ObjectId::new(recipient.actor_id())],
@@ -46,7 +46,7 @@ impl CreateOrUpdatePrivateMessage {
 }
 
 #[async_trait::async_trait(?Send)]
-impl ActivityHandler for CreateOrUpdatePrivateMessage {
+impl ActivityHandler for CreateOrUpdateChatMessage {
   type DataType = LemmyContext;
   type Error = LemmyError;
 
index 8d296332e01a083151f74f8498a3b04a80b41efa..8298a6fe04fcf2ebf9dde6d27aafb1f4bc3512fc 100644 (file)
@@ -1,6 +1,5 @@
 use crate::{
   activities::{
-    community::announce::GetCommunity,
     deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
     generate_activity_id,
   },
@@ -10,7 +9,6 @@ use crate::{
 };
 use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler};
 use activitystreams_kinds::activity::DeleteType;
-use anyhow::anyhow;
 use lemmy_db_schema::{
   source::{
     comment::{Comment, CommentUpdateForm},
@@ -117,6 +115,7 @@ impl Delete {
       kind: DeleteType::Delete,
       summary,
       id,
+      audience: community.map(|c| ObjectId::<ApubCommunity>::new(c.actor_id.clone())),
     })
   }
 }
@@ -191,27 +190,3 @@ pub(in crate::activities) async fn receive_remove_action(
   }
   Ok(())
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for Delete {
-  #[tracing::instrument(skip_all)]
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    _request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    let community_id = match DeletableObjects::read_from_db(self.object.id(), context).await? {
-      DeletableObjects::Community(c) => c.id,
-      DeletableObjects::Comment(c) => {
-        let post = Post::read(context.pool(), c.post_id).await?;
-        post.community_id
-      }
-      DeletableObjects::Post(p) => p.community_id,
-      DeletableObjects::PrivateMessage(_) => {
-        return Err(anyhow!("Private message is not part of community").into())
-      }
-    };
-    let community = Community::read(context.pool(), community_id).await?;
-    Ok(community.into())
-  }
-}
index 5307e36801a8cd0d62b868017f50419e673bb6a4..bf4b920a81c07b813baca532f734eb5335dcb304 100644 (file)
@@ -1,6 +1,6 @@
 use crate::{
   activities::{
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     send_lemmy_activity,
     verify_is_public,
     verify_mod_action,
@@ -16,7 +16,10 @@ use crate::{
     post::ApubPost,
     private_message::ApubPrivateMessage,
   },
-  protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
+  protocol::{
+    activities::deletion::{delete::Delete, undo_delete::UndoDelete},
+    InCommunity,
+  },
   ActorType,
 };
 use activitypub_federation::{
@@ -175,7 +178,7 @@ pub(in crate::activities) async fn verify_delete_activity(
       verify_delete_post_or_comment(
         &activity.actor,
         &p.ap_id.clone().into(),
-        &activity.get_community(context, request_counter).await?,
+        &activity.community(context, request_counter).await?,
         is_mod_action,
         context,
         request_counter,
@@ -187,7 +190,7 @@ pub(in crate::activities) async fn verify_delete_activity(
       verify_delete_post_or_comment(
         &activity.actor,
         &c.ap_id.clone().into(),
-        &activity.get_community(context, request_counter).await?,
+        &activity.community(context, request_counter).await?,
         is_mod_action,
         context,
         request_counter,
index c3533ad5e5c2964e0d39c3ab9259f4b057d1a2ce..8b845400e52a62f16c217075de6b46e13323d19b 100644 (file)
@@ -1,6 +1,5 @@
 use crate::{
   activities::{
-    community::announce::GetCommunity,
     deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
     generate_activity_id,
   },
@@ -117,6 +116,7 @@ impl UndoDelete {
       cc: cc.into_iter().collect(),
       kind: UndoType::Undo,
       id,
+      audience: community.map(|c| ObjectId::<ApubCommunity>::new(c.actor_id.clone())),
     })
   }
 
@@ -187,15 +187,3 @@ impl UndoDelete {
     Ok(())
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for UndoDelete {
-  #[tracing::instrument(skip_all)]
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    self.object.get_community(context, request_counter).await
-  }
-}
index 3cf9771e13b912570b54a02a7842ee1600f95dd7..c38eadcda2a000ae8c74af1b70015fe80f27460f 100644 (file)
@@ -130,6 +130,16 @@ pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> Result<(), LemmyError>
   Ok(())
 }
 
+pub(crate) fn verify_community_matches(
+  a: &ApubCommunity,
+  b: CommunityId,
+) -> Result<(), LemmyError> {
+  if a.id != b {
+    return Err(LemmyError::from_message("Invalid community"));
+  }
+  Ok(())
+}
+
 pub(crate) fn check_community_deleted_or_removed(community: &Community) -> Result<(), LemmyError> {
   if community.deleted || community.removed {
     Err(LemmyError::from_message(
index 2c1a1b2deb140905a58ed12cd099655ebd623447..20c9432cde52957362b31fa5b1785607ada51717 100644 (file)
@@ -1,6 +1,6 @@
 use crate::{
   activities::{
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     generate_activity_id,
     verify_person_in_community,
     voting::{undo_vote_comment, undo_vote_post},
@@ -8,9 +8,12 @@ use crate::{
   activity_lists::AnnouncableActivities,
   local_instance,
   objects::{community::ApubCommunity, person::ApubPerson},
-  protocol::activities::voting::{
-    undo_vote::UndoVote,
-    vote::{Vote, VoteType},
+  protocol::{
+    activities::voting::{
+      undo_vote::UndoVote,
+      vote::{Vote, VoteType},
+    },
+    InCommunity,
   },
   ActorType,
   PostOrComment,
@@ -41,7 +44,7 @@ impl UndoVote {
   ) -> Result<(), LemmyError> {
     let community: ApubCommunity = Community::read(context.pool(), community_id).await?.into();
 
-    let object = Vote::new(object, actor, kind.clone(), context)?;
+    let object = Vote::new(object, actor, &community, kind.clone(), context)?;
     let id = generate_activity_id(
       UndoType::Undo,
       &context.settings().get_protocol_and_hostname(),
@@ -51,6 +54,7 @@ impl UndoVote {
       object,
       kind: UndoType::Undo,
       id: id.clone(),
+      audience: Some(ObjectId::new(community.actor_id())),
     };
     let activity = AnnouncableActivities::UndoVote(undo_vote);
     send_activity_in_community(activity, actor, &community, vec![], false, context).await
@@ -76,7 +80,7 @@ impl ActivityHandler for UndoVote {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     verify_urls_match(self.actor.inner(), self.object.actor.inner())?;
     self.object.verify(context, request_counter).await?;
@@ -104,15 +108,3 @@ impl ActivityHandler for UndoVote {
     }
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for UndoVote {
-  #[tracing::instrument(skip_all)]
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    self.object.get_community(context, request_counter).await
-  }
-}
index 2b60206a1c02a6f938347b4b0014b249c8d37f1b..f8d44ed9878444b48f0dae5c166a58ed2ec13602 100644 (file)
@@ -1,6 +1,6 @@
 use crate::{
   activities::{
-    community::{announce::GetCommunity, send_activity_in_community},
+    community::send_activity_in_community,
     generate_activity_id,
     verify_person_in_community,
     voting::{vote_comment, vote_post},
@@ -8,7 +8,10 @@ use crate::{
   activity_lists::AnnouncableActivities,
   local_instance,
   objects::{community::ApubCommunity, person::ApubPerson},
-  protocol::activities::voting::vote::{Vote, VoteType},
+  protocol::{
+    activities::voting::vote::{Vote, VoteType},
+    InCommunity,
+  },
   ActorType,
   PostOrComment,
 };
@@ -16,7 +19,7 @@ use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::Acti
 use anyhow::anyhow;
 use lemmy_db_schema::{
   newtypes::CommunityId,
-  source::{community::Community, local_site::LocalSite, post::Post},
+  source::{community::Community, local_site::LocalSite},
   traits::Crud,
 };
 use lemmy_utils::error::LemmyError;
@@ -29,6 +32,7 @@ impl Vote {
   pub(in crate::activities::voting) fn new(
     object: &PostOrComment,
     actor: &ApubPerson,
+    community: &ApubCommunity,
     kind: VoteType,
     context: &LemmyContext,
   ) -> Result<Vote, LemmyError> {
@@ -37,6 +41,7 @@ impl Vote {
       object: ObjectId::new(object.ap_id()),
       kind: kind.clone(),
       id: generate_activity_id(kind, &context.settings().get_protocol_and_hostname())?,
+      audience: Some(ObjectId::new(community.actor_id())),
     })
   }
 
@@ -49,7 +54,7 @@ impl Vote {
     context: &LemmyContext,
   ) -> Result<(), LemmyError> {
     let community = Community::read(context.pool(), community_id).await?.into();
-    let vote = Vote::new(object, actor, kind, context)?;
+    let vote = Vote::new(object, actor, &community, kind, context)?;
 
     let activity = AnnouncableActivities::Vote(vote);
     send_activity_in_community(activity, actor, &community, vec![], false, context).await
@@ -75,7 +80,7 @@ impl ActivityHandler for Vote {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let community = self.get_community(context, request_counter).await?;
+    let community = self.community(context, request_counter).await?;
     verify_person_in_community(&self.actor, &community, context, request_counter).await?;
     let enable_downvotes = LocalSite::read(context.pool())
       .await
@@ -107,24 +112,3 @@ impl ActivityHandler for Vote {
     }
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl GetCommunity for Vote {
-  #[tracing::instrument(skip_all)]
-  async fn get_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    let object = self
-      .object
-      .dereference(context, local_instance(context).await, request_counter)
-      .await?;
-    let cid = match object {
-      PostOrComment::Post(p) => p.community_id,
-      PostOrComment::Comment(c) => Post::read(context.pool(), c.post_id).await?.community_id,
-    };
-    let community = Community::read(context.pool(), cid).await?;
-    Ok(community.into())
-  }
-}
index 242f26a1f5088218b1ec1c4ed94cbe5bc371cc0b..fa8eece38921fbd29bd22c7a354c0b0fb9c07e9d 100644 (file)
@@ -1,5 +1,4 @@
 use crate::{
-  activities::community::announce::GetCommunity,
   objects::community::ApubCommunity,
   protocol::{
     activities::{
@@ -12,15 +11,16 @@ use crate::{
         update::UpdateCommunity,
       },
       create_or_update::{
-        comment::CreateOrUpdateComment,
-        post::CreateOrUpdatePost,
-        private_message::CreateOrUpdatePrivateMessage,
+        chat_message::CreateOrUpdateChatMessage,
+        note::CreateOrUpdateNote,
+        page::CreateOrUpdatePage,
       },
       deletion::{delete::Delete, delete_user::DeleteUser, undo_delete::UndoDelete},
       following::{accept::AcceptFollow, follow::Follow, undo_follow::UndoFollow},
       voting::{undo_vote::UndoVote, vote::Vote},
     },
     objects::page::Page,
+    InCommunity,
   },
 };
 use activitypub_federation::{data::Data, deser::context::WithContext, traits::ActivityHandler};
@@ -54,8 +54,7 @@ pub enum GroupInboxActivities {
 pub enum PersonInboxActivities {
   AcceptFollow(AcceptFollow),
   UndoFollow(UndoFollow),
-  FollowCommunity(Follow),
-  CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage),
+  CreateOrUpdatePrivateMessage(CreateOrUpdateChatMessage),
   Delete(Delete),
   UndoDelete(UndoDelete),
   AnnounceActivity(AnnounceActivity),
@@ -76,8 +75,8 @@ pub enum PersonInboxActivitiesWithAnnouncable {
 #[serde(untagged)]
 #[enum_delegate::implement(ActivityHandler)]
 pub enum AnnouncableActivities {
-  CreateOrUpdateComment(CreateOrUpdateComment),
-  CreateOrUpdatePost(CreateOrUpdatePost),
+  CreateOrUpdateComment(CreateOrUpdateNote),
+  CreateOrUpdatePost(CreateOrUpdatePage),
   Vote(Vote),
   UndoVote(UndoVote),
   Delete(Delete),
@@ -102,29 +101,28 @@ pub enum SiteInboxActivities {
 }
 
 #[async_trait::async_trait(?Send)]
-impl GetCommunity for AnnouncableActivities {
+impl InCommunity for AnnouncableActivities {
   #[tracing::instrument(skip(self, context))]
-  async fn get_community(
+  async fn 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?,
-      BlockUser(a) => a.get_community(context, request_counter).await?,
-      UndoBlockUser(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?,
+    match self {
+      CreateOrUpdateComment(a) => a.community(context, request_counter).await,
+      CreateOrUpdatePost(a) => a.community(context, request_counter).await,
+      Vote(a) => a.community(context, request_counter).await,
+      UndoVote(a) => a.community(context, request_counter).await,
+      Delete(a) => a.community(context, request_counter).await,
+      UndoDelete(a) => a.community(context, request_counter).await,
+      UpdateCommunity(a) => a.community(context, request_counter).await,
+      BlockUser(a) => a.community(context, request_counter).await,
+      UndoBlockUser(a) => a.community(context, request_counter).await,
+      AddMod(a) => a.community(context, request_counter).await,
+      RemoveMod(a) => a.community(context, request_counter).await,
       Page(_) => unimplemented!(),
-    };
-    Ok(community)
+    }
   }
 }
 
index bc0a224c6497520069dbe1512757c3224075af1b..c7742de725451300365b082cde4ab2a6b11a7a17 100644 (file)
@@ -6,7 +6,7 @@ use crate::{
   protocol::{
     activities::{
       community::announce::AnnounceActivity,
-      create_or_update::post::CreateOrUpdatePost,
+      create_or_update::page::CreateOrUpdatePage,
       CreateOrUpdateType,
     },
     collections::group_outbox::GroupOutbox,
@@ -70,7 +70,7 @@ impl ApubObject for ApubCommunityOutbox {
     for post in self.0 {
       let person = Person::read(data.1.pool(), post.creator_id).await?.into();
       let create =
-        CreateOrUpdatePost::new(post, &person, &data.0, CreateOrUpdateType::Create, &data.1)
+        CreateOrUpdatePage::new(post, &person, &data.0, CreateOrUpdateType::Create, &data.1)
           .await?;
       let announcable = AnnouncableActivities::CreateOrUpdatePost(create);
       let announce = AnnounceActivity::new(announcable.try_into()?, &data.0, &data.1)?;
index dc425e21bf5668ffbe223289662c9235d5bf7737..d2d0b91f64e6fae2c0e58ab08619dfe1ac8033ea 100644 (file)
@@ -1,9 +1,16 @@
 use crate::{
-  objects::{comment::ApubComment, post::ApubPost},
-  protocol::objects::{note::Note, page::Page},
+  objects::{comment::ApubComment, community::ApubCommunity, post::ApubPost},
+  protocol::{
+    objects::{note::Note, page::Page},
+    InCommunity,
+  },
 };
 use activitypub_federation::traits::ApubObject;
 use chrono::NaiveDateTime;
+use lemmy_db_schema::{
+  source::{community::Community, post::Post},
+  traits::Crud,
+};
 use lemmy_utils::error::LemmyError;
 use lemmy_websocket::LemmyContext;
 use serde::Deserialize;
@@ -99,3 +106,18 @@ impl PostOrComment {
     .into()
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for PostOrComment {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    _: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let cid = match self {
+      PostOrComment::Post(p) => p.community_id,
+      PostOrComment::Comment(c) => Post::read(context.pool(), c.post_id).await?.community_id,
+    };
+    Ok(Community::read(context.pool(), cid).await?.into())
+  }
+}
index ba3e518bc2a5be1fdc52277a64f5736522eb5f06..df20700fbd5b6bdca4c77b42dd5e077cd5a5404e 100644 (file)
@@ -7,6 +7,7 @@ use crate::{
   objects::{read_from_string_or_source, verify_is_remote_object},
   protocol::{
     objects::{note::Note, LanguageTag},
+    InCommunity,
     Source,
   },
   PostOrComment,
@@ -103,8 +104,13 @@ impl ApubObject for ApubComment {
       ObjectId::<PostOrComment>::new(post.ap_id)
     };
     let language = LanguageTag::new_single(self.language_id, context.pool()).await?;
-    let maa =
-      collect_non_local_mentions(&self, ObjectId::new(community.actor_id), context, &mut 0).await?;
+    let maa = collect_non_local_mentions(
+      &self,
+      ObjectId::new(community.actor_id.clone()),
+      context,
+      &mut 0,
+    )
+    .await?;
 
     let note = Note {
       r#type: NoteType::Note,
@@ -121,6 +127,7 @@ impl ApubObject for ApubComment {
       tag: maa.tags,
       distinguished: Some(self.distinguished),
       language,
+      audience: Some(ObjectId::new(community.actor_id)),
     };
 
     Ok(note)
@@ -136,9 +143,7 @@ impl ApubObject for ApubComment {
     verify_domains_match(note.id.inner(), expected_domain)?;
     verify_domains_match(note.attributed_to.inner(), note.id.inner())?;
     verify_is_public(&note.to, &note.cc)?;
-    let (post, _) = note.get_parents(context, request_counter).await?;
-    let community_id = post.community_id;
-    let community = Community::read(context.pool(), community_id).await?;
+    let community = note.community(context, request_counter).await?;
     let local_site_data = fetch_local_site_data(context.pool()).await?;
 
     check_apub_id_valid_with_strictness(
@@ -148,13 +153,8 @@ impl ApubObject for ApubComment {
       context.settings(),
     )?;
     verify_is_remote_object(note.id.inner(), context.settings())?;
-    verify_person_in_community(
-      &note.attributed_to,
-      &community.into(),
-      context,
-      request_counter,
-    )
-    .await?;
+    verify_person_in_community(&note.attributed_to, &community, context, request_counter).await?;
+    let (post, _) = note.get_parents(context, request_counter).await?;
     if post.locked {
       return Err(LemmyError::from_message("Post is locked"));
     }
index 01cb858193f66844303453b486f862ef9c27e637..b7d38e347fed06f87fae2b3a2c2d2173ac4a5371 100644 (file)
@@ -10,6 +10,7 @@ use crate::{
       LanguageTag,
     },
     ImageObject,
+    InCommunity,
     Source,
   },
 };
@@ -102,7 +103,7 @@ impl ApubObject for ApubPost {
       kind: PageType::Page,
       id: ObjectId::new(self.ap_id.clone()),
       attributed_to: AttributedTo::Lemmy(ObjectId::new(creator.actor_id)),
-      to: vec![community.actor_id.into(), public()],
+      to: vec![community.actor_id.clone().into(), public()],
       cc: vec![],
       name: self.name.clone(),
       content: self.body.as_ref().map(|b| markdown_to_html(b)),
@@ -117,6 +118,7 @@ impl ApubObject for ApubPost {
       language,
       published: Some(convert_datetime(self.published)),
       updated: self.updated.map(convert_datetime),
+      audience: Some(ObjectId::new(community.actor_id)),
     };
     Ok(page)
   }
@@ -137,7 +139,7 @@ impl ApubObject for ApubPost {
 
     let local_site_data = fetch_local_site_data(context.pool()).await?;
 
-    let community = page.extract_community(context, request_counter).await?;
+    let community = page.community(context, request_counter).await?;
     check_apub_id_valid_with_strictness(
       page.id.inner(),
       community.local,
@@ -164,7 +166,7 @@ impl ApubObject for ApubPost {
       .creator()?
       .dereference(context, local_instance(context).await, request_counter)
       .await?;
-    let community = page.extract_community(context, request_counter).await?;
+    let community = page.community(context, request_counter).await?;
 
     let form = if !page.is_mod_action(context).await? {
       let first_attachment = page.attachment.into_iter().map(Attachment::url).next();
index 3925c55c790def35d7ab7da3b623ddccf58176b6..91467a96ca2060412d44332027c1d2ad3d4adc29 100644 (file)
@@ -1,10 +1,20 @@
-use crate::{activities::block::SiteOrCommunity, objects::person::ApubPerson};
+use crate::{
+  activities::{block::SiteOrCommunity, verify_community_matches},
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::InCommunity,
+};
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
 use activitystreams_kinds::activity::BlockType;
+use anyhow::anyhow;
 use chrono::{DateTime, FixedOffset};
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
+use serde_with::skip_serializing_none;
 use url::Url;
 
+#[skip_serializing_none]
 #[derive(Clone, Debug, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct BlockUser {
@@ -18,6 +28,7 @@ pub struct BlockUser {
   #[serde(rename = "type")]
   pub(crate) kind: BlockType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
 
   /// Quick and dirty solution.
   /// TODO: send a separate Delete activity instead
@@ -26,3 +37,30 @@ pub struct BlockUser {
   pub(crate) summary: Option<String>,
   pub(crate) expires: Option<DateTime<FixedOffset>>,
 }
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for BlockUser {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let target = self
+      .target
+      .dereference(context, local_instance(context).await, request_counter)
+      .await?;
+    let target_community = match target {
+      SiteOrCommunity::Community(c) => c,
+      SiteOrCommunity::Site(_) => return Err(anyhow!("activity is not in community").into()),
+    };
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, target_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(target_community)
+    }
+  }
+}
index df1611437caed80be51af88869c903cecfeccb67..ade126eec684ea7cdb9ae9b7f65b88f7e8ea2e92 100644 (file)
@@ -1,9 +1,18 @@
-use crate::{objects::person::ApubPerson, protocol::activities::block::block_user::BlockUser};
+use crate::{
+  activities::verify_community_matches,
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::{activities::block::block_user::BlockUser, InCommunity},
+};
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
 use activitystreams_kinds::activity::UndoType;
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
+use serde_with::skip_serializing_none;
 use url::Url;
 
+#[skip_serializing_none]
 #[derive(Clone, Debug, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct UndoBlockUser {
@@ -16,4 +25,25 @@ pub struct UndoBlockUser {
   #[serde(rename = "type")]
   pub(crate) kind: UndoType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for UndoBlockUser {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let object_community = self.object.community(context, request_counter).await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, object_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(object_community)
+    }
+  }
 }
index b9ce2420ae495a2619a2cc032a8c420b9609cde2..f23fcbae01b0f93832b152d63788fb213d059875 100644 (file)
@@ -1,6 +1,13 @@
-use crate::objects::person::ApubPerson;
+use crate::{
+  activities::{community::get_community_from_moderators_url, verify_community_matches},
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::InCommunity,
+};
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
 use activitystreams_kinds::activity::AddType;
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -17,4 +24,26 @@ pub struct AddMod {
   #[serde(rename = "type")]
   pub(crate) kind: AddType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for AddMod {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let mod_community =
+      get_community_from_moderators_url(&self.target, context, request_counter).await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, mod_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(mod_community)
+    }
+  }
 }
index 6fd20af4b22e5be596e135c2daa21457d4c79be5..2ee744b7fbed62aed2d9db0b3b520065889c49e3 100644 (file)
@@ -1,6 +1,13 @@
-use crate::objects::person::ApubPerson;
+use crate::{
+  activities::{community::get_community_from_moderators_url, verify_community_matches},
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::InCommunity,
+};
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
 use activitystreams_kinds::activity::RemoveType;
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -17,4 +24,26 @@ pub struct RemoveMod {
   pub(crate) kind: RemoveType,
   pub(crate) target: Url,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for RemoveMod {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let mod_community =
+      get_community_from_moderators_url(&self.target, context, request_counter).await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, mod_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(mod_community)
+    }
+  }
 }
index f9830c85dbec047a2c15a8e734528af3d201e0e3..34738c56a49bfee338255c02dbf93566f5aa9c33 100644 (file)
@@ -1,9 +1,14 @@
 use crate::{
+  activities::verify_community_matches,
   fetcher::post_or_comment::PostOrComment,
+  local_instance,
   objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::InCommunity,
 };
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one};
 use activitystreams_kinds::activity::FlagType;
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -18,4 +23,27 @@ pub struct Report {
   #[serde(rename = "type")]
   pub(crate) kind: FlagType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for Report {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let to_community = self.to[0]
+      .dereference(context, local_instance(context).await, request_counter)
+      .await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, to_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(to_community)
+    }
+  }
 }
index f6ef99c0938e23b23ac3b2bf242823f137b79c4d..f534f236945f0747e504d72cf86319a3eeaca8af 100644 (file)
@@ -1,6 +1,13 @@
-use crate::{objects::person::ApubPerson, protocol::objects::group::Group};
+use crate::{
+  activities::verify_community_matches,
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::{objects::group::Group, InCommunity},
+};
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
 use activitystreams_kinds::activity::UpdateType;
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -19,4 +26,27 @@ pub struct UpdateCommunity {
   #[serde(rename = "type")]
   pub(crate) kind: UpdateType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for UpdateCommunity {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let object_community: ApubCommunity = ObjectId::new(self.object.id.clone())
+      .dereference(context, local_instance(context).await, request_counter)
+      .await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, object_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(object_community)
+    }
+  }
 }
similarity index 93%
rename from crates/apub/src/protocol/activities/create_or_update/private_message.rs
rename to crates/apub/src/protocol/activities/create_or_update/chat_message.rs
index 6a9b585bfd33a0ba8da2ee1041e7f8df2a22b18f..07a71d255987b576c9dd9d34c74dace553a14d67 100644 (file)
@@ -8,7 +8,7 @@ use url::Url;
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
-pub struct CreateOrUpdatePrivateMessage {
+pub struct CreateOrUpdateChatMessage {
   pub(crate) id: Url,
   pub(crate) actor: ObjectId<ApubPerson>,
   #[serde(deserialize_with = "deserialize_one")]
diff --git a/crates/apub/src/protocol/activities/create_or_update/comment.rs b/crates/apub/src/protocol/activities/create_or_update/comment.rs
deleted file mode 100644 (file)
index 3049b79..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-use crate::{
-  mentions::MentionOrValue,
-  objects::person::ApubPerson,
-  protocol::{activities::CreateOrUpdateType, objects::note::Note},
-};
-use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
-use serde::{Deserialize, Serialize};
-use url::Url;
-
-#[derive(Clone, Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct CreateOrUpdateComment {
-  pub(crate) actor: ObjectId<ApubPerson>,
-  #[serde(deserialize_with = "deserialize_one_or_many")]
-  pub(crate) to: Vec<Url>,
-  pub(crate) object: Note,
-  #[serde(deserialize_with = "deserialize_one_or_many")]
-  pub(crate) cc: Vec<Url>,
-  #[serde(default)]
-  pub(crate) tag: Vec<MentionOrValue>,
-  #[serde(rename = "type")]
-  pub(crate) kind: CreateOrUpdateType,
-  pub(crate) id: Url,
-}
index 0d233ccfcfafff1902c0ea1b84f96517b9a820cc..9e41d57fb1a91eb4aaece13d24bf6592e62606c7 100644 (file)
@@ -1,33 +1,33 @@
-pub mod comment;
-pub mod post;
-pub mod private_message;
+pub mod chat_message;
+pub mod note;
+pub mod page;
 
 #[cfg(test)]
 mod tests {
   use crate::protocol::{
     activities::create_or_update::{
-      comment::CreateOrUpdateComment,
-      post::CreateOrUpdatePost,
-      private_message::CreateOrUpdatePrivateMessage,
+      chat_message::CreateOrUpdateChatMessage,
+      note::CreateOrUpdateNote,
+      page::CreateOrUpdatePage,
     },
     tests::test_parse_lemmy_item,
   };
 
   #[test]
   fn test_parse_lemmy_create_or_update() {
-    test_parse_lemmy_item::<CreateOrUpdatePost>(
+    test_parse_lemmy_item::<CreateOrUpdatePage>(
       "assets/lemmy/activities/create_or_update/create_page.json",
     )
     .unwrap();
-    test_parse_lemmy_item::<CreateOrUpdatePost>(
+    test_parse_lemmy_item::<CreateOrUpdatePage>(
       "assets/lemmy/activities/create_or_update/update_page.json",
     )
     .unwrap();
-    test_parse_lemmy_item::<CreateOrUpdateComment>(
+    test_parse_lemmy_item::<CreateOrUpdateNote>(
       "assets/lemmy/activities/create_or_update/create_note.json",
     )
     .unwrap();
-    test_parse_lemmy_item::<CreateOrUpdatePrivateMessage>(
+    test_parse_lemmy_item::<CreateOrUpdateChatMessage>(
       "assets/lemmy/activities/create_or_update/create_private_message.json",
     )
     .unwrap();
diff --git a/crates/apub/src/protocol/activities/create_or_update/note.rs b/crates/apub/src/protocol/activities/create_or_update/note.rs
new file mode 100644 (file)
index 0000000..0de7161
--- /dev/null
@@ -0,0 +1,51 @@
+use crate::{
+  activities::verify_community_matches,
+  local_instance,
+  mentions::MentionOrValue,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::{activities::CreateOrUpdateType, objects::note::Note, InCommunity},
+};
+use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
+use lemmy_db_schema::{source::community::Community, traits::Crud};
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
+use serde::{Deserialize, Serialize};
+use url::Url;
+
+#[derive(Clone, Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CreateOrUpdateNote {
+  pub(crate) actor: ObjectId<ApubPerson>,
+  #[serde(deserialize_with = "deserialize_one_or_many")]
+  pub(crate) to: Vec<Url>,
+  pub(crate) object: Note,
+  #[serde(deserialize_with = "deserialize_one_or_many")]
+  pub(crate) cc: Vec<Url>,
+  #[serde(default)]
+  pub(crate) tag: Vec<MentionOrValue>,
+  #[serde(rename = "type")]
+  pub(crate) kind: CreateOrUpdateType,
+  pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for CreateOrUpdateNote {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let post = self.object.get_parents(context, request_counter).await?.0;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, post.community_id)?;
+      Ok(audience)
+    } else {
+      let community = Community::read(context.pool(), post.community_id).await?;
+      Ok(community.into())
+    }
+  }
+}
diff --git a/crates/apub/src/protocol/activities/create_or_update/page.rs b/crates/apub/src/protocol/activities/create_or_update/page.rs
new file mode 100644 (file)
index 0000000..b0311b5
--- /dev/null
@@ -0,0 +1,46 @@
+use crate::{
+  activities::verify_community_matches,
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::{activities::CreateOrUpdateType, objects::page::Page, InCommunity},
+};
+use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
+use serde::{Deserialize, Serialize};
+use url::Url;
+
+#[derive(Clone, Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CreateOrUpdatePage {
+  pub(crate) actor: ObjectId<ApubPerson>,
+  #[serde(deserialize_with = "deserialize_one_or_many")]
+  pub(crate) to: Vec<Url>,
+  pub(crate) object: Page,
+  #[serde(deserialize_with = "deserialize_one_or_many")]
+  pub(crate) cc: Vec<Url>,
+  #[serde(rename = "type")]
+  pub(crate) kind: CreateOrUpdateType,
+  pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for CreateOrUpdatePage {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let object_community = self.object.community(context, request_counter).await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, object_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(object_community)
+    }
+  }
+}
diff --git a/crates/apub/src/protocol/activities/create_or_update/post.rs b/crates/apub/src/protocol/activities/create_or_update/post.rs
deleted file mode 100644 (file)
index 70b1567..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-use crate::{
-  objects::person::ApubPerson,
-  protocol::{activities::CreateOrUpdateType, objects::page::Page},
-};
-use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
-use serde::{Deserialize, Serialize};
-use url::Url;
-
-#[derive(Clone, Debug, Deserialize, Serialize)]
-#[serde(rename_all = "camelCase")]
-pub struct CreateOrUpdatePost {
-  pub(crate) actor: ObjectId<ApubPerson>,
-  #[serde(deserialize_with = "deserialize_one_or_many")]
-  pub(crate) to: Vec<Url>,
-  pub(crate) object: Page,
-  #[serde(deserialize_with = "deserialize_one_or_many")]
-  pub(crate) cc: Vec<Url>,
-  #[serde(rename = "type")]
-  pub(crate) kind: CreateOrUpdateType,
-  pub(crate) id: Url,
-}
index d3dcaf57995eb93bf015d6f0f93e42a89115cc72..f5ae40d8a9b82708490ef8b60edf6d5ed14c319a 100644 (file)
@@ -1,9 +1,18 @@
 use crate::{
-  objects::person::ApubPerson,
-  protocol::{objects::tombstone::Tombstone, IdOrNestedObject},
+  activities::{deletion::DeletableObjects, verify_community_matches},
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::{objects::tombstone::Tombstone, IdOrNestedObject, InCommunity},
 };
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
 use activitystreams_kinds::activity::DeleteType;
+use anyhow::anyhow;
+use lemmy_db_schema::{
+  source::{community::Community, post::Post},
+  traits::Crud,
+};
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use serde_with::skip_serializing_none;
 use url::Url;
@@ -19,6 +28,7 @@ pub struct Delete {
   #[serde(rename = "type")]
   pub(crate) kind: DeleteType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
 
   #[serde(deserialize_with = "deserialize_one_or_many")]
   #[serde(default)]
@@ -28,3 +38,34 @@ pub struct Delete {
   /// deleting their own content.
   pub(crate) summary: Option<String>,
 }
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for Delete {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let community_id = match DeletableObjects::read_from_db(self.object.id(), context).await? {
+      DeletableObjects::Community(c) => c.id,
+      DeletableObjects::Comment(c) => {
+        let post = Post::read(context.pool(), c.post_id).await?;
+        post.community_id
+      }
+      DeletableObjects::Post(p) => p.community_id,
+      DeletableObjects::PrivateMessage(_) => {
+        return Err(anyhow!("Private message is not part of community").into())
+      }
+    };
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, community_id)?;
+      Ok(audience)
+    } else {
+      let community = Community::read(context.pool(), community_id).await?;
+      Ok(community.into())
+    }
+  }
+}
index 02cbf1785f44f40a821beb8e4714d1dd37115b6e..c4946850a1896e55ce848466de407ced7886e42a 100644 (file)
@@ -1,9 +1,18 @@
-use crate::{objects::person::ApubPerson, protocol::activities::deletion::delete::Delete};
+use crate::{
+  activities::verify_community_matches,
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::{activities::deletion::delete::Delete, InCommunity},
+};
 use activitypub_federation::{core::object_id::ObjectId, deser::helpers::deserialize_one_or_many};
 use activitystreams_kinds::activity::UndoType;
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
+use serde_with::skip_serializing_none;
 use url::Url;
 
+#[skip_serializing_none]
 #[derive(Clone, Debug, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct UndoDelete {
@@ -14,8 +23,29 @@ pub struct UndoDelete {
   #[serde(rename = "type")]
   pub(crate) kind: UndoType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
 
   #[serde(deserialize_with = "deserialize_one_or_many", default)]
   #[serde(skip_serializing_if = "Vec::is_empty")]
   pub(crate) cc: Vec<Url>,
 }
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for UndoDelete {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let object_community = self.object.community(context, request_counter).await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, object_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(object_community)
+    }
+  }
+}
index fcd3153c318410dcb779bd2e91d0d7775402d299..670c4466f4125e8681ec034f63e521c5dc44ca01 100644 (file)
@@ -19,7 +19,7 @@ mod tests {
   use crate::protocol::{
     activities::{
       community::announce::AnnounceActivity,
-      create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost},
+      create_or_update::{note::CreateOrUpdateNote, page::CreateOrUpdatePage},
       deletion::delete::Delete,
       following::{follow::Follow, undo_follow::UndoFollow},
       voting::{undo_vote::UndoVote, vote::Vote},
@@ -29,19 +29,19 @@ mod tests {
 
   #[test]
   fn test_parse_smithereen_activities() {
-    test_json::<CreateOrUpdateComment>("assets/smithereen/activities/create_note.json").unwrap();
+    test_json::<CreateOrUpdateNote>("assets/smithereen/activities/create_note.json").unwrap();
   }
 
   #[test]
   fn test_parse_pleroma_activities() {
-    test_json::<CreateOrUpdateComment>("assets/pleroma/activities/create_note.json").unwrap();
+    test_json::<CreateOrUpdateNote>("assets/pleroma/activities/create_note.json").unwrap();
     test_json::<Delete>("assets/pleroma/activities/delete.json").unwrap();
     test_json::<Follow>("assets/pleroma/activities/follow.json").unwrap();
   }
 
   #[test]
   fn test_parse_mastodon_activities() {
-    test_json::<CreateOrUpdateComment>("assets/mastodon/activities/create_note.json").unwrap();
+    test_json::<CreateOrUpdateNote>("assets/mastodon/activities/create_note.json").unwrap();
     test_json::<Delete>("assets/mastodon/activities/delete.json").unwrap();
     test_json::<Follow>("assets/mastodon/activities/follow.json").unwrap();
     test_json::<UndoFollow>("assets/mastodon/activities/undo_follow.json").unwrap();
@@ -51,17 +51,17 @@ mod tests {
 
   #[test]
   fn test_parse_lotide_activities() {
-    test_json::<CreateOrUpdatePost>("assets/lotide/activities/create_page.json").unwrap();
-    test_json::<CreateOrUpdatePost>("assets/lotide/activities/create_page_image.json").unwrap();
-    test_json::<CreateOrUpdateComment>("assets/lotide/activities/create_note_reply.json").unwrap();
+    test_json::<CreateOrUpdatePage>("assets/lotide/activities/create_page.json").unwrap();
+    test_json::<CreateOrUpdatePage>("assets/lotide/activities/create_page_image.json").unwrap();
+    test_json::<CreateOrUpdateNote>("assets/lotide/activities/create_note_reply.json").unwrap();
   }
 
   #[test]
   fn test_parse_friendica_activities() {
-    test_json::<CreateOrUpdatePost>("assets/friendica/activities/create_page_1.json").unwrap();
-    test_json::<CreateOrUpdatePost>("assets/friendica/activities/create_page_2.json").unwrap();
-    test_json::<CreateOrUpdateComment>("assets/friendica/activities/create_note.json").unwrap();
-    test_json::<CreateOrUpdateComment>("assets/friendica/activities/update_note.json").unwrap();
+    test_json::<CreateOrUpdatePage>("assets/friendica/activities/create_page_1.json").unwrap();
+    test_json::<CreateOrUpdatePage>("assets/friendica/activities/create_page_2.json").unwrap();
+    test_json::<CreateOrUpdateNote>("assets/friendica/activities/create_note.json").unwrap();
+    test_json::<CreateOrUpdateNote>("assets/friendica/activities/update_note.json").unwrap();
     test_json::<Delete>("assets/friendica/activities/delete.json").unwrap();
     test_json::<Vote>("assets/friendica/activities/like_page.json").unwrap();
     test_json::<Vote>("assets/friendica/activities/dislike_page.json").unwrap();
@@ -70,8 +70,8 @@ mod tests {
 
   #[test]
   fn test_parse_gnusocial_activities() {
-    test_json::<CreateOrUpdatePost>("assets/gnusocial/activities/create_page.json").unwrap();
-    test_json::<CreateOrUpdateComment>("assets/gnusocial/activities/create_note.json").unwrap();
+    test_json::<CreateOrUpdatePage>("assets/gnusocial/activities/create_page.json").unwrap();
+    test_json::<CreateOrUpdateNote>("assets/gnusocial/activities/create_note.json").unwrap();
     test_json::<Vote>("assets/gnusocial/activities/like_note.json").unwrap();
   }
 
index ee258539fea15fc8a5cf084295eeb8314fe4bec3..1d17cf158963e1a3f01047ec476db06ca42fcb43 100644 (file)
@@ -1,6 +1,13 @@
-use crate::{objects::person::ApubPerson, protocol::activities::voting::vote::Vote};
+use crate::{
+  activities::verify_community_matches,
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::{activities::voting::vote::Vote, InCommunity},
+};
 use activitypub_federation::core::object_id::ObjectId;
 use activitystreams_kinds::activity::UndoType;
+use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -12,4 +19,26 @@ pub struct UndoVote {
   #[serde(rename = "type")]
   pub(crate) kind: UndoType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
+}
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for UndoVote {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let local_instance = local_instance(context).await;
+    let object_community = self.object.community(context, request_counter).await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance, request_counter)
+        .await?;
+      verify_community_matches(&audience, object_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(object_community)
+    }
+  }
 }
index 002d235c0e23b3ce303da7dee6eadc6663999566..5da9b791c8d7770daa63fcfb9d4d8968752eacda 100644 (file)
@@ -1,6 +1,13 @@
-use crate::{fetcher::post_or_comment::PostOrComment, objects::person::ApubPerson};
+use crate::{
+  activities::verify_community_matches,
+  fetcher::post_or_comment::PostOrComment,
+  local_instance,
+  objects::{community::ApubCommunity, person::ApubPerson},
+  protocol::InCommunity,
+};
 use activitypub_federation::core::object_id::ObjectId;
 use lemmy_utils::error::LemmyError;
+use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use std::convert::TryFrom;
 use strum_macros::Display;
@@ -14,6 +21,7 @@ pub struct Vote {
   #[serde(rename = "type")]
   pub(crate) kind: VoteType,
   pub(crate) id: Url,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
 }
 
 #[derive(Clone, Debug, Display, Deserialize, Serialize, PartialEq, Eq)]
@@ -42,3 +50,29 @@ impl From<&VoteType> for i16 {
     }
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for Vote {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let local_instance = local_instance(context).await;
+    let object_community = self
+      .object
+      .dereference(context, local_instance, request_counter)
+      .await?
+      .community(context, request_counter)
+      .await?;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance, request_counter)
+        .await?;
+      verify_community_matches(&audience, object_community.id)?;
+      Ok(audience)
+    } else {
+      Ok(object_community)
+    }
+  }
+}
index c259a6e996bd13f26579c0cfd84336e9c283a088..a65e74da225a1d77b6b63956fc321bcf0f65839f 100644 (file)
@@ -1,4 +1,4 @@
-use crate::local_instance;
+use crate::{local_instance, objects::community::ApubCommunity};
 use activitypub_federation::{deser::values::MediaTypeMarkdown, utils::fetch_object_http};
 use activitystreams_kinds::object::ImageType;
 use lemmy_db_schema::newtypes::DbUrl;
@@ -81,6 +81,17 @@ impl<Kind: Id + DeserializeOwned> IdOrNestedObject<Kind> {
   }
 }
 
+#[async_trait::async_trait(?Send)]
+pub trait InCommunity {
+  // TODO: after we use audience field and remove backwards compat, it should be possible to change
+  //       this to simply `fn community(&self)  -> Result<ObjectId<ApubCommunity>, LemmyError>`
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError>;
+}
+
 #[cfg(test)]
 pub(crate) mod tests {
   use activitypub_federation::deser::context::WithContext;
index 727b98994941175846cd007cccf33058544926a4..21f7bcf38b67ffc30c12d7c7001afe3cc1d5f82a 100644 (file)
@@ -1,9 +1,10 @@
 use crate::{
+  activities::verify_community_matches,
   fetcher::post_or_comment::PostOrComment,
   local_instance,
   mentions::MentionOrValue,
-  objects::{comment::ApubComment, person::ApubPerson, post::ApubPost},
-  protocol::{objects::LanguageTag, Source},
+  objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
+  protocol::{objects::LanguageTag, InCommunity, Source},
 };
 use activitypub_federation::{
   core::object_id::ObjectId,
@@ -14,7 +15,10 @@ use activitypub_federation::{
 };
 use activitystreams_kinds::object::NoteType;
 use chrono::{DateTime, FixedOffset};
-use lemmy_db_schema::{source::post::Post, traits::Crud};
+use lemmy_db_schema::{
+  source::{community::Community, post::Post},
+  traits::Crud,
+};
 use lemmy_utils::error::LemmyError;
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
@@ -46,6 +50,7 @@ pub struct Note {
   // lemmy extension
   pub(crate) distinguished: Option<bool>,
   pub(crate) language: Option<LanguageTag>,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
 }
 
 impl Note {
@@ -75,3 +80,24 @@ impl Note {
     }
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for Note {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let (post, _) = self.get_parents(context, request_counter).await?;
+    let community_id = post.community_id;
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, local_instance(context).await, request_counter)
+        .await?;
+      verify_community_matches(&audience, community_id)?;
+      Ok(audience)
+    } else {
+      Ok(Community::read(context.pool(), community_id).await?.into())
+    }
+  }
+}
index ba76f62fbe041d74c5425d6f8fb47b9d5ccc97da..b25e1d97c742161596659a7eee9396ebcf0eba2e 100644 (file)
@@ -1,8 +1,9 @@
 use crate::{
+  activities::verify_community_matches,
   fetcher::user_or_community::{PersonOrGroupType, UserOrCommunity},
   local_instance,
   objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
-  protocol::{objects::LanguageTag, ImageObject, Source},
+  protocol::{objects::LanguageTag, ImageObject, InCommunity, Source},
 };
 use activitypub_federation::{
   core::object_id::ObjectId,
@@ -67,6 +68,7 @@ pub struct Page {
   pub(crate) published: Option<DateTime<FixedOffset>>,
   pub(crate) updated: Option<DateTime<FixedOffset>>,
   pub(crate) language: Option<LanguageTag>,
+  pub(crate) audience: Option<ObjectId<ApubCommunity>>,
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
@@ -169,39 +171,6 @@ impl Page {
     false
   }
 
-  pub(crate) async fn extract_community(
-    &self,
-    context: &LemmyContext,
-    request_counter: &mut i32,
-  ) -> Result<ApubCommunity, LemmyError> {
-    match &self.attributed_to {
-      AttributedTo::Lemmy(_) => {
-        let mut iter = self.to.iter().merge(self.cc.iter());
-        loop {
-          if let Some(cid) = iter.next() {
-            let cid = ObjectId::new(cid.clone());
-            if let Ok(c) = cid
-              .dereference(context, local_instance(context).await, request_counter)
-              .await
-            {
-              break Ok(c);
-            }
-          } else {
-            return Err(LemmyError::from_message("No community found in cc"));
-          }
-        }
-      }
-      AttributedTo::Peertube(p) => {
-        p.iter()
-          .find(|a| a.kind == PersonOrGroupType::Group)
-          .map(|a| ObjectId::<ApubCommunity>::new(a.id.clone().into_inner()))
-          .ok_or_else(|| LemmyError::from_message("page does not specify group"))?
-          .dereference(context, local_instance(context).await, request_counter)
-          .await
-      }
-    }
-  }
-
   pub(crate) fn creator(&self) -> Result<ObjectId<ApubPerson>, LemmyError> {
     match &self.attributed_to {
       AttributedTo::Lemmy(l) => Ok(l.clone()),
@@ -250,3 +219,46 @@ impl ActivityHandler for Page {
     Ok(())
   }
 }
+
+#[async_trait::async_trait(?Send)]
+impl InCommunity for Page {
+  async fn community(
+    &self,
+    context: &LemmyContext,
+    request_counter: &mut i32,
+  ) -> Result<ApubCommunity, LemmyError> {
+    let instance = local_instance(context).await;
+    let community = match &self.attributed_to {
+      AttributedTo::Lemmy(_) => {
+        let mut iter = self.to.iter().merge(self.cc.iter());
+        loop {
+          if let Some(cid) = iter.next() {
+            let cid = ObjectId::new(cid.clone());
+            if let Ok(c) = cid.dereference(context, instance, request_counter).await {
+              break c;
+            }
+          } else {
+            return Err(LemmyError::from_message("No community found in cc"));
+          }
+        }
+      }
+      AttributedTo::Peertube(p) => {
+        p.iter()
+          .find(|a| a.kind == PersonOrGroupType::Group)
+          .map(|a| ObjectId::<ApubCommunity>::new(a.id.clone().into_inner()))
+          .ok_or_else(|| LemmyError::from_message("page does not specify group"))?
+          .dereference(context, instance, request_counter)
+          .await?
+      }
+    };
+    if let Some(audience) = &self.audience {
+      let audience = audience
+        .dereference(context, instance, request_counter)
+        .await?;
+      verify_community_matches(&audience, community.id)?;
+      Ok(audience)
+    } else {
+      Ok(community)
+    }
+  }
+}