Update activitystreams library to latest version (#71)

Merge branch 'main' into more-upgrade-apub-3

Update activitystreams library to latest version

Remove remaining usages of old activitystreams library

Migrate community inbox and user inbox

Migrate private message

Migrate post

Migrate community activities

Migrate extensions to new activitystreams library

Co-authored-by: dessalines <dessalines@noreply.yerbamate.dev>
Co-authored-by: Felix Ableitner <me@nutomic.com>
Reviewed-on: https://yerbamate.dev/LemmyNet/lemmy/pulls/71
This commit is contained in:
nutomic 2020-07-17 21:11:07 +00:00 committed by dessalines
parent 09f892a7fa
commit 77a2a5eb01
19 changed files with 831 additions and 1160 deletions

323
server/Cargo.lock generated vendored
View file

@ -1,35 +1,9 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "activitystreams"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "464cb473bfb402b857cc15b1153974c203a43f1485da4dda15cd17a738548958"
dependencies = [
"activitystreams-derive",
"chrono",
"mime",
"serde 1.0.114",
"serde_json",
"thiserror",
"url",
]
[[package]]
name = "activitystreams-derive"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c39ba5929399e9f921055bac76dd8f47419fa5b6b6da1ac4c1e82b94ed0ac7b4"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "activitystreams-ext"
version = "0.1.0"
source = "git+https://git.asonix.dog/asonix/activitystreams-ext#e5c97f4ea9f60e49bc7ff27fb0fb515d3190fd25"
source = "git+https://git.asonix.dog/asonix/activitystreams-ext?branch=main#9acc466c7cb550ada31b669a1c47ea088f1c8471"
dependencies = [
"activitystreams-new",
"serde 1.0.114",
@ -39,12 +13,14 @@ dependencies = [
[[package]]
name = "activitystreams-new"
version = "0.1.0"
source = "git+https://git.asonix.dog/asonix/activitystreams-sketch#99c7e9aa5596eda846a1ebd5978ca72d11d4c08a"
source = "git+https://git.asonix.dog/asonix/activitystreams-sketch?branch=main#857d5167dfa13054dd0d21d3d54f8147eea0d546"
dependencies = [
"activitystreams",
"chrono",
"mime",
"serde 1.0.114",
"serde_json",
"typed-builder",
"thiserror",
"url",
]
[[package]]
@ -111,9 +87,9 @@ dependencies = [
[[package]]
name = "actix-files"
version = "0.3.0-alpha.1"
version = "0.3.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b32e0fdd5998c2712549cbc39dff46c8754d55e3dd9f4d017d9e28de30cac6"
checksum = "627f597ad98061816766201db8afc7444752992f2919b2e60f53a7fa27f01aed"
dependencies = [
"actix-http",
"actix-service",
@ -132,9 +108,9 @@ dependencies = [
[[package]]
name = "actix-http"
version = "2.0.0-alpha.4"
version = "2.0.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd7ea0568480d199952a51de70271946da57c33cc0e8b83f54383e70958dff21"
checksum = "33f501768e82e8548763b7f55309e2f8bcc7f9f4273c75b47af99ac2b2581f37"
dependencies = [
"actix-codec",
"actix-connect",
@ -147,6 +123,7 @@ dependencies = [
"bitflags",
"brotli2",
"bytes",
"cookie",
"copyless",
"derive_more",
"either",
@ -160,6 +137,7 @@ dependencies = [
"http",
"httparse",
"indexmap",
"itoa",
"language-tags",
"lazy_static",
"log",
@ -171,7 +149,7 @@ dependencies = [
"serde 1.0.114",
"serde_json",
"serde_urlencoded",
"sha-1",
"sha-1 0.9.1",
"slab",
"time 0.2.16",
]
@ -260,16 +238,16 @@ dependencies = [
[[package]]
name = "actix-threadpool"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91164716d956745c79dcea5e66d2aa04506549958accefcede5368c70f2fd4ff"
checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30"
dependencies = [
"derive_more",
"futures-channel",
"lazy_static",
"log",
"num_cpus",
"parking_lot 0.10.2",
"parking_lot 0.11.0",
"threadpool",
]
@ -313,9 +291,9 @@ dependencies = [
[[package]]
name = "actix-web"
version = "3.0.0-alpha.3"
version = "3.0.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd6df56ec5f9a1a0d8335f156f36e1e8f76dbd736fa0cc0f6bc3a69be1e6124"
checksum = "9125c29b7d9911bfdb4d0d4d8f1cf4fee4f21515cf2a405a423c30c245364297"
dependencies = [
"actix-codec",
"actix-http",
@ -353,24 +331,25 @@ dependencies = [
[[package]]
name = "actix-web-actors"
version = "3.0.0-alpha.1"
version = "3.0.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b5efeb3907582f9c724ce27be093ab8aafabd97be828bc6750c0d467f5e1aa3"
checksum = "55ef22b33c49a28dda61866d5573c5b8ceb080a099cd59e7371b78b48bbf1bc0"
dependencies = [
"actix",
"actix-codec",
"actix-http",
"actix-web",
"bytes",
"futures",
"futures-channel",
"futures-core",
"pin-project",
]
[[package]]
name = "actix-web-codegen"
version = "0.2.2"
version = "0.3.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a71bf475cbe07281d0b3696abb48212db118e7e23219f13596ce865235ff5766"
checksum = "df9679f5b1f4c819de08b63b0a61a131b2fdc30b367c2c208984fda8eaa07fa0"
dependencies = [
"proc-macro2",
"quote",
@ -390,24 +369,18 @@ dependencies = [
[[package]]
name = "addr2line"
version = "0.12.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "602d785912f476e480434627e8732e6766b760c045bbf897d9dfaa9f4fbd399c"
checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc9a9dd069569f212bc4330af9f17c4afb5e8ce185e83dbb14f1349dda18b10"
[[package]]
name = "adler32"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "aho-corasick"
@ -481,9 +454,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "awc"
version = "2.0.0-alpha.2"
version = "2.0.0-beta.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7038a9747cd5159b9f0550895eaf865c0143baa7e4eee834e9294d0a7e0e4be"
checksum = "374057b508d4083208996be82141891c2e14c8885f45991b21c1621200ab6df3"
dependencies = [
"actix-codec",
"actix-http",
@ -505,14 +478,14 @@ dependencies = [
[[package]]
name = "backtrace"
version = "0.3.49"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c"
checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide 0.3.7",
"miniz_oxide",
"object",
"rustc-demangle",
]
@ -590,7 +563,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array 0.14.2",
"generic-array 0.14.3",
]
[[package]]
@ -599,7 +572,7 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10"
dependencies = [
"generic-array 0.14.2",
"generic-array 0.14.3",
]
[[package]]
@ -642,6 +615,15 @@ dependencies = [
"libc",
]
[[package]]
name = "buf-min"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6ae7069aad07c7cdefe6a22a671f00650728bd2331a4cc62e1e5d0becdf9ca4"
dependencies = [
"bytes",
]
[[package]]
name = "bufstream"
version = "0.1.4"
@ -668,12 +650,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "bytes"
version = "0.5.5"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b"
dependencies = [
"loom",
]
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "bytestring"
@ -686,9 +665,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.57"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fde55d2a2bfaa4c9668bbc63f531fbdeee3ffe188f4662511ce2c22b3eedebe"
checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
[[package]]
name = "cfg-if"
@ -698,9 +677,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "chrono"
version = "0.4.12"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0fee792e164f78f5fe0c296cc2eb3688a2ca2b70cdff33040922d298203f0c4"
checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6"
dependencies = [
"num-integer",
"num-traits 0.2.12",
@ -770,6 +749,16 @@ dependencies = [
"serde-hjson",
]
[[package]]
name = "cookie"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca761767cf3fa9068cc893ec8c247a22d0fd0535848e65640c0548bd1f8bbb36"
dependencies = [
"percent-encoding",
"time 0.2.16",
]
[[package]]
name = "copyless"
version = "0.1.5"
@ -794,9 +783,9 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
[[package]]
name = "cpuid-bool"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d375c433320f6c5057ae04a04376eef4d04ce2801448cf8863a78da99107be4"
checksum = "ec6763c20301ab0dc67051d1b6f4cc9132ad9e6eddcb1f10c6c53ea6d6ae2183"
[[package]]
name = "crc32fast"
@ -950,7 +939,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array 0.14.2",
"generic-array 0.14.3",
]
[[package]]
@ -1142,7 +1131,7 @@ dependencies = [
"cfg-if",
"crc32fast",
"libc",
"miniz_oxide 0.4.0",
"miniz_oxide",
]
[[package]]
@ -1292,19 +1281,6 @@ dependencies = [
"byteorder",
]
[[package]]
name = "generator"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68"
dependencies = [
"cc",
"libc",
"log",
"rustc_version",
"winapi 0.3.9",
]
[[package]]
name = "generic-array"
version = "0.12.3"
@ -1316,9 +1292,9 @@ dependencies = [
[[package]]
name = "generic-array"
version = "0.14.2"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980"
checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63"
dependencies = [
"typenum",
"version_check 0.9.2",
@ -1337,15 +1313,15 @@ dependencies = [
[[package]]
name = "gimli"
version = "0.21.0"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
[[package]]
name = "h2"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff"
checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
dependencies = [
"bytes",
"fnv",
@ -1354,10 +1330,10 @@ dependencies = [
"futures-util",
"http",
"indexmap",
"log",
"slab",
"tokio",
"tokio-util 0.3.1",
"tracing",
]
[[package]]
@ -1371,9 +1347,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.14"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909"
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
dependencies = [
"libc",
]
@ -1481,9 +1457,9 @@ dependencies = [
[[package]]
name = "instant"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69da7ce1490173c2bf4d26bc8be429aaeeaf4cce6c4b970b7949651fa17655fe"
checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
[[package]]
name = "iovec"
@ -1523,9 +1499,9 @@ checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]]
name = "js-sys"
version = "0.3.41"
version = "0.3.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916"
checksum = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
dependencies = [
"wasm-bindgen",
]
@ -1579,13 +1555,13 @@ dependencies = [
"sha2",
"strum",
"strum_macros",
"url",
]
[[package]]
name = "lemmy_server"
version = "0.0.1"
dependencies = [
"activitystreams",
"activitystreams-ext",
"activitystreams-new",
"actix",
@ -1693,9 +1669,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
[[package]]
name = "linked-hash-map"
@ -1724,33 +1700,22 @@ dependencies = [
[[package]]
name = "lock_api"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de302ce1fe7482db13738fbaf2e21cfb06a986b89c0bf38d88abf16681aada4e"
checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.8"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if",
]
[[package]]
name = "loom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
]
[[package]]
name = "lru-cache"
version = "0.1.2"
@ -1827,15 +1792,6 @@ dependencies = [
"unicase",
]
[[package]]
name = "miniz_oxide"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
dependencies = [
"adler32",
]
[[package]]
name = "miniz_oxide"
version = "0.4.0"
@ -2060,7 +2016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
dependencies = [
"instant",
"lock_api 0.4.0",
"lock_api 0.4.1",
"parking_lot_core 0.8.0",
]
@ -2150,7 +2106,7 @@ checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
"sha-1",
"sha-1 0.8.2",
]
[[package]]
@ -2187,9 +2143,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
[[package]]
name = "ppv-lite86"
@ -2434,9 +2390,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.1.56"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "regex"
@ -2559,12 +2515,6 @@ dependencies = [
"parking_lot 0.11.0",
]
[[package]]
name = "scoped-tls"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -2703,6 +2653,19 @@ dependencies = [
"opaque-debug 0.2.3",
]
[[package]]
name = "sha-1"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
"cpuid-bool",
"digest 0.9.0",
"opaque-debug 0.3.0",
]
[[package]]
name = "sha1"
version = "0.6.0"
@ -2734,9 +2697,9 @@ dependencies = [
[[package]]
name = "simple_asn1"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b25ecba7165254f0c97d6c22a64b1122a03634b18d20a34daf21e18f892e618"
checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b"
dependencies = [
"chrono",
"num-bigint",
@ -2751,9 +2714,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "smallvec"
version = "1.4.0"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f"
[[package]]
name = "socket2"
@ -2869,9 +2832,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.33"
version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd"
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
dependencies = [
"proc-macro2",
"quote",
@ -3076,6 +3039,26 @@ dependencies = [
"tokio",
]
[[package]]
name = "tracing"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2e2a2de6b0d5cbb13fc21193a2296888eaab62b6044479aafb3c54c01c29fcd"
dependencies = [
"cfg-if",
"log",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94ae75f0d28ae10786f3b1895c55fe72e79928fd5ccdebb5438c75e93fec178f"
dependencies = [
"lazy_static",
]
[[package]]
name = "trust-dns-proto"
version = "0.19.5"
@ -3132,17 +3115,6 @@ version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
[[package]]
name = "typed-builder"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85fc4459191c621a53ef6c6ca5642e6e0e5ccc61f3e5b8ad6b6ab5317f0200fb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "typenum"
version = "1.12.0"
@ -3251,18 +3223,19 @@ dependencies = [
[[package]]
name = "v_escape"
version = "0.7.4"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "660b101c07b5d0863deb9e7fb3138777e858d6d2a79f9e6049a27d1cc77c6da6"
checksum = "b66158ce426982197fd44266d68125fd4000f1d42f5ee33ef02b500b4b6b0024"
dependencies = [
"buf-min",
"v_escape_derive",
]
[[package]]
name = "v_escape_derive"
version = "0.5.6"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae"
checksum = "cae7cffca0b1f9af9b20610f6fdeee9ffcce61417b5ad186a5d482dc904e24cd"
dependencies = [
"nom 4.2.3",
"proc-macro2",
@ -3272,9 +3245,9 @@ dependencies = [
[[package]]
name = "v_htmlescape"
version = "0.4.5"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33e939c0d8cf047514fb6ba7d5aac78bc56677a6938b2ee67000b91f2e97e41"
checksum = "f5fd25529cb2f78527b5ee507bcfb357b26d057b5e480853c26d49a4ead5c629"
dependencies = [
"cfg-if",
"v_escape",
@ -3312,9 +3285,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasm-bindgen"
version = "0.2.64"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -3322,9 +3295,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.64"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
dependencies = [
"bumpalo",
"lazy_static",
@ -3337,9 +3310,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.64"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -3347,9 +3320,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.64"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
dependencies = [
"proc-macro2",
"quote",
@ -3360,15 +3333,15 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.64"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
[[package]]
name = "web-sys"
version = "0.3.41"
version = "0.3.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d"
checksum = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2"
dependencies = [
"js-sys",
"wasm-bindgen",

5
server/Cargo.toml vendored
View file

@ -18,9 +18,8 @@ lemmy_db = { path = "./lemmy_db" }
diesel = "1.4.4"
diesel_migrations = "1.4.0"
dotenv = "0.15.0"
activitystreams = "0.6.2"
activitystreams-new = { git = "https://git.asonix.dog/asonix/activitystreams-sketch" }
activitystreams-ext = { git = "https://git.asonix.dog/asonix/activitystreams-ext" }
activitystreams-new = { git = "https://git.asonix.dog/asonix/activitystreams-sketch", branch = "main" }
activitystreams-ext = { git = "https://git.asonix.dog/asonix/activitystreams-ext", branch = "main" }
bcrypt = "0.8.0"
chrono = { version = "0.4.7", features = ["serde"] }
serde_json = { version = "1.0.52", features = ["preserve_order"]}

View file

@ -12,4 +12,5 @@ strum = "0.18.0"
strum_macros = "0.18.0"
log = "0.4.0"
sha2 = "0.9"
bcrypt = "0.8.0"
bcrypt = "0.8.0"
url = { version = "2.1.1", features = ["serde"] }

View file

@ -1,5 +1,6 @@
use super::{post::Post, *};
use crate::schema::{comment, comment_like, comment_saved};
use url::{ParseError, Url};
// WITH RECURSIVE MyTree AS (
// SELECT * FROM comment WHERE parent_id IS NULL
@ -42,6 +43,12 @@ pub struct CommentForm {
pub local: bool,
}
impl CommentForm {
pub fn get_ap_id(&self) -> Result<Url, ParseError> {
Url::parse(&self.ap_id)
}
}
impl Crud<CommentForm> for Comment {
fn read(conn: &PgConnection, comment_id: i32) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;

View file

@ -8,6 +8,7 @@ use crate::{
};
use diesel::{dsl::*, result::Error, *};
use serde::{Deserialize, Serialize};
use url::{ParseError, Url};
#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
#[table_name = "post"]
@ -56,6 +57,12 @@ pub struct PostForm {
pub local: bool,
}
impl PostForm {
pub fn get_ap_id(&self) -> Result<Url, ParseError> {
Url::parse(&self.ap_id)
}
}
impl Post {
pub fn read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
use crate::schema::post::dsl::*;

View file

@ -6,41 +6,20 @@ use crate::{
request::retry_custom,
DbPool, LemmyError,
};
use activitystreams::{context, object::properties::ObjectProperties, public, Activity, Base};
use activitystreams_new::base::AnyBase;
use actix_web::client::Client;
use lemmy_db::{community::Community, user::User_};
use log::debug;
use serde::Serialize;
use std::fmt::Debug;
use url::Url;
pub fn populate_object_props(
props: &mut ObjectProperties,
addressed_ccs: Vec<String>,
object_id: &str,
) -> Result<(), LemmyError> {
props
.set_context_xsd_any_uri(context())?
// TODO: the activity needs a seperate id from the object
.set_id(object_id)?
// TODO: should to/cc go on the Create, or on the Post? or on both?
// TODO: handle privacy on the receiving side (at least ignore anything thats not public)
.set_to_xsd_any_uri(public())?
.set_many_cc_xsd_any_uris(addressed_ccs)?;
Ok(())
}
pub async fn send_activity_to_community<A>(
pub async fn send_activity_to_community(
creator: &User_,
community: &Community,
to: Vec<String>,
activity: A,
activity: AnyBase,
client: &Client,
pool: &DbPool,
) -> Result<(), LemmyError>
where
A: Activity + Base + Serialize + Debug + Clone + Send + 'static,
{
) -> Result<(), LemmyError> {
insert_activity(creator.id, activity.clone(), true, pool).await?;
// if this is a local community, we need to do an announce from the community instead
@ -54,15 +33,12 @@ where
}
/// Send an activity to a list of recipients, using the correct headers etc.
pub async fn send_activity<A>(
pub async fn send_activity(
client: &Client,
activity: &A,
activity: &AnyBase,
actor: &dyn ActorType,
to: Vec<String>,
) -> Result<(), LemmyError>
where
A: Serialize,
{
) -> Result<(), LemmyError> {
let activity = serde_json::to_string(&activity)?;
debug!("Sending activitypub activity {} to {:?}", activity, to);

View file

@ -19,7 +19,6 @@ use activitystreams_new::{
link::Mention,
object::{kind::NoteType, Note, Tombstone},
prelude::*,
primitives::XsdAnyUri,
public,
};
use actix_web::{body::Body, client::Client, web::Path, HttpResponse};
@ -35,7 +34,7 @@ use lemmy_utils::{convert_datetime, scrape_text_for_mentions, MentionData};
use log::debug;
use serde::Deserialize;
use serde_json::Error;
use std::str::FromStr;
use url::Url;
#[derive(Deserialize)]
pub struct CommentQuery {
@ -86,15 +85,15 @@ impl ToApub for Comment {
comment
// Not needed when the Post is embedded in a collection (like for community outbox)
.set_context(context())
.set_id(self.ap_id.parse::<XsdAnyUri>()?)
.set_published(convert_datetime(self.published).into())
.set_id(Url::parse(&self.ap_id)?)
.set_published(convert_datetime(self.published))
.set_to(community.actor_id)
.set_many_in_reply_tos(in_reply_to_vec)
.set_content(self.content.to_owned())
.set_attributed_to(creator.actor_id);
if let Some(u) = self.updated {
comment.set_updated(convert_datetime(u).into());
comment.set_updated(convert_datetime(u));
}
Ok(comment)
@ -105,7 +104,7 @@ impl ToApub for Comment {
self.deleted,
&self.ap_id,
self.updated,
NoteType.to_string(),
NoteType::Note.to_string(),
)
}
}
@ -119,6 +118,7 @@ impl FromApub for CommentForm {
note: &Note,
client: &Client,
pool: &DbPool,
actor_id: &Url,
) -> Result<CommentForm, LemmyError> {
let creator_actor_id = &note
.attributed_to()
@ -129,14 +129,14 @@ impl FromApub for CommentForm {
let creator = get_or_fetch_and_upsert_remote_user(creator_actor_id, client, pool).await?;
let mut in_reply_tos = note
.in_reply_to
.in_reply_to()
.as_ref()
.unwrap()
.as_many()
.unwrap()
.iter()
.map(|i| i.as_xsd_any_uri().unwrap());
let post_ap_id = in_reply_tos.next().unwrap().to_string();
let post_ap_id = in_reply_tos.next().unwrap();
// This post, or the parent comment might not yet exist on this server yet, fetch them.
let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?;
@ -145,7 +145,7 @@ impl FromApub for CommentForm {
// For deeply nested comments, FromApub automatically gets called recursively
let parent_id: Option<i32> = match in_reply_tos.next() {
Some(parent_comment_uri) => {
let parent_comment_ap_id = &parent_comment_uri.to_string();
let parent_comment_ap_id = &parent_comment_uri;
let parent_comment =
get_or_fetch_and_insert_remote_comment(&parent_comment_ap_id, client, pool).await?;
@ -166,12 +166,10 @@ impl FromApub for CommentForm {
.to_string(),
removed: None,
read: None,
published: note
.published()
.map(|u| u.as_ref().to_owned().naive_local()),
updated: note.updated().map(|u| u.as_ref().to_owned().naive_local()),
published: note.published().map(|u| u.to_owned().naive_local()),
updated: note.updated().map(|u| u.to_owned().naive_local()),
deleted: None,
ap_id: note.id().unwrap().to_string(),
ap_id: note.id(actor_id.domain().unwrap())?.unwrap().to_string(),
local: false,
})
}
@ -201,13 +199,21 @@ impl ApubObjectType for Comment {
let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?);
create
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(maa.addressed_ccs.to_owned())
// Set the mention tags
.set_many_tags(maa.get_tags()?);
send_activity_to_community(&creator, &community, maa.inboxes, create, client, pool).await?;
send_activity_to_community(
&creator,
&community,
maa.inboxes,
create.into_any_base()?,
client,
pool,
)
.await?;
Ok(())
}
@ -233,13 +239,21 @@ impl ApubObjectType for Comment {
let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?);
update
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(maa.addressed_ccs.to_owned())
// Set the mention tags
.set_many_tags(maa.get_tags()?);
send_activity_to_community(&creator, &community, maa.inboxes, update, client, pool).await?;
send_activity_to_community(
&creator,
&community,
maa.inboxes,
update.into_any_base()?,
client,
pool,
)
.await?;
Ok(())
}
@ -261,7 +275,7 @@ impl ApubObjectType for Comment {
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
delete
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -269,7 +283,7 @@ impl ApubObjectType for Comment {
&creator,
&community,
vec![community.get_shared_inbox_url()],
delete,
delete.into_any_base()?,
client,
pool,
)
@ -296,7 +310,7 @@ impl ApubObjectType for Comment {
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
delete
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -306,7 +320,7 @@ impl ApubObjectType for Comment {
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
undo
.set_context(context())
.set_id(XsdAnyUri::from_str(&undo_id)?)
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -314,7 +328,7 @@ impl ApubObjectType for Comment {
&creator,
&community,
vec![community.get_shared_inbox_url()],
undo,
undo.into_any_base()?,
client,
pool,
)
@ -340,7 +354,7 @@ impl ApubObjectType for Comment {
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
remove
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -348,7 +362,7 @@ impl ApubObjectType for Comment {
&mod_,
&community,
vec![community.get_shared_inbox_url()],
remove,
remove.into_any_base()?,
client,
pool,
)
@ -375,7 +389,7 @@ impl ApubObjectType for Comment {
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
remove
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -384,7 +398,7 @@ impl ApubObjectType for Comment {
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
undo
.set_context(context())
.set_id(XsdAnyUri::from_str(&undo_id)?)
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -392,7 +406,7 @@ impl ApubObjectType for Comment {
&mod_,
&community,
vec![community.get_shared_inbox_url()],
undo,
undo.into_any_base()?,
client,
pool,
)
@ -422,7 +436,7 @@ impl ApubLikeableType for Comment {
let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?);
like
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -430,7 +444,7 @@ impl ApubLikeableType for Comment {
&creator,
&community,
vec![community.get_shared_inbox_url()],
like,
like.into_any_base()?,
client,
pool,
)
@ -457,7 +471,7 @@ impl ApubLikeableType for Comment {
let mut dislike = Dislike::new(creator.actor_id.to_owned(), note.into_any_base()?);
dislike
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -465,7 +479,7 @@ impl ApubLikeableType for Comment {
&creator,
&community,
vec![community.get_shared_inbox_url()],
dislike,
dislike.into_any_base()?,
client,
pool,
)
@ -492,7 +506,7 @@ impl ApubLikeableType for Comment {
let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?);
like
.set_context(context())
.set_id(XsdAnyUri::from_str(&id)?)
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -502,7 +516,7 @@ impl ApubLikeableType for Comment {
let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?);
undo
.set_context(context())
.set_id(XsdAnyUri::from_str(&undo_id)?)
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
@ -510,7 +524,7 @@ impl ApubLikeableType for Comment {
&creator,
&community,
vec![community.get_shared_inbox_url()],
undo,
undo.into_any_base()?,
client,
pool,
)

View file

@ -1,29 +1,24 @@
use crate::{
apub::{
activities::{populate_object_props, send_activity},
create_apub_response, create_apub_tombstone_response, create_tombstone,
extensions::group_extensions::GroupExtension,
fetcher::get_or_fetch_and_upsert_remote_user,
get_shared_inbox, insert_activity, ActorType, FromApub, GroupExt, ToApub,
activities::send_activity, create_apub_response, create_apub_tombstone_response,
create_tombstone, extensions::group_extensions::GroupExtension,
fetcher::get_or_fetch_and_upsert_remote_user, get_shared_inbox, insert_activity, ActorType,
FromApub, GroupExt, ToApub,
},
blocking,
routes::DbPoolParam,
DbPool, LemmyError,
};
use activitystreams::{
activity::{Accept, Announce, Delete, Remove, Undo},
Activity, Base, BaseBox,
};
use activitystreams_ext::Ext2;
use activitystreams_new::{
activity::Follow,
activity::{Accept, Announce, Delete, Follow, Remove, Undo},
actor::{kind::GroupType, ApActor, Endpoints, Group},
base::BaseExt,
base::{AnyBase, BaseExt},
collection::UnorderedCollection,
context,
object::Tombstone,
prelude::*,
primitives::{XsdAnyUri, XsdDateTime},
public,
};
use actix_web::{body::Body, client::Client, web, HttpResponse};
use itertools::Itertools;
@ -34,8 +29,8 @@ use lemmy_db::{
user::User_,
};
use lemmy_utils::convert_datetime;
use serde::{Deserialize, Serialize};
use std::{fmt::Debug, str::FromStr};
use serde::Deserialize;
use url::Url;
#[derive(Deserialize)]
pub struct CommunityQuery {
@ -62,13 +57,13 @@ impl ToApub for Community {
let mut group = Group::new();
group
.set_context(context())
.set_id(XsdAnyUri::from_str(&self.actor_id)?)
.set_id(Url::parse(&self.actor_id)?)
.set_name(self.name.to_owned())
.set_published(XsdDateTime::from(convert_datetime(self.published)))
.set_published(convert_datetime(self.published))
.set_many_attributed_tos(moderators);
if let Some(u) = self.updated.to_owned() {
group.set_updated(XsdDateTime::from(convert_datetime(u)));
group.set_updated(convert_datetime(u));
}
if let Some(d) = self.description.to_owned() {
// TODO: this should be html, also add source field with raw markdown
@ -107,14 +102,14 @@ impl ToApub for Community {
self.deleted,
&self.actor_id,
self.updated,
GroupType.to_string(),
GroupType::Group.to_string(),
)
}
}
#[async_trait::async_trait(?Send)]
impl ActorType for Community {
fn actor_id(&self) -> String {
fn actor_id_str(&self) -> String {
self.actor_id.to_owned()
}
@ -128,27 +123,23 @@ impl ActorType for Community {
/// As a local community, accept the follow request from a remote user.
async fn send_accept_follow(
&self,
follow: &Follow,
follow: Follow,
client: &Client,
pool: &DbPool,
) -> Result<(), LemmyError> {
let actor_uri = follow.actor.as_single_xsd_any_uri().unwrap().to_string();
let actor_uri = follow.actor()?.as_single_xsd_any_uri().unwrap().to_string();
let id = format!("{}/accept/{}", self.actor_id, uuid::Uuid::new_v4());
let mut accept = Accept::new();
accept
.object_props
.set_context_xsd_any_uri(context())?
.set_id(id)?;
accept
.accept_props
.set_actor_xsd_any_uri(self.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(follow.clone())?)?;
let mut accept = Accept::new(self.actor_id.to_owned(), follow.into_any_base()?);
let to = format!("{}/inbox", actor_uri);
accept
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(to.clone());
insert_activity(self.creator_id, accept.clone(), true, pool).await?;
send_activity(client, &accept, self, vec![to]).await?;
send_activity(client, &accept.into_any_base()?, self, vec![to]).await?;
Ok(())
}
@ -162,17 +153,12 @@ impl ActorType for Community {
let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4());
let mut delete = Delete::default();
populate_object_props(
&mut delete.object_props,
vec![self.get_followers_url()],
&id,
)?;
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
delete
.delete_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(group)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![self.get_followers_url()]);
insert_activity(self.creator_id, delete.clone(), true, pool).await?;
@ -181,7 +167,7 @@ impl ActorType for Community {
// Note: For an accept, since it was automatic, no one pushed a button,
// the community was the actor.
// But for delete, the creator is the actor, and does the signing
send_activity(client, &delete, creator, inboxes).await?;
send_activity(client, &delete.into_any_base()?, creator, inboxes).await?;
Ok(())
}
@ -195,33 +181,22 @@ impl ActorType for Community {
let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4());
let mut delete = Delete::default();
populate_object_props(
&mut delete.object_props,
vec![self.get_followers_url()],
&id,
)?;
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
delete
.delete_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(group)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![self.get_followers_url()]);
// TODO
// Undo that fake activity
let undo_id = format!("{}/undo/delete/{}", self.actor_id, uuid::Uuid::new_v4());
let mut undo = Undo::default();
populate_object_props(
&mut undo.object_props,
vec![self.get_followers_url()],
&undo_id,
)?;
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
undo
.undo_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(delete)?;
.set_context(context())
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![self.get_followers_url()]);
insert_activity(self.creator_id, undo.clone(), true, pool).await?;
@ -230,7 +205,7 @@ impl ActorType for Community {
// Note: For an accept, since it was automatic, no one pushed a button,
// the community was the actor.
// But for delete, the creator is the actor, and does the signing
send_activity(client, &undo, creator, inboxes).await?;
send_activity(client, &undo.into_any_base()?, creator, inboxes).await?;
Ok(())
}
@ -244,17 +219,12 @@ impl ActorType for Community {
let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4());
let mut remove = Remove::default();
populate_object_props(
&mut remove.object_props,
vec![self.get_followers_url()],
&id,
)?;
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
remove
.remove_props
.set_actor_xsd_any_uri(mod_.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(group)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![self.get_followers_url()]);
insert_activity(mod_.id, remove.clone(), true, pool).await?;
@ -263,7 +233,7 @@ impl ActorType for Community {
// Note: For an accept, since it was automatic, no one pushed a button,
// the community was the actor.
// But for delete, the creator is the actor, and does the signing
send_activity(client, &remove, mod_, inboxes).await?;
send_activity(client, &remove.into_any_base()?, mod_, inboxes).await?;
Ok(())
}
@ -277,32 +247,21 @@ impl ActorType for Community {
let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4());
let mut remove = Remove::default();
populate_object_props(
&mut remove.object_props,
vec![self.get_followers_url()],
&id,
)?;
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
remove
.remove_props
.set_actor_xsd_any_uri(mod_.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(group)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![self.get_followers_url()]);
// Undo that fake activity
let undo_id = format!("{}/undo/remove/{}", self.actor_id, uuid::Uuid::new_v4());
let mut undo = Undo::default();
populate_object_props(
&mut undo.object_props,
vec![self.get_followers_url()],
&undo_id,
)?;
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
undo
.undo_props
.set_actor_xsd_any_uri(mod_.actor_id.to_owned())?
.set_object_base_box(remove)?;
.set_context(context())
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![self.get_followers_url()]);
insert_activity(mod_.id, undo.clone(), true, pool).await?;
@ -311,7 +270,7 @@ impl ActorType for Community {
// Note: For an accept, since it was automatic, no one pushed a button,
// the community was the actor.
// But for remove , the creator is the actor, and does the signing
send_activity(client, &undo, mod_, inboxes).await?;
send_activity(client, &undo.into_any_base()?, mod_, inboxes).await?;
Ok(())
}
@ -325,7 +284,7 @@ impl ActorType for Community {
.await??;
let inboxes = inboxes
.into_iter()
.map(|c| get_shared_inbox(&c.user_actor_id))
.map(|c| get_shared_inbox(&Url::parse(&c.user_actor_id).unwrap()))
.filter(|s| !s.is_empty())
.unique()
.collect();
@ -357,8 +316,13 @@ impl FromApub for CommunityForm {
type ApubType = GroupExt;
/// Parse an ActivityPub group received from another instance into a Lemmy community.
async fn from_apub(group: &GroupExt, client: &Client, pool: &DbPool) -> Result<Self, LemmyError> {
let creator_and_moderator_uris = group.attributed_to().unwrap();
async fn from_apub(
group: &GroupExt,
client: &Client,
pool: &DbPool,
actor_id: &Url,
) -> Result<Self, LemmyError> {
let creator_and_moderator_uris = group.inner.attributed_to().unwrap();
let creator_uri = creator_and_moderator_uris
.as_many()
.unwrap()
@ -371,23 +335,34 @@ impl FromApub for CommunityForm {
let creator = get_or_fetch_and_upsert_remote_user(creator_uri, client, pool).await?;
Ok(CommunityForm {
name: group.name().unwrap().as_single_xsd_string().unwrap().into(),
name: group
.inner
.name()
.unwrap()
.as_one()
.unwrap()
.as_xsd_string()
.unwrap()
.into(),
title: group.inner.preferred_username().unwrap().to_string(),
// TODO: should be parsed as html and tags like <script> removed (or use markdown source)
// -> same for post.content etc
description: group
.inner
.content()
.map(|s| s.as_single_xsd_string().unwrap().into()),
category_id: group.ext_one.category.identifier.parse::<i32>()?,
creator_id: creator.id,
removed: None,
published: group
.published()
.map(|u| u.as_ref().to_owned().naive_local()),
updated: group.updated().map(|u| u.as_ref().to_owned().naive_local()),
published: group.inner.published().map(|u| u.to_owned().naive_local()),
updated: group.inner.updated().map(|u| u.to_owned().naive_local()),
deleted: None,
nsfw: group.ext_one.sensitive,
actor_id: group.id().unwrap().to_string(),
actor_id: group
.inner
.id(actor_id.domain().unwrap())?
.unwrap()
.to_string(),
local: false,
private_key: None,
public_key: Some(group.ext_two.to_owned().public_key.public_key_pem),
@ -440,26 +415,20 @@ pub async fn get_apub_community_followers(
Ok(create_apub_response(&collection))
}
pub async fn do_announce<A>(
activity: A,
pub async fn do_announce(
activity: AnyBase,
community: &Community,
sender: &dyn ActorType,
client: &Client,
pool: &DbPool,
) -> Result<HttpResponse, LemmyError>
where
A: Activity + Base + Serialize + Debug,
{
let mut announce = Announce::default();
populate_object_props(
&mut announce.object_props,
vec![community.get_followers_url()],
&format!("{}/announce/{}", community.actor_id, uuid::Uuid::new_v4()),
)?;
) -> Result<HttpResponse, LemmyError> {
let id = format!("{}/announce/{}", community.actor_id, uuid::Uuid::new_v4());
let mut announce = Announce::new(community.actor_id.to_owned(), activity);
announce
.announce_props
.set_actor_xsd_any_uri(community.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(activity)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
insert_activity(community.creator_id, announce.clone(), true, pool).await?;
@ -470,7 +439,7 @@ where
// this seems to be the "easiest" stable alternative for remove_item()
to.retain(|x| *x != sender.get_shared_inbox_url());
send_activity(client, &announce, community, to).await?;
send_activity(client, &announce.into_any_base()?, community, to).await?;
Ok(HttpResponse::Ok().finish())
}

View file

@ -8,8 +8,10 @@ use crate::{
routes::{ChatServerParam, DbPoolParam},
LemmyError,
};
use activitystreams::activity::Undo;
use activitystreams_new::activity::Follow;
use activitystreams_new::{
activity::{Follow, Undo},
prelude::*,
};
use actix_web::{client::Client, web, HttpRequest, HttpResponse};
use lemmy_db::{
community::{Community, CommunityFollower, CommunityFollowerForm},
@ -31,14 +33,9 @@ impl CommunityAcceptedObjects {
fn follow(&self) -> Result<Follow, LemmyError> {
match self {
CommunityAcceptedObjects::Follow(f) => Ok(f.to_owned()),
CommunityAcceptedObjects::Undo(u) => Ok(
u.undo_props
.get_object_base_box()
.to_owned()
.unwrap()
.to_owned()
.into_concrete::<Follow>()?,
),
CommunityAcceptedObjects::Undo(u) => {
Ok(Follow::from_any_base(u.object().as_one().unwrap().to_owned())?.unwrap())
}
}
}
}
@ -71,11 +68,11 @@ pub async fn community_inbox(
&community.name, &input
);
let follow = input.follow()?;
let user_uri = follow.actor.as_single_xsd_any_uri().unwrap();
let community_uri = follow.object.as_single_xsd_any_uri().unwrap().to_string();
let user_uri = follow.actor()?.as_single_xsd_any_uri().unwrap();
let community_uri = follow.object().as_single_xsd_any_uri().unwrap();
let user = get_or_fetch_and_upsert_remote_user(&user_uri, &client, &db).await?;
let community = get_or_fetch_and_upsert_remote_community(&community_uri, &client, &db).await?;
let community = get_or_fetch_and_upsert_remote_community(community_uri, &client, &db).await?;
verify(&request, &user)?;
@ -107,7 +104,7 @@ async fn handle_follow(
})
.await?;
community.send_accept_follow(&follow, &client, &db).await?;
community.send_accept_follow(follow, &client, &db).await?;
Ok(HttpResponse::Ok().finish())
}

View file

@ -1,5 +1,6 @@
use crate::LemmyError;
use activitystreams::{ext::Extension, Actor};
use activitystreams_ext::UnparsedExtension;
use activitystreams_new::unparsed::UnparsedMutExt;
use diesel::PgConnection;
use lemmy_db::{category::Category, Crud};
use serde::{Deserialize, Serialize};
@ -37,4 +38,22 @@ impl GroupExtension {
}
}
impl<T> Extension<T> for GroupExtension where T: Actor {}
impl<U> UnparsedExtension<U> for GroupExtension
where
U: UnparsedMutExt,
{
type Error = serde_json::Error;
fn try_from_unparsed(unparsed_mut: &mut U) -> Result<Self, Self::Error> {
Ok(GroupExtension {
category: unparsed_mut.remove("category")?,
sensitive: unparsed_mut.remove("sensitive")?,
})
}
fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> {
unparsed_mut.insert("category", self.category)?;
unparsed_mut.insert("sensitive", self.sensitive)?;
Ok(())
}
}

View file

@ -1,4 +1,5 @@
use activitystreams::{ext::Extension, Base};
use activitystreams_ext::UnparsedExtension;
use activitystreams_new::unparsed::UnparsedMutExt;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
@ -8,4 +9,22 @@ pub struct PageExtension {
pub sensitive: bool,
}
impl<T> Extension<T> for PageExtension where T: Base {}
impl<U> UnparsedExtension<U> for PageExtension
where
U: UnparsedMutExt,
{
type Error = serde_json::Error;
fn try_from_unparsed(unparsed_mut: &mut U) -> Result<Self, Self::Error> {
Ok(PageExtension {
comments_enabled: unparsed_mut.remove("commentsEnabled")?,
sensitive: unparsed_mut.remove("sensitive")?,
})
}
fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> {
unparsed_mut.insert("commentsEnabled", self.comments_enabled)?;
unparsed_mut.insert("sensitive", self.sensitive)?;
Ok(())
}
}

View file

@ -1,5 +1,6 @@
use crate::{apub::ActorType, LemmyError};
use activitystreams::ext::Extension;
use activitystreams_ext::UnparsedExtension;
use activitystreams_new::unparsed::UnparsedMutExt;
use actix_web::{client::ClientRequest, HttpRequest};
use http_signature_normalization_actix::{
digest::{DigestClient, SignExt},
@ -24,7 +25,7 @@ pub async fn sign(
actor: &dyn ActorType,
activity: String,
) -> Result<DigestClient<String>, LemmyError> {
let signing_key_id = format!("{}#main-key", actor.actor_id());
let signing_key_id = format!("{}#main-key", actor.actor_id()?);
let private_key = actor.private_key();
let digest_client = request
@ -98,4 +99,20 @@ impl PublicKey {
}
}
impl<T> Extension<T> for PublicKeyExtension where T: activitystreams::Actor {}
impl<U> UnparsedExtension<U> for PublicKeyExtension
where
U: UnparsedMutExt,
{
type Error = serde_json::Error;
fn try_from_unparsed(unparsed_mut: &mut U) -> Result<Self, Self::Error> {
Ok(PublicKeyExtension {
public_key: unparsed_mut.remove("publicKey")?,
})
}
fn try_into_unparsed(self, unparsed_mut: &mut U) -> Result<(), Self::Error> {
unparsed_mut.insert("publicKey", self.public_key)?;
Ok(())
}
}

View file

@ -6,7 +6,7 @@ use crate::{
routes::nodeinfo::{NodeInfo, NodeInfoWellKnown},
DbPool, LemmyError,
};
use activitystreams_new::{base::BaseExt, object::Note, prelude::*, primitives::XsdAnyUri};
use activitystreams_new::{base::BaseExt, object::Note, prelude::*};
use actix_web::client::Client;
use chrono::NaiveDateTime;
use diesel::{result::Error::NotFound, PgConnection};
@ -133,9 +133,10 @@ pub async fn search_by_apub_id(
users: vec![],
};
let domain = query_url.domain().unwrap();
let response = match fetch_remote_object::<SearchAcceptedObjects>(client, &query_url).await? {
SearchAcceptedObjects::Person(p) => {
let user_uri = p.inner.id().unwrap();
let user_uri = p.inner.id(domain)?.unwrap();
let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?;
@ -144,10 +145,9 @@ pub async fn search_by_apub_id(
response
}
SearchAcceptedObjects::Group(g) => {
let community_uri = g.inner.id().unwrap().to_string();
let community_uri = g.inner.id(domain)?.unwrap();
let community =
get_or_fetch_and_upsert_remote_community(&community_uri, client, pool).await?;
let community = get_or_fetch_and_upsert_remote_community(community_uri, client, pool).await?;
// TODO Maybe at some point in the future, fetch all the history of a community
// fetch_community_outbox(&c, conn)?;
@ -161,7 +161,7 @@ pub async fn search_by_apub_id(
response
}
SearchAcceptedObjects::Page(p) => {
let post_form = PostForm::from_apub(&p, client, pool).await?;
let post_form = PostForm::from_apub(&p, client, pool, &query_url).await?;
let p = blocking(pool, move |conn| upsert_post(&post_form, conn)).await??;
response.posts = vec![blocking(pool, move |conn| PostView::read(conn, p.id, None)).await??];
@ -169,13 +169,13 @@ pub async fn search_by_apub_id(
response
}
SearchAcceptedObjects::Comment(c) => {
let post_url = c.in_reply_to.as_ref().unwrap().as_many().unwrap();
let post_url = c.in_reply_to().as_ref().unwrap().as_many().unwrap();
// TODO: also fetch parent comments if any
let x = post_url.first().unwrap().as_xsd_any_uri().unwrap();
let post = fetch_remote_object(client, x.as_url()).await?;
let post_form = PostForm::from_apub(&post, client, pool).await?;
let comment_form = CommentForm::from_apub(&c, client, pool).await?;
let post = fetch_remote_object(client, x).await?;
let post_form = PostForm::from_apub(&post, client, pool, &query_url).await?;
let comment_form = CommentForm::from_apub(&c, client, pool, &query_url).await?;
blocking(pool, move |conn| upsert_post(&post_form, conn)).await??;
let c = blocking(pool, move |conn| upsert_comment(&comment_form, conn)).await??;
@ -191,7 +191,7 @@ pub async fn search_by_apub_id(
/// Check if a remote user exists, create if not found, if its too old update it.Fetch a user, insert/update it in the database and return the user.
pub async fn get_or_fetch_and_upsert_remote_user(
apub_id: &XsdAnyUri,
apub_id: &Url,
client: &Client,
pool: &DbPool,
) -> Result<User_, LemmyError> {
@ -205,9 +205,9 @@ pub async fn get_or_fetch_and_upsert_remote_user(
// If its older than a day, re-fetch it
Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => {
debug!("Fetching and updating from remote user: {}", apub_id);
let person = fetch_remote_object::<PersonExt>(client, apub_id.as_url()).await?;
let person = fetch_remote_object::<PersonExt>(client, apub_id).await?;
let mut uf = UserForm::from_apub(&person, client, pool).await?;
let mut uf = UserForm::from_apub(&person, client, pool, apub_id).await?;
uf.last_refreshed_at = Some(naive_now());
let user = blocking(pool, move |conn| User_::update(conn, u.id, &uf)).await??;
@ -216,9 +216,9 @@ pub async fn get_or_fetch_and_upsert_remote_user(
Ok(u) => Ok(u),
Err(NotFound {}) => {
debug!("Fetching and creating remote user: {}", apub_id);
let person = fetch_remote_object::<PersonExt>(client, apub_id.as_url()).await?;
let person = fetch_remote_object::<PersonExt>(client, apub_id).await?;
let uf = UserForm::from_apub(&person, client, pool).await?;
let uf = UserForm::from_apub(&person, client, pool, apub_id).await?;
let user = blocking(pool, move |conn| User_::create(conn, &uf)).await??;
Ok(user)
@ -243,22 +243,22 @@ fn should_refetch_actor(last_refreshed: NaiveDateTime) -> bool {
/// Check if a remote community exists, create if not found, if its too old update it.Fetch a community, insert/update it in the database and return the community.
pub async fn get_or_fetch_and_upsert_remote_community(
apub_id: &str,
apub_id: &Url,
client: &Client,
pool: &DbPool,
) -> Result<Community, LemmyError> {
let apub_id_owned = apub_id.to_owned();
let community = blocking(pool, move |conn| {
Community::read_from_actor_id(conn, &apub_id_owned)
Community::read_from_actor_id(conn, apub_id_owned.as_str())
})
.await?;
match community {
Ok(c) if !c.local && should_refetch_actor(c.last_refreshed_at) => {
debug!("Fetching and updating from remote community: {}", apub_id);
let group = fetch_remote_object::<GroupExt>(client, &Url::parse(apub_id)?).await?;
let group = fetch_remote_object::<GroupExt>(client, apub_id).await?;
let mut cf = CommunityForm::from_apub(&group, client, pool).await?;
let mut cf = CommunityForm::from_apub(&group, client, pool, apub_id).await?;
cf.last_refreshed_at = Some(naive_now());
let community = blocking(pool, move |conn| Community::update(conn, c.id, &cf)).await??;
@ -267,14 +267,14 @@ pub async fn get_or_fetch_and_upsert_remote_community(
Ok(c) => Ok(c),
Err(NotFound {}) => {
debug!("Fetching and creating remote community: {}", apub_id);
let group = fetch_remote_object::<GroupExt>(client, &Url::parse(apub_id)?).await?;
let group = fetch_remote_object::<GroupExt>(client, apub_id).await?;
let cf = CommunityForm::from_apub(&group, client, pool).await?;
let cf = CommunityForm::from_apub(&group, client, pool, apub_id).await?;
let community = blocking(pool, move |conn| Community::create(conn, &cf)).await??;
// Also add the community moderators too
let attributed_to = group.inner.attributed_to().unwrap();
let creator_and_moderator_uris: Vec<&XsdAnyUri> = attributed_to
let creator_and_moderator_uris: Vec<&Url> = attributed_to
.as_many()
.unwrap()
.iter()
@ -319,13 +319,13 @@ fn upsert_post(post_form: &PostForm, conn: &PgConnection) -> Result<Post, LemmyE
}
pub async fn get_or_fetch_and_insert_remote_post(
post_ap_id: &str,
post_ap_id: &Url,
client: &Client,
pool: &DbPool,
) -> Result<Post, LemmyError> {
let post_ap_id_owned = post_ap_id.to_owned();
let post = blocking(pool, move |conn| {
Post::read_from_apub_id(conn, &post_ap_id_owned)
Post::read_from_apub_id(conn, post_ap_id_owned.as_str())
})
.await?;
@ -333,8 +333,8 @@ pub async fn get_or_fetch_and_insert_remote_post(
Ok(p) => Ok(p),
Err(NotFound {}) => {
debug!("Fetching and creating remote post: {}", post_ap_id);
let post = fetch_remote_object::<PageExt>(client, &Url::parse(post_ap_id)?).await?;
let post_form = PostForm::from_apub(&post, client, pool).await?;
let post = fetch_remote_object::<PageExt>(client, post_ap_id).await?;
let post_form = PostForm::from_apub(&post, client, pool, post_ap_id).await?;
let post = blocking(pool, move |conn| Post::create(conn, &post_form)).await??;
@ -354,13 +354,13 @@ fn upsert_comment(comment_form: &CommentForm, conn: &PgConnection) -> Result<Com
}
pub async fn get_or_fetch_and_insert_remote_comment(
comment_ap_id: &str,
comment_ap_id: &Url,
client: &Client,
pool: &DbPool,
) -> Result<Comment, LemmyError> {
let comment_ap_id_owned = comment_ap_id.to_owned();
let comment = blocking(pool, move |conn| {
Comment::read_from_apub_id(conn, &comment_ap_id_owned)
Comment::read_from_apub_id(conn, comment_ap_id_owned.as_str())
})
.await?;
@ -371,8 +371,8 @@ pub async fn get_or_fetch_and_insert_remote_comment(
"Fetching and creating remote comment and its parents: {}",
comment_ap_id
);
let comment = fetch_remote_object::<Note>(client, &Url::parse(comment_ap_id)?).await?;
let comment_form = CommentForm::from_apub(&comment, client, pool).await?;
let comment = fetch_remote_object::<Note>(client, comment_ap_id).await?;
let comment_form = CommentForm::from_apub(&comment, client, pool, comment_ap_id).await?;
let comment = blocking(pool, move |conn| Comment::create(conn, &comment_form)).await??;

View file

@ -27,7 +27,6 @@ use activitystreams_new::{
actor::{ApActor, Group, Person},
object::{Page, Tombstone},
prelude::*,
primitives::XsdAnyUri,
};
use actix_web::{body::Body, client::Client, HttpResponse};
use chrono::NaiveDateTime;
@ -36,8 +35,7 @@ use lemmy_db::{activity::do_insert_activity, user::User_};
use lemmy_utils::{convert_datetime, get_apub_protocol_string, settings::Settings, MentionData};
use log::debug;
use serde::Serialize;
use std::str::FromStr;
use url::Url;
use url::{ParseError, Url};
type GroupExt = Ext2<ApActor<Group>, GroupExtension, PublicKeyExtension>;
type PersonExt = Ext1<ApActor<Person>, PublicKeyExtension>;
@ -115,7 +113,7 @@ fn create_tombstone(
let mut tombstone = Tombstone::new();
tombstone.set_id(object_id.parse()?);
tombstone.set_former_type(former_type);
tombstone.set_deleted(convert_datetime(updated).into());
tombstone.set_deleted(convert_datetime(updated));
Ok(tombstone)
} else {
Err(format_err!("Cant convert to tombstone because updated time was None.").into())
@ -132,6 +130,7 @@ pub trait FromApub {
apub: &Self::ApubType,
client: &Client,
pool: &DbPool,
actor_id: &Url,
) -> Result<Self, LemmyError>
where
Self: Sized;
@ -199,13 +198,12 @@ pub trait ApubLikeableType {
) -> Result<(), LemmyError>;
}
pub fn get_shared_inbox(actor_id: &str) -> String {
let url = Url::parse(actor_id).unwrap();
pub fn get_shared_inbox(actor_id: &Url) -> String {
format!(
"{}://{}{}/inbox",
&url.scheme(),
&url.host_str().unwrap(),
if let Some(port) = url.port() {
&actor_id.scheme(),
&actor_id.host_str().unwrap(),
if let Some(port) = actor_id.port() {
format!(":{}", port)
} else {
"".to_string()
@ -215,7 +213,7 @@ pub fn get_shared_inbox(actor_id: &str) -> String {
#[async_trait::async_trait(?Send)]
pub trait ActorType {
fn actor_id(&self) -> String;
fn actor_id_str(&self) -> String;
fn public_key(&self) -> String;
fn private_key(&self) -> String;
@ -239,7 +237,7 @@ pub trait ActorType {
#[allow(unused_variables)]
async fn send_accept_follow(
&self,
follow: &Follow,
follow: Follow,
client: &Client,
pool: &DbPool,
) -> Result<(), LemmyError>;
@ -273,35 +271,40 @@ pub trait ActorType {
/// For a given community, returns the inboxes of all followers.
async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<String>, LemmyError>;
// TODO move these to the db rows
fn get_inbox_url(&self) -> String {
format!("{}/inbox", &self.actor_id())
fn actor_id(&self) -> Result<Url, ParseError> {
Url::parse(&self.actor_id_str())
}
// TODO move these to the db rows
fn get_inbox_url(&self) -> String {
format!("{}/inbox", &self.actor_id_str())
}
// TODO: make this return `Result<Url, ParseError>
fn get_shared_inbox_url(&self) -> String {
get_shared_inbox(&self.actor_id())
get_shared_inbox(&self.actor_id().unwrap())
}
fn get_outbox_url(&self) -> String {
format!("{}/outbox", &self.actor_id())
format!("{}/outbox", &self.actor_id_str())
}
fn get_followers_url(&self) -> String {
format!("{}/followers", &self.actor_id())
format!("{}/followers", &self.actor_id_str())
}
fn get_following_url(&self) -> String {
format!("{}/following", &self.actor_id())
format!("{}/following", &self.actor_id_str())
}
fn get_liked_url(&self) -> String {
format!("{}/liked", &self.actor_id())
format!("{}/liked", &self.actor_id_str())
}
fn get_public_key_ext(&self) -> PublicKeyExtension {
PublicKey {
id: format!("{}#main-key", self.actor_id()),
owner: self.actor_id(),
id: format!("{}#main-key", self.actor_id_str()),
owner: self.actor_id_str(),
public_key_pem: self.public_key(),
}
.to_ext()
@ -311,7 +314,7 @@ pub trait ActorType {
pub async fn fetch_webfinger_url(
mention: &MentionData,
client: &Client,
) -> Result<XsdAnyUri, LemmyError> {
) -> Result<Url, LemmyError> {
let fetch_url = format!(
"{}://{}/.well-known/webfinger?resource=acct:{}@{}",
get_apub_protocol_string(),
@ -336,7 +339,7 @@ pub async fn fetch_webfinger_url(
link
.href
.to_owned()
.map(|u| XsdAnyUri::from_str(&u))
.map(|u| Url::parse(&u))
.transpose()?
.ok_or_else(|| format_err!("No href found.").into())
}

View file

@ -1,6 +1,6 @@
use crate::{
apub::{
activities::{populate_object_props, send_activity_to_community},
activities::send_activity_to_community,
create_apub_response, create_apub_tombstone_response, create_tombstone,
extensions::page_extension::PageExtension,
fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user},
@ -10,16 +10,13 @@ use crate::{
routes::DbPoolParam,
DbPool, LemmyError,
};
use activitystreams::{
activity::{Create, Delete, Dislike, Like, Remove, Undo, Update},
BaseBox,
};
use activitystreams_ext::Ext1;
use activitystreams_new::{
activity::{Create, Delete, Dislike, Like, Remove, Undo, Update},
context,
object::{kind::PageType, Image, Page, Tombstone},
prelude::*,
primitives::{XsdAnyUri, XsdDateTime},
public,
};
use actix_web::{body::Body, client::Client, web, HttpResponse};
use lemmy_db::{
@ -30,6 +27,7 @@ use lemmy_db::{
};
use lemmy_utils::{convert_datetime, get_apub_protocol_string, settings::Settings};
use serde::Deserialize;
use url::Url;
#[derive(Deserialize)]
pub struct PostQuery {
@ -70,11 +68,11 @@ impl ToApub for Post {
// TODO: need to set proper context defining sensitive/commentsEnabled fields
// https://git.asonix.dog/Aardwolf/activitystreams/issues/5
.set_context(context())
.set_id(self.ap_id.parse::<XsdAnyUri>()?)
.set_id(self.ap_id.parse::<Url>()?)
// Use summary field to be consistent with mastodon content warning.
// https://mastodon.xyz/@Louisa/103987265222901387.json
.set_summary(self.name.to_owned())
.set_published(convert_datetime(self.published).into())
.set_published(convert_datetime(self.published))
.set_to(community.actor_id)
.set_attributed_to(creator.actor_id);
@ -121,7 +119,7 @@ impl ToApub for Post {
}
if let Some(u) = self.updated {
page.set_updated(XsdDateTime::from(convert_datetime(u)));
page.set_updated(convert_datetime(u));
}
let ext = PageExtension {
@ -136,7 +134,7 @@ impl ToApub for Post {
self.deleted,
&self.ap_id,
self.updated,
PageType.to_string(),
PageType::Page.to_string(),
)
}
}
@ -150,11 +148,12 @@ impl FromApub for PostForm {
page: &PageExt,
client: &Client,
pool: &DbPool,
actor_id: &Url,
) -> Result<PostForm, LemmyError> {
let ext = &page.ext_one;
let creator_actor_id = page
.inner
.attributed_to
.attributed_to()
.as_ref()
.unwrap()
.as_single_xsd_any_uri()
@ -164,20 +163,19 @@ impl FromApub for PostForm {
let community_actor_id = page
.inner
.to
.to()
.as_ref()
.unwrap()
.as_single_xsd_any_uri()
.unwrap()
.as_str();
.unwrap();
let community =
get_or_fetch_and_upsert_remote_community(community_actor_id, client, pool).await?;
let thumbnail_url = match &page.inner.image {
let thumbnail_url = match &page.inner.image() {
Some(any_image) => Image::from_any_base(any_image.to_owned().as_one().unwrap().to_owned())?
.unwrap()
.url
.url()
.unwrap()
.as_single_xsd_any_uri()
.map(|u| u.to_string()),
@ -186,10 +184,10 @@ impl FromApub for PostForm {
let (embed_title, embed_description, embed_html) = match page.inner.preview() {
Some(preview) => {
let preview_page = Page::from_any_base(preview.as_one().unwrap().to_owned())?.unwrap();
let preview_page = Page::from_any_base(preview.one().unwrap().to_owned())?.unwrap();
let name = preview_page
.name()
.map(|n| n.as_single_xsd_string().unwrap().to_string());
.map(|n| n.as_one().unwrap().as_xsd_string().unwrap().to_string());
let summary = preview_page
.summary()
.map(|s| s.as_single_xsd_string().unwrap().to_string());
@ -203,18 +201,18 @@ impl FromApub for PostForm {
let url = page
.inner
.url
.url()
.as_ref()
.map(|u| u.as_single_xsd_string().unwrap().to_string());
let body = page
.inner
.content
.content()
.as_ref()
.map(|c| c.as_single_xsd_string().unwrap().to_string());
Ok(PostForm {
name: page
.inner
.summary
.summary()
.as_ref()
.unwrap()
.as_single_xsd_string()
@ -228,14 +226,14 @@ impl FromApub for PostForm {
locked: Some(!ext.comments_enabled),
published: page
.inner
.published
.published()
.as_ref()
.map(|u| u.as_ref().to_owned().naive_local()),
.map(|u| u.to_owned().naive_local()),
updated: page
.inner
.updated
.updated()
.as_ref()
.map(|u| u.as_ref().to_owned().naive_local()),
.map(|u| u.to_owned().naive_local()),
deleted: None,
nsfw: ext.sensitive,
stickied: None, // -> put it in "featured" collection of the community
@ -243,7 +241,11 @@ impl FromApub for PostForm {
embed_description,
embed_html,
thumbnail_url,
ap_id: page.inner.id().unwrap().to_string(),
ap_id: page
.inner
.id(actor_id.domain().unwrap())?
.unwrap()
.to_string(),
local: false,
})
}
@ -265,22 +267,18 @@ impl ApubObjectType for Post {
let id = format!("{}/create/{}", self.ap_id, uuid::Uuid::new_v4());
let mut create = Create::new();
populate_object_props(
&mut create.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut create = Create::new(creator.actor_id.to_owned(), page.into_any_base()?);
create
.create_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
creator,
&community,
vec![community.get_shared_inbox_url()],
create,
create.into_any_base()?,
client,
pool,
)
@ -302,22 +300,18 @@ impl ApubObjectType for Post {
let id = format!("{}/update/{}", self.ap_id, uuid::Uuid::new_v4());
let mut update = Update::new();
populate_object_props(
&mut update.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut update = Update::new(creator.actor_id.to_owned(), page.into_any_base()?);
update
.update_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
creator,
&community,
vec![community.get_shared_inbox_url()],
update,
update.into_any_base()?,
client,
pool,
)
@ -337,24 +331,18 @@ impl ApubObjectType for Post {
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4());
let mut delete = Delete::default();
populate_object_props(
&mut delete.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
delete
.delete_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
creator,
&community,
vec![community.get_shared_inbox_url()],
delete,
delete.into_any_base()?,
client,
pool,
)
@ -374,40 +362,28 @@ impl ApubObjectType for Post {
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
let id = format!("{}/delete/{}", self.ap_id, uuid::Uuid::new_v4());
let mut delete = Delete::default();
populate_object_props(
&mut delete.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
delete
.delete_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
// TODO
// Undo that fake activity
let undo_id = format!("{}/undo/delete/{}", self.ap_id, uuid::Uuid::new_v4());
let mut undo = Undo::default();
populate_object_props(
&mut undo.object_props,
vec![community.get_followers_url()],
&undo_id,
)?;
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
undo
.undo_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(delete)?;
.set_context(context())
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
creator,
&community,
vec![community.get_shared_inbox_url()],
undo,
undo.into_any_base()?,
client,
pool,
)
@ -427,24 +403,18 @@ impl ApubObjectType for Post {
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
let id = format!("{}/remove/{}", self.ap_id, uuid::Uuid::new_v4());
let mut remove = Remove::default();
populate_object_props(
&mut remove.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
remove
.remove_props
.set_actor_xsd_any_uri(mod_.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
mod_,
&community,
vec![community.get_shared_inbox_url()],
remove,
remove.into_any_base()?,
client,
pool,
)
@ -464,39 +434,27 @@ impl ApubObjectType for Post {
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
let id = format!("{}/remove/{}", self.ap_id, uuid::Uuid::new_v4());
let mut remove = Remove::default();
populate_object_props(
&mut remove.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
remove
.remove_props
.set_actor_xsd_any_uri(mod_.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
// Undo that fake activity
let undo_id = format!("{}/undo/remove/{}", self.ap_id, uuid::Uuid::new_v4());
let mut undo = Undo::default();
populate_object_props(
&mut undo.object_props,
vec![community.get_followers_url()],
&undo_id,
)?;
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
undo
.undo_props
.set_actor_xsd_any_uri(mod_.actor_id.to_owned())?
.set_object_base_box(remove)?;
.set_context(context())
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
mod_,
&community,
vec![community.get_shared_inbox_url()],
undo,
undo.into_any_base()?,
client,
pool,
)
@ -520,22 +478,18 @@ impl ApubLikeableType for Post {
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
let mut like = Like::new();
populate_object_props(
&mut like.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?);
like
.like_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
&creator,
&community,
vec![community.get_shared_inbox_url()],
like,
like.into_any_base()?,
client,
pool,
)
@ -556,22 +510,18 @@ impl ApubLikeableType for Post {
let id = format!("{}/dislike/{}", self.ap_id, uuid::Uuid::new_v4());
let mut dislike = Dislike::new();
populate_object_props(
&mut dislike.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut dislike = Dislike::new(creator.actor_id.to_owned(), page.into_any_base()?);
dislike
.dislike_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
&creator,
&community,
vec![community.get_shared_inbox_url()],
dislike,
dislike.into_any_base()?,
client,
pool,
)
@ -592,38 +542,28 @@ impl ApubLikeableType for Post {
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
let mut like = Like::new();
populate_object_props(
&mut like.object_props,
vec![community.get_followers_url()],
&id,
)?;
let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?);
like
.like_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(BaseBox::from_concrete(page)?)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
// TODO
// Undo that fake activity
let undo_id = format!("{}/undo/like/{}", self.ap_id, uuid::Uuid::new_v4());
let mut undo = Undo::default();
populate_object_props(
&mut undo.object_props,
vec![community.get_followers_url()],
&undo_id,
)?;
let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?);
undo
.undo_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(like)?;
.set_context(context())
.set_id(Url::parse(&undo_id)?)
.set_to(public())
.set_many_ccs(vec![community.get_followers_url()]);
send_activity_to_community(
&creator,
&community,
vec![community.get_shared_inbox_url()],
undo,
undo.into_any_base()?,
client,
pool,
)

View file

@ -5,12 +5,12 @@ use crate::{
},
blocking, DbPool, LemmyError,
};
use activitystreams::{
use activitystreams_new::{
activity::{Create, Delete, Undo, Update},
context,
object::{kind::NoteType, properties::ObjectProperties, Note},
object::{kind::NoteType, Note, Tombstone},
prelude::*,
};
use activitystreams_new::object::Tombstone;
use actix_web::client::Client;
use lemmy_db::{
private_message::{PrivateMessage, PrivateMessageForm},
@ -18,14 +18,14 @@ use lemmy_db::{
Crud,
};
use lemmy_utils::convert_datetime;
use url::Url;
#[async_trait::async_trait(?Send)]
impl ToApub for PrivateMessage {
type Response = Note;
async fn to_apub(&self, pool: &DbPool) -> Result<Note, LemmyError> {
let mut private_message = Note::default();
let oprops: &mut ObjectProperties = private_message.as_mut();
let mut private_message = Note::new();
let creator_id = self.creator_id;
let creator = blocking(pool, move |conn| User_::read(conn, creator_id)).await??;
@ -33,16 +33,16 @@ impl ToApub for PrivateMessage {
let recipient_id = self.recipient_id;
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
oprops
.set_context_xsd_any_uri(context())?
.set_id(self.ap_id.to_owned())?
.set_published(convert_datetime(self.published))?
.set_content_xsd_string(self.content.to_owned())?
.set_to_xsd_any_uri(recipient.actor_id)?
.set_attributed_to_xsd_any_uri(creator.actor_id)?;
private_message
.set_context(context())
.set_id(Url::parse(&self.ap_id.to_owned())?)
.set_published(convert_datetime(self.published))
.set_content(self.content.to_owned())
.set_to(recipient.actor_id)
.set_attributed_to(creator.actor_id);
if let Some(u) = self.updated {
oprops.set_updated(convert_datetime(u))?;
private_message.set_updated(convert_datetime(u));
}
Ok(private_message)
@ -53,7 +53,7 @@ impl ToApub for PrivateMessage {
self.deleted,
&self.ap_id,
self.updated,
NoteType.to_string(),
NoteType::Note.to_string(),
)
}
}
@ -67,32 +67,35 @@ impl FromApub for PrivateMessageForm {
note: &Note,
client: &Client,
pool: &DbPool,
actor_id: &Url,
) -> Result<PrivateMessageForm, LemmyError> {
let oprops = &note.object_props;
let creator_actor_id = &oprops.get_attributed_to_xsd_any_uri().unwrap();
let creator_actor_id = note
.attributed_to()
.unwrap()
.clone()
.single_xsd_any_uri()
.unwrap();
let creator = get_or_fetch_and_upsert_remote_user(&creator_actor_id, client, pool).await?;
let recipient_actor_id = &oprops.get_to_xsd_any_uri().unwrap();
let recipient_actor_id = note.to().unwrap().clone().single_xsd_any_uri().unwrap();
let recipient = get_or_fetch_and_upsert_remote_user(&recipient_actor_id, client, pool).await?;
Ok(PrivateMessageForm {
creator_id: creator.id,
recipient_id: recipient.id,
content: oprops
.get_content_xsd_string()
.map(|c| c.to_string())
.unwrap(),
published: oprops
.get_published()
.map(|u| u.as_ref().to_owned().naive_local()),
updated: oprops
.get_updated()
.map(|u| u.as_ref().to_owned().naive_local()),
content: note
.content()
.unwrap()
.as_single_xsd_string()
.unwrap()
.to_string(),
published: note.published().map(|u| u.to_owned().naive_local()),
updated: note.updated().map(|u| u.to_owned().naive_local()),
deleted: None,
read: None,
ap_id: oprops.get_id().unwrap().to_string(),
ap_id: note.id(actor_id.domain().unwrap())?.unwrap().to_string(),
local: false,
})
}
@ -113,21 +116,16 @@ impl ApubObjectType for PrivateMessage {
let recipient_id = self.recipient_id;
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
let mut create = Create::new();
create
.object_props
.set_context_xsd_any_uri(context())?
.set_id(id)?;
let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?);
let to = format!("{}/inbox", recipient.actor_id);
create
.create_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(note)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(to.clone());
insert_activity(creator.id, create.clone(), true, pool).await?;
send_activity(client, &create, creator, vec![to]).await?;
send_activity(client, &create.into_any_base()?, creator, vec![to]).await?;
Ok(())
}
@ -144,21 +142,16 @@ impl ApubObjectType for PrivateMessage {
let recipient_id = self.recipient_id;
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
let mut update = Update::new();
update
.object_props
.set_context_xsd_any_uri(context())?
.set_id(id)?;
let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?);
let to = format!("{}/inbox", recipient.actor_id);
update
.update_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(note)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(to.clone());
insert_activity(creator.id, update.clone(), true, pool).await?;
send_activity(client, &update, creator, vec![to]).await?;
send_activity(client, &update.into_any_base()?, creator, vec![to]).await?;
Ok(())
}
@ -174,21 +167,16 @@ impl ApubObjectType for PrivateMessage {
let recipient_id = self.recipient_id;
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
let mut delete = Delete::new();
delete
.object_props
.set_context_xsd_any_uri(context())?
.set_id(id)?;
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
let to = format!("{}/inbox", recipient.actor_id);
delete
.delete_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(note)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(to.clone());
insert_activity(creator.id, delete.clone(), true, pool).await?;
send_activity(client, &delete, creator, vec![to]).await?;
send_activity(client, &delete.into_any_base()?, creator, vec![to]).await?;
Ok(())
}
@ -204,36 +192,25 @@ impl ApubObjectType for PrivateMessage {
let recipient_id = self.recipient_id;
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
let mut delete = Delete::new();
delete
.object_props
.set_context_xsd_any_uri(context())?
.set_id(id)?;
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
let to = format!("{}/inbox", recipient.actor_id);
delete
.delete_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(note)?;
.set_context(context())
.set_id(Url::parse(&id)?)
.set_to(to.clone());
// TODO
// Undo that fake activity
let undo_id = format!("{}/undo/delete/{}", self.ap_id, uuid::Uuid::new_v4());
let mut undo = Undo::default();
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
undo
.object_props
.set_context_xsd_any_uri(context())?
.set_id(undo_id)?;
undo
.undo_props
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
.set_object_base_box(delete)?;
.set_context(context())
.set_id(Url::parse(&undo_id)?)
.set_to(to.clone());
insert_activity(creator.id, undo.clone(), true, pool).await?;
send_activity(client, &undo, creator, vec![to]).await?;
send_activity(client, &undo.into_any_base()?, creator, vec![to]).await?;
Ok(())
}

File diff suppressed because it is too large Load diff

View file

@ -15,16 +15,15 @@ use activitystreams_new::{
context,
object::{Image, Tombstone},
prelude::*,
primitives::{XsdAnyUri, XsdDateTime},
};
use actix_web::{body::Body, client::Client, web, HttpResponse};
use failure::_core::str::FromStr;
use lemmy_db::{
naive_now,
user::{UserForm, User_},
};
use lemmy_utils::convert_datetime;
use serde::Deserialize;
use url::Url;
#[derive(Deserialize)]
pub struct UserQuery {
@ -41,12 +40,12 @@ impl ToApub for User_ {
let mut person = Person::new();
person
.set_context(context())
.set_id(XsdAnyUri::from_str(&self.actor_id)?)
.set_id(Url::parse(&self.actor_id)?)
.set_name(self.name.to_owned())
.set_published(XsdDateTime::from(convert_datetime(self.published)));
.set_published(convert_datetime(self.published));
if let Some(u) = self.updated {
person.set_updated(XsdDateTime::from(convert_datetime(u)));
person.set_updated(convert_datetime(u));
}
if let Some(avatar_url) = &self.avatar {
@ -79,7 +78,7 @@ impl ToApub for User_ {
#[async_trait::async_trait(?Send)]
impl ActorType for User_ {
fn actor_id(&self) -> String {
fn actor_id_str(&self) -> String {
self.actor_id.to_owned()
}
@ -105,7 +104,7 @@ impl ActorType for User_ {
insert_activity(self.id, follow.clone(), true, pool).await?;
send_activity(client, &follow, self, vec![to]).await?;
send_activity(client, &follow.into_any_base()?, self, vec![to]).await?;
Ok(())
}
@ -124,12 +123,12 @@ impl ActorType for User_ {
// TODO
// Undo that fake activity
let undo_id = format!("{}/undo/follow/{}", self.actor_id, uuid::Uuid::new_v4());
let mut undo = Undo::new(self.actor_id.parse::<XsdAnyUri>()?, follow.into_any_base()?);
let mut undo = Undo::new(Url::parse(&self.actor_id)?, follow.into_any_base()?);
undo.set_context(context()).set_id(undo_id.parse()?);
insert_activity(self.id, undo.clone(), true, pool).await?;
send_activity(client, &undo, self, vec![to]).await?;
send_activity(client, &undo.into_any_base()?, self, vec![to]).await?;
Ok(())
}
@ -171,7 +170,7 @@ impl ActorType for User_ {
async fn send_accept_follow(
&self,
_follow: &Follow,
_follow: Follow,
_client: &Client,
_pool: &DbPool,
) -> Result<(), LemmyError> {
@ -187,12 +186,17 @@ impl ActorType for User_ {
impl FromApub for UserForm {
type ApubType = PersonExt;
/// Parse an ActivityPub person received from another instance into a Lemmy user.
async fn from_apub(person: &PersonExt, _: &Client, _: &DbPool) -> Result<Self, LemmyError> {
async fn from_apub(
person: &PersonExt,
_: &Client,
_: &DbPool,
actor_id: &Url,
) -> Result<Self, LemmyError> {
let avatar = match person.icon() {
Some(any_image) => Image::from_any_base(any_image.as_one().unwrap().clone())
.unwrap()
.unwrap()
.url
.url()
.unwrap()
.as_single_xsd_any_uri()
.map(|u| u.to_string()),
@ -203,18 +207,18 @@ impl FromApub for UserForm {
name: person
.name()
.unwrap()
.as_single_xsd_string()
.one()
.unwrap()
.into(),
.as_xsd_string()
.unwrap()
.to_string(),
preferred_username: person.inner.preferred_username().map(|u| u.to_string()),
password_encrypted: "".to_string(),
admin: false,
banned: false,
email: None,
avatar,
updated: person
.updated()
.map(|u| u.as_ref().to_owned().naive_local()),
updated: person.updated().map(|u| u.to_owned().naive_local()),
show_nsfw: false,
theme: "".to_string(),
default_sort_type: 0,
@ -223,8 +227,9 @@ impl FromApub for UserForm {
show_avatars: false,
send_notifications_to_email: false,
matrix_user_id: None,
actor_id: person.id().unwrap().to_string(),
actor_id: person.id(actor_id.domain().unwrap())?.unwrap().to_string(),
bio: person
.inner
.summary()
.map(|s| s.as_single_xsd_string().unwrap().into()),
local: false,

View file

@ -10,9 +10,10 @@ use crate::{
websocket::{server::SendUserRoomMessage, UserOperation},
DbPool, LemmyError,
};
use activitystreams::{
use activitystreams_new::{
activity::{Accept, Create, Delete, Undo, Update},
object::Note,
prelude::*,
};
use actix_web::{client::Client, web, HttpRequest, HttpResponse};
use lemmy_db::{
@ -76,11 +77,7 @@ async fn receive_accept(
client: &Client,
pool: &DbPool,
) -> Result<HttpResponse, LemmyError> {
let community_uri = accept
.accept_props
.get_actor_xsd_any_uri()
.unwrap()
.to_string();
let community_uri = accept.actor()?.to_owned().single_xsd_any_uri().unwrap();
let community = get_or_fetch_and_upsert_remote_community(&community_uri, client, pool).await?;
verify(request, &community)?;
@ -113,22 +110,15 @@ async fn receive_create_private_message(
pool: &DbPool,
chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> {
let note = create
.create_props
.get_object_base_box()
.to_owned()
.unwrap()
.to_owned()
.into_concrete::<Note>()?;
let user_uri = &create.actor()?.to_owned().single_xsd_any_uri().unwrap();
let note = Note::from_any_base(create.object().as_one().unwrap().to_owned())?.unwrap();
let user_uri = create.create_props.get_actor_xsd_any_uri().unwrap();
let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?;
let user = get_or_fetch_and_upsert_remote_user(user_uri, client, pool).await?;
verify(request, &user)?;
insert_activity(user.id, create, false, pool).await?;
let private_message = PrivateMessageForm::from_apub(&note, client, pool).await?;
let private_message = PrivateMessageForm::from_apub(&note, client, pool, user_uri).await?;
let inserted_private_message = blocking(pool, move |conn| {
PrivateMessage::create(conn, &private_message)
@ -161,22 +151,15 @@ async fn receive_update_private_message(
pool: &DbPool,
chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> {
let note = update
.update_props
.get_object_base_box()
.to_owned()
.unwrap()
.to_owned()
.into_concrete::<Note>()?;
let user_uri = update.update_props.get_actor_xsd_any_uri().unwrap();
let user_uri = &update.actor()?.to_owned().single_xsd_any_uri().unwrap();
let note = Note::from_any_base(update.object().as_one().unwrap().to_owned())?.unwrap();
let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?;
verify(request, &user)?;
insert_activity(user.id, update, false, pool).await?;
let private_message_form = PrivateMessageForm::from_apub(&note, client, pool).await?;
let private_message_form = PrivateMessageForm::from_apub(&note, client, pool, user_uri).await?;
let private_message_ap_id = private_message_form.ap_id.clone();
let private_message = blocking(pool, move |conn| {
@ -217,22 +200,15 @@ async fn receive_delete_private_message(
pool: &DbPool,
chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> {
let note = delete
.delete_props
.get_object_base_box()
.to_owned()
.unwrap()
.to_owned()
.into_concrete::<Note>()?;
let user_uri = delete.delete_props.get_actor_xsd_any_uri().unwrap();
let user_uri = &delete.actor()?.to_owned().single_xsd_any_uri().unwrap();
let note = Note::from_any_base(delete.object().as_one().unwrap().to_owned())?.unwrap();
let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?;
verify(request, &user)?;
insert_activity(user.id, delete, false, pool).await?;
let private_message_form = PrivateMessageForm::from_apub(&note, client, pool).await?;
let private_message_form = PrivateMessageForm::from_apub(&note, client, pool, user_uri).await?;
let private_message_ap_id = private_message_form.ap_id;
let private_message = blocking(pool, move |conn| {
@ -285,30 +261,16 @@ async fn receive_undo_delete_private_message(
pool: &DbPool,
chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> {
let delete = undo
.undo_props
.get_object_base_box()
.to_owned()
.unwrap()
.to_owned()
.into_concrete::<Delete>()?;
let note = delete
.delete_props
.get_object_base_box()
.to_owned()
.unwrap()
.to_owned()
.into_concrete::<Note>()?;
let user_uri = delete.delete_props.get_actor_xsd_any_uri().unwrap();
let delete = Delete::from_any_base(undo.object().as_one().unwrap().to_owned())?.unwrap();
let note = Note::from_any_base(delete.object().as_one().unwrap().to_owned())?.unwrap();
let user_uri = &delete.actor()?.to_owned().single_xsd_any_uri().unwrap();
let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?;
verify(request, &user)?;
insert_activity(user.id, delete, false, pool).await?;
let private_message = PrivateMessageForm::from_apub(&note, client, pool).await?;
let private_message = PrivateMessageForm::from_apub(&note, client, pool, user_uri).await?;
let private_message_ap_id = private_message.ap_id.clone();
let private_message_id = blocking(pool, move |conn| {