Add tests for parsing activities and collections
This commit is contained in:
parent
aaaf039779
commit
0bde2d595e
55 changed files with 1112 additions and 177 deletions
13
crates/apub/assets/lemmy/activities/community/add_mod.json
Normal file
13
crates/apub/assets/lemmy/activities/community/add_mod.json
Normal file
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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": "<p>updated 2</p>\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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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": "<p>test body</p>\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"
|
||||||
|
}
|
|
@ -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": "<p>test body</p>\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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
17
crates/apub/assets/lemmy/activities/following/accept.json
Normal file
17
crates/apub/assets/lemmy/activities/following/accept.json
Normal file
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
12
crates/apub/assets/lemmy/activities/voting/dislike_page.json
Normal file
12
crates/apub/assets/lemmy/activities/voting/dislike_page.json
Normal file
|
@ -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"
|
||||||
|
}
|
12
crates/apub/assets/lemmy/activities/voting/like_note.json
Normal file
12
crates/apub/assets/lemmy/activities/voting/like_note.json
Normal file
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"id": "http://enterprise.lemmy.ml/c/main/followers",
|
||||||
|
"type": "Collection",
|
||||||
|
"totalItems": 3,
|
||||||
|
"items": []
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"type": "OrderedCollection",
|
||||||
|
"id": "https://enterprise.lemmy.ml/c/tenforward/moderators",
|
||||||
|
"orderedItems": [
|
||||||
|
"https://enterprise.lemmy.ml/u/picard"
|
||||||
|
]
|
||||||
|
}
|
209
crates/apub/assets/lemmy/collections/group_outbox.json
Normal file
209
crates/apub/assets/lemmy/collections/group_outbox.json
Normal file
|
@ -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": "<p>test</p>\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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
6
crates/apub/assets/lemmy/collections/person_outbox.json
Normal file
6
crates/apub/assets/lemmy/collections/person_outbox.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"type": "OrderedCollection",
|
||||||
|
"id": "http://ds9.lemmy.ml/u/lemmy_alpha/outbox",
|
||||||
|
"orderedItems": [],
|
||||||
|
"totalItems": 0
|
||||||
|
}
|
|
@ -13,6 +13,11 @@
|
||||||
"content": "This is a post in the /c/tenforward community",
|
"content": "This is a post in the /c/tenforward community",
|
||||||
"mediaType": "text/markdown"
|
"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,
|
"sensitive": false,
|
||||||
"commentsEnabled": true,
|
"commentsEnabled": true,
|
||||||
"stickied": true,
|
"stickied": true,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
"type": "Image",
|
"type": "Image",
|
||||||
"url": "https://enterprise.lemmy.ml/pictrs/image/XenaYI5hTn.png"
|
"url": "https://enterprise.lemmy.ml/pictrs/image/XenaYI5hTn.png"
|
||||||
},
|
},
|
||||||
|
"matrix_user_id": "@picard:matrix.org",
|
||||||
"inbox": "https://enterprise.lemmy.ml/u/picard/inbox",
|
"inbox": "https://enterprise.lemmy.ml/u/picard/inbox",
|
||||||
"outbox": "https://enterprise.lemmy.ml/u/picard/outbox",
|
"outbox": "https://enterprise.lemmy.ml/u/picard/outbox",
|
||||||
"endpoints": {
|
"endpoints": {
|
||||||
|
|
|
@ -128,16 +128,3 @@ impl GetCommunity for CreateOrUpdateComment {
|
||||||
Ok(community.into())
|
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::<CreateOrUpdateComment>("assets/pleroma/activities/create-note.json");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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::{
|
use crate::{
|
||||||
activities::community::announce::GetCommunity,
|
activities::community::announce::GetCommunity,
|
||||||
objects::community::ApubCommunity,
|
objects::community::ApubCommunity,
|
||||||
|
@ -35,6 +26,10 @@ use crate::{
|
||||||
voting::{undo_vote::UndoVote, vote::Vote},
|
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)]
|
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
|
@ -107,7 +102,6 @@ impl GetCommunity for AnnouncableActivities {
|
||||||
AddMod(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?,
|
RemoveMod(a) => a.get_community(context, request_counter).await?,
|
||||||
};
|
};
|
||||||
verify_urls_match(self.actor(), &community.actor_id())?;
|
|
||||||
Ok(community)
|
Ok(community)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,3 +120,74 @@ impl ApubObject for ApubCommunityModerators {
|
||||||
Ok(ApubCommunityModerators { 0: vec![] })
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,13 +18,8 @@ use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fetcher::object_id::ObjectId,
|
fetcher::object_id::ObjectId,
|
||||||
objects::{
|
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
||||||
comment::ApubComment,
|
protocol::objects::{group::Group, note::Note, page::Page, person::Person},
|
||||||
community::ApubCommunity,
|
|
||||||
person::{ApubPerson, Person},
|
|
||||||
post::ApubPost,
|
|
||||||
},
|
|
||||||
protocol::objects::{group::Group, note::Note, page::Page},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Attempt to parse the query as URL, and fetch an ActivityPub object from it.
|
/// Attempt to parse the query as URL, and fetch an ActivityPub object from it.
|
||||||
|
|
|
@ -18,15 +18,12 @@ use crate::{
|
||||||
objects::community::ApubCommunity,
|
objects::community::ApubCommunity,
|
||||||
protocol::{
|
protocol::{
|
||||||
activities::community::announce::AnnounceActivity,
|
activities::community::announce::AnnounceActivity,
|
||||||
collections::group_followers::CommunityFollowers,
|
collections::group_followers::GroupFollowers,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
|
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub_lib::{
|
use lemmy_apub_lib::traits::{ActivityFields, ApubObject};
|
||||||
traits::{ActivityFields, ActorType, ApubObject},
|
|
||||||
verify::verify_domains_match,
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::source::community::Community;
|
use lemmy_db_schema::source::community::Community;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
@ -84,7 +81,6 @@ pub(in crate::http) async fn receive_group_inbox(
|
||||||
if let GroupInboxActivities::AnnouncableActivities(announcable) = activity {
|
if let GroupInboxActivities::AnnouncableActivities(announcable) = activity {
|
||||||
let community = announcable.get_community(context, &mut 0).await?;
|
let community = announcable.get_community(context, &mut 0).await?;
|
||||||
let actor_id = ObjectId::new(announcable.actor().clone());
|
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?;
|
verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
|
||||||
if community.local {
|
if community.local {
|
||||||
AnnounceActivity::send(announcable, &community, vec![], context).await?;
|
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)
|
Community::read_from_name(conn, &info.community_name)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
let followers = CommunityFollowers::new(community, &context).await?;
|
let followers = GroupFollowers::new(community, &context).await?;
|
||||||
Ok(create_apub_response(&followers))
|
Ok(create_apub_response(&followers))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
receive_activity,
|
receive_activity,
|
||||||
},
|
},
|
||||||
objects::person::ApubPerson,
|
objects::person::ApubPerson,
|
||||||
protocol::collections::person_outbox::UserOutbox,
|
protocol::collections::person_outbox::PersonOutbox,
|
||||||
};
|
};
|
||||||
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
|
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
|
||||||
use lemmy_api_common::blocking;
|
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)
|
Person::find_by_name(conn, &info.user_name)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
let outbox = UserOutbox::new(person).await?;
|
let outbox = PersonOutbox::new(person).await?;
|
||||||
Ok(create_apub_response(&outbox))
|
Ok(create_apub_response(&outbox))
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,26 +188,20 @@ impl ApubObject for ApubComment {
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::objects::{
|
use crate::objects::{
|
||||||
community::ApubCommunity,
|
community::{tests::parse_lemmy_community, ApubCommunity},
|
||||||
person::ApubPerson,
|
person::{tests::parse_lemmy_person, ApubPerson},
|
||||||
post::ApubPost,
|
post::ApubPost,
|
||||||
tests::{file_to_json_object, init_context},
|
tests::{file_to_json_object, init_context},
|
||||||
};
|
};
|
||||||
use assert_json_diff::assert_json_include;
|
use assert_json_diff::assert_json_include;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
pub(crate) async fn prepare_comment_test(
|
async fn prepare_comment_test(
|
||||||
url: &Url,
|
url: &Url,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> (ApubPerson, ApubCommunity, ApubPost) {
|
) -> (ApubPerson, ApubCommunity, ApubPost) {
|
||||||
let person_json = file_to_json_object("assets/lemmy/objects/person.json");
|
let person = parse_lemmy_person(context).await;
|
||||||
let person = ApubPerson::from_apub(&person_json, context, url, &mut 0)
|
let community = parse_lemmy_community(context).await;
|
||||||
.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 post_json = file_to_json_object("assets/lemmy/objects/page.json");
|
let post_json = file_to_json_object("assets/lemmy/objects/page.json");
|
||||||
let post = ApubPost::from_apub(&post_json, context, url, &mut 0)
|
let post = ApubPost::from_apub(&post_json, context, url, &mut 0)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -222,42 +222,39 @@ impl ApubCommunity {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::objects::tests::{file_to_json_object, init_context};
|
use crate::objects::tests::{file_to_json_object, init_context};
|
||||||
use assert_json_diff::assert_json_include;
|
|
||||||
use lemmy_db_schema::traits::Crud;
|
use lemmy_db_schema::traits::Crud;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
#[actix_rt::test]
|
pub(crate) async fn parse_lemmy_community(context: &LemmyContext) -> ApubCommunity {
|
||||||
#[serial]
|
|
||||||
async fn test_parse_lemmy_community() {
|
|
||||||
let context = init_context();
|
|
||||||
let mut json: Group = file_to_json_object("assets/lemmy/objects/group.json");
|
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
|
// change these links so they dont fetch over the network
|
||||||
json.moderators = Some(ObjectId::new(
|
json.moderators = None;
|
||||||
Url::parse("https://enterprise.lemmy.ml/c/tenforward/not_moderators").unwrap(),
|
|
||||||
));
|
|
||||||
json.outbox =
|
json.outbox =
|
||||||
ObjectId::new(Url::parse("https://enterprise.lemmy.ml/c/tenforward/not_outbox").unwrap());
|
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 url = Url::parse("https://enterprise.lemmy.ml/c/tenforward").unwrap();
|
||||||
let mut request_counter = 0;
|
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
|
.await
|
||||||
.unwrap();
|
.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_eq!(community.title, "Ten Forward");
|
||||||
assert!(community.public_key.is_some());
|
assert!(community.public_key.is_some());
|
||||||
assert!(!community.local);
|
assert!(!community.local);
|
||||||
assert_eq!(community.description.as_ref().unwrap().len(), 132);
|
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();
|
Community::delete(&*context.pool().get().unwrap(), community.id).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,16 @@ use crate::{
|
||||||
check_is_apub_id_valid,
|
check_is_apub_id_valid,
|
||||||
generate_outbox_url,
|
generate_outbox_url,
|
||||||
objects::get_summary_from_string_or_source,
|
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 activitystreams::{actor::Endpoints, object::kind::ImageType};
|
||||||
use chrono::{DateTime, FixedOffset, NaiveDateTime};
|
use chrono::NaiveDateTime;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub_lib::{
|
use lemmy_apub_lib::{
|
||||||
signatures::PublicKey,
|
|
||||||
traits::{ActorType, ApubObject},
|
traits::{ActorType, ApubObject},
|
||||||
values::MediaTypeMarkdown,
|
values::MediaTypeMarkdown,
|
||||||
verify::verify_domains_match,
|
verify::verify_domains_match,
|
||||||
|
@ -22,54 +25,9 @@ use lemmy_utils::{
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use serde_with::skip_serializing_none;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use url::Url;
|
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<String>,
|
|
||||||
summary: Option<String>,
|
|
||||||
source: Option<Source>,
|
|
||||||
/// user avatar
|
|
||||||
icon: Option<ImageObject>,
|
|
||||||
/// user banner
|
|
||||||
image: Option<ImageObject>,
|
|
||||||
matrix_user_id: Option<String>,
|
|
||||||
inbox: Url,
|
|
||||||
/// mandatory field in activitypub, currently empty in lemmy
|
|
||||||
outbox: Url,
|
|
||||||
endpoints: Endpoints<Url>,
|
|
||||||
public_key: PublicKey,
|
|
||||||
published: Option<DateTime<FixedOffset>>,
|
|
||||||
updated: Option<DateTime<FixedOffset>>,
|
|
||||||
#[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)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct ApubPerson(DbPerson);
|
pub struct ApubPerson(DbPerson);
|
||||||
|
|
||||||
|
@ -170,7 +128,8 @@ impl ApubObject for ApubPerson {
|
||||||
expected_domain: &Url,
|
expected_domain: &Url,
|
||||||
_request_counter: &mut i32,
|
_request_counter: &mut i32,
|
||||||
) -> Result<ApubPerson, LemmyError> {
|
) -> Result<ApubPerson, LemmyError> {
|
||||||
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 name = person.preferred_username.clone();
|
||||||
let display_name: Option<String> = person.name.clone();
|
let display_name: Option<String> = person.name.clone();
|
||||||
let bio = get_summary_from_string_or_source(&person.summary, &person.source);
|
let bio = get_summary_from_string_or_source(&person.summary, &person.source);
|
||||||
|
@ -245,33 +204,33 @@ impl ActorType for ApubPerson {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::objects::tests::{file_to_json_object, init_context};
|
use crate::objects::tests::{file_to_json_object, init_context};
|
||||||
use assert_json_diff::assert_json_include;
|
|
||||||
use lemmy_db_schema::traits::Crud;
|
use lemmy_db_schema::traits::Crud;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
|
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)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(request_counter, 0);
|
||||||
|
person
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_person() {
|
async fn test_parse_lemmy_person() {
|
||||||
let context = init_context();
|
let context = init_context();
|
||||||
let json = file_to_json_object("assets/lemmy/objects/person.json");
|
let person = parse_lemmy_person(&context).await;
|
||||||
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)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(person.actor_id.clone().into_inner(), url);
|
|
||||||
assert_eq!(person.display_name, Some("Jean-Luc Picard".to_string()));
|
assert_eq!(person.display_name, Some("Jean-Luc Picard".to_string()));
|
||||||
assert!(person.public_key.is_some());
|
assert!(person.public_key.is_some());
|
||||||
assert!(!person.local);
|
assert!(!person.local);
|
||||||
assert_eq!(person.bio.as_ref().unwrap().len(), 39);
|
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();
|
DbPerson::delete(&*context.pool().get().unwrap(), person.id).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,28 +193,22 @@ impl ApubObject for ApubPost {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::objects::{
|
use crate::objects::{
|
||||||
community::ApubCommunity,
|
community::tests::parse_lemmy_community,
|
||||||
person::ApubPerson,
|
person::tests::parse_lemmy_person,
|
||||||
post::ApubPost,
|
post::ApubPost,
|
||||||
tests::{file_to_json_object, init_context},
|
tests::{file_to_json_object, init_context},
|
||||||
};
|
};
|
||||||
use assert_json_diff::assert_json_include;
|
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_parse_lemmy_post() {
|
async fn test_parse_lemmy_post() {
|
||||||
let context = init_context();
|
let context = init_context();
|
||||||
let url = Url::parse("https://enterprise.lemmy.ml/post/55143").unwrap();
|
let community = parse_lemmy_community(&context).await;
|
||||||
let community_json = file_to_json_object("assets/lemmy/objects/group.json");
|
let person = parse_lemmy_person(&context).await;
|
||||||
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 json = file_to_json_object("assets/lemmy/objects/page.json");
|
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 mut request_counter = 0;
|
||||||
let post = ApubPost::from_apub(&json, &context, &url, &mut request_counter)
|
let post = ApubPost::from_apub(&json, &context, &url, &mut request_counter)
|
||||||
.await
|
.await
|
||||||
|
@ -228,9 +222,6 @@ mod tests {
|
||||||
assert!(post.stickied);
|
assert!(post.stickied);
|
||||||
assert_eq!(request_counter, 0);
|
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();
|
Post::delete(&*context.pool().get().unwrap(), post.id).unwrap();
|
||||||
Person::delete(&*context.pool().get().unwrap(), person.id).unwrap();
|
Person::delete(&*context.pool().get().unwrap(), person.id).unwrap();
|
||||||
Community::delete(&*context.pool().get().unwrap(), community.id).unwrap();
|
Community::delete(&*context.pool().get().unwrap(), community.id).unwrap();
|
||||||
|
|
|
@ -5,3 +5,44 @@ pub mod remove_mod;
|
||||||
pub mod report;
|
pub mod report;
|
||||||
pub mod undo_block_user;
|
pub mod undo_block_user;
|
||||||
pub mod update;
|
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::<Announce>(
|
||||||
|
"assets/lemmy/activities/community/announce_create_page.json",
|
||||||
|
);
|
||||||
|
|
||||||
|
test_parse_lemmy_item::<AddMod>("assets/lemmy/activities/community/add_mod.json");
|
||||||
|
test_parse_lemmy_item::<RemoveMod>("assets/lemmy/activities/community/remove_mod.json");
|
||||||
|
|
||||||
|
test_parse_lemmy_item::<BlockUserFromCommunity>(
|
||||||
|
"assets/lemmy/activities/community/block_user.json",
|
||||||
|
);
|
||||||
|
test_parse_lemmy_item::<UndoBlockUserFromCommunity>(
|
||||||
|
"assets/lemmy/activities/community/undo_block_user.json",
|
||||||
|
);
|
||||||
|
|
||||||
|
test_parse_lemmy_item::<UpdateCommunity>(
|
||||||
|
"assets/lemmy/activities/community/update_community.json",
|
||||||
|
);
|
||||||
|
|
||||||
|
test_parse_lemmy_item::<Report>("assets/lemmy/activities/community/report_page.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,34 @@
|
||||||
pub mod comment;
|
pub mod comment;
|
||||||
pub mod post;
|
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::<CreateOrUpdatePost>(
|
||||||
|
"assets/lemmy/activities/create_or_update/create_page.json",
|
||||||
|
);
|
||||||
|
test_parse_lemmy_item::<CreateOrUpdatePost>(
|
||||||
|
"assets/lemmy/activities/create_or_update/update_page.json",
|
||||||
|
);
|
||||||
|
test_parse_lemmy_item::<CreateOrUpdateComment>(
|
||||||
|
"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::<CreateOrUpdateComment>("assets/pleroma/activities/create_note.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,21 @@
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
pub mod undo_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::<Delete>("assets/lemmy/activities/deletion/remove_note.json");
|
||||||
|
test_parse_lemmy_item::<Delete>("assets/lemmy/activities/deletion/delete_page.json");
|
||||||
|
|
||||||
|
test_parse_lemmy_item::<UndoDelete>("assets/lemmy/activities/deletion/undo_remove_note.json");
|
||||||
|
test_parse_lemmy_item::<UndoDelete>("assets/lemmy/activities/deletion/undo_delete_page.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,26 @@
|
||||||
pub(crate) mod accept;
|
pub(crate) mod accept;
|
||||||
pub mod follow;
|
pub mod follow;
|
||||||
pub mod undo_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::<FollowCommunity>("assets/lemmy/activities/following/follow.json");
|
||||||
|
test_parse_lemmy_item::<AcceptFollowCommunity>("assets/lemmy/activities/following/accept.json");
|
||||||
|
test_parse_lemmy_item::<UndoFollowCommunity>(
|
||||||
|
"assets/lemmy/activities/following/undo_follow.json",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,30 @@
|
||||||
pub mod create_or_update;
|
pub mod create_or_update;
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
pub mod undo_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::<CreateOrUpdatePrivateMessage>(
|
||||||
|
"assets/lemmy/activities/private_message/create.json",
|
||||||
|
);
|
||||||
|
test_parse_lemmy_item::<DeletePrivateMessage>(
|
||||||
|
"assets/lemmy/activities/private_message/delete.json",
|
||||||
|
);
|
||||||
|
test_parse_lemmy_item::<UndoDeletePrivateMessage>(
|
||||||
|
"assets/lemmy/activities/private_message/undo_delete.json",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,21 @@
|
||||||
pub mod undo_vote;
|
pub mod undo_vote;
|
||||||
pub mod 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::<Vote>("assets/lemmy/activities/voting/like_note.json");
|
||||||
|
test_parse_lemmy_item::<Vote>("assets/lemmy/activities/voting/dislike_page.json");
|
||||||
|
|
||||||
|
test_parse_lemmy_item::<UndoVote>("assets/lemmy/activities/voting/undo_like_note.json");
|
||||||
|
test_parse_lemmy_item::<UndoVote>("assets/lemmy/activities/voting/undo_dislike_page.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,25 +10,25 @@ use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub(crate) struct CommunityFollowers {
|
pub(crate) struct GroupFollowers {
|
||||||
id: Url,
|
id: Url,
|
||||||
r#type: CollectionType,
|
r#type: CollectionType,
|
||||||
total_items: i32,
|
total_items: i32,
|
||||||
items: Vec<()>,
|
items: Vec<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommunityFollowers {
|
impl GroupFollowers {
|
||||||
pub(crate) async fn new(
|
pub(crate) async fn new(
|
||||||
community: Community,
|
community: Community,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<CommunityFollowers, LemmyError> {
|
) -> Result<GroupFollowers, LemmyError> {
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let community_followers = blocking(context.pool(), move |conn| {
|
let community_followers = blocking(context.pool(), move |conn| {
|
||||||
CommunityFollowerView::for_community(conn, community_id)
|
CommunityFollowerView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
Ok(CommunityFollowers {
|
Ok(GroupFollowers {
|
||||||
id: generate_followers_url(&community.actor_id)?.into_inner(),
|
id: generate_followers_url(&community.actor_id)?.into_inner(),
|
||||||
r#type: CollectionType::Collection,
|
r#type: CollectionType::Collection,
|
||||||
total_items: community_followers.len() as i32,
|
total_items: community_followers.len() as i32,
|
||||||
|
|
|
@ -2,3 +2,27 @@ pub(crate) mod group_followers;
|
||||||
pub(crate) mod group_moderators;
|
pub(crate) mod group_moderators;
|
||||||
pub(crate) mod group_outbox;
|
pub(crate) mod group_outbox;
|
||||||
pub(crate) mod person_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::<GroupFollowers>("assets/lemmy/collections/group_followers.json");
|
||||||
|
let outbox = test_parse_lemmy_item::<GroupOutbox>("assets/lemmy/collections/group_outbox.json");
|
||||||
|
assert_eq!(outbox.ordered_items.len() as i32, outbox.total_items);
|
||||||
|
test_parse_lemmy_item::<GroupModerators>("assets/lemmy/collections/group_moderators.json");
|
||||||
|
test_parse_lemmy_item::<PersonOutbox>("assets/lemmy/collections/person_outbox.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,16 +7,16 @@ use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub(crate) struct UserOutbox {
|
pub(crate) struct PersonOutbox {
|
||||||
r#type: OrderedCollectionType,
|
r#type: OrderedCollectionType,
|
||||||
id: Url,
|
id: Url,
|
||||||
ordered_items: Vec<()>,
|
ordered_items: Vec<()>,
|
||||||
total_items: i32,
|
total_items: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserOutbox {
|
impl PersonOutbox {
|
||||||
pub(crate) async fn new(user: Person) -> Result<UserOutbox, LemmyError> {
|
pub(crate) async fn new(user: Person) -> Result<PersonOutbox, LemmyError> {
|
||||||
Ok(UserOutbox {
|
Ok(PersonOutbox {
|
||||||
r#type: OrderedCollectionType::OrderedCollection,
|
r#type: OrderedCollectionType::OrderedCollection,
|
||||||
id: generate_outbox_url(&user.actor_id)?.into_inner(),
|
id: generate_outbox_url(&user.actor_id)?.into_inner(),
|
||||||
ordered_items: vec![],
|
ordered_items: vec![],
|
||||||
|
|
|
@ -22,3 +22,20 @@ pub struct ImageObject {
|
||||||
pub(crate) kind: ImageType,
|
pub(crate) kind: ImageType,
|
||||||
pub(crate) url: Url,
|
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<T: Serialize + DeserializeOwned>(path: &str) -> T {
|
||||||
|
let parsed = file_to_json_object::<T>(path);
|
||||||
|
|
||||||
|
// ensure that no field is ignored when parsing
|
||||||
|
let raw = file_to_json_object::<HashMap<String, serde_json::Value>>(path);
|
||||||
|
assert_json_include!(actual: &parsed, expected: raw);
|
||||||
|
parsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,4 +2,24 @@ pub(crate) mod chat_message;
|
||||||
pub(crate) mod group;
|
pub(crate) mod group;
|
||||||
pub(crate) mod note;
|
pub(crate) mod note;
|
||||||
pub(crate) mod page;
|
pub(crate) mod page;
|
||||||
|
pub(crate) mod person;
|
||||||
pub(crate) mod tombstone;
|
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::<Person>("assets/lemmy/objects/person.json");
|
||||||
|
test_parse_lemmy_item::<Group>("assets/lemmy/objects/group.json");
|
||||||
|
test_parse_lemmy_item::<Page>("assets/lemmy/objects/page.json");
|
||||||
|
test_parse_lemmy_item::<Note>("assets/lemmy/objects/note.json");
|
||||||
|
test_parse_lemmy_item::<ChatMessage>("assets/lemmy/objects/chat_message.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
41
crates/apub/src/protocol/objects/person.rs
Normal file
41
crates/apub/src/protocol/objects/person.rs
Normal file
|
@ -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<String>,
|
||||||
|
pub(crate) summary: Option<String>,
|
||||||
|
pub(crate) source: Option<Source>,
|
||||||
|
/// user avatar
|
||||||
|
pub(crate) icon: Option<ImageObject>,
|
||||||
|
/// user banner
|
||||||
|
pub(crate) image: Option<ImageObject>,
|
||||||
|
pub(crate) matrix_user_id: Option<String>,
|
||||||
|
pub(crate) inbox: Url,
|
||||||
|
/// mandatory field in activitypub, currently empty in lemmy
|
||||||
|
pub(crate) outbox: Url,
|
||||||
|
pub(crate) endpoints: Endpoints<Url>,
|
||||||
|
pub(crate) public_key: PublicKey,
|
||||||
|
pub(crate) published: Option<DateTime<FixedOffset>>,
|
||||||
|
pub(crate) updated: Option<DateTime<FixedOffset>>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub(crate) unparsed: Unparsed,
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::{newtypes::DbUrl, source::activity::*, traits::Crud};
|
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::Serialize;
|
||||||
use serde_json::Value;
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
io::{Error as IoError, ErrorKind},
|
io::{Error as IoError, ErrorKind},
|
||||||
|
@ -75,26 +74,6 @@ impl Activity {
|
||||||
use crate::schema::activity::dsl::*;
|
use crate::schema::activity::dsl::*;
|
||||||
diesel::delete(activity.filter(published.lt(now - 6.months()))).execute(conn)
|
diesel::delete(activity.filter(published.lt(now - 6.months()))).execute(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_community_outbox(
|
|
||||||
conn: &PgConnection,
|
|
||||||
community_actor_id: &DbUrl,
|
|
||||||
) -> Result<Vec<Value>, Error> {
|
|
||||||
use crate::schema::activity::dsl::*;
|
|
||||||
let res: Vec<Value> = 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::<Text, _>(community_actor_id)
|
|
||||||
.sql(" ORDER BY activity.published DESC"),
|
|
||||||
)
|
|
||||||
.limit(20)
|
|
||||||
.get_results(conn)?;
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -28,7 +28,7 @@ services:
|
||||||
- ./volumes/pictrs_alpha:/mnt
|
- ./volumes/pictrs_alpha:/mnt
|
||||||
|
|
||||||
lemmy-alpha-ui:
|
lemmy-alpha-ui:
|
||||||
image: dessalines/lemmy-ui:dev
|
image: dessalines/lemmy-ui:0.13.3
|
||||||
environment:
|
environment:
|
||||||
- LEMMY_INTERNAL_HOST=lemmy-alpha:8541
|
- LEMMY_INTERNAL_HOST=lemmy-alpha:8541
|
||||||
- LEMMY_EXTERNAL_HOST=localhost:8541
|
- LEMMY_EXTERNAL_HOST=localhost:8541
|
||||||
|
@ -57,7 +57,7 @@ services:
|
||||||
- ./volumes/postgres_alpha:/var/lib/postgresql/data
|
- ./volumes/postgres_alpha:/var/lib/postgresql/data
|
||||||
|
|
||||||
lemmy-beta-ui:
|
lemmy-beta-ui:
|
||||||
image: dessalines/lemmy-ui:dev
|
image: dessalines/lemmy-ui:0.13.3
|
||||||
environment:
|
environment:
|
||||||
- LEMMY_INTERNAL_HOST=lemmy-beta:8551
|
- LEMMY_INTERNAL_HOST=lemmy-beta:8551
|
||||||
- LEMMY_EXTERNAL_HOST=localhost:8551
|
- LEMMY_EXTERNAL_HOST=localhost:8551
|
||||||
|
|
Loading…
Reference in a new issue