From: Felix Ableitner Date: Mon, 1 Nov 2021 13:05:20 +0000 (+0100) Subject: Add tests for parsing activities and collections X-Git-Url: http://these/git/%7B%60%24%7BwebArchiveUrl%7D/%22%7B%7D/%22https:/hacktivis.me/readmes/README.zh.hant.md?a=commitdiff_plain;h=0bde2d595e793c0b6eb31b592036f0111321cebd;p=lemmy.git Add tests for parsing activities and collections --- diff --git a/crates/apub/assets/lemmy/activities/community/add_mod.json b/crates/apub/assets/lemmy/activities/community/add_mod.json new file mode 100644 index 00000000..d0eedd8b --- /dev/null +++ b/crates/apub/assets/lemmy/activities/community/add_mod.json @@ -0,0 +1,13 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/u/lemmy_alpha", + "target": "http://enterprise.lemmy.ml/c/main/moderators", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Add", + "id": "http://enterprise.lemmy.ml/activities/add/ec069147-77c3-447f-88c8-0ef1df10403f" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/community/announce_create_page.json b/crates/apub/assets/lemmy/activities/community/announce_create_page.json new file mode 100644 index 00000000..6b58cf1c --- /dev/null +++ b/crates/apub/assets/lemmy/activities/community/announce_create_page.json @@ -0,0 +1,37 @@ +{ + "actor": "http://enterprise.lemmy.ml/c/main", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "http://enterprise.lemmy.ml/post/7", + "attributedTo": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "http://enterprise.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "post 4", + "mediaType": "text/html", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-11-01T12:11:22.871846+00:00" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Create", + "id": "http://enterprise.lemmy.ml/activities/create/2807c9ec-3ad8-4859-a9e0-28b59b6e499f" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main/followers" + ], + "type": "Announce", + "id": "http://enterprise.lemmy.ml/activities/announce/8030b171-803a-4108-94b1-342688f375cf" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/community/block_user.json b/crates/apub/assets/lemmy/activities/community/block_user.json new file mode 100644 index 00000000..9ca00816 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/community/block_user.json @@ -0,0 +1,13 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/u/lemmy_alpha", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "target": "http://enterprise.lemmy.ml/c/main", + "type": "Block", + "id": "http://enterprise.lemmy.ml/activities/block/5d42fffb-0903-4625-86d4-0b39bb344fc2" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/community/remove_mod.json b/crates/apub/assets/lemmy/activities/community/remove_mod.json new file mode 100644 index 00000000..2932fec3 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/community/remove_mod.json @@ -0,0 +1,13 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/u/lemmy_alpha", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Remove", + "target": "http://enterprise.lemmy.ml/c/main/moderators", + "id": "http://enterprise.lemmy.ml/activities/remove/aab114f8-cfbd-4935-a5b7-e1a64603650d" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/community/report_page.json b/crates/apub/assets/lemmy/activities/community/report_page.json new file mode 100644 index 00000000..bd1691b5 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/community/report_page.json @@ -0,0 +1,10 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "http://enterprise.lemmy.ml/c/main" + ], + "object": "http://enterprise.lemmy.ml/post/7", + "summary": "report this post", + "type": "Flag", + "id": "http://ds9.lemmy.ml/activities/flag/98b0933f-5e45-4a95-a15f-e0dc86361ba4" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/community/undo_block_user.json b/crates/apub/assets/lemmy/activities/community/undo_block_user.json new file mode 100644 index 00000000..5810b4f4 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/community/undo_block_user.json @@ -0,0 +1,24 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/u/lemmy_alpha", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "target": "http://enterprise.lemmy.ml/c/main", + "type": "Block", + "id": "http://enterprise.lemmy.ml/activities/block/726f43ab-bd0e-4ab3-89c8-627e976f553c" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Undo", + "id": "http://enterprise.lemmy.ml/activities/undo/06a20ffb-3e32-42fb-8f4c-674b36d7c557" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/community/update_community.json b/crates/apub/assets/lemmy/activities/community/update_community.json new file mode 100644 index 00000000..275d6d2b --- /dev/null +++ b/crates/apub/assets/lemmy/activities/community/update_community.json @@ -0,0 +1,37 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Group", + "id": "http://enterprise.lemmy.ml/c/main", + "preferredUsername": "main", + "name": "The Updated Community", + "summary": "

updated 2

\n", + "source": { + "content": "updated 2", + "mediaType": "text/markdown" + }, + "sensitive": false, + "moderators": "http://enterprise.lemmy.ml/c/main/moderators", + "inbox": "http://enterprise.lemmy.ml/c/main/inbox", + "outbox": "http://enterprise.lemmy.ml/c/main/outbox", + "followers": "http://enterprise.lemmy.ml/c/main/followers", + "endpoints": { + "sharedInbox": "http://enterprise.lemmy.ml/inbox" + }, + "publicKey": { + "id": "http://enterprise.lemmy.ml/c/main#main-key", + "owner": "http://enterprise.lemmy.ml/c/main", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA16Xh06V1l2yy0WAIMUTV\nnvZIuAuKDxzDQUNT+n8gmcVuvBu7tkpbPTQ3DjGB3bQfGC2ekew/yldwOXyZ7ry1\npbJSYSrCBJrAlPLs/ao3OPTqmcl3vnSWti/hqopEV+Um2t7fwpkCjVrnzVKRSlys\nihnrth64ZiwAqq2llpaXzWc1SR2URZYSdnry/4d9UNrZVkumIeg1gk9KbCAo4j/O\njsv/aBjpZcTeLmtMZf6fcrvGre9duJdx6e2Tg/YNcnSnARosqev/UwVTzzGNVWXg\n9rItaa0a0aea4se4Bn6QXvOBbcq3+OYZMR6a34hh5BTeNG8WbpwmVahS0WFUsv9G\nswIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "published": "2021-10-29T15:05:51.476984+00:00", + "updated": "2021-11-01T12:23:50.151874+00:00" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Update", + "id": "http://ds9.lemmy.ml/activities/update/d3717cf5-096d-473f-9530-5d52f9d51f5f" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/create_or_update/create_note.json b/crates/apub/assets/lemmy/activities/create_or_update/create_note.json new file mode 100644 index 00000000..4360ce92 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/create_or_update/create_note.json @@ -0,0 +1,29 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Note", + "id": "http://ds9.lemmy.ml/comment/1", + "attributedTo": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "content": "hello", + "mediaType": "text/html", + "source": { + "content": "hello", + "mediaType": "text/markdown" + }, + "inReplyTo": "http://ds9.lemmy.ml/post/1", + "published": "2021-11-01T11:45:49.794920+00:00" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main", + "http://ds9.lemmy.ml/u/lemmy_alpha" + ], + "tag": [], + "type": "Create", + "id": "http://ds9.lemmy.ml/activities/create/1e77d67c-44ac-45ed-bf2a-460e21f60236" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/create_or_update/create_page.json b/crates/apub/assets/lemmy/activities/create_or_update/create_page.json new file mode 100644 index 00000000..b223120b --- /dev/null +++ b/crates/apub/assets/lemmy/activities/create_or_update/create_page.json @@ -0,0 +1,32 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "http://ds9.lemmy.ml/post/1", + "attributedTo": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "http://enterprise.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "test post", + "content": "

test body

\n", + "mediaType": "text/html", + "source": { + "content": "test body", + "mediaType": "text/markdown" + }, + "url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-10-29T15:10:51.557399+00:00" + }, + "cc": [ + "http://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 diff --git a/crates/apub/assets/lemmy/activities/create_or_update/update_page.json b/crates/apub/assets/lemmy/activities/create_or_update/update_page.json new file mode 100644 index 00000000..beadfa0d --- /dev/null +++ b/crates/apub/assets/lemmy/activities/create_or_update/update_page.json @@ -0,0 +1,33 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "http://ds9.lemmy.ml/post/1", + "attributedTo": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "http://enterprise.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "test post 1", + "content": "

test body

\n", + "mediaType": "text/html", + "source": { + "content": "test body", + "mediaType": "text/markdown" + }, + "url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-10-29T15:10:51.557399+00:00", + "updated": "2021-10-29T15:11:35.976374+00:00" + }, + "cc": [ + "http://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 diff --git a/crates/apub/assets/lemmy/activities/deletion/delete_page.json b/crates/apub/assets/lemmy/activities/deletion/delete_page.json new file mode 100644 index 00000000..8dd26a10 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/deletion/delete_page.json @@ -0,0 +1,12 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/post/1", + "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 diff --git a/crates/apub/assets/lemmy/activities/deletion/remove_note.json b/crates/apub/assets/lemmy/activities/deletion/remove_note.json new file mode 100644 index 00000000..8ea35404 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/deletion/remove_note.json @@ -0,0 +1,13 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/comment/1", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Delete", + "summary": "bad comment", + "id": "http://enterprise.lemmy.ml/activities/delete/42ca1a79-f99e-4518-a2ca-ba2df221eb5e" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/deletion/undo_delete_page.json b/crates/apub/assets/lemmy/activities/deletion/undo_delete_page.json new file mode 100644 index 00000000..9f824fa1 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/deletion/undo_delete_page.json @@ -0,0 +1,23 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/post/1", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Delete", + "id": "http://ds9.lemmy.ml/activities/delete/b13cca96-7737-41e1-9769-8fbf972b3509" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Undo", + "id": "http://ds9.lemmy.ml/activities/undo/5e939cfb-b8a1-4de8-950f-9d684e9162b9" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/deletion/undo_remove_note.json b/crates/apub/assets/lemmy/activities/deletion/undo_remove_note.json new file mode 100644 index 00000000..413cf16b --- /dev/null +++ b/crates/apub/assets/lemmy/activities/deletion/undo_remove_note.json @@ -0,0 +1,24 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/comment/1", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Delete", + "summary": "bad comment", + "id": "http://enterprise.lemmy.ml/activities/delete/2598435c-87a3-49cd-81f3-a44b03b7af9d" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Undo", + "id": "http://enterprise.lemmy.ml/activities/undo/a850cf21-3866-4b3a-b80b-56aa00997fee" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/following/accept.json b/crates/apub/assets/lemmy/activities/following/accept.json new file mode 100644 index 00000000..d5bcfaf4 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/following/accept.json @@ -0,0 +1,17 @@ +{ + "actor": "http://enterprise.lemmy.ml/c/main", + "to": [ + "http://ds9.lemmy.ml/u/lemmy_alpha" + ], + "object": { + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "http://enterprise.lemmy.ml/c/main" + ], + "object": "http://enterprise.lemmy.ml/c/main", + "type": "Follow", + "id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866" + }, + "type": "Accept", + "id": "http://enterprise.lemmy.ml/activities/accept/75f080cc-3d45-4654-8186-8f3bb853fa27" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/following/follow.json b/crates/apub/assets/lemmy/activities/following/follow.json new file mode 100644 index 00000000..50cc77dc --- /dev/null +++ b/crates/apub/assets/lemmy/activities/following/follow.json @@ -0,0 +1,9 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "http://enterprise.lemmy.ml/c/main" + ], + "object": "http://enterprise.lemmy.ml/c/main", + "type": "Follow", + "id": "http://ds9.lemmy.ml/activities/follow/6abcd50b-b8ca-4952-86b0-a6dd8cc12866" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/following/undo_follow.json b/crates/apub/assets/lemmy/activities/following/undo_follow.json new file mode 100644 index 00000000..d27bec0a --- /dev/null +++ b/crates/apub/assets/lemmy/activities/following/undo_follow.json @@ -0,0 +1,17 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "http://enterprise.lemmy.ml/c/main" + ], + "object": { + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "http://enterprise.lemmy.ml/c/main" + ], + "object": "http://enterprise.lemmy.ml/c/main", + "type": "Follow", + "id": "http://ds9.lemmy.ml/activities/follow/dc2f1bc5-f3a0-4daa-a46b-428cbfbd023c" + }, + "type": "Undo", + "id": "http://ds9.lemmy.ml/activities/undo/dd83c482-8ebd-4b6c-9008-c8373bd1a86a" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/private_message/create.json b/crates/apub/assets/lemmy/activities/private_message/create.json new file mode 100644 index 00000000..de080a8f --- /dev/null +++ b/crates/apub/assets/lemmy/activities/private_message/create.json @@ -0,0 +1,23 @@ +{ + "id": "http://enterprise.lemmy.ml/activities/create/987d05fa-f637-46d7-85be-13d112bc269f", + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "http://ds9.lemmy.ml/u/lemmy_alpha" + ], + "object": { + "type": "ChatMessage", + "id": "http://enterprise.lemmy.ml/private_message/1", + "attributedTo": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "http://ds9.lemmy.ml/u/lemmy_alpha" + ], + "content": "hello", + "mediaType": "text/html", + "source": { + "content": "hello", + "mediaType": "text/markdown" + }, + "published": "2021-10-29T15:31:56.058289+00:00" + }, + "type": "Create" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/private_message/delete.json b/crates/apub/assets/lemmy/activities/private_message/delete.json new file mode 100644 index 00000000..f5f85ac3 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/private_message/delete.json @@ -0,0 +1,9 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "http://enterprise.lemmy.ml/u/lemmy_beta" + ], + "object": "http://enterprise.lemmy.ml/private_message/1", + "type": "Delete", + "id": "http://enterprise.lemmy.ml/activities/delete/041d9858-5eef-4ad9-84ae-7455b4d87ed9" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/private_message/undo_delete.json b/crates/apub/assets/lemmy/activities/private_message/undo_delete.json new file mode 100644 index 00000000..d9b4ed75 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/private_message/undo_delete.json @@ -0,0 +1,17 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "http://ds9.lemmy.ml/u/lemmy_alpha" + ], + "object": { + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "http://enterprise.lemmy.ml/u/lemmy_beta" + ], + "object": "http://enterprise.lemmy.ml/private_message/1", + "type": "Delete", + "id": "http://enterprise.lemmy.ml/activities/delete/616c41be-04ed-4bd4-b865-30712186b122" + }, + "type": "Undo", + "id": "http://enterprise.lemmy.ml/activities/undo/35e5b337-014c-4bbe-8d63-6fac96f51409" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/voting/dislike_page.json b/crates/apub/assets/lemmy/activities/voting/dislike_page.json new file mode 100644 index 00000000..822a9d35 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/voting/dislike_page.json @@ -0,0 +1,12 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/post/1", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Dislike", + "id": "http://enterprise.lemmy.ml/activities/dislike/64d40d40-a829-43a5-8247-1fb595b3ca1c" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/voting/like_note.json b/crates/apub/assets/lemmy/activities/voting/like_note.json new file mode 100644 index 00000000..35e96906 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/voting/like_note.json @@ -0,0 +1,12 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/comment/1", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Like", + "id": "http://ds9.lemmy.ml/activities/like/fd61d070-7382-46a9-b2b7-6bb253732877" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/voting/undo_dislike_page.json b/crates/apub/assets/lemmy/activities/voting/undo_dislike_page.json new file mode 100644 index 00000000..4123ebab --- /dev/null +++ b/crates/apub/assets/lemmy/activities/voting/undo_dislike_page.json @@ -0,0 +1,23 @@ +{ + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "actor": "http://enterprise.lemmy.ml/u/lemmy_beta", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/post/1", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Like", + "id": "http://enterprise.lemmy.ml/activities/like/2227ab2c-79e2-4fca-a1d2-1d67dacf2457" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Undo", + "id": "http://enterprise.lemmy.ml/activities/undo/6cc6fb71-39fe-49ea-9506-f0423b101e98" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/activities/voting/undo_like_note.json b/crates/apub/assets/lemmy/activities/voting/undo_like_note.json new file mode 100644 index 00000000..84a6efe5 --- /dev/null +++ b/crates/apub/assets/lemmy/activities/voting/undo_like_note.json @@ -0,0 +1,23 @@ +{ + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "actor": "http://ds9.lemmy.ml/u/lemmy_alpha", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "http://ds9.lemmy.ml/comment/1", + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Like", + "id": "http://ds9.lemmy.ml/activities/like/efcf7ae2-dfcc-4ff4-9ce4-6adf251ff004" + }, + "cc": [ + "http://enterprise.lemmy.ml/c/main" + ], + "type": "Undo", + "id": "http://ds9.lemmy.ml/activities/undo/3518565c-24a7-4d9e-8e0a-f7a2f45ac618" +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/collections/group_followers.json b/crates/apub/assets/lemmy/collections/group_followers.json new file mode 100644 index 00000000..a2b03ab1 --- /dev/null +++ b/crates/apub/assets/lemmy/collections/group_followers.json @@ -0,0 +1,6 @@ +{ + "id": "http://enterprise.lemmy.ml/c/main/followers", + "type": "Collection", + "totalItems": 3, + "items": [] +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/collections/group_moderators.json b/crates/apub/assets/lemmy/collections/group_moderators.json new file mode 100644 index 00000000..eccd0dad --- /dev/null +++ b/crates/apub/assets/lemmy/collections/group_moderators.json @@ -0,0 +1,7 @@ +{ + "type": "OrderedCollection", + "id": "https://enterprise.lemmy.ml/c/tenforward/moderators", + "orderedItems": [ + "https://enterprise.lemmy.ml/u/picard" + ] +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/collections/group_outbox.json b/crates/apub/assets/lemmy/collections/group_outbox.json new file mode 100644 index 00000000..cf68742f --- /dev/null +++ b/crates/apub/assets/lemmy/collections/group_outbox.json @@ -0,0 +1,209 @@ +{ + "type": "OrderedCollection", + "id": "https://ds9.lemmy.ml/c/main/outbox", + "totalItems": 7, + "orderedItems": [ + { + "actor": "https://ds9.lemmy.ml/u/dess_ds9", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "https://ds9.lemmy.ml/post/1685", + "attributedTo": "https://ds9.lemmy.ml/u/dess_ds9", + "to": [ + "https://ds9.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "Test post", + "mediaType": "text/html", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-09-30T16:37:58.425718+00:00", + "updated": "2021-09-30T16:39:50.934055+00:00" + }, + "cc": [ + "https://ds9.lemmy.ml/c/main" + ], + "type": "Create", + "id": "https://ds9.lemmy.ml/activities/create/157bc329-05cb-4dc3-ad9e-5110fde3f3aa" + }, + { + "actor": "https://ds9.lemmy.ml/u/nutomic", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "https://ds9.lemmy.ml/post/1665", + "attributedTo": "https://ds9.lemmy.ml/u/nutomic", + "to": [ + "https://ds9.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "another webmention test", + "mediaType": "text/html", + "url": "https://webmention.rocks/test/1", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-09-17T13:22:15.026912+00:00" + }, + "cc": [ + "https://ds9.lemmy.ml/c/main" + ], + "type": "Create", + "id": "https://ds9.lemmy.ml/activities/create/c54e4509-16ac-42bf-b3b4-0bf8516f8152" + }, + { + "actor": "https://ds9.lemmy.ml/u/nutomic", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "https://ds9.lemmy.ml/post/1664", + "attributedTo": "https://ds9.lemmy.ml/u/nutomic", + "to": [ + "https://ds9.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "another test", + "mediaType": "text/html", + "url": "https://webmention.rocks/test/1", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-09-17T13:13:21.675891+00:00" + }, + "cc": [ + "https://ds9.lemmy.ml/c/main" + ], + "type": "Create", + "id": "https://ds9.lemmy.ml/activities/create/25f7d2cb-11d5-4c9c-aa3c-85fbff9f9e0c" + }, + { + "actor": "https://ds9.lemmy.ml/u/nutomic", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "https://ds9.lemmy.ml/post/1663", + "attributedTo": "https://ds9.lemmy.ml/u/nutomic", + "to": [ + "https://ds9.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "Webmention test from Lemmy", + "mediaType": "text/html", + "url": "https://webmention.rocks/test/1", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-09-17T13:00:15.392844+00:00" + }, + "cc": [ + "https://ds9.lemmy.ml/c/main" + ], + "type": "Create", + "id": "https://ds9.lemmy.ml/activities/create/cfbd12b8-2e11-42b6-a609-b482decbaf11" + }, + { + "actor": "https://ds9.lemmy.ml/u/dess_tester_3", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "https://ds9.lemmy.ml/post/1644", + "attributedTo": "https://ds9.lemmy.ml/u/dess_tester_3", + "to": [ + "https://ds9.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "The best wireless earbuds you can buy right now | Engadget", + "mediaType": "text/html", + "url": "https://www.engadget.com/best-wireless-earbuds-120058222.html", + "image": { + "type": "Image", + "url": "https://ds9.lemmy.ml/pictrs/image/0WWsYOuwAE.jpg" + }, + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-08-26T01:22:06.428368+00:00" + }, + "cc": [ + "https://ds9.lemmy.ml/c/main" + ], + "type": "Create", + "id": "https://ds9.lemmy.ml/activities/create/76c94408-944a-4a2f-a88b-d10f12b472b0" + }, + { + "actor": "https://ds9.lemmy.ml/u/dess_ds9", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "https://ds9.lemmy.ml/post/1643", + "attributedTo": "https://ds9.lemmy.ml/u/dess_ds9", + "to": [ + "https://ds9.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "First Look: Cadillac’s luxury EV debut seems like a winner | Engadges", + "content": "

test

\n", + "mediaType": "text/html", + "source": { + "content": "test", + "mediaType": "text/markdown" + }, + "url": "https://www.engadget.com/cadillac-lyriq-luxury-ev-first-look-video-171543752.html", + "image": { + "type": "Image", + "url": "https://ds9.lemmy.ml/pictrs/image/gnmtvgXP31.jpg" + }, + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-08-23T23:43:06.560543+00:00", + "updated": "2021-08-23T23:52:51.832606+00:00" + }, + "cc": [ + "https://ds9.lemmy.ml/c/main" + ], + "type": "Create", + "id": "https://ds9.lemmy.ml/activities/create/b1f95918-f593-4951-91cf-2c3340cd9509" + }, + { + "actor": "https://ds9.lemmy.ml/u/dess_ds9_2", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": { + "type": "Page", + "id": "https://ds9.lemmy.ml/post/1642", + "attributedTo": "https://ds9.lemmy.ml/u/dess_ds9_2", + "to": [ + "https://ds9.lemmy.ml/c/main", + "https://www.w3.org/ns/activitystreams#Public" + ], + "name": "A test post from DS9", + "mediaType": "text/html", + "commentsEnabled": true, + "sensitive": false, + "stickied": false, + "published": "2021-08-06T14:10:47.493075+00:00" + }, + "cc": [ + "https://ds9.lemmy.ml/c/main" + ], + "type": "Create", + "id": "https://ds9.lemmy.ml/activities/create/6359b2e7-badb-4241-b5ee-b093078361bd" + } + ] +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/collections/person_outbox.json b/crates/apub/assets/lemmy/collections/person_outbox.json new file mode 100644 index 00000000..8da56102 --- /dev/null +++ b/crates/apub/assets/lemmy/collections/person_outbox.json @@ -0,0 +1,6 @@ +{ + "type": "OrderedCollection", + "id": "http://ds9.lemmy.ml/u/lemmy_alpha/outbox", + "orderedItems": [], + "totalItems": 0 +} \ No newline at end of file diff --git a/crates/apub/assets/lemmy/objects/page.json b/crates/apub/assets/lemmy/objects/page.json index 2c39acce..36cac596 100644 --- a/crates/apub/assets/lemmy/objects/page.json +++ b/crates/apub/assets/lemmy/objects/page.json @@ -13,6 +13,11 @@ "content": "This is a post in the /c/tenforward community", "mediaType": "text/markdown" }, + "url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png", + "image": { + "type": "Image", + "url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png" + }, "sensitive": false, "commentsEnabled": true, "stickied": true, diff --git a/crates/apub/assets/lemmy/objects/person.json b/crates/apub/assets/lemmy/objects/person.json index 769f2f3e..e21fa4d2 100644 --- a/crates/apub/assets/lemmy/objects/person.json +++ b/crates/apub/assets/lemmy/objects/person.json @@ -16,6 +16,7 @@ "type": "Image", "url": "https://enterprise.lemmy.ml/pictrs/image/XenaYI5hTn.png" }, + "matrix_user_id": "@picard:matrix.org", "inbox": "https://enterprise.lemmy.ml/u/picard/inbox", "outbox": "https://enterprise.lemmy.ml/u/picard/outbox", "endpoints": { diff --git a/crates/apub/assets/pleroma/activities/create-note.json b/crates/apub/assets/pleroma/activities/create_note.json similarity index 100% rename from crates/apub/assets/pleroma/activities/create-note.json rename to crates/apub/assets/pleroma/activities/create_note.json diff --git a/crates/apub/src/activities/comment/create_or_update.rs b/crates/apub/src/activities/comment/create_or_update.rs index 79259180..a9c1a9ee 100644 --- a/crates/apub/src/activities/comment/create_or_update.rs +++ b/crates/apub/src/activities/comment/create_or_update.rs @@ -128,16 +128,3 @@ impl GetCommunity for CreateOrUpdateComment { Ok(community.into()) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::objects::tests::file_to_json_object; - use serial_test::serial; - - #[actix_rt::test] - #[serial] - async fn test_parse_pleroma_create_comment() { - file_to_json_object::("assets/pleroma/activities/create-note.json"); - } -} diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs index 9fd1a9dc..1197af85 100644 --- a/crates/apub/src/activity_lists.rs +++ b/crates/apub/src/activity_lists.rs @@ -1,12 +1,3 @@ -use serde::{Deserialize, Serialize}; - -use lemmy_apub_lib::{ - traits::{ActivityFields, ActivityHandler, ActorType}, - verify::verify_urls_match, -}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - use crate::{ activities::community::announce::GetCommunity, objects::community::ApubCommunity, @@ -35,6 +26,10 @@ use crate::{ voting::{undo_vote::UndoVote, vote::Vote}, }, }; +use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler}; +use lemmy_utils::LemmyError; +use lemmy_websocket::LemmyContext; +use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)] #[serde(untagged)] @@ -107,7 +102,6 @@ impl GetCommunity for AnnouncableActivities { AddMod(a) => a.get_community(context, request_counter).await?, RemoveMod(a) => a.get_community(context, request_counter).await?, }; - verify_urls_match(self.actor(), &community.actor_id())?; Ok(community) } } diff --git a/crates/apub/src/collections/community_moderators.rs b/crates/apub/src/collections/community_moderators.rs index 1a5a96d3..d97affe2 100644 --- a/crates/apub/src/collections/community_moderators.rs +++ b/crates/apub/src/collections/community_moderators.rs @@ -120,3 +120,74 @@ impl ApubObject for ApubCommunityModerators { Ok(ApubCommunityModerators { 0: vec![] }) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::objects::{ + community::tests::parse_lemmy_community, + person::tests::parse_lemmy_person, + tests::{file_to_json_object, init_context}, + }; + use lemmy_db_schema::{ + source::{ + community::Community, + person::{Person, PersonForm}, + }, + traits::Crud, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_community_moderators() { + let context = init_context(); + let community = parse_lemmy_community(&context).await; + let community_id = community.id; + + let old_mod = PersonForm { + name: "holly".into(), + ..PersonForm::default() + }; + let old_mod = Person::create(&context.pool().get().unwrap(), &old_mod).unwrap(); + let community_moderator_form = CommunityModeratorForm { + community_id: community.id, + person_id: old_mod.id, + }; + + CommunityModerator::join(&context.pool().get().unwrap(), &community_moderator_form).unwrap(); + + let new_mod = parse_lemmy_person(&context).await; + + let json: GroupModerators = + file_to_json_object("assets/lemmy/collections/group_moderators.json"); + let url = Url::parse("https://enterprise.lemmy.ml/c/tenforward").unwrap(); + let mut request_counter = 0; + let community_context = CommunityContext { + 0: community, + 1: context, + }; + ApubCommunityModerators::from_apub(&json, &community_context, &url, &mut request_counter) + .await + .unwrap(); + assert_eq!(request_counter, 0); + + let current_moderators = blocking(community_context.1.pool(), move |conn| { + CommunityModeratorView::for_community(conn, community_id) + }) + .await + .unwrap() + .unwrap(); + + assert_eq!(current_moderators.len(), 1); + assert_eq!(current_moderators[0].moderator.id, new_mod.id); + + Person::delete(&*community_context.1.pool().get().unwrap(), old_mod.id).unwrap(); + Person::delete(&*community_context.1.pool().get().unwrap(), new_mod.id).unwrap(); + Community::delete( + &*community_context.1.pool().get().unwrap(), + community_context.0.id, + ) + .unwrap(); + } +} diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index 77a23828..51699eb0 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -18,13 +18,8 @@ use lemmy_websocket::LemmyContext; use crate::{ fetcher::object_id::ObjectId, - objects::{ - comment::ApubComment, - community::ApubCommunity, - person::{ApubPerson, Person}, - post::ApubPost, - }, - protocol::objects::{group::Group, note::Note, page::Page}, + objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost}, + protocol::objects::{group::Group, note::Note, page::Page, person::Person}, }; /// Attempt to parse the query as URL, and fetch an ActivityPub object from it. diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index ffc76d3f..4110d2b2 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -18,15 +18,12 @@ use crate::{ objects::community::ApubCommunity, protocol::{ activities::community::announce::AnnounceActivity, - collections::group_followers::CommunityFollowers, + collections::group_followers::GroupFollowers, }, }; use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; -use lemmy_apub_lib::{ - traits::{ActivityFields, ActorType, ApubObject}, - verify::verify_domains_match, -}; +use lemmy_apub_lib::traits::{ActivityFields, ApubObject}; use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -84,7 +81,6 @@ pub(in crate::http) async fn receive_group_inbox( if let GroupInboxActivities::AnnouncableActivities(announcable) = activity { let community = announcable.get_community(context, &mut 0).await?; let actor_id = ObjectId::new(announcable.actor().clone()); - verify_domains_match(&community.actor_id(), announcable.id_unchecked())?; verify_person_in_community(&actor_id, &community, context, &mut 0).await?; if community.local { AnnounceActivity::send(announcable, &community, vec![], context).await?; @@ -103,7 +99,7 @@ pub(crate) async fn get_apub_community_followers( Community::read_from_name(conn, &info.community_name) }) .await??; - let followers = CommunityFollowers::new(community, &context).await?; + let followers = GroupFollowers::new(community, &context).await?; Ok(create_apub_response(&followers)) } diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 3f18bcc5..a5ea4ad1 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -8,7 +8,7 @@ use crate::{ receive_activity, }, objects::person::ApubPerson, - protocol::collections::person_outbox::UserOutbox, + protocol::collections::person_outbox::PersonOutbox, }; use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; @@ -74,6 +74,6 @@ pub(crate) async fn get_apub_person_outbox( Person::find_by_name(conn, &info.user_name) }) .await??; - let outbox = UserOutbox::new(person).await?; + let outbox = PersonOutbox::new(person).await?; Ok(create_apub_response(&outbox)) } diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index 736d1453..b5f72ca3 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -188,26 +188,20 @@ impl ApubObject for ApubComment { pub(crate) mod tests { use super::*; use crate::objects::{ - community::ApubCommunity, - person::ApubPerson, + community::{tests::parse_lemmy_community, ApubCommunity}, + person::{tests::parse_lemmy_person, ApubPerson}, post::ApubPost, tests::{file_to_json_object, init_context}, }; use assert_json_diff::assert_json_include; use serial_test::serial; - pub(crate) async fn prepare_comment_test( + async fn prepare_comment_test( url: &Url, context: &LemmyContext, ) -> (ApubPerson, ApubCommunity, ApubPost) { - let person_json = file_to_json_object("assets/lemmy/objects/person.json"); - let person = ApubPerson::from_apub(&person_json, context, url, &mut 0) - .await - .unwrap(); - let community_json = file_to_json_object("assets/lemmy/objects/group.json"); - let community = ApubCommunity::from_apub(&community_json, context, url, &mut 0) - .await - .unwrap(); + let person = parse_lemmy_person(context).await; + let community = parse_lemmy_community(context).await; let post_json = file_to_json_object("assets/lemmy/objects/page.json"); let post = ApubPost::from_apub(&post_json, context, url, &mut 0) .await diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index e1a37e8b..89258fe0 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -222,42 +222,39 @@ impl ApubCommunity { } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; use crate::objects::tests::{file_to_json_object, init_context}; - use assert_json_diff::assert_json_include; use lemmy_db_schema::traits::Crud; use serial_test::serial; - #[actix_rt::test] - #[serial] - async fn test_parse_lemmy_community() { - let context = init_context(); + pub(crate) async fn parse_lemmy_community(context: &LemmyContext) -> ApubCommunity { let mut json: Group = file_to_json_object("assets/lemmy/objects/group.json"); - let json_orig = json.clone(); // change these links so they dont fetch over the network - json.moderators = Some(ObjectId::new( - Url::parse("https://enterprise.lemmy.ml/c/tenforward/not_moderators").unwrap(), - )); + json.moderators = None; json.outbox = ObjectId::new(Url::parse("https://enterprise.lemmy.ml/c/tenforward/not_outbox").unwrap()); let url = Url::parse("https://enterprise.lemmy.ml/c/tenforward").unwrap(); let mut request_counter = 0; - let community = ApubCommunity::from_apub(&json, &context, &url, &mut request_counter) + let community = ApubCommunity::from_apub(&json, context, &url, &mut request_counter) .await .unwrap(); + // this makes two requests to the (intentionally) broken outbox/moderators collections + assert_eq!(request_counter, 1); + community + } + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_community() { + let context = init_context(); + let community = parse_lemmy_community(&context).await; - assert_eq!(community.actor_id.clone().into_inner(), url); assert_eq!(community.title, "Ten Forward"); assert!(community.public_key.is_some()); assert!(!community.local); assert_eq!(community.description.as_ref().unwrap().len(), 132); - // this makes two requests to the (intentionally) broken outbox/moderators collections - assert_eq!(request_counter, 2); - - let to_apub = community.to_apub(&context).await.unwrap(); - assert_json_include!(actual: json_orig, expected: to_apub); Community::delete(&*context.pool().get().unwrap(), community.id).unwrap(); } diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 9e487ed3..18522e56 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -2,13 +2,16 @@ use crate::{ check_is_apub_id_valid, generate_outbox_url, objects::get_summary_from_string_or_source, - protocol::{ImageObject, Source}, + protocol::{ + objects::person::{Person, UserTypes}, + ImageObject, + Source, + }, }; -use activitystreams::{actor::Endpoints, object::kind::ImageType, unparsed::Unparsed}; -use chrono::{DateTime, FixedOffset, NaiveDateTime}; +use activitystreams::{actor::Endpoints, object::kind::ImageType}; +use chrono::NaiveDateTime; use lemmy_api_common::blocking; use lemmy_apub_lib::{ - signatures::PublicKey, traits::{ActorType, ApubObject}, values::MediaTypeMarkdown, verify::verify_domains_match, @@ -22,54 +25,9 @@ use lemmy_utils::{ LemmyError, }; use lemmy_websocket::LemmyContext; -use serde::{Deserialize, Serialize}; -use serde_with::skip_serializing_none; use std::ops::Deref; use url::Url; -#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)] -pub enum UserTypes { - Person, - Service, -} - -#[skip_serializing_none] -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct Person { - #[serde(rename = "type")] - kind: UserTypes, - id: Url, - /// username, set at account creation and can never be changed - preferred_username: String, - /// displayname (can be changed at any time) - name: Option, - summary: Option, - source: Option, - /// user avatar - icon: Option, - /// user banner - image: Option, - matrix_user_id: Option, - inbox: Url, - /// mandatory field in activitypub, currently empty in lemmy - outbox: Url, - endpoints: Endpoints, - public_key: PublicKey, - published: Option>, - updated: Option>, - #[serde(flatten)] - unparsed: Unparsed, -} - -// TODO: can generate this with a derive macro -impl Person { - pub(crate) fn id(&self, expected_domain: &Url) -> Result<&Url, LemmyError> { - verify_domains_match(&self.id, expected_domain)?; - Ok(&self.id) - } -} - #[derive(Clone, Debug, PartialEq)] pub struct ApubPerson(DbPerson); @@ -170,7 +128,8 @@ impl ApubObject for ApubPerson { expected_domain: &Url, _request_counter: &mut i32, ) -> Result { - let actor_id = Some(person.id(expected_domain)?.clone().into()); + verify_domains_match(&person.id, expected_domain)?; + let actor_id = Some(person.id.clone().into()); let name = person.preferred_username.clone(); let display_name: Option = person.name.clone(); let bio = get_summary_from_string_or_source(&person.summary, &person.source); @@ -245,33 +204,33 @@ impl ActorType for ApubPerson { } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; use crate::objects::tests::{file_to_json_object, init_context}; - use assert_json_diff::assert_json_include; use lemmy_db_schema::traits::Crud; use serial_test::serial; - #[actix_rt::test] - #[serial] - async fn test_parse_lemmy_person() { - let context = init_context(); + pub(crate) async fn parse_lemmy_person(context: &LemmyContext) -> ApubPerson { let json = file_to_json_object("assets/lemmy/objects/person.json"); let url = Url::parse("https://enterprise.lemmy.ml/u/picard").unwrap(); let mut request_counter = 0; - let person = ApubPerson::from_apub(&json, &context, &url, &mut request_counter) + let person = ApubPerson::from_apub(&json, context, &url, &mut request_counter) .await .unwrap(); + assert_eq!(request_counter, 0); + person + } + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_person() { + let context = init_context(); + let person = parse_lemmy_person(&context).await; - assert_eq!(person.actor_id.clone().into_inner(), url); assert_eq!(person.display_name, Some("Jean-Luc Picard".to_string())); assert!(person.public_key.is_some()); assert!(!person.local); assert_eq!(person.bio.as_ref().unwrap().len(), 39); - assert_eq!(request_counter, 0); - - let to_apub = person.to_apub(&context).await.unwrap(); - assert_json_include!(actual: json, expected: to_apub); DbPerson::delete(&*context.pool().get().unwrap(), person.id).unwrap(); } diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index e5a83297..7f142be5 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -193,28 +193,22 @@ impl ApubObject for ApubPost { mod tests { use super::*; use crate::objects::{ - community::ApubCommunity, - person::ApubPerson, + community::tests::parse_lemmy_community, + person::tests::parse_lemmy_person, post::ApubPost, tests::{file_to_json_object, init_context}, }; - use assert_json_diff::assert_json_include; use serial_test::serial; #[actix_rt::test] #[serial] async fn test_parse_lemmy_post() { let context = init_context(); - let url = Url::parse("https://enterprise.lemmy.ml/post/55143").unwrap(); - let community_json = file_to_json_object("assets/lemmy/objects/group.json"); - let community = ApubCommunity::from_apub(&community_json, &context, &url, &mut 0) - .await - .unwrap(); - let person_json = file_to_json_object("assets/lemmy/objects/person.json"); - let person = ApubPerson::from_apub(&person_json, &context, &url, &mut 0) - .await - .unwrap(); + let community = parse_lemmy_community(&context).await; + let person = parse_lemmy_person(&context).await; + let json = file_to_json_object("assets/lemmy/objects/page.json"); + let url = Url::parse("https://enterprise.lemmy.ml/post/55143").unwrap(); let mut request_counter = 0; let post = ApubPost::from_apub(&json, &context, &url, &mut request_counter) .await @@ -228,9 +222,6 @@ mod tests { assert!(post.stickied); assert_eq!(request_counter, 0); - let to_apub = post.to_apub(&context).await.unwrap(); - assert_json_include!(actual: json, expected: to_apub); - Post::delete(&*context.pool().get().unwrap(), post.id).unwrap(); Person::delete(&*context.pool().get().unwrap(), person.id).unwrap(); Community::delete(&*context.pool().get().unwrap(), community.id).unwrap(); diff --git a/crates/apub/src/protocol/activities/community/mod.rs b/crates/apub/src/protocol/activities/community/mod.rs index 62f8329b..a7bc8141 100644 --- a/crates/apub/src/protocol/activities/community/mod.rs +++ b/crates/apub/src/protocol/activities/community/mod.rs @@ -5,3 +5,44 @@ pub mod remove_mod; pub mod report; pub mod undo_block_user; pub mod update; + +#[cfg(test)] +mod tests { + use crate::protocol::{ + activities::community::{ + add_mod::AddMod, + block_user::BlockUserFromCommunity, + remove_mod::RemoveMod, + report::Report, + undo_block_user::UndoBlockUserFromCommunity, + update::UpdateCommunity, + }, + tests::test_parse_lemmy_item, + }; + use activitystreams::activity::Announce; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_community() { + test_parse_lemmy_item::( + "assets/lemmy/activities/community/announce_create_page.json", + ); + + test_parse_lemmy_item::("assets/lemmy/activities/community/add_mod.json"); + test_parse_lemmy_item::("assets/lemmy/activities/community/remove_mod.json"); + + test_parse_lemmy_item::( + "assets/lemmy/activities/community/block_user.json", + ); + test_parse_lemmy_item::( + "assets/lemmy/activities/community/undo_block_user.json", + ); + + test_parse_lemmy_item::( + "assets/lemmy/activities/community/update_community.json", + ); + + test_parse_lemmy_item::("assets/lemmy/activities/community/report_page.json"); + } +} diff --git a/crates/apub/src/protocol/activities/create_or_update/mod.rs b/crates/apub/src/protocol/activities/create_or_update/mod.rs index 38203b5e..1048d46a 100644 --- a/crates/apub/src/protocol/activities/create_or_update/mod.rs +++ b/crates/apub/src/protocol/activities/create_or_update/mod.rs @@ -1,2 +1,34 @@ pub mod comment; pub mod post; + +#[cfg(test)] +mod tests { + use crate::{ + objects::tests::file_to_json_object, + protocol::{ + activities::create_or_update::{comment::CreateOrUpdateComment, post::CreateOrUpdatePost}, + tests::test_parse_lemmy_item, + }, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_create_or_update() { + test_parse_lemmy_item::( + "assets/lemmy/activities/create_or_update/create_page.json", + ); + test_parse_lemmy_item::( + "assets/lemmy/activities/create_or_update/update_page.json", + ); + test_parse_lemmy_item::( + "assets/lemmy/activities/create_or_update/create_note.json", + ); + } + + #[actix_rt::test] + #[serial] + async fn test_parse_pleroma_create_or_update() { + file_to_json_object::("assets/pleroma/activities/create_note.json"); + } +} diff --git a/crates/apub/src/protocol/activities/deletion/mod.rs b/crates/apub/src/protocol/activities/deletion/mod.rs index b440edd6..c77492a3 100644 --- a/crates/apub/src/protocol/activities/deletion/mod.rs +++ b/crates/apub/src/protocol/activities/deletion/mod.rs @@ -1,2 +1,21 @@ pub mod delete; pub mod undo_delete; + +#[cfg(test)] +mod tests { + use crate::protocol::{ + activities::deletion::{delete::Delete, undo_delete::UndoDelete}, + tests::test_parse_lemmy_item, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_voting() { + test_parse_lemmy_item::("assets/lemmy/activities/deletion/remove_note.json"); + test_parse_lemmy_item::("assets/lemmy/activities/deletion/delete_page.json"); + + test_parse_lemmy_item::("assets/lemmy/activities/deletion/undo_remove_note.json"); + test_parse_lemmy_item::("assets/lemmy/activities/deletion/undo_delete_page.json"); + } +} diff --git a/crates/apub/src/protocol/activities/following/mod.rs b/crates/apub/src/protocol/activities/following/mod.rs index 5dc6a3f8..473dfca3 100644 --- a/crates/apub/src/protocol/activities/following/mod.rs +++ b/crates/apub/src/protocol/activities/following/mod.rs @@ -1,3 +1,26 @@ pub(crate) mod accept; pub mod follow; pub mod undo_follow; + +#[cfg(test)] +mod tests { + use crate::protocol::{ + activities::following::{ + accept::AcceptFollowCommunity, + follow::FollowCommunity, + undo_follow::UndoFollowCommunity, + }, + tests::test_parse_lemmy_item, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_accept_follow() { + test_parse_lemmy_item::("assets/lemmy/activities/following/follow.json"); + test_parse_lemmy_item::("assets/lemmy/activities/following/accept.json"); + test_parse_lemmy_item::( + "assets/lemmy/activities/following/undo_follow.json", + ); + } +} diff --git a/crates/apub/src/protocol/activities/private_message/mod.rs b/crates/apub/src/protocol/activities/private_message/mod.rs index 4bcda7c7..b54e66c0 100644 --- a/crates/apub/src/protocol/activities/private_message/mod.rs +++ b/crates/apub/src/protocol/activities/private_message/mod.rs @@ -1,3 +1,30 @@ pub mod create_or_update; pub mod delete; pub mod undo_delete; + +#[cfg(test)] +mod tests { + use crate::protocol::{ + activities::private_message::{ + create_or_update::CreateOrUpdatePrivateMessage, + delete::DeletePrivateMessage, + undo_delete::UndoDeletePrivateMessage, + }, + tests::test_parse_lemmy_item, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_private_message() { + test_parse_lemmy_item::( + "assets/lemmy/activities/private_message/create.json", + ); + test_parse_lemmy_item::( + "assets/lemmy/activities/private_message/delete.json", + ); + test_parse_lemmy_item::( + "assets/lemmy/activities/private_message/undo_delete.json", + ); + } +} diff --git a/crates/apub/src/protocol/activities/voting/mod.rs b/crates/apub/src/protocol/activities/voting/mod.rs index 4583c231..48e30f0b 100644 --- a/crates/apub/src/protocol/activities/voting/mod.rs +++ b/crates/apub/src/protocol/activities/voting/mod.rs @@ -1,2 +1,21 @@ pub mod undo_vote; pub mod vote; + +#[cfg(test)] +mod tests { + use crate::protocol::{ + activities::voting::{undo_vote::UndoVote, vote::Vote}, + tests::test_parse_lemmy_item, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_voting() { + test_parse_lemmy_item::("assets/lemmy/activities/voting/like_note.json"); + test_parse_lemmy_item::("assets/lemmy/activities/voting/dislike_page.json"); + + test_parse_lemmy_item::("assets/lemmy/activities/voting/undo_like_note.json"); + test_parse_lemmy_item::("assets/lemmy/activities/voting/undo_dislike_page.json"); + } +} diff --git a/crates/apub/src/protocol/collections/group_followers.rs b/crates/apub/src/protocol/collections/group_followers.rs index 41155b19..d3df5e22 100644 --- a/crates/apub/src/protocol/collections/group_followers.rs +++ b/crates/apub/src/protocol/collections/group_followers.rs @@ -10,25 +10,25 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub(crate) struct CommunityFollowers { +pub(crate) struct GroupFollowers { id: Url, r#type: CollectionType, total_items: i32, items: Vec<()>, } -impl CommunityFollowers { +impl GroupFollowers { pub(crate) async fn new( community: Community, context: &LemmyContext, - ) -> Result { + ) -> Result { let community_id = community.id; let community_followers = blocking(context.pool(), move |conn| { CommunityFollowerView::for_community(conn, community_id) }) .await??; - Ok(CommunityFollowers { + Ok(GroupFollowers { id: generate_followers_url(&community.actor_id)?.into_inner(), r#type: CollectionType::Collection, total_items: community_followers.len() as i32, diff --git a/crates/apub/src/protocol/collections/mod.rs b/crates/apub/src/protocol/collections/mod.rs index 646abbeb..2e2d5c20 100644 --- a/crates/apub/src/protocol/collections/mod.rs +++ b/crates/apub/src/protocol/collections/mod.rs @@ -2,3 +2,27 @@ pub(crate) mod group_followers; pub(crate) mod group_moderators; pub(crate) mod group_outbox; pub(crate) mod person_outbox; + +#[cfg(test)] +mod tests { + use crate::protocol::{ + collections::{ + group_followers::GroupFollowers, + group_moderators::GroupModerators, + group_outbox::GroupOutbox, + person_outbox::PersonOutbox, + }, + tests::test_parse_lemmy_item, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_collections() { + test_parse_lemmy_item::("assets/lemmy/collections/group_followers.json"); + let outbox = test_parse_lemmy_item::("assets/lemmy/collections/group_outbox.json"); + assert_eq!(outbox.ordered_items.len() as i32, outbox.total_items); + test_parse_lemmy_item::("assets/lemmy/collections/group_moderators.json"); + test_parse_lemmy_item::("assets/lemmy/collections/person_outbox.json"); + } +} diff --git a/crates/apub/src/protocol/collections/person_outbox.rs b/crates/apub/src/protocol/collections/person_outbox.rs index 59c6975e..6ec75840 100644 --- a/crates/apub/src/protocol/collections/person_outbox.rs +++ b/crates/apub/src/protocol/collections/person_outbox.rs @@ -7,16 +7,16 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub(crate) struct UserOutbox { +pub(crate) struct PersonOutbox { r#type: OrderedCollectionType, id: Url, ordered_items: Vec<()>, total_items: i32, } -impl UserOutbox { - pub(crate) async fn new(user: Person) -> Result { - Ok(UserOutbox { +impl PersonOutbox { + pub(crate) async fn new(user: Person) -> Result { + Ok(PersonOutbox { r#type: OrderedCollectionType::OrderedCollection, id: generate_outbox_url(&user.actor_id)?.into_inner(), ordered_items: vec![], diff --git a/crates/apub/src/protocol/mod.rs b/crates/apub/src/protocol/mod.rs index f587dba7..22df0354 100644 --- a/crates/apub/src/protocol/mod.rs +++ b/crates/apub/src/protocol/mod.rs @@ -22,3 +22,20 @@ pub struct ImageObject { pub(crate) kind: ImageType, pub(crate) url: Url, } + +#[cfg(test)] +pub(crate) mod tests { + use crate::objects::tests::file_to_json_object; + use assert_json_diff::assert_json_include; + use serde::{de::DeserializeOwned, Serialize}; + use std::collections::HashMap; + + pub(crate) fn test_parse_lemmy_item(path: &str) -> T { + let parsed = file_to_json_object::(path); + + // ensure that no field is ignored when parsing + let raw = file_to_json_object::>(path); + assert_json_include!(actual: &parsed, expected: raw); + parsed + } +} diff --git a/crates/apub/src/protocol/objects/mod.rs b/crates/apub/src/protocol/objects/mod.rs index 3e133831..529ee637 100644 --- a/crates/apub/src/protocol/objects/mod.rs +++ b/crates/apub/src/protocol/objects/mod.rs @@ -2,4 +2,24 @@ pub(crate) mod chat_message; pub(crate) mod group; pub(crate) mod note; pub(crate) mod page; +pub(crate) mod person; pub(crate) mod tombstone; + +#[cfg(test)] +mod tests { + use crate::protocol::{ + objects::{chat_message::ChatMessage, group::Group, note::Note, page::Page, person::Person}, + tests::test_parse_lemmy_item, + }; + use serial_test::serial; + + #[actix_rt::test] + #[serial] + async fn test_parse_lemmy_object() { + test_parse_lemmy_item::("assets/lemmy/objects/person.json"); + test_parse_lemmy_item::("assets/lemmy/objects/group.json"); + test_parse_lemmy_item::("assets/lemmy/objects/page.json"); + test_parse_lemmy_item::("assets/lemmy/objects/note.json"); + test_parse_lemmy_item::("assets/lemmy/objects/chat_message.json"); + } +} diff --git a/crates/apub/src/protocol/objects/person.rs b/crates/apub/src/protocol/objects/person.rs new file mode 100644 index 00000000..2aecf945 --- /dev/null +++ b/crates/apub/src/protocol/objects/person.rs @@ -0,0 +1,41 @@ +use crate::protocol::{ImageObject, Source}; +use activitystreams::{actor::Endpoints, unparsed::Unparsed, url::Url}; +use chrono::{DateTime, FixedOffset}; +use lemmy_apub_lib::signatures::PublicKey; +use serde::{Deserialize, Serialize}; +use serde_with::skip_serializing_none; + +#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)] +pub enum UserTypes { + Person, + Service, +} + +#[skip_serializing_none] +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Person { + #[serde(rename = "type")] + pub(crate) kind: UserTypes, + pub(crate) id: Url, + /// username, set at account creation and can never be changed + pub(crate) preferred_username: String, + /// displayname (can be changed at any time) + pub(crate) name: Option, + pub(crate) summary: Option, + pub(crate) source: Option, + /// user avatar + pub(crate) icon: Option, + /// user banner + pub(crate) image: Option, + pub(crate) matrix_user_id: Option, + pub(crate) inbox: Url, + /// mandatory field in activitypub, currently empty in lemmy + pub(crate) outbox: Url, + pub(crate) endpoints: Endpoints, + pub(crate) public_key: PublicKey, + pub(crate) published: Option>, + pub(crate) updated: Option>, + #[serde(flatten)] + pub(crate) unparsed: Unparsed, +} diff --git a/crates/db_schema/src/impls/activity.rs b/crates/db_schema/src/impls/activity.rs index 4f1cfd2d..5efb3b23 100644 --- a/crates/db_schema/src/impls/activity.rs +++ b/crates/db_schema/src/impls/activity.rs @@ -1,7 +1,6 @@ use crate::{newtypes::DbUrl, source::activity::*, traits::Crud}; -use diesel::{dsl::*, result::Error, sql_types::Text, *}; +use diesel::{dsl::*, result::Error, *}; use serde::Serialize; -use serde_json::Value; use std::{ fmt::Debug, io::{Error as IoError, ErrorKind}, @@ -75,26 +74,6 @@ impl Activity { use crate::schema::activity::dsl::*; diesel::delete(activity.filter(published.lt(now - 6.months()))).execute(conn) } - - pub fn read_community_outbox( - conn: &PgConnection, - community_actor_id: &DbUrl, - ) -> Result, Error> { - use crate::schema::activity::dsl::*; - let res: Vec = activity - .select(data) - .filter( - sql("activity.data ->> 'type' = 'Announce'") - .sql(" AND activity.data -> 'object' ->> 'type' = 'Create'") - .sql(" AND activity.data -> 'object' -> 'object' ->> 'type' = 'Page'") - .sql(" AND activity.data ->> 'actor' = ") - .bind::(community_actor_id) - .sql(" ORDER BY activity.published DESC"), - ) - .limit(20) - .get_results(conn)?; - Ok(res) - } } #[cfg(test)] diff --git a/docker/federation/docker-compose.yml b/docker/federation/docker-compose.yml index 3a8447c1..bcd4f914 100644 --- a/docker/federation/docker-compose.yml +++ b/docker/federation/docker-compose.yml @@ -28,7 +28,7 @@ services: - ./volumes/pictrs_alpha:/mnt lemmy-alpha-ui: - image: dessalines/lemmy-ui:dev + image: dessalines/lemmy-ui:0.13.3 environment: - LEMMY_INTERNAL_HOST=lemmy-alpha:8541 - LEMMY_EXTERNAL_HOST=localhost:8541 @@ -57,7 +57,7 @@ services: - ./volumes/postgres_alpha:/var/lib/postgresql/data lemmy-beta-ui: - image: dessalines/lemmy-ui:dev + image: dessalines/lemmy-ui:0.13.3 environment: - LEMMY_INTERNAL_HOST=lemmy-beta:8551 - LEMMY_EXTERNAL_HOST=localhost:8551